From 0039f452765b62d52ec4b058b71b0fff1b4ae08c Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Sat, 15 Jul 2023 12:42:56 +0100 Subject: [PATCH] vmm: Use LocalX2Apic in MADT/MAT Using this over the LocalApic supports APIC IDs (and hence number of vCPUs) above 256 (size increases from u8 to u32.) Signed-off-by: Rob Bradford --- vmm/src/acpi.rs | 2 +- vmm/src/cpu.rs | 31 +++++++++++++++++-------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index 075a6c613..eaecc0027 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -25,7 +25,7 @@ use zerocopy::AsBytes; /* Values for Type in APIC sub-headers */ #[cfg(target_arch = "x86_64")] -pub const ACPI_APIC_PROCESSOR: u8 = 0; +pub const ACPI_X2APIC_PROCESSOR: u8 = 9; #[cfg(target_arch = "x86_64")] pub const ACPI_APIC_IO: u8 = 1; #[cfg(target_arch = "x86_64")] diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 912ccb3bf..f2ec1410a 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -185,12 +185,13 @@ pub type Result = result::Result; #[allow(dead_code)] #[repr(packed)] #[derive(AsBytes)] -struct LocalApic { +struct LocalX2Apic { pub r#type: u8, pub length: u8, - pub processor_id: u8, - pub apic_id: u8, + pub _reserved: u16, + pub apic_id: u32, pub flags: u32, + pub processor_id: u32, } #[allow(dead_code)] @@ -1293,16 +1294,17 @@ impl CpuManager { madt.write(36, arch::layout::APIC_START.0); for cpu in 0..self.config.max_vcpus { - let lapic = LocalApic { - r#type: acpi::ACPI_APIC_PROCESSOR, - length: 8, - processor_id: cpu, - apic_id: cpu, + let lapic = LocalX2Apic { + r#type: acpi::ACPI_X2APIC_PROCESSOR, + length: 16, + processor_id: cpu.into(), + apic_id: cpu.into(), flags: if cpu < self.config.boot_vcpus { 1 << MADT_CPU_ENABLE_FLAG } else { 0 } | 1 << MADT_CPU_ONLINE_CAPABLE_FLAG, + _reserved: 0, }; madt.append(lapic); } @@ -1736,18 +1738,19 @@ const MADT_CPU_ONLINE_CAPABLE_FLAG: usize = 1; impl Cpu { #[cfg(target_arch = "x86_64")] fn generate_mat(&self) -> Vec { - let lapic = LocalApic { - r#type: 0, - length: 8, - processor_id: self.cpu_id, - apic_id: self.cpu_id, + let lapic = LocalX2Apic { + r#type: crate::acpi::ACPI_X2APIC_PROCESSOR, + length: 16, + processor_id: self.cpu_id.into(), + apic_id: self.cpu_id.into(), flags: 1 << MADT_CPU_ENABLE_FLAG, + _reserved: 0, }; let mut mat_data: Vec = Vec::new(); mat_data.resize(std::mem::size_of_val(&lapic), 0); // SAFETY: mat_data is large enough to hold lapic - unsafe { *(mat_data.as_mut_ptr() as *mut LocalApic) = lapic }; + unsafe { *(mat_data.as_mut_ptr() as *mut LocalX2Apic) = lapic }; mat_data }