Skip to content

Commit

Permalink
fix(virtio): prevent MSI-X change if irqfd linked
Browse files Browse the repository at this point in the history
If the MSI-X table entry 0 is mapped to queue 0, and queue 0 is
offloaded to a vhost backend, and later the guest maps table entry
1 to queue 0, we will need to find out the iqrfd of table entry 1,
and send a message to the vhost backend to update the irqfd. This is
much more complicated than just updating table entry 0, which only
involves updating the GSI table at the VMM side.

For now we simply prevent such changes if a queue is already mapped
to an MSI-X entry that is linked to an irqfd.

Signed-off-by: Changyuan Lyu <[email protected]>
  • Loading branch information
Lencerf committed Jun 3, 2024
1 parent d1baa6e commit b36af49
Showing 1 changed file with 43 additions and 10 deletions.
53 changes: 43 additions & 10 deletions alioth/src/virtio/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,23 @@ where
q.enabled.store(false, Ordering::Release);
}
}

fn msix_change_allowed(&self, old: u16) -> bool {
let Some(entry) = self.irq_sender.msix_entries.get(old as usize) else {
return true;
};
let entry = entry.read();
if let MsixTableMmioEntry::IrqFd(fd) = &*entry {
log::error!(
"{}: MSI-X vector {old:#x} was assigned to irqfd {:#x}",
self.name,
fd.as_fd().as_raw_fd(),
);
false
} else {
true
}
}
}

impl<M> Mmio for VirtioPciRegisterMmio<M>
Expand Down Expand Up @@ -367,11 +384,19 @@ where
}
VirtioCommonCfg::LAYOUT_CONFIG_MSIX_VECTOR => {
let config_msix = &self.irq_sender.msix_vector.config;
let old = config_msix.swap(val as u16, Ordering::AcqRel);
log::trace!(
"{}: config MSI-X vector update: {old:#x} -> {val:#x}",
self.name
);
let old = config_msix.load(Ordering::Acquire);
if self.msix_change_allowed(old) {
config_msix.store(val as u16, Ordering::Release);
log::trace!(
"{}: config MSI-X vector update: {old:#x} -> {val:#x}",
self.name
);
} else {
log::error!(
"{}: cannot change config MSI-X vector from {old:#x} to {val:#x}",
self.name
)
}
}
VirtioCommonCfg::LAYOUT_DEVICE_STATUS => {
let status = DevStatus::from_bits_truncate(val as u8);
Expand Down Expand Up @@ -406,11 +431,19 @@ where
VirtioCommonCfg::LAYOUT_QUEUE_MSIX_VECTOR => {
let q_sel = reg.queue_sel.load(Ordering::Relaxed) as usize;
if let Some(msix_vector) = self.irq_sender.msix_vector.queues.get(q_sel) {
let old = msix_vector.swap(val as u16, Ordering::AcqRel);
log::trace!(
"{}: queue {q_sel} MSI-X vector update: {old:#x} -> {val:#x}",
self.name
);
let old = msix_vector.load(Ordering::Acquire);
if self.msix_change_allowed(old) {
msix_vector.store(val as u16, Ordering::Release);
log::trace!(
"{}: queue {q_sel} MSI-X vector update: {old:#x} -> {val:#x}",
self.name
);
} else {
log::error!(
"{}: cannot change queue {q_sel} MSI-X vector from {old:#x} to {val:#x}",
self.name
)
}
}
}
VirtioCommonCfg::LAYOUT_QUEUE_ENABLE => {
Expand Down

0 comments on commit b36af49

Please sign in to comment.