Skip to content

Commit 915a344

Browse files
committed
Add vCPU hotplug controller and extend GED
Define new ACPI devices related to hotplugging, including a hotplug controller, a CPU container, and individual CPU devices. Add hotplugging devices to GED. Signed-off-by: James Curtis <[email protected]>
1 parent 5b8acb2 commit 915a344

File tree

7 files changed

+553
-17
lines changed

7 files changed

+553
-17
lines changed

src/vmm/src/acpi/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ pub mod tests {
186186
use crate::acpi::{AcpiError, AcpiTableWriter};
187187
use crate::arch::x86_64::layout::{SYSTEM_MEM_SIZE, SYSTEM_MEM_START};
188188
use crate::builder::tests::default_vmm;
189+
use crate::device_manager::mmio::MMIO_LEN;
189190
use crate::utilities::test_utils::arch_mem;
190191

191192
struct MockSdt(Vec<u8>);
@@ -263,7 +264,7 @@ pub mod tests {
263264
fn test_write_acpi_table_small_memory() {
264265
let mut vmm = default_vmm();
265266
vmm.guest_memory = arch_mem(
266-
(SYSTEM_MEM_START + SYSTEM_MEM_SIZE - 4096)
267+
(SYSTEM_MEM_START + SYSTEM_MEM_SIZE - 2 * MMIO_LEN)
267268
.try_into()
268269
.unwrap(),
269270
);
@@ -272,15 +273,18 @@ pub mod tests {
272273
resource_allocator: &mut vmm.resource_allocator,
273274
};
274275

275-
let mut sdt = MockSdt(vec![0; usize::try_from(SYSTEM_MEM_SIZE).unwrap()]);
276+
let mut sdt = MockSdt(vec![
277+
0;
278+
usize::try_from(SYSTEM_MEM_SIZE - MMIO_LEN).unwrap()
279+
]);
276280
let err = writer.write_acpi_table(&mut sdt).unwrap_err();
277281
assert!(
278282
matches!(
279-
err,
283+
&err,
280284
AcpiError::AcpiTables(acpi_tables::AcpiError::GuestMemory(
281285
vm_memory::GuestMemoryError::PartialBuffer {
282-
expected: 263168, // SYSTEM_MEM_SIZE
283-
completed: 259072 // SYSTEM_MEM_SIZE - 4096
286+
expected: 259072, // SYSTEM_MEM_SIZE - MMIO_LEN
287+
completed: 254976 // SYSTEM_MEM_SIZE - MMIO_LEN * 2
284288
},
285289
))
286290
),

src/vmm/src/builder.rs

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ use crate::device_manager::persist::{
4444
ACPIDeviceManagerConstructorArgs, ACPIDeviceManagerRestoreError, MMIODevManagerConstructorArgs,
4545
};
4646
use crate::device_manager::resources::ResourceAllocator;
47+
#[cfg(target_arch = "x86_64")]
48+
use crate::devices::acpi::cpu_container::{CpuContainer, CpuContainerError};
4749
use crate::devices::acpi::vmgenid::{VmGenId, VmGenIdError};
4850
use crate::devices::legacy::serial::SerialOut;
4951
#[cfg(target_arch = "aarch64")]
@@ -56,8 +58,6 @@ use crate::devices::virtio::mmio::MmioTransport;
5658
use crate::devices::virtio::net::Net;
5759
use crate::devices::virtio::rng::Entropy;
5860
use crate::devices::virtio::vsock::{Vsock, VsockUnixBackend};
59-
#[cfg(target_arch = "x86_64")]
60-
use crate::devices::BusDevice;
6161
use crate::logger::{debug, error};
6262
use crate::persist::{MicrovmState, MicrovmStateError};
6363
use crate::resources::VmResources;
@@ -77,6 +77,9 @@ pub enum StartMicrovmError {
7777
AttachBlockDevice(io::Error),
7878
/// Unable to attach the VMGenID device: {0}
7979
AttachVmgenidDevice(kvm_ioctls::Error),
80+
/// Unable to attach the CpuContainer device: {0}
81+
#[cfg(target_arch = "x86_64")]
82+
AttachCpuContainerDevice(kvm_ioctls::Error),
8083
/// System configuration error: {0}
8184
ConfigureSystem(crate::arch::ConfigurationError),
8285
/// Failed to create guest config: {0}
@@ -90,6 +93,9 @@ pub enum StartMicrovmError {
9093
CreateLegacyDevice(device_manager::legacy::LegacyDeviceError),
9194
/// Error creating VMGenID device: {0}
9295
CreateVMGenID(VmGenIdError),
96+
/// Error creating CpuContainer device: {0}
97+
#[cfg(target_arch = "x86_64")]
98+
CreateCpuContainer(#[from] CpuContainerError),
9399
/// Invalid Memory Configuration: {0}
94100
GuestMemory(crate::vstate::memory::MemoryError),
95101
/// Cannot load initrd due to an invalid memory configuration.
@@ -318,6 +324,9 @@ pub fn build_microvm_for_boot(
318324
attach_boot_timer_device(&mut vmm, request_ts)?;
319325
}
320326

327+
#[cfg(target_arch = "x86_64")]
328+
attach_cpu_container_device(&mut vmm, vm_resources.vm_config.vcpu_count)?;
329+
321330
if let Some(balloon) = vm_resources.balloon.get() {
322331
attach_balloon_device(&mut vmm, &mut boot_cmdline, balloon, event_manager)?;
323332
}
@@ -1012,6 +1021,18 @@ fn attach_balloon_device(
10121021
attach_virtio_device(event_manager, vmm, id, balloon.clone(), cmdline, false)
10131022
}
10141023

1024+
#[cfg(target_arch = "x86_64")]
1025+
fn attach_cpu_container_device(vmm: &mut Vmm, vcpu_count: u8) -> Result<(), StartMicrovmError> {
1026+
let cpu_container = Arc::new(Mutex::new(CpuContainer::new(
1027+
&mut vmm.resource_allocator,
1028+
vcpu_count,
1029+
)?));
1030+
vmm.acpi_device_manager
1031+
.attach_cpu_container(cpu_container, vmm.vm.fd())
1032+
.map_err(StartMicrovmError::AttachCpuContainerDevice)?;
1033+
Ok(())
1034+
}
1035+
10151036
// Adds `O_NONBLOCK` to the stdout flags.
10161037
pub(crate) fn set_stdout_nonblocking() {
10171038
// SAFETY: Call is safe since parameters are valid.
@@ -1036,6 +1057,8 @@ pub mod tests {
10361057
use super::*;
10371058
use crate::arch::DeviceType;
10381059
use crate::device_manager::resources::ResourceAllocator;
1060+
#[cfg(target_arch = "x86_64")]
1061+
use crate::devices::acpi::cpu_container::CpuContainer;
10391062
use crate::devices::virtio::block::CacheType;
10401063
use crate::devices::virtio::rng::device::ENTROPY_DEV_ID;
10411064
use crate::devices::virtio::vsock::{TYPE_VSOCK, VSOCK_DEV_ID};
@@ -1114,8 +1137,19 @@ pub mod tests {
11141137

11151138
let mut vm = Vm::new(vec![]).unwrap();
11161139
vm.memory_init(&guest_memory, false).unwrap();
1140+
1141+
#[cfg(target_arch = "x86_64")]
1142+
let mut resource_allocator = ResourceAllocator::new().unwrap();
1143+
#[cfg(target_arch = "aarch64")]
1144+
let resource_allocator = ResourceAllocator::new().unwrap();
1145+
11171146
let mmio_device_manager = MMIODeviceManager::new();
1147+
1148+
#[cfg(target_arch = "x86_64")]
1149+
let mut acpi_device_manager = ACPIDeviceManager::new();
1150+
#[cfg(target_arch = "aarch64")]
11181151
let acpi_device_manager = ACPIDeviceManager::new();
1152+
11191153
#[cfg(target_arch = "x86_64")]
11201154
let pio_device_manager = PortIODeviceManager::new(
11211155
Arc::new(Mutex::new(SerialWrapper {
@@ -1135,6 +1169,16 @@ pub mod tests {
11351169
#[cfg(target_arch = "x86_64")]
11361170
setup_interrupt_controller(&mut vm).unwrap();
11371171

1172+
#[cfg(target_arch = "x86_64")]
1173+
{
1174+
let cpu_container = Arc::new(Mutex::new(
1175+
CpuContainer::new(&mut resource_allocator, 1).unwrap(),
1176+
));
1177+
acpi_device_manager
1178+
.attach_cpu_container(cpu_container, vm.fd())
1179+
.unwrap();
1180+
}
1181+
11381182
#[cfg(target_arch = "aarch64")]
11391183
{
11401184
let exit_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
@@ -1153,7 +1197,7 @@ pub mod tests {
11531197
vcpus_exit_evt,
11541198
#[cfg(target_arch = "x86_64")]
11551199
seccomp_filters: crate::seccomp_filters::get_empty_filters(),
1156-
resource_allocator: ResourceAllocator::new().unwrap(),
1200+
resource_allocator,
11571201
mmio_device_manager,
11581202
#[cfg(target_arch = "x86_64")]
11591203
pio_device_manager,
@@ -1515,8 +1559,8 @@ pub mod tests {
15151559
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
15161560
assert!(cmdline_contains(
15171561
&cmdline,
1518-
"virtio_mmio.device=4K@0xd0000000:5 virtio_mmio.device=4K@0xd0001000:6 \
1519-
virtio_mmio.device=4K@0xd0002000:7"
1562+
"virtio_mmio.device=4K@0xd0001000:6 virtio_mmio.device=4K@0xd0002000:7 \
1563+
virtio_mmio.device=4K@0xd0003000:8"
15201564
));
15211565
}
15221566

@@ -1611,7 +1655,7 @@ pub mod tests {
16111655
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
16121656
assert!(cmdline_contains(
16131657
&cmdline,
1614-
"virtio_mmio.device=4K@0xd0000000:5"
1658+
"virtio_mmio.device=4K@0xd0001000:6"
16151659
));
16161660
}
16171661

@@ -1628,7 +1672,7 @@ pub mod tests {
16281672
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
16291673
assert!(cmdline_contains(
16301674
&cmdline,
1631-
"virtio_mmio.device=4K@0xd0000000:5"
1675+
"virtio_mmio.device=4K@0xd0001000:6"
16321676
));
16331677
}
16341678

@@ -1647,7 +1691,7 @@ pub mod tests {
16471691
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
16481692
assert!(cmdline_contains(
16491693
&cmdline,
1650-
"virtio_mmio.device=4K@0xd0000000:5"
1694+
"virtio_mmio.device=4K@0xd0001000:6"
16511695
));
16521696
}
16531697
}

0 commit comments

Comments
 (0)