mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
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:
parent
d78d05bf7f
commit
c5e7a4879e
2 changed files with 22 additions and 39 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue