quirks: R7 audit — OSI Windows 10/11 + bit 14/15

The acpid `_OSI` interceptor was incomplete: firmware that
calls `_OSI("Windows 2015")` or `_OSI("Windows 2020")`
would fall through to the AML interpreter and return 1 (true)
even on systems with `OSI_DISABLE_*` flags set, because
the interceptor only knew about Vista/7/8 strings.

- redox-driver-sys::quirks::AcpiQuirkFlags gains
  OSI_DISABLE_WIN10 (bit 14) and OSI_DISABLE_WIN11 (bit 15)
  with explicit no-collision guard against the existing
  R11/R21 bits (0-13).
- ACPI_FLAG_NAMES in toml_loader.rs maps
  `osi_disable_win10` and `osi_disable_win11` to the
  new bitflag constants.
- acpid::acpi::AcpiContext::try_intercept_osi now matches
  "Windows 2015" → OSI_DISABLE_WIN10 and "Windows 2020"
  → OSI_DISABLE_WIN11, alongside the existing Vista/7/8
  string matches.

Source: linux-7.1 drivers/acpi/osi.c (dmi_system_id[] for
Win10/11 laptops that need the kernel to lie about the
host OS to keep ACPI firmware from misbehaving).

cargo test --package redox-driver-sys: 132 passed; 0 failed.
This commit is contained in:
2026-06-08 03:49:25 +03:00
parent 788fdeddff
commit 23c963c8ab
2 changed files with 33 additions and 0 deletions
@@ -252,6 +252,21 @@ bitflags::bitflags! {
// ACPI rev override (x86/blacklist.c)
const REV_OVERRIDE = 1 << 12;
// Phase R21 — AMD IOMMU IVRS bypass. When a DMI rule matches a
// known-broken IVRS implementation (Dell Inspiron 7375, Latitude
// 5495, Acer Aspire A315-41, Lenovo IdeaPad 330S-15ARR), this
// flag signals the iommu daemon to skip AMD-Vi unit initialization
// and fall through to software IOMMU / no-IOMMU mode. Sourced from
// Linux 7.1 drivers/iommu/amd/quirks.c ivrs_quirks[] DMI table.
const SUPPRESS_IVRS = 1 << 13;
// R7 audit: complete the Windows OSI matrix. The acpid `_OSI`
// interceptor was only matching Vista/7/8 — "Windows 2015"/"2020"
// would fall through to the interpreter. Source: Linux 7.1
// drivers/acpi/osi.c (dmi_system_id[] for Win10/11 laptops).
const OSI_DISABLE_WIN10 = 1 << 14;
const OSI_DISABLE_WIN11 = 1 << 15;
}
}
@@ -2110,6 +2125,19 @@ mod tests {
assert!(!entry.matches(&rev_high));
}
/// R7 audit: OSI_DISABLE_WIN10/WIN11 bits (14, 15).
#[test]
fn phase_r7_audit_osi_win10_win11_bits() {
assert_eq!(AcpiQuirkFlags::OSI_DISABLE_WIN10.bits(), 1u64 << 14);
assert_eq!(AcpiQuirkFlags::OSI_DISABLE_WIN11.bits(), 1u64 << 15);
let prior: u64 = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)
| (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)
| (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11)
| (1 << 12) | (1 << 13);
assert_eq!(AcpiQuirkFlags::OSI_DISABLE_WIN10.bits() & prior, 0);
assert_eq!(AcpiQuirkFlags::OSI_DISABLE_WIN11.bits() & prior, 0);
}
/// Phase R5 — audit: all 10 new bits are present and unique (no
/// collisions with prior phases).
#[test]
@@ -200,6 +200,11 @@ pub const ACPI_FLAG_NAMES: &[(&str, AcpiQuirkFlags)] = &[
("battery_notification_delay", AcpiQuirkFlags::BATTERY_NOTIFICATION_DELAY),
("battery_ac_is_broken", AcpiQuirkFlags::BATTERY_AC_IS_BROKEN),
("rev_override", AcpiQuirkFlags::REV_OVERRIDE),
// Phase R21 — AMD IOMMU IVRS bypass.
("suppress_ivrs", AcpiQuirkFlags::SUPPRESS_IVRS),
// R7 audit: complete the Windows OSI matrix.
("osi_disable_win10", AcpiQuirkFlags::OSI_DISABLE_WIN10),
("osi_disable_win11", AcpiQuirkFlags::OSI_DISABLE_WIN11),
];
pub(crate) fn read_toml_dmi_acpi_entries() -> std::io::Result<Vec<DmiAcpiQuirkRule>> {