From 5faf8b756c39dea3cf6aea8b63b5be4c5fc081b4 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Wed, 20 Nov 2019 13:39:16 +0000 Subject: [PATCH] vmm: acpi: Add an _MAT for the CPU devices containing a LAPIC The Linux kernel expects all CPUs, whether they be enabled or disabled to have an _MAT entry containing the LAPIC details for this CPU with the enabled bit set to 1 (in the flags.) In the MADT table the same bit is used to determine if the CPU is present at boot vs available later. Signed-off-by: Rob Bradford --- vmm/src/acpi.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index 40ee93ca0..a22c7b027 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -113,8 +113,22 @@ struct CPU { present: bool, } +const MADT_CPU_ENABLE_FLAG: usize = 0; + impl aml::Aml for CPU { fn to_aml_bytes(&self) -> Vec { + let lapic = LocalAPIC { + r#type: 0, + length: 8, + processor_id: self.cpu_id, + apic_id: self.cpu_id, + flags: 1 << MADT_CPU_ENABLE_FLAG, + }; + + let mut mat_data: Vec = Vec::new(); + mat_data.resize(std::mem::size_of_val(&lapic), 0); + unsafe { *(mat_data.as_mut_ptr() as *mut LocalAPIC) = lapic }; + aml::Device::new( format!("C{:03}", self.cpu_id).as_str().into(), vec![ @@ -139,6 +153,10 @@ impl aml::Aml for CPU { &aml::ZERO })], ), + // The Linux kernel expects every CPU device to have a _MAT entry + // containing the LAPIC for this processor with the enabled bit set + // even it if is disabled in the MADT (non-boot CPU) + &aml::Name::new("_MAT".into(), &aml::Buffer::new(mat_data)) ], ) .to_aml_bytes() @@ -322,7 +340,7 @@ pub fn create_acpi_tables( length: 8, processor_id: cpu, apic_id: cpu, - flags: 1, + flags: 1 << MADT_CPU_ENABLE_FLAG, }; madt.append(lapic); }