Files
RedBear-OS/local/patches/base/P18-9-msi-allocation-resilience.patch
T
vasilito 419ff3c536 fix: regenerate P18-9, P19-init, P19-acpid patches as -U0 -w resilient format
All 58 base patches now pass repo validate-patches base.

- P18-9-msi-allocation-resilience: regenerated against P0-P18-8 baseline
  with correct upstream content (deamon typo preserved for virtio-netd)
- P19-init-startup-hardening: regenerated against P0-P18-9 baseline
- P19-acpid-startup-hardening: regenerated against P0-P18-9 + P19-init
  baseline with all 39 hunks in -U0 -w format (zero context lines)
2026-05-18 16:05:52 +03:00

209 lines
9.4 KiB
Diff

diff --git a/drivers/net/virtio-netd/src/main.rs b/drivers/net/virtio-netd/src/main.rs
index 17d168ef..5271a2f1 100644
--- a/drivers/net/virtio-netd/src/main.rs
+++ b/drivers/net/virtio-netd/src/main.rs
@@ -34,2 +34,7 @@ fn daemon_runner(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
- deamon(daemon, pcid_handle).unwrap();
- unreachable!();
+ match deamon(daemon, pcid_handle) {
+ Ok(()) => unreachable!(),
+ Err(err) => {
+ log::error!("virtio-netd: fatal error: {err}");
+ std::process::exit(1);
+ }
+ }
diff --git a/drivers/pcid/src/driver_interface/irq_helpers.rs b/drivers/pcid/src/driver_interface/irq_helpers.rs
index 28ca077a..39b0b048 100644
--- a/drivers/pcid/src/driver_interface/irq_helpers.rs
+++ b/drivers/pcid/src/driver_interface/irq_helpers.rs
@@ -121 +121 @@ pub fn allocate_aligned_interrupt_vectors(
- let mut first = None;
+ let mut first_aligned: Option<u8> = None;
@@ -130,2 +130,2 @@ pub fn allocate_aligned_interrupt_vectors(
- let first = *first.get_or_insert(number);
- let irq_number = first + index;
+ let base = *first_aligned.get_or_insert(number);
+ let irq_number = base + index;
@@ -143,0 +144,9 @@ pub fn allocate_aligned_interrupt_vectors(
+ // Vector already allocated by another process; release any partial range and
+ // restart the search from the next aligned position.
+ Err(err) if err.kind() == io::ErrorKind::AlreadyExists => {
+ drop(handles.drain(..));
+ first_aligned = None;
+ index = 0;
+ continue;
+ }
+
@@ -155 +164 @@ pub fn allocate_aligned_interrupt_vectors(
- let first = match first {
+ let first = match first_aligned {
@@ -183 +192 @@ pub fn allocate_single_interrupt_vector(cpu_id: usize) -> io::Result<Option<(u8,
-pub fn allocate_single_interrupt_vector_for_msi(cpu_id: usize) -> (MsiAddrAndData, File) {
+pub fn allocate_single_interrupt_vector_for_msi(cpu_id: usize) -> Option<(MsiAddrAndData, File)> {
@@ -187 +196,7 @@ pub fn allocate_single_interrupt_vector_for_msi(cpu_id: usize) -> (MsiAddrAndDat
- let lapic_id = u8::try_from(cpu_id).expect("CPU id couldn't fit inside u8");
+ let lapic_id = match u8::try_from(cpu_id) {
+ Ok(id) => id,
+ Err(_) => {
+ log::warn!("cpu_id {} too large for MSI address format", cpu_id);
+ return None;
+ }
+ };
@@ -192,3 +207,11 @@ pub fn allocate_single_interrupt_vector_for_msi(cpu_id: usize) -> (MsiAddrAndDat
- let (vector, interrupt_handle) = allocate_single_interrupt_vector(cpu_id)
- .expect("failed to allocate interrupt vector")
- .expect("no interrupt vectors left");
+ let (vector, interrupt_handle) = match allocate_single_interrupt_vector(cpu_id) {
+ Ok(Some(result)) => result,
+ Ok(None) => {
+ log::warn!("no interrupt vectors available for MSI on CPU {}", cpu_id);
+ return None;
+ }
+ Err(err) => {
+ log::warn!("failed to allocate interrupt vector for MSI on CPU {}: {}", cpu_id, err);
+ return None;
+ }
+ };
@@ -197 +220 @@ pub fn allocate_single_interrupt_vector_for_msi(cpu_id: usize) -> (MsiAddrAndDat
- (
+ Some((
@@ -203 +226 @@ pub fn allocate_single_interrupt_vector_for_msi(cpu_id: usize) -> (MsiAddrAndDat
- )
+ ))
@@ -209 +232 @@ pub fn allocate_first_msi_interrupt_on_bsp(
-) -> File {
+) -> Option<File> {
@@ -214 +237,7 @@ pub fn allocate_first_msi_interrupt_on_bsp(
- let destination_id = read_bsp_apic_id().expect("failed to read BSP apic id");
+ let destination_id = match read_bsp_apic_id() {
+ Ok(id) => id,
+ Err(err) => {
+ log::warn!("failed to read BSP apic id: {}", err);
+ return None;
+ }
+ };
@@ -216 +245 @@ pub fn allocate_first_msi_interrupt_on_bsp(
- allocate_single_interrupt_vector_for_msi(destination_id);
+ allocate_single_interrupt_vector_for_msi(destination_id)?;
@@ -228 +257 @@ pub fn allocate_first_msi_interrupt_on_bsp(
- interrupt_handle
+ Some(interrupt_handle)
@@ -285,2 +313,0 @@ pub fn pci_allocate_interrupt_vector(
- pcid_handle.enable_feature(crate::driver_interface::PciFeature::MsiX);
-
@@ -289,3 +316,9 @@ pub fn pci_allocate_interrupt_vector(
- let bsp_cpu_id = read_bsp_apic_id()
- .unwrap_or_else(|err| panic!("{driver}: failed to read BSP APIC ID: {err}"));
- let (msg_addr_and_data, irq_handle) = allocate_single_interrupt_vector_for_msi(bsp_cpu_id);
+ let bsp_cpu_id = match read_bsp_apic_id() {
+ Ok(id) => id,
+ Err(err) => {
+ log::warn!("{driver}: failed to read BSP APIC ID: {err}");
+ // fall through to MSI
+ 0
+ }
+ };
+ if let Some((msg_addr_and_data, irq_handle)) = allocate_single_interrupt_vector_for_msi(bsp_cpu_id) {
@@ -295 +328,3 @@ pub fn pci_allocate_interrupt_vector(
- InterruptVector {
+ pcid_handle.enable_feature(crate::driver_interface::PciFeature::MsiX);
+
+ return InterruptVector {
@@ -298,0 +334 @@ pub fn pci_allocate_interrupt_vector(
+ };
@@ -300,3 +336,8 @@ pub fn pci_allocate_interrupt_vector(
- } else if has_msi {
- InterruptVector {
- irq_handle: allocate_first_msi_interrupt_on_bsp(pcid_handle),
+ log::warn!("{driver}: MSI-X vector allocation failed, falling back");
+ // fall through to MSI
+ }
+
+ if has_msi {
+ if let Some(irq_handle) = allocate_first_msi_interrupt_on_bsp(pcid_handle) {
+ return InterruptVector {
+ irq_handle,
@@ -304,0 +346,3 @@ pub fn pci_allocate_interrupt_vector(
+ };
+ }
+ log::warn!("{driver}: MSI allocation failed, falling back to legacy");
@@ -306 +350,2 @@ pub fn pci_allocate_interrupt_vector(
- } else if let Some(irq) = pcid_handle.config().func.legacy_interrupt_line {
+
+ if let Some(irq) = pcid_handle.config().func.legacy_interrupt_line {
@@ -308 +353 @@ pub fn pci_allocate_interrupt_vector(
- InterruptVector {
+ return InterruptVector {
@@ -311,0 +357 @@ pub fn pci_allocate_interrupt_vector(
+ };
@@ -313 +359 @@ pub fn pci_allocate_interrupt_vector(
- } else {
+
@@ -316 +361,0 @@ pub fn pci_allocate_interrupt_vector(
-}
diff --git a/drivers/storage/virtio-blkd/src/main.rs b/drivers/storage/virtio-blkd/src/main.rs
index d21236b3..95089eb9 100644
--- a/drivers/storage/virtio-blkd/src/main.rs
+++ b/drivers/storage/virtio-blkd/src/main.rs
@@ -106,2 +106,7 @@ fn daemon_runner(redox_daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -
- daemon(redox_daemon, pcid_handle).unwrap();
- unreachable!();
+ match daemon(redox_daemon, pcid_handle) {
+ Ok(()) => unreachable!(),
+ Err(err) => {
+ log::error!("virtio-blkd: fatal error: {err}");
+ std::process::exit(1);
+ }
+ }
diff --git a/drivers/usb/xhcid/src/main.rs b/drivers/usb/xhcid/src/main.rs
index d345a52f..da9cabe1 100644
--- a/drivers/usb/xhcid/src/main.rs
+++ b/drivers/usb/xhcid/src/main.rs
@@ -79,2 +79,3 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> (Option<File>, Interru
- let (msg_addr_and_data, interrupt_handle) =
- allocate_single_interrupt_vector_for_msi(destination_id);
+ if let Some((msg_addr_and_data, interrupt_handle)) =
+ allocate_single_interrupt_vector_for_msi(destination_id)
+ {
@@ -84,3 +84,0 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> (Option<File>, Interru
- (Some(interrupt_handle), InterruptMethod::Msi)
- };
-
@@ -90,5 +88,16 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> (Option<File>, Interru
- method
- } else if has_msi {
- let interrupt_handle = allocate_first_msi_interrupt_on_bsp(pcid_handle);
- (Some(interrupt_handle), InterruptMethod::Msi)
- } else if let Some(irq) = pci_config.func.legacy_interrupt_line {
+ return (Some(interrupt_handle), InterruptMethod::Msi);
+ }
+
+ // MSI-X allocation failed; fall through to MSI or legacy.
+ log::warn!("xhcid: MSI-X vector allocation failed, falling back");
+ };
+ }
+
+ if has_msi {
+ if let Some(interrupt_handle) = allocate_first_msi_interrupt_on_bsp(pcid_handle) {
+ return (Some(interrupt_handle), InterruptMethod::Msi);
+ }
+ log::warn!("xhcid: MSI allocation failed, falling back to legacy");
+ }
+
+ if let Some(irq) = pci_config.func.legacy_interrupt_line {
diff --git a/drivers/virtio-core/src/arch/x86.rs b/drivers/virtio-core/src/arch/x86.rs
index aea86c4a..8fdc7ca6 100644
--- a/drivers/virtio-core/src/arch/x86.rs
+++ b/drivers/virtio-core/src/arch/x86.rs
@@ -26 +26,2 @@ pub fn enable_msix(pcid_handle: &mut PciFunctionHandle) -> Result<File, Error> {
- allocate_single_interrupt_vector_for_msi(destination_id);
+ allocate_single_interrupt_vector_for_msi(destination_id)
+ .ok_or(Error::MsiAllocationFailed)?;
diff --git a/drivers/virtio-core/src/transport.rs b/drivers/virtio-core/src/transport.rs
index d3445d2d..b961265c 100644
--- a/drivers/virtio-core/src/transport.rs
+++ b/drivers/virtio-core/src/transport.rs
@@ -21,0 +22,2 @@ pub enum Error {
+ #[error("MSI/MSI-X vector allocation failed")]
+ MsiAllocationFailed,