x86_64: acpi: support for assigning physical GPEs

Wire up GPE eventfd forwarding and crosvm's GPE emulation.

This patch allows to provide ACPIPMResource with the list of GPEs
which should work as direct physical (passthrough) GPEs rather than
purely emulated ones.

BUG=b:205072342
TEST=see CL:3492224

Change-Id: Idb8ef36299c793f56d73246d15ff89f495bb30ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3492223
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Tomasz Nowicki <tnowicki@google.com>
This commit is contained in:
Dmytro Maluka 2022-02-25 18:00:17 +00:00 committed by Commit Bot
parent e6fb841b3f
commit 74031b483f
5 changed files with 43 additions and 3 deletions

View file

@ -115,7 +115,7 @@ chromeos = ["base/chromeos", "audio_cras", "devices/chromeos"]
composite-disk = ["protos/composite-disk", "protobuf", "disk/composite-disk"]
default = ["audio", "gpu", "usb"]
default-no-sandbox = []
direct = ["devices/direct", "x86_64/direct"]
direct = ["devices/direct", "arch/direct", "x86_64/direct"]
gdb = ["gdbstub", "gdbstub_arch", "arch/gdb", "vm_control/gdb", "x86_64/gdb"]
gfxstream = ["devices/gfxstream"]
gpu = ["devices/gpu"]

View file

@ -7,6 +7,7 @@ edition = "2021"
[features]
power-monitor-powerd = ["power_monitor/powerd"]
gdb = ["gdbstub_arch"]
direct = []
[dependencies]
acpi_tables = { path = "../acpi_tables" }

View file

@ -101,6 +101,8 @@ pub struct VmComponents {
pub host_cpu_topology: bool,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub force_s2idle: bool,
#[cfg(feature = "direct")]
pub direct_gpe: Vec<u32>,
}
/// Holds the elements needed to run a Linux VM. Created by `build_vm`.

View file

@ -835,6 +835,8 @@ fn setup_vm_components(cfg: &Config) -> Result<VmComponents> {
vcpu_affinity: cfg.vcpu_affinity.clone(),
cpu_clusters: cfg.cpu_clusters.clone(),
cpu_capacity: cfg.cpu_capacity.clone(),
#[cfg(feature = "direct")]
direct_gpe: Vec::new(),
no_smt: cfg.no_smt,
hugepages: cfg.hugepages,
vm_image,

View file

@ -102,6 +102,9 @@ pub enum Error {
CreateEvent(base::Error),
#[error("failed to create fdt: {0}")]
CreateFdt(arch::fdt::Error),
#[cfg(feature = "direct")]
#[error("failed to enable GPE forwarding: {0}")]
CreateGpe(devices::DirectIrqError),
#[error("failed to create IOAPIC device: {0}")]
CreateIoapicDevice(base::Error),
#[error("failed to create a PCI root hub: {0}")]
@ -536,6 +539,8 @@ impl arch::LinuxArch for X8664arch {
suspend_evt.try_clone().map_err(Error::CloneEvent)?,
exit_evt.try_clone().map_err(Error::CloneEvent)?,
components.acpi_sdts,
#[cfg(feature = "direct")]
components.direct_gpe,
irq_chip.as_irq_chip_mut(),
sci_irq,
battery,
@ -1268,6 +1273,7 @@ impl X8664arch {
suspend_evt: Event,
exit_evt: Event,
sdts: Vec<SDT>,
#[cfg(feature = "direct")] direct_gpe: Vec<u32>,
irq_chip: &mut dyn IrqChip,
sci_irq: u32,
battery: (&Option<BatteryType>, Option<Minijail>),
@ -1299,13 +1305,42 @@ impl X8664arch {
irq_chip
.register_irq_event(sci_irq, &pm_sci_evt, Some(&pm_sci_evt_resample))
.map_err(Error::RegisterIrqfd)?;
#[cfg(feature = "direct")]
let sci_direct = if direct_gpe.is_empty() {
None
} else {
let direct_sci_evt = Event::new().map_err(Error::CreateEvent)?;
let direct_sci_evt_resample = Event::new().map_err(Error::CreateEvent)?;
let mut sci_devirq = devices::DirectIrq::new(
direct_sci_evt.try_clone().map_err(Error::CloneEvent)?,
Some(
direct_sci_evt_resample
.try_clone()
.map_err(Error::CloneEvent)?,
),
)
.map_err(Error::CreateGpe)?;
sci_devirq.sci_irq_prepare().map_err(Error::CreateGpe)?;
for gpe in &direct_gpe {
sci_devirq
.gpe_enable_forwarding(*gpe)
.map_err(Error::CreateGpe)?;
}
Some((direct_sci_evt, direct_sci_evt_resample))
};
let mut pmresource = devices::ACPIPMResource::new(
pm_sci_evt,
pm_sci_evt_resample,
#[cfg(feature = "direct")]
None,
sci_direct,
#[cfg(feature = "direct")]
Vec::new(),
direct_gpe,
suspend_evt,
exit_evt,
);