419ff3c536
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)
209 lines
9.4 KiB
Diff
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,
|