crosvm: vfio: allow forwarding of multiple non-MSI IRQs

For vfio-platform we will have many platform IRQs per vfio-platform
device, so we need to pass the irq index to these functions in this
commit, rather than inferring the IRQ index from the IRQ type (intx
vs msi vs msix).

In other words, this commit eliminates some assumptions in the common
vfio code that we are working with vfio-pci devices when doing vfio
passthrough.

BUG=b:185504618
TEST=cros_workon_make

Change-Id: Iaa02c387fb8a679217d4cc9dabecf7fc61f9c9fb
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2829293
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Tomasz Jeznach <tjeznach@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Micah Morton <mortonm@chromium.org>
This commit is contained in:
Micah Morton 2021-04-15 11:56:37 -07:00 committed by Commit Bot
parent d78d05bf7f
commit c5e7a4879e
2 changed files with 22 additions and 39 deletions

View file

@ -549,22 +549,25 @@ impl VfioPciDevice {
if let Some(ref interrupt_evt) = self.interrupt_evt {
let mut fds = Vec::new();
fds.push(interrupt_evt);
if let Err(e) = self.device.irq_enable(fds, VfioIrqType::Intx) {
if let Err(e) = self.device.irq_enable(fds, VFIO_PCI_INTX_IRQ_INDEX) {
error!("Intx enable failed: {}", e);
return;
}
if let Some(ref irq_resample_evt) = self.interrupt_resample_evt {
if let Err(e) = self.device.irq_mask(VfioIrqType::Intx) {
if let Err(e) = self.device.irq_mask(VFIO_PCI_INTX_IRQ_INDEX) {
error!("Intx mask failed: {}", e);
self.disable_intx();
return;
}
if let Err(e) = self.device.resample_virq_enable(irq_resample_evt) {
if let Err(e) = self
.device
.resample_virq_enable(irq_resample_evt, VFIO_PCI_INTX_IRQ_INDEX)
{
error!("resample enable failed: {}", e);
self.disable_intx();
return;
}
if let Err(e) = self.device.irq_unmask(VfioIrqType::Intx) {
if let Err(e) = self.device.irq_unmask(VFIO_PCI_INTX_IRQ_INDEX) {
error!("Intx unmask failed: {}", e);
self.disable_intx();
return;
@ -576,7 +579,7 @@ impl VfioPciDevice {
}
fn disable_intx(&mut self) {
if let Err(e) = self.device.irq_disable(VfioIrqType::Intx) {
if let Err(e) = self.device.irq_disable(VFIO_PCI_INTX_IRQ_INDEX) {
error!("Intx disable failed: {}", e);
}
self.irq_type = None;
@ -616,7 +619,7 @@ impl VfioPciDevice {
let mut fds = Vec::new();
fds.push(irqfd);
if let Err(e) = self.device.irq_enable(fds, VfioIrqType::Msi) {
if let Err(e) = self.device.irq_enable(fds, VFIO_PCI_MSI_IRQ_INDEX) {
error!("failed to enable msi: {}", e);
self.enable_intx();
return;
@ -626,7 +629,7 @@ impl VfioPciDevice {
}
fn disable_msi(&mut self) {
if let Err(e) = self.device.irq_disable(VfioIrqType::Msi) {
if let Err(e) = self.device.irq_disable(VFIO_PCI_MSI_IRQ_INDEX) {
error!("failed to disable msi: {}", e);
return;
}
@ -643,7 +646,7 @@ impl VfioPciDevice {
};
if let Some(descriptors) = irqfds {
if let Err(e) = self.device.irq_enable(descriptors, VfioIrqType::Msix) {
if let Err(e) = self.device.irq_enable(descriptors, VFIO_PCI_MSIX_IRQ_INDEX) {
error!("failed to enable msix: {}", e);
self.enable_intx();
return;
@ -657,7 +660,7 @@ impl VfioPciDevice {
}
fn disable_msix(&mut self) {
if let Err(e) = self.device.irq_disable(VfioIrqType::Msix) {
if let Err(e) = self.device.irq_disable(VFIO_PCI_MSIX_IRQ_INDEX) {
error!("failed to disable msix: {}", e);
return;
}

View file

@ -391,21 +391,13 @@ impl VfioDevice {
/// Enable vfio device's irq and associate Irqfd Event with device.
/// When MSIx is enabled, multi vectors will be supported, so descriptors is vector and the vector
/// length is the num of MSIx vectors
pub fn irq_enable(
&self,
descriptors: Vec<&Event>,
irq_type: VfioIrqType,
) -> Result<(), VfioError> {
pub fn irq_enable(&self, descriptors: Vec<&Event>, index: u32) -> Result<(), VfioError> {
let count = descriptors.len();
let u32_size = mem::size_of::<u32>();
let mut irq_set = vec_with_array_field::<vfio_irq_set, u32>(count);
irq_set[0].argsz = (mem::size_of::<vfio_irq_set>() + count * u32_size) as u32;
irq_set[0].flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
match irq_type {
VfioIrqType::Intx => irq_set[0].index = VFIO_PCI_INTX_IRQ_INDEX,
VfioIrqType::Msi => irq_set[0].index = VFIO_PCI_MSI_IRQ_INDEX,
VfioIrqType::Msix => irq_set[0].index = VFIO_PCI_MSIX_IRQ_INDEX,
}
irq_set[0].index = index;
irq_set[0].start = 0;
irq_set[0].count = count as u32;
@ -438,11 +430,11 @@ impl VfioDevice {
/// This function enable resample irqfd and let vfio kernel could get EOI notification.
///
/// descriptor: should be resample IrqFd.
pub fn resample_virq_enable(&self, descriptor: &Event) -> Result<(), VfioError> {
pub fn resample_virq_enable(&self, descriptor: &Event, index: u32) -> Result<(), VfioError> {
let mut irq_set = vec_with_array_field::<vfio_irq_set, u32>(1);
irq_set[0].argsz = (mem::size_of::<vfio_irq_set>() + mem::size_of::<u32>()) as u32;
irq_set[0].flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_UNMASK;
irq_set[0].index = VFIO_PCI_INTX_IRQ_INDEX;
irq_set[0].index = index;
irq_set[0].start = 0;
irq_set[0].count = 1;
@ -465,15 +457,11 @@ impl VfioDevice {
}
/// disable vfio device's irq and disconnect Irqfd Event with device
pub fn irq_disable(&self, irq_type: VfioIrqType) -> Result<(), VfioError> {
pub fn irq_disable(&self, index: u32) -> Result<(), VfioError> {
let mut irq_set = vec_with_array_field::<vfio_irq_set, u32>(0);
irq_set[0].argsz = mem::size_of::<vfio_irq_set>() as u32;
irq_set[0].flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
match irq_type {
VfioIrqType::Intx => irq_set[0].index = VFIO_PCI_INTX_IRQ_INDEX,
VfioIrqType::Msi => irq_set[0].index = VFIO_PCI_MSI_IRQ_INDEX,
VfioIrqType::Msix => irq_set[0].index = VFIO_PCI_MSIX_IRQ_INDEX,
}
irq_set[0].index = index;
irq_set[0].start = 0;
irq_set[0].count = 0;
@ -487,15 +475,11 @@ impl VfioDevice {
}
/// Unmask vfio device irq
pub fn irq_unmask(&self, irq_type: VfioIrqType) -> Result<(), VfioError> {
pub fn irq_unmask(&self, index: u32) -> Result<(), VfioError> {
let mut irq_set = vec_with_array_field::<vfio_irq_set, u32>(0);
irq_set[0].argsz = mem::size_of::<vfio_irq_set>() as u32;
irq_set[0].flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK;
match irq_type {
VfioIrqType::Intx => irq_set[0].index = VFIO_PCI_INTX_IRQ_INDEX,
VfioIrqType::Msi => irq_set[0].index = VFIO_PCI_MSI_IRQ_INDEX,
VfioIrqType::Msix => irq_set[0].index = VFIO_PCI_MSIX_IRQ_INDEX,
}
irq_set[0].index = index;
irq_set[0].start = 0;
irq_set[0].count = 1;
@ -509,15 +493,11 @@ impl VfioDevice {
}
/// Mask vfio device irq
pub fn irq_mask(&self, irq_type: VfioIrqType) -> Result<(), VfioError> {
pub fn irq_mask(&self, index: u32) -> Result<(), VfioError> {
let mut irq_set = vec_with_array_field::<vfio_irq_set, u32>(0);
irq_set[0].argsz = mem::size_of::<vfio_irq_set>() as u32;
irq_set[0].flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_MASK;
match irq_type {
VfioIrqType::Intx => irq_set[0].index = VFIO_PCI_INTX_IRQ_INDEX,
VfioIrqType::Msi => irq_set[0].index = VFIO_PCI_MSI_IRQ_INDEX,
VfioIrqType::Msix => irq_set[0].index = VFIO_PCI_MSIX_IRQ_INDEX,
}
irq_set[0].index = index;
irq_set[0].start = 0;
irq_set[0].count = 1;