diff --git a/devices/src/pci/acpi.rs b/devices/src/pci/acpi.rs index d969634e47..bcb5f166df 100644 --- a/devices/src/pci/acpi.rs +++ b/devices/src/pci/acpi.rs @@ -45,6 +45,14 @@ impl Aml for DeviceVcfgRegister { &4096_usize, ) .to_aml_bytes(bytes); + aml::Field::new( + "VREG".into(), + aml::FieldAccessType::DWord, + aml::FieldLockRule::Lock, + aml::FieldUpdateRule::Preserve, + vec![aml::FieldEntry::Named(*b"PFPM", 32)], + ) + .to_aml_bytes(bytes); aml::OpRegion::new( "SHAM".into(), aml::OpRegionSpace::SystemMemory, @@ -58,3 +66,47 @@ impl Aml for DeviceVcfgRegister { .to_aml_bytes(bytes); } } + +pub struct PowerResourceMethod {} + +impl Aml for PowerResourceMethod { + fn to_aml_bytes(&self, aml: &mut Vec) { + aml::PowerResource::new( + "PRIC".into(), + 0u8, + 0u16, + vec![ + &aml::Name::new("_STA".into(), &aml::ONE), + &aml::Method::new( + "_ON_".into(), + 0, + true, + vec![ + &aml::Store::new(&aml::Name::new_field_name("PFPM"), &aml::ONE), + &aml::Store::new(&aml::Name::new_field_name("_STA"), &aml::ONE), + ], + ), + &aml::Method::new( + "_OFF".into(), + 0, + true, + vec![ + &aml::Store::new(&aml::Name::new_field_name("_STA"), &aml::ZERO), + &aml::Store::new(&aml::Name::new_field_name("PFPM"), &aml::ZERO), + ], + ), + ], + ) + .to_aml_bytes(aml); + aml::Name::new( + "_PR0".into(), + &aml::Package::new(vec![&aml::Name::new_field_name("PRIC")]), + ) + .to_aml_bytes(aml); + aml::Name::new( + "_PR3".into(), + &aml::Package::new(vec![&aml::Name::new_field_name("PRIC")]), + ) + .to_aml_bytes(aml); + } +} diff --git a/devices/src/pci/mod.rs b/devices/src/pci/mod.rs index 3944c315c1..8c52b77b1b 100644 --- a/devices/src/pci/mod.rs +++ b/devices/src/pci/mod.rs @@ -42,6 +42,7 @@ pub use self::ac97::Ac97Dev; #[cfg(all(unix, feature = "audio"))] pub use self::ac97::Ac97Parameters; pub use self::acpi::DeviceVcfgRegister; +pub use self::acpi::PowerResourceMethod; #[cfg(unix)] pub use self::coiommu::CoIommuDev; #[cfg(unix)] diff --git a/devices/src/pci/vfio_pci.rs b/devices/src/pci/vfio_pci.rs index 7ab97a56f8..31831b8ce0 100644 --- a/devices/src/pci/vfio_pci.rs +++ b/devices/src/pci/vfio_pci.rs @@ -51,6 +51,7 @@ use vm_control::VmRequest; use vm_control::VmResponse; use crate::pci::acpi::DeviceVcfgRegister; +use crate::pci::acpi::PowerResourceMethod; use crate::pci::acpi::SHM_OFFSET; use crate::pci::msi::MsiConfig; use crate::pci::msi::MsiStatus; @@ -2159,6 +2160,11 @@ impl PciDevice for VfioPciDevice { .create_shm_mmap() .map(|shm| (vcfg_offset + SHM_OFFSET, shm)); self.vcfg_shm_mmap = vcfg_register.create_shm_mmap(); + // All vfio-pci devices should have virtual _PRx method, otherwise + // host couldn't know whether device has enter into suspend state, + // host would always think it is in active state, so its parent PCIe + // switch couldn't enter into suspend state. + PowerResourceMethod {}.to_aml_bytes(&mut amls); } }