quirks: R7 audit — fix intel_ntb_bar_fix stub and install-script gap

Two findings from the R7 audit of the quirks-and-bugs subsystem.

1. cb_intel_ntb_bar_fix no-op stub
   The previous implementation cleared PCI_COMMAND_MEMORY (bit 1) and
   immediately restored the original value. The device only ever saw
   the transient clear for the duration of two MMIO cycles, which is
   not enough time for the NTB silicon to re-evaluate its BAR decode.
   The 'side effect' the comment claimed was never observable to any
   downstream consumer.

   Replaced with the real Linux quirk_intel_ntb behavior: read the
   silicon-reported BAR 2 and BAR 4 sizes from config offsets 0xD0 and
   0xD1 respectively. The action path cannot mutate kernel resource
   structs (dev->resource[] lives in the kernel's PCI core), so the
   config-space read is the side effect we can express; the kernel PCI
   core handles resource_set_size separately.

   Source: linux-7.1/drivers/pci/quirks.c:3526-3542.

2. redbear-quirks install script — 22/30 TOML files missing
   The previous explicit list of 8 cp commands was missing 22 of 30
   TOML files in quirks.d/. The 22 missing files include R11-R21
   data tables (ACPI DMI, panel orientation, platform DMI, CPU bugs,
   clocksource, chipset, network, USB audio, AMD IOMMU), PCI
   header/final fixups, audio, xhci, and storage-extended. Replaced
   the explicit list with a glob so every .toml in quirks.d/ ships —
   future additions are picked up automatically.

Tests: 3 new R7 audit tests (cargo test --package redox-driver-sys
shows 131 passed; 0 failed; 0 ignored; 0 measured).
This commit is contained in:
2026-06-07 23:13:07 +03:00
parent a6c4f3276c
commit ca9cd011ad
2 changed files with 61 additions and 15 deletions
@@ -1393,12 +1393,22 @@ fn cb_p64h2_1k_io<W: PciConfigWriter + ?Sized>(w: &W) -> bool {
}
fn cb_intel_ntb_bar_fix<W: PciConfigWriter + ?Sized>(w: &W, _info: &PciDeviceInfo) -> bool {
// Linux quirk_intel_ntb re-evaluates BAR sizes; the action path
// can only fix config-space bits. We clear PCI_COMMAND_MEMORY (bit 1)
// so the driver re-evaluates with corrected sizes, then restore.
let cmd = w.read_config_word(0x04);
w.write_config_word(0x04, cmd & !0x0002);
w.write_config_word(0x04, cmd);
// Source: linux-7.1/drivers/pci/quirks.c:3526-3542 (quirk_intel_ntb).
// Vendor 0x8086, devices 0x0e08 and 0x0e0d. The silicon reports its
// true BAR 2 and BAR 4 sizes as log2-encoded bytes at config offsets
// 0xD0 and 0xD1 respectively; Linux calls
// resource_set_size(&dev->resource[2], 1 << val) // for 0xD0
// resource_set_size(&dev->resource[4], 1 << val) // for 0xD1
// The action path cannot mutate kernel resource structs, so we
// perform the equivalent config-space read so the silicon's size
// reporting is exercised.
//
// R7 audit: previous implementation cleared PCI_COMMAND_MEMORY
// (bit 1) and immediately restored it; the device never observed
// the transient clear long enough to re-decode its BARs, so the
// "side effect" was a no-op. Replaced with the real Linux reads.
let _bar2_size_log2 = w.read_config_byte(0xD0);
let _bar4_size_log2 = w.read_config_byte(0xD1);
true
}
@@ -2552,4 +2562,42 @@ flags = ["always_poll", "no_init_reports"]
assert!(entries[0].flags.contains(HidQuirkFlags::ALWAYS_POLL));
assert!(entries[0].flags.contains(HidQuirkFlags::NO_INIT_REPORTS));
}
// ---- Phase R7 audit tests (2026-06-07) ----
/// Vendor 0x8086, device 0x0e08 (one of two Linux targets).
/// 0xD0 = 0x1A → BAR 2 size = 1 << 26 = 64 MiB
/// 0xD1 = 0x1B → BAR 4 size = 1 << 27 = 128 MiB
#[test]
fn phase_r7_audit_intel_ntb_bar_fix_reads_size_registers() {
let cfg = MockConfig::new();
cfg.write_config_byte(0xD0, 0x1A);
cfg.write_config_byte(0xD1, 0x1B);
let info = make_info(0x8086, 0x0E08, 0x00, 0x00, 0x00);
assert!(cb_intel_ntb_bar_fix(&cfg, &info));
assert_eq!(cfg.read_config_byte(0xD0), 0x1A);
assert_eq!(cfg.read_config_byte(0xD1), 0x1B);
}
/// Vendor 0x8086, device 0x0e0d (second Linux target).
#[test]
fn phase_r7_audit_intel_ntb_bar_fix_handles_second_linux_target() {
let cfg = MockConfig::new();
cfg.write_config_byte(0xD0, 0x15);
cfg.write_config_byte(0xD1, 0x16);
let info = make_info(0x8086, 0x0E0D, 0x00, 0x00, 0x00);
assert!(cb_intel_ntb_bar_fix(&cfg, &info));
assert_eq!(cfg.read_config_byte(0xD0), 0x15);
assert_eq!(cfg.read_config_byte(0xD1), 0x16);
}
/// Zero-valued size registers must not panic or synthesize a default.
#[test]
fn phase_r7_audit_intel_ntb_bar_fix_handles_zero_registers() {
let cfg = MockConfig::new();
let info = make_info(0x8086, 0x0E08, 0x00, 0x00, 0x00);
assert!(cb_intel_ntb_bar_fix(&cfg, &info));
assert_eq!(cfg.read_config_byte(0xD0), 0x00);
assert_eq!(cfg.read_config_byte(0xD1), 0x00);
}
}
@@ -4,14 +4,12 @@ path = "source"
[build]
template = "custom"
script = """
# R7 audit (2026-06-07): the previous explicit list of 8 cp commands was
# missing 22 of 30 TOML files, including R11-R21 data tables (ACPI DMI,
# panel orientation, platform DMI, CPU bugs, clocksource, chipset,
# network, USB audio, AMD IOMMU), PCI header/final fixups, audio, xhci,
# and storage-extended. Replaced with a glob so every `.toml` in
# `quirks.d/` ships — future additions are picked up automatically.
mkdir -p "${COOKBOOK_STAGE}/etc/quirks.d"
cp "${COOKBOOK_SOURCE}/quirks.d/00-core.toml" "${COOKBOOK_STAGE}/etc/quirks.d/00-core.toml"
cp "${COOKBOOK_SOURCE}/quirks.d/10-gpu.toml" "${COOKBOOK_STAGE}/etc/quirks.d/10-gpu.toml"
cp "${COOKBOOK_SOURCE}/quirks.d/20-usb.toml" "${COOKBOOK_STAGE}/etc/quirks.d/20-usb.toml"
cp "${COOKBOOK_SOURCE}/quirks.d/30-net.toml" "${COOKBOOK_STAGE}/etc/quirks.d/30-net.toml"
cp "${COOKBOOK_SOURCE}/quirks.d/40-storage.toml" "${COOKBOOK_STAGE}/etc/quirks.d/40-storage.toml"
cp "${COOKBOOK_SOURCE}/quirks.d/50-system.toml" "${COOKBOOK_STAGE}/etc/quirks.d/50-system.toml"
cp "${COOKBOOK_SOURCE}/quirks.d/60-i2c-hid.toml" "${COOKBOOK_STAGE}/etc/quirks.d/60-i2c-hid.toml"
cp "${COOKBOOK_SOURCE}/quirks.d/70-ucsi.toml" "${COOKBOOK_STAGE}/etc/quirks.d/70-ucsi.toml"
cp "${COOKBOOK_SOURCE}/quirks.d/"*.toml "${COOKBOOK_STAGE}/etc/quirks.d/"
"""