From 1bbe48b24c381ee22e9c04979bed1c8dc3df15a4 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Mon, 25 Nov 2019 15:13:46 +0000 Subject: [PATCH] vmm: acpi: Mark non-boot vCPUs as disabled in the MADT table The MADT table contains the details of all the potential vCPUs and whether they are present at boot (as indicated by the flags field.) Signed-off-by: Rob Bradford --- vmm/src/acpi.rs | 17 +++++++++++++---- vmm/src/vm.rs | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index 973d24daf..ec47331e1 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -355,9 +355,11 @@ pub fn create_dsdt_table( dsdt } + pub fn create_acpi_tables( guest_mem: &GuestMemoryMmap, - num_cpus: u8, + boot_vcpus: u8, + max_vcpus: u8, serial_enabled: bool, start_of_device_area: GuestAddress, end_of_device_area: GuestAddress, @@ -372,7 +374,7 @@ pub fn create_acpi_tables( serial_enabled, start_of_device_area, end_of_device_area, - num_cpus, + boot_vcpus, ); let dsdt_offset = rsdp_offset.checked_add(RSDP::len() as u64).unwrap(); guest_mem @@ -413,13 +415,20 @@ pub fn create_acpi_tables( let mut madt = SDT::new(*b"APIC", 44, 5, *b"CLOUDH", *b"CHMADT ", 1); madt.write(36, layout::APIC_START); - for cpu in 0..num_cpus { + // This is also checked in the commandline parsing. + assert!(boot_vcpus <= max_vcpus); + + for cpu in 0..max_vcpus { let lapic = LocalAPIC { r#type: 0, length: 8, processor_id: cpu, apic_id: cpu, - flags: 1 << MADT_CPU_ENABLE_FLAG, + flags: if cpu < boot_vcpus { + 1 << MADT_CPU_ENABLE_FLAG + } else { + 0 + }, }; madt.append(lapic); } diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 8571803d4..6ee88c11b 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -513,6 +513,7 @@ impl Vm { ) .map_err(|_| Error::CmdLine)?; let boot_vcpus = self.cpu_manager.lock().unwrap().boot_vcpus(); + let max_vcpus = self.cpu_manager.lock().unwrap().max_vcpus(); #[allow(unused_mut, unused_assignments)] let mut rsdp_addr: Option = None; @@ -533,6 +534,7 @@ impl Vm { crate::acpi::create_acpi_tables( &mem, boot_vcpus, + max_vcpus, self.config.serial.mode != ConsoleOutputMode::Off, start_of_device_area, end_of_range,