From 7dbf22331b7000ee0015f22a2231e0a41d8d3143 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Jan 2024 13:38:31 +0100 Subject: [PATCH] Share msix config validation code --- nvmed/src/main.rs | 1 + pcid/src/pci/msi.rs | 36 ++++++++++++++++++++++++++++++++++ rtl8139d/src/main.rs | 14 ++----------- rtl8168d/src/main.rs | 15 ++------------ virtio-core/src/arch/x86_64.rs | 14 ++----------- xhcid/src/main.rs | 14 ++----------- 6 files changed, 45 insertions(+), 49 deletions(-) diff --git a/nvmed/src/main.rs b/nvmed/src/main.rs index 8e57eb4db0..92f5c14729 100644 --- a/nvmed/src/main.rs +++ b/nvmed/src/main.rs @@ -88,6 +88,7 @@ fn get_int_method( PciFeatureInfo::MsiX(msix) => msix, _ => unreachable!(), }; + capability_struct.validate(function.bars); fn bar_base( allocated_bars: &AllocatedBars, function: &PciFunction, diff --git a/pcid/src/pci/msi.rs b/pcid/src/pci/msi.rs index fe09768a91..a3c06d538a 100644 --- a/pcid/src/pci/msi.rs +++ b/pcid/src/pci/msi.rs @@ -203,6 +203,42 @@ impl MsiCapability { } impl MsixCapability { + pub fn validate(&self, bars: [PciBar; 6]) { + let table_size = self.table_size(); + let table_base = self.table_base_pointer(bars); + let table_min_length = table_size * 16; + let pba_min_length = table_size.div_ceil(8); + + let pba_base = self.pba_base_pointer(bars); + + let bir = self.table_bir() as usize; + let bar = &bars[bir]; + let (bar_ptr, bar_size) = bar.expect_mem(); + + // Ensure that the table and PBA are within the BAR. + let bar_range = bar_ptr as u64..bar_ptr as u64 + bar_size as u64; + + if !bar_range.contains(&(table_base as u64 + table_min_length as u64)) { + panic!( + "Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", + table_base, + table_base + table_min_length as usize, + bar_ptr, + bar_ptr + bar_size + ); + } + + if !bar_range.contains(&(pba_base as u64 + pba_min_length as u64)) { + panic!( + "PBA {:#x}{:#x} outside of BAR {:#x}:{:#X}", + pba_base, + pba_base + pba_min_length as usize, + bar_ptr, + bar_ptr + bar_size + ); + } + } + const MC_MSIX_ENABLED_BIT: u16 = 1 << 15; const MC_MSIX_ENABLED_SHIFT: u8 = 15; const MC_FUNCTION_MASK_BIT: u16 = 1 << 14; diff --git a/rtl8139d/src/main.rs b/rtl8139d/src/main.rs index e0bfbf2648..24e5e916fe 100644 --- a/rtl8139d/src/main.rs +++ b/rtl8139d/src/main.rs @@ -161,27 +161,17 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { PciFeatureInfo::Msi(_) => panic!(), PciFeatureInfo::MsiX(s) => s, }; - let table_size = capability.table_size(); + capability.validate(pci_config.func.bars); let table_base = capability.table_base_pointer(pci_config.func.bars); - let table_min_length = table_size * 16; - let pba_min_length = div_round_up(table_size, 8); let pba_base = capability.pba_base_pointer(pci_config.func.bars); let bir = capability.table_bir() as usize; let bar = &pci_config.func.bars[bir]; - let (bar_ptr, bar_size) = bar.expect_mem(); + let (bar_ptr, _) = bar.expect_mem(); let address = unsafe { bar.physmap_mem("rtl8139d") } as usize; - if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(table_base as u64 + table_min_length as u64)) { - panic!("Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", table_base, table_base + table_min_length as usize, bar_ptr, bar_ptr + bar_size); - } - - if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(pba_base as u64 + pba_min_length as u64)) { - panic!("PBA {:#x}{:#x} outside of BAR {:#x}:{:#X}", pba_base, pba_base + pba_min_length as usize, bar_ptr, bar_ptr + bar_size); - } - let virt_table_base = ((table_base - bar_ptr) + address) as *mut MsixTableEntry; let virt_pba_base = ((pba_base - bar_ptr) + address) as *mut u64; diff --git a/rtl8168d/src/main.rs b/rtl8168d/src/main.rs index d157ab8706..e93cf984bf 100644 --- a/rtl8168d/src/main.rs +++ b/rtl8168d/src/main.rs @@ -159,27 +159,16 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { PciFeatureInfo::Msi(_) => panic!(), PciFeatureInfo::MsiX(s) => s, }; - let table_size = capability.table_size(); + capability.validate(pci_config.func.bars); let table_base = capability.table_base_pointer(pci_config.func.bars); - let table_min_length = table_size * 16; - let pba_min_length = div_round_up(table_size, 8); - let pba_base = capability.pba_base_pointer(pci_config.func.bars); let bir = capability.table_bir() as usize; let bar = &pci_config.func.bars[bir]; - let (bar_ptr, bar_size) = bar.expect_mem(); + let (bar_ptr, _) = bar.expect_mem(); let address = unsafe { bar.physmap_mem("rtl8168d") } as usize; - if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(table_base as u64 + table_min_length as u64)) { - panic!("Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", table_base, table_base + table_min_length as usize, bar_ptr, bar_ptr + bar_size); - } - - if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(pba_base as u64 + pba_min_length as u64)) { - panic!("PBA {:#x}{:#x} outside of BAR {:#x}:{:#X}", pba_base, pba_base + pba_min_length as usize, bar_ptr, bar_ptr + bar_size); - } - let virt_table_base = ((table_base - bar_ptr) + address) as *mut MsixTableEntry; let virt_pba_base = ((pba_base - bar_ptr) + address) as *mut u64; diff --git a/virtio-core/src/arch/x86_64.rs b/virtio-core/src/arch/x86_64.rs index a160f508cd..0273423eb4 100644 --- a/virtio-core/src/arch/x86_64.rs +++ b/virtio-core/src/arch/x86_64.rs @@ -18,26 +18,16 @@ pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result { PciFeatureInfo::MsiX(capability) => capability, _ => unreachable!(), }; + capability.validate(pci_config.func.bars); - let table_size = capability.table_size(); let table_base = capability.table_base_pointer(pci_config.func.bars); - let table_min_length = table_size * 16; - let pba_min_length = table_size.div_ceil(8); - - let pba_base = capability.pba_base_pointer(pci_config.func.bars); let bir = capability.table_bir() as usize; let bar = &pci_config.func.bars[bir]; - let (bar_ptr, bar_size) = bar.expect_mem(); + let (bar_ptr, _) = bar.expect_mem(); let address = unsafe { bar.physmap_mem("virtio-core") } as usize; - // Ensure that the table and PBA are be within the BAR. - { - let bar_range = bar_ptr as u64..bar_ptr as u64 + bar_size as u64; - assert!(bar_range.contains(&(table_base as u64 + table_min_length as u64))); - assert!(bar_range.contains(&(pba_base as u64 + pba_min_length as u64))); - } let virt_table_base = ((table_base - bar_ptr as usize) + address) as *mut MsixTableEntry; diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index c6dd1565a5..96821f5f35 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -137,21 +137,11 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option PciFeatureInfo::Msi(_) => panic!(), PciFeatureInfo::MsiX(s) => s, }; - let table_size = capability.table_size(); + capability.validate(pci_config.func.bars); + let table_base = capability.table_base_pointer(pci_config.func.bars); - let table_min_length = table_size * 16; - let pba_min_length = crate::xhci::scheme::div_round_up(table_size, 8); - let pba_base = capability.pba_base_pointer(pci_config.func.bars); - if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(table_base as u64 + table_min_length as u64)) { - panic!("Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", table_base, table_base + table_min_length as usize, bar_ptr, bar_ptr + bar_size); - } - - if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(pba_base as u64 + pba_min_length as u64)) { - panic!("PBA {:#x}{:#x} outside of BAR {:#x}:{:#X}", pba_base, pba_base + pba_min_length as usize, bar_ptr, bar_ptr + bar_size); - } - let virt_table_base = ((table_base - bar_ptr as usize) + address) as *mut MsixTableEntry; let virt_pba_base = ((pba_base - bar_ptr as usize) + address) as *mut u64;