Files
RedBear-OS/local/patches/kernel/P21-x2apic-smp-fix.patch
T
vasilito f6c2eb2a8e feat: ACPI Wave 1 boot-critical hardening (P19) + robust patch generation
- 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
2026-05-18 14:07:42 +03:00

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) {