From e8313e3e6943170efe19a45a1f62e2aefe0c89cb Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Mon, 16 Dec 2019 16:09:24 +0000 Subject: [PATCH] vmm: acpi: Refactor ACPI CPU notification Continue to notify on all vCPUs but instead separate the notification functionality into two methods, CSCN that walks through all the CPUs and CTFY which notifies based on the numerical CPU id. This is an interim step towards only notifying on changed CPUs and ultimately CPU removal. Signed-off-by: Rob Bradford --- vmm/src/cpu.rs | 53 ++++++++++++++++++++++++++++++--------- vmm/src/device_manager.rs | 2 +- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 245461141..40066e124 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -740,6 +740,22 @@ impl Aml for CPU { } } +struct CPUNotify { + cpu_id: u8, +} + +#[cfg(feature = "acpi")] +impl Aml for CPUNotify { + fn to_aml_bytes(&self) -> Vec { + let object = aml::Path::new(&format!("C{:03}", self.cpu_id)); + aml::If::new( + &aml::Equal::new(&aml::Arg(0), &self.cpu_id), + vec![&aml::Notify::new(&object, &aml::Arg(1))], + ) + .to_aml_bytes() + } +} + struct CPUMethods { max_vcpus: u8, } @@ -774,24 +790,37 @@ impl Aml for CPUMethods { .to_aml_bytes(), ); - let mut paths = Vec::new(); + let mut cpu_notifies = Vec::new(); for cpu_id in 0..self.max_vcpus { - paths.push(aml::Path::new(format!("C{:03}", cpu_id).as_str())) - } - let mut notify_methods = Vec::new(); - - for cpu_id in 0..self.max_vcpus { - notify_methods.push(aml::Notify::new(&paths[usize::from(cpu_id)], &aml::ONE)); + cpu_notifies.push(CPUNotify { cpu_id }); } - let mut notify_methods_inner: Vec<&dyn aml::Aml> = Vec::new(); - for notify_method in notify_methods.iter() { - notify_methods_inner.push(notify_method); + let mut cpu_notifies_refs: Vec<&dyn aml::Aml> = Vec::new(); + for cpu_id in 0..self.max_vcpus { + cpu_notifies_refs.push(&cpu_notifies[usize::from(cpu_id)]); } bytes.extend_from_slice( - // Notify all vCPUs - &aml::Method::new("CTFY".into(), 0, true, notify_methods_inner).to_aml_bytes(), + &aml::Method::new("CTFY".into(), 2, true, cpu_notifies_refs).to_aml_bytes(), + ); + + bytes.extend_from_slice( + &aml::Method::new( + "CSCN".into(), + 0, + true, + vec![ + &aml::Store::new(&aml::Local(0), &aml::ZERO), + &aml::While::new( + &aml::LessThan::new(&aml::Local(0), &self.max_vcpus), + vec![ + &aml::MethodCall::new("CTFY".into(), vec![&aml::Local(0), &aml::ONE]), + &aml::Add::new(&aml::Local(0), &aml::Local(0), &aml::ONE), + ], + ), + ], + ) + .to_aml_bytes(), ); bytes } diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index d425b6465..cecbb5fd4 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1685,7 +1685,7 @@ fn create_ged_device(ged_irq: u32) -> Vec { true, vec![&aml::If::new( &aml::Equal::new(&aml::Path::new("GDAT"), &aml::ONE), - vec![&aml::MethodCall::new("\\_SB_.CPUS.CTFY".into(), vec![])], + vec![&aml::MethodCall::new("\\_SB_.CPUS.CSCN".into(), vec![])], )], ), ],