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 <rbradford@rivosinc.com>
This commit is contained in:
Rob Bradford 2023-07-15 12:42:56 +01:00 committed by Bo Chen
parent b792d4751d
commit 0039f45276
2 changed files with 18 additions and 15 deletions

View File

@ -25,7 +25,7 @@ use zerocopy::AsBytes;
/* Values for Type in APIC sub-headers */ /* Values for Type in APIC sub-headers */
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub const ACPI_APIC_PROCESSOR: u8 = 0; pub const ACPI_X2APIC_PROCESSOR: u8 = 9;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub const ACPI_APIC_IO: u8 = 1; pub const ACPI_APIC_IO: u8 = 1;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]

View File

@ -185,12 +185,13 @@ pub type Result<T> = result::Result<T, Error>;
#[allow(dead_code)] #[allow(dead_code)]
#[repr(packed)] #[repr(packed)]
#[derive(AsBytes)] #[derive(AsBytes)]
struct LocalApic { struct LocalX2Apic {
pub r#type: u8, pub r#type: u8,
pub length: u8, pub length: u8,
pub processor_id: u8, pub _reserved: u16,
pub apic_id: u8, pub apic_id: u32,
pub flags: u32, pub flags: u32,
pub processor_id: u32,
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -1293,16 +1294,17 @@ impl CpuManager {
madt.write(36, arch::layout::APIC_START.0); madt.write(36, arch::layout::APIC_START.0);
for cpu in 0..self.config.max_vcpus { for cpu in 0..self.config.max_vcpus {
let lapic = LocalApic { let lapic = LocalX2Apic {
r#type: acpi::ACPI_APIC_PROCESSOR, r#type: acpi::ACPI_X2APIC_PROCESSOR,
length: 8, length: 16,
processor_id: cpu, processor_id: cpu.into(),
apic_id: cpu, apic_id: cpu.into(),
flags: if cpu < self.config.boot_vcpus { flags: if cpu < self.config.boot_vcpus {
1 << MADT_CPU_ENABLE_FLAG 1 << MADT_CPU_ENABLE_FLAG
} else { } else {
0 0
} | 1 << MADT_CPU_ONLINE_CAPABLE_FLAG, } | 1 << MADT_CPU_ONLINE_CAPABLE_FLAG,
_reserved: 0,
}; };
madt.append(lapic); madt.append(lapic);
} }
@ -1736,18 +1738,19 @@ const MADT_CPU_ONLINE_CAPABLE_FLAG: usize = 1;
impl Cpu { impl Cpu {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn generate_mat(&self) -> Vec<u8> { fn generate_mat(&self) -> Vec<u8> {
let lapic = LocalApic { let lapic = LocalX2Apic {
r#type: 0, r#type: crate::acpi::ACPI_X2APIC_PROCESSOR,
length: 8, length: 16,
processor_id: self.cpu_id, processor_id: self.cpu_id.into(),
apic_id: self.cpu_id, apic_id: self.cpu_id.into(),
flags: 1 << MADT_CPU_ENABLE_FLAG, flags: 1 << MADT_CPU_ENABLE_FLAG,
_reserved: 0,
}; };
let mut mat_data: Vec<u8> = Vec::new(); let mut mat_data: Vec<u8> = Vec::new();
mat_data.resize(std::mem::size_of_val(&lapic), 0); mat_data.resize(std::mem::size_of_val(&lapic), 0);
// SAFETY: mat_data is large enough to hold lapic // 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 mat_data
} }