mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 20:48:55 +00:00
acpi: event listener: ignore events for direct GPEs
Ignore ACPI netlink events for GPEs which are configured as direct GPEs. Such GPEs are forwarded to the guest directly as physical GPEs using eventfd based forwarding of physical SCI interrupts (which ensures that the GPE handling in the guest is synchronized with SCI interrupt context in the host). Forwarding via netlink should be used for emulated GPEs only. With this change, we are still propagating all GPE events received by the host to the guest. In the future we may need to enhance this logic, since for some types of GPEs we may not want to inject them to the guest at all, e.g. for Thunderbolt hotplug GPE we want to receive it in crosvm and then inject a normal PCI hotplug interrupt instead. BUG=b:197247746, b:205072342 TEST=Make sure that GPE marked as direct are ignored Change-Id: Id5b05a99951455f52dcb375289cb10d040e8ff7f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3492225 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Tomasz Nowicki <tnowicki@google.com>
This commit is contained in:
parent
3323fc3530
commit
ab50403924
1 changed files with 21 additions and 3 deletions
|
@ -130,6 +130,14 @@ impl ACPIPMResource {
|
|||
None
|
||||
};
|
||||
|
||||
#[cfg(feature = "direct")]
|
||||
// Direct GPEs are forwarded via direct SCI forwarding,
|
||||
// not via ACPI netlink events.
|
||||
let acpi_event_ignored_gpe = self.direct_gpe.iter().map(|gpe| gpe.num).collect();
|
||||
|
||||
#[cfg(not(feature = "direct"))]
|
||||
let acpi_event_ignored_gpe = Vec::new();
|
||||
|
||||
let worker_result = thread::Builder::new()
|
||||
.name("ACPI PM worker".to_string())
|
||||
.spawn(move || {
|
||||
|
@ -139,6 +147,7 @@ impl ACPIPMResource {
|
|||
sci_evt,
|
||||
pm1,
|
||||
gpe0,
|
||||
acpi_event_ignored_gpe,
|
||||
#[cfg(feature = "direct")]
|
||||
sci_direct_evt,
|
||||
) {
|
||||
|
@ -159,6 +168,7 @@ fn run_worker(
|
|||
sci_evt: Event,
|
||||
pm1: Arc<Mutex<Pm1Resource>>,
|
||||
gpe0: Arc<Mutex<GpeResource>>,
|
||||
acpi_event_ignored_gpe: Vec<u32>,
|
||||
#[cfg(feature = "direct")] sci_direct_evt: Option<(Event, Event)>,
|
||||
) -> Result<(), ACPIPMError> {
|
||||
// Get group id corresponding to acpi_mc_group of acpi_event family
|
||||
|
@ -211,7 +221,7 @@ fn run_worker(
|
|||
for event in events.iter().filter(|e| e.is_readable) {
|
||||
match event.token {
|
||||
Token::AcpiEvent => {
|
||||
acpi_event_run(&acpi_event_sock, &gpe0, &sci_evt);
|
||||
acpi_event_run(&acpi_event_sock, &gpe0, &sci_evt, &acpi_event_ignored_gpe);
|
||||
}
|
||||
Token::InterruptResample => {
|
||||
let _ = sci_resample.read();
|
||||
|
@ -249,9 +259,10 @@ fn acpi_event_gpe_class(
|
|||
_type: u32,
|
||||
gpe0: &Arc<Mutex<GpeResource>>,
|
||||
sci_evt: &Event,
|
||||
ignored_gpe: &[u32],
|
||||
) {
|
||||
// If gpe event, emulate GPE and trigger SCI
|
||||
if _type == 0 && gpe_number < 256 {
|
||||
if _type == 0 && gpe_number < 256 && !ignored_gpe.contains(&gpe_number) {
|
||||
let mut gpe0 = gpe0.lock();
|
||||
let byte = gpe_number as usize / 8;
|
||||
|
||||
|
@ -278,6 +289,7 @@ fn acpi_event_run(
|
|||
acpi_event_sock: &NetlinkGenericSocket,
|
||||
gpe0: &Arc<Mutex<GpeResource>>,
|
||||
sci_evt: &Event,
|
||||
ignored_gpe: &[u32],
|
||||
) {
|
||||
let nl_msg = match acpi_event_sock.recv() {
|
||||
Ok(msg) => msg,
|
||||
|
@ -297,7 +309,13 @@ fn acpi_event_run(
|
|||
};
|
||||
match acpi_event.device_class.as_str() {
|
||||
"gpe" => {
|
||||
acpi_event_gpe_class(acpi_event.data, acpi_event._type, gpe0, sci_evt);
|
||||
acpi_event_gpe_class(
|
||||
acpi_event.data,
|
||||
acpi_event._type,
|
||||
gpe0,
|
||||
sci_evt,
|
||||
ignored_gpe,
|
||||
);
|
||||
}
|
||||
c => warn!("unknown acpi event {}", c),
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue