pci: vfio: Propagate errors when enabling interrupts

Make sure to propagate the error coming from VfioDevice when trying to
enable INTx, MSI or MSI-X interrutps.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-02-10 14:30:24 +01:00 committed by Rob Bradford
parent 169a6bb83b
commit 27515a6ec4

View File

@ -33,18 +33,19 @@ use vmm_sys_util::eventfd::EventFd;
#[derive(Debug)] #[derive(Debug)]
pub enum VfioPciError { pub enum VfioPciError {
AllocateGsi, AllocateGsi,
EnableIntx(VfioError),
EnableMsi(VfioError),
EnableMsix(VfioError),
EventFd(io::Error), EventFd(io::Error),
InterruptSourceGroupCreate(io::Error), InterruptSourceGroupCreate(io::Error),
IrqFd(hypervisor::HypervisorVmError), IrqFd(hypervisor::HypervisorVmError),
NewVfioPciDevice,
MapRegionGuest(anyhow::Error), MapRegionGuest(anyhow::Error),
SetGsiRouting(hypervisor::HypervisorVmError), MissingNotifier,
MsiNotConfigured, MsiNotConfigured,
MsixNotConfigured, MsixNotConfigured,
NewVfioPciDevice,
SetGsiRouting(hypervisor::HypervisorVmError),
UpdateMemory(VfioError), UpdateMemory(VfioError),
UpdateIntxEventFd,
UpdateMsiEventFd,
UpdateMsixEventFd,
} }
pub type Result<T> = std::result::Result<T, VfioPciError>; pub type Result<T> = std::result::Result<T, VfioPciError>;
@ -52,22 +53,23 @@ impl fmt::Display for VfioPciError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
VfioPciError::AllocateGsi => write!(f, "failed to allocate GSI"), VfioPciError::AllocateGsi => write!(f, "failed to allocate GSI"),
VfioPciError::EnableIntx(e) => write!(f, "failed to enable INTx: {}", e),
VfioPciError::EnableMsi(e) => write!(f, "failed to enable MSI: {}", e),
VfioPciError::EnableMsix(e) => write!(f, "failed to enable MSI-X: {}", e),
VfioPciError::EventFd(e) => write!(f, "failed to create eventfd: {}", e), VfioPciError::EventFd(e) => write!(f, "failed to create eventfd: {}", e),
VfioPciError::InterruptSourceGroupCreate(e) => { VfioPciError::InterruptSourceGroupCreate(e) => {
write!(f, "failed to create interrupt source group: {}", e) write!(f, "failed to create interrupt source group: {}", e)
} }
VfioPciError::IrqFd(e) => write!(f, "failed to register irqfd: {}", e), VfioPciError::IrqFd(e) => write!(f, "failed to register irqfd: {}", e),
VfioPciError::NewVfioPciDevice => write!(f, "failed to create VFIO PCI device"),
VfioPciError::MapRegionGuest(e) => { VfioPciError::MapRegionGuest(e) => {
write!(f, "failed to map VFIO PCI region into guest: {}", e) write!(f, "failed to map VFIO PCI region into guest: {}", e)
} }
VfioPciError::SetGsiRouting(e) => write!(f, "failed to set GSI routes: {}", e), VfioPciError::MissingNotifier => write!(f, "failed to notifier's eventfd"),
VfioPciError::MsiNotConfigured => write!(f, "MSI interrupt not yet configured"), VfioPciError::MsiNotConfigured => write!(f, "MSI interrupt not yet configured"),
VfioPciError::MsixNotConfigured => write!(f, "MSI-X interrupt not yet configured"), VfioPciError::MsixNotConfigured => write!(f, "MSI-X interrupt not yet configured"),
VfioPciError::NewVfioPciDevice => write!(f, "failed to create VFIO PCI device"),
VfioPciError::SetGsiRouting(e) => write!(f, "failed to set GSI routes: {}", e),
VfioPciError::UpdateMemory(e) => write!(f, "failed to update memory: {}", e), VfioPciError::UpdateMemory(e) => write!(f, "failed to update memory: {}", e),
VfioPciError::UpdateIntxEventFd => write!(f, "failed to update INTx eventfd"),
VfioPciError::UpdateMsiEventFd => write!(f, "failed to update MSI eventfd"),
VfioPciError::UpdateMsixEventFd => write!(f, "failed to update MSI-X eventfd"),
} }
} }
} }
@ -355,16 +357,13 @@ impl VfioPciDevice {
if let Some(intx) = &mut self.interrupt.intx { if let Some(intx) = &mut self.interrupt.intx {
if !intx.enabled { if !intx.enabled {
if let Some(eventfd) = intx.interrupt_source_group.notifier(0) { if let Some(eventfd) = intx.interrupt_source_group.notifier(0) {
if let Err(e) = self self.device
.device
.enable_irq(VFIO_PCI_INTX_IRQ_INDEX, vec![&eventfd]) .enable_irq(VFIO_PCI_INTX_IRQ_INDEX, vec![&eventfd])
{ .map_err(VfioPciError::EnableIntx)?;
warn!("Could not enable INTx: {}", e);
} else { intx.enabled = true;
intx.enabled = true;
}
} else { } else {
return Err(VfioPciError::UpdateIntxEventFd); return Err(VfioPciError::MissingNotifier);
} }
} }
} }
@ -376,7 +375,7 @@ impl VfioPciDevice {
if let Some(intx) = &mut self.interrupt.intx { if let Some(intx) = &mut self.interrupt.intx {
if intx.enabled { if intx.enabled {
if let Err(e) = self.device.disable_irq(VFIO_PCI_INTX_IRQ_INDEX) { if let Err(e) = self.device.disable_irq(VFIO_PCI_INTX_IRQ_INDEX) {
warn!("Could not disable INTx: {}", e); error!("Could not disable INTx: {}", e);
} else { } else {
intx.enabled = false; intx.enabled = false;
} }
@ -391,13 +390,13 @@ impl VfioPciDevice {
if let Some(eventfd) = msi.interrupt_source_group.notifier(i as InterruptIndex) { if let Some(eventfd) = msi.interrupt_source_group.notifier(i as InterruptIndex) {
irq_fds.push(eventfd); irq_fds.push(eventfd);
} else { } else {
return Err(VfioPciError::UpdateMsiEventFd); return Err(VfioPciError::MissingNotifier);
} }
} }
if let Err(e) = self.device.enable_msi(irq_fds.iter().collect()) { self.device
warn!("Could not enable MSI: {}", e); .enable_msi(irq_fds.iter().collect())
} .map_err(VfioPciError::EnableMsi)?;
} }
Ok(()) Ok(())
@ -405,7 +404,7 @@ impl VfioPciDevice {
fn disable_msi(&self) { fn disable_msi(&self) {
if let Err(e) = self.device.disable_msi() { if let Err(e) = self.device.disable_msi() {
warn!("Could not disable MSI: {}", e); error!("Could not disable MSI: {}", e);
} }
} }
@ -416,13 +415,13 @@ impl VfioPciDevice {
if let Some(eventfd) = msix.interrupt_source_group.notifier(i as InterruptIndex) { if let Some(eventfd) = msix.interrupt_source_group.notifier(i as InterruptIndex) {
irq_fds.push(eventfd); irq_fds.push(eventfd);
} else { } else {
return Err(VfioPciError::UpdateMsixEventFd); return Err(VfioPciError::MissingNotifier);
} }
} }
if let Err(e) = self.device.enable_msix(irq_fds.iter().collect()) { self.device
warn!("Could not enable MSI-X: {}", e); .enable_msix(irq_fds.iter().collect())
} .map_err(VfioPciError::EnableMsi)?;
} }
Ok(()) Ok(())
@ -430,7 +429,7 @@ impl VfioPciDevice {
fn disable_msix(&self) { fn disable_msix(&self) {
if let Err(e) = self.device.disable_msix() { if let Err(e) = self.device.disable_msix() {
warn!("Could not disable MSI-X: {}", e); error!("Could not disable MSI-X: {}", e);
} }
} }