Share msix config validation code

This commit is contained in:
bjorn3
2024-01-23 13:38:31 +01:00
parent 5f845538ea
commit 7dbf22331b
6 changed files with 45 additions and 49 deletions
+1
View File
@@ -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,
+36
View File
@@ -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;
+2 -12
View File
@@ -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;
+2 -13
View File
@@ -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;
+2 -12
View File
@@ -18,26 +18,16 @@ pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result<File, Error> {
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;
+2 -12
View File
@@ -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;