Skip to content
19 changes: 19 additions & 0 deletions alioth/src/pci/cap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,25 @@ where
*entry = MsixTableMmioEntry::default();
}
}

/// Replaces irqfds with plain entries that keep the address, data and
/// mask programmed by the guest.
pub fn release_irqfds(&self) {
let mut entries = self.entries.write();
for entry in entries.iter_mut() {
let MsixTableMmioEntry::IrqFd(fd) = entry else {
continue;
};
let mut control = MsixVectorCtrl(0);
control.set_masked(fd.get_masked());
*entry = MsixTableMmioEntry::Entry(MsixTableEntry {
addr_lo: fd.get_addr_lo(),
addr_hi: fd.get_addr_hi(),
data: fd.get_data(),
control,
});
}
}
}

impl<F> Mmio for MsixTableMmio<F>
Expand Down
41 changes: 41 additions & 0 deletions alioth/src/pci/cap_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,47 @@ fn test_msix_table_mmio() {
);
}

#[test]
fn test_msix_table_release_irqfds() {
let irqfd = TestIrqFd::default();
irqfd.set_addr_lo(0xfee0_0000).unwrap();
irqfd.set_addr_hi(0x1).unwrap();
irqfd.set_data(0x41).unwrap();
irqfd.set_masked(false).unwrap();
let entries = Box::new([
MsixTableMmioEntry::Entry(MsixTableEntry {
addr_lo: 0xfee0_1000,
addr_hi: 0,
data: 0x42,
control: MsixVectorCtrl(1),
}),
MsixTableMmioEntry::IrqFd(irqfd),
]);
let table = MsixTableMmio {
entries: RwLock::new(entries),
};

// Irqfds are gone, but the guest programming stays.
table.release_irqfds();
assert_matches!(
**table.entries.read(),
[
MsixTableMmioEntry::Entry(MsixTableEntry {
addr_lo: 0xfee0_1000,
addr_hi: 0,
data: 0x42,
control: MsixVectorCtrl(1),
}),
MsixTableMmioEntry::Entry(MsixTableEntry {
addr_lo: 0xfee0_0000,
addr_hi: 0x1,
data: 0x41,
control: MsixVectorCtrl(0),
})
]
);
}

#[test]
fn test_pci_cap_list() {
let caps: Vec<Box<dyn PciCap>> = vec![
Expand Down
Loading
Loading