f6c2eb2a8e
- P19-init-startup-hardening: Replace panic-grade expect/unwrap in init startup paths (getns, register_scheme_to_ns, setrens, filename parsing) with graceful error handling and logging - P19-acpid-startup-hardening: Replace panic-grade calls in acpid with graceful degradation (rxsdt read failure → warn + exit 0, SDT parse → error + exit 1, I/O privilege → fatal, scheme registration → fatal, setrens → warn + continue, event loop errors → log + continue) - P18-9-msi-allocation-resilience: Regenerate with git diff -U0 -w format for maximum context resilience - fetch.rs: Change --fuzz=0 to --fuzz=3 for resilient patch application - AGENTS.md: Document robust patch generation technique as mandatory - Add P4/P5/P6/P7 patches (estale, dmi, i2c, ps2d hardening) - Add P21 kernel x2apic SMP fix patch - Multiple local recipe source improvements (redox-drm, driver-manager, driver-acpi, thermald) - Config updates for redbear-mini and redbear-device-services - Subsystem assessment document
89 lines
4.5 KiB
Diff
89 lines
4.5 KiB
Diff
--- a/src/acpi/madt/arch/x86.rs
|
|
+++ b/src/acpi/madt/arch/x86.rs
|
|
@@ -189,8 +189,18 @@
|
|
let preliminary_cpu_count = madt
|
|
.iter()
|
|
.filter(|entry| match entry {
|
|
- MadtEntry::LocalApic(local) => u32::from(local.id) == me.get() || local.flags & 1 == 1,
|
|
- MadtEntry::LocalX2Apic(local) => local.x2apic_id == me.get() || local.flags & 1 == 1,
|
|
+ // When x2APIC is active, LocalApic entries use 8-bit IDs that don't
|
|
+ // match the BSP's 32-bit x2APIC ID. Use LocalX2Apic entries instead.
|
|
+ MadtEntry::LocalApic(local) if !local_apic.x2 => {
|
|
+ u32::from(local.id) == me.get() || local.flags & 1 == 1
|
|
+ }
|
|
+ MadtEntry::LocalApic(_) => false,
|
|
+ // xAPIC mode: cannot use 32-bit x2APIC IDs via 8-bit ICR.
|
|
+ // Skip LocalX2Apic entries and use LocalApic exclusively.
|
|
+ MadtEntry::LocalX2Apic(local) if local_apic.x2 => {
|
|
+ local.x2apic_id == me.get() || local.flags & 1 == 1
|
|
+ }
|
|
+ MadtEntry::LocalX2Apic(_) => false,
|
|
_ => false,
|
|
})
|
|
.count();
|
|
@@ -205,18 +215,28 @@
|
|
let _ = seen_apic_ids.insert(me.get()); // BSP
|
|
for entry in madt.iter() {
|
|
match entry {
|
|
- MadtEntry::LocalApic(local) if local.flags & 1 == 1 => {
|
|
+ MadtEntry::LocalApic(local) if local.flags & 1 == 1 && !local_apic.x2 => {
|
|
let id = u32::from(local.id);
|
|
if !seen_apic_ids.insert(id) {
|
|
warn!("MADT: duplicate APIC ID {} in LocalApic entry, firmware bug", id);
|
|
}
|
|
}
|
|
- MadtEntry::LocalX2Apic(local) if local.flags & 1 == 1 => {
|
|
+ MadtEntry::LocalApic(local) if local.flags & 1 == 1 && local_apic.x2 => {
|
|
+ // x2APIC mode: skip 8-bit LocalApic IDs; they conflict with
|
|
+ // 32-bit x2APIC IDs. Dedup only among LocalX2Apic entries.
|
|
+ debug!("MADT: ignoring 8-bit LocalApic ID {} in x2APIC mode", local.id);
|
|
+ }
|
|
+ MadtEntry::LocalX2Apic(local) if local.flags & 1 == 1 && local_apic.x2 => {
|
|
let id = local.x2apic_id;
|
|
if !seen_apic_ids.insert(id) {
|
|
warn!("MADT: duplicate x2APIC ID {} in LocalX2Apic entry, firmware bug", id);
|
|
}
|
|
}
|
|
+ MadtEntry::LocalX2Apic(local) if local.flags & 1 == 1 && !local_apic.x2 => {
|
|
+ // xAPIC mode: skip 32-bit x2APIC IDs; dedup only among LocalApic entries.
|
|
+ let id = local.x2apic_id; // Copy from packed struct
|
|
+ debug!("MADT: ignoring 32-bit x2APIC ID {} in xAPIC mode", id);
|
|
+ }
|
|
_ => {}
|
|
}
|
|
}
|
|
@@ -225,7 +245,16 @@
|
|
for madt_entry in madt.iter() {
|
|
debug!(" {:x?}", madt_entry);
|
|
if let MadtEntry::LocalApic(ap_local_apic) = madt_entry {
|
|
- if u32::from(ap_local_apic.id) == me.get() {
|
|
+ // x2APIC mode: LocalApic entries have 8-bit IDs that don't match
|
|
+ // the BSP's 32-bit x2APIC ID. All entries would be treated as APs,
|
|
+ // and SIPI would target the wrong processors. Skip them and rely
|
|
+ // on LocalX2Apic entries exclusively.
|
|
+ if local_apic.x2 {
|
|
+ debug!(
|
|
+ " Skipping 8-bit LocalApic id={} (x2APIC active, using LocalX2Apic entries)",
|
|
+ ap_local_apic.id
|
|
+ );
|
|
+ } else if u32::from(ap_local_apic.id) == me.get() {
|
|
debug!(" This is my local APIC");
|
|
} else if ap_local_apic.flags & 1 == 1 {
|
|
// Allocate a stack
|
|
@@ -388,7 +417,14 @@
|
|
let apic_id = ap_x2apic.x2apic_id;
|
|
let flags = ap_x2apic.flags;
|
|
|
|
- if apic_id == me.get() {
|
|
+ // xAPIC mode: cannot target 32-bit x2APIC IDs via 8-bit ICR.
|
|
+ // Skip LocalX2Apic entries; use LocalApic entries exclusively.
|
|
+ if !local_apic.x2 {
|
|
+ debug!(
|
|
+ " Skipping 32-bit x2APIC id={} (xAPIC mode, using LocalApic entries)",
|
|
+ apic_id
|
|
+ );
|
|
+ } else if apic_id == me.get() {
|
|
debug!(" This is my local x2APIC");
|
|
} else if flags & 1 == 1 {
|
|
let alloc = match allocate_p2frame(4) {
|