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 <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2019-11-25 15:13:46 +00:00
parent 4bc8635c59
commit 1bbe48b24c
2 changed files with 15 additions and 4 deletions

View File

@ -355,9 +355,11 @@ pub fn create_dsdt_table(
dsdt dsdt
} }
pub fn create_acpi_tables( pub fn create_acpi_tables(
guest_mem: &GuestMemoryMmap, guest_mem: &GuestMemoryMmap,
num_cpus: u8, boot_vcpus: u8,
max_vcpus: u8,
serial_enabled: bool, serial_enabled: bool,
start_of_device_area: GuestAddress, start_of_device_area: GuestAddress,
end_of_device_area: GuestAddress, end_of_device_area: GuestAddress,
@ -372,7 +374,7 @@ pub fn create_acpi_tables(
serial_enabled, serial_enabled,
start_of_device_area, start_of_device_area,
end_of_device_area, end_of_device_area,
num_cpus, boot_vcpus,
); );
let dsdt_offset = rsdp_offset.checked_add(RSDP::len() as u64).unwrap(); let dsdt_offset = rsdp_offset.checked_add(RSDP::len() as u64).unwrap();
guest_mem 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); let mut madt = SDT::new(*b"APIC", 44, 5, *b"CLOUDH", *b"CHMADT ", 1);
madt.write(36, layout::APIC_START); 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 { let lapic = LocalAPIC {
r#type: 0, r#type: 0,
length: 8, length: 8,
processor_id: cpu, processor_id: cpu,
apic_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); madt.append(lapic);
} }

View File

@ -513,6 +513,7 @@ impl Vm {
) )
.map_err(|_| Error::CmdLine)?; .map_err(|_| Error::CmdLine)?;
let boot_vcpus = self.cpu_manager.lock().unwrap().boot_vcpus(); 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)] #[allow(unused_mut, unused_assignments)]
let mut rsdp_addr: Option<GuestAddress> = None; let mut rsdp_addr: Option<GuestAddress> = None;
@ -533,6 +534,7 @@ impl Vm {
crate::acpi::create_acpi_tables( crate::acpi::create_acpi_tables(
&mem, &mem,
boot_vcpus, boot_vcpus,
max_vcpus,
self.config.serial.mode != ConsoleOutputMode::Off, self.config.serial.mode != ConsoleOutputMode::Off,
start_of_device_area, start_of_device_area,
end_of_range, end_of_range,