mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 21:55:20 +00:00
vfio: pci: Update irqfd registration
In order to improve the existing VFIO code, this patch registers the eventfds used to trigger KVM interrupts only when the interrupts are enabled, and unregisters them when interrupts are disabled. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
1379abb94b
commit
4115fa8a87
@ -236,19 +236,26 @@ struct InterruptRoute {
|
||||
}
|
||||
|
||||
impl InterruptRoute {
|
||||
fn new(vm: &Arc<VmFd>, allocator: &mut SystemAllocator, msi_vector: MsiVector) -> Result<Self> {
|
||||
fn new(allocator: &mut SystemAllocator, msi_vector: MsiVector) -> Result<Self> {
|
||||
let irq_fd = EventFd::new(libc::EFD_NONBLOCK).map_err(VfioPciError::EventFd)?;
|
||||
let gsi = allocator.allocate_gsi().ok_or(VfioPciError::AllocateGsi)?;
|
||||
|
||||
vm.register_irqfd(&irq_fd, gsi)
|
||||
.map_err(VfioPciError::IrqFd)?;
|
||||
|
||||
Ok(InterruptRoute {
|
||||
gsi,
|
||||
irq_fd,
|
||||
msi_vector,
|
||||
})
|
||||
}
|
||||
|
||||
fn enable(&self, vm: &Arc<VmFd>) -> Result<()> {
|
||||
vm.register_irqfd(&self.irq_fd, self.gsi)
|
||||
.map_err(VfioPciError::IrqFd)
|
||||
}
|
||||
|
||||
fn disable(&self, vm: &Arc<VmFd>) -> Result<()> {
|
||||
vm.unregister_irqfd(&self.irq_fd, self.gsi)
|
||||
.map_err(VfioPciError::IrqFd)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -361,23 +368,32 @@ impl VfioPciDevice {
|
||||
let max_interrupts = vfio_pci_device.device.max_interrupts();
|
||||
for _ in 0..max_interrupts {
|
||||
let msi_vector: MsiVector = Default::default();
|
||||
let route = InterruptRoute::new(vm_fd, allocator, msi_vector)?;
|
||||
let route = InterruptRoute::new(allocator, msi_vector)?;
|
||||
vfio_pci_device.interrupt_routes.push(route);
|
||||
}
|
||||
|
||||
Ok(vfio_pci_device)
|
||||
}
|
||||
|
||||
fn irq_fds(&self) -> Result<Vec<&EventFd>> {
|
||||
fn enable_irq_fds(&self) -> Result<Vec<&EventFd>> {
|
||||
let mut irq_fds: Vec<&EventFd> = Vec::new();
|
||||
|
||||
for r in &self.interrupt_routes {
|
||||
r.enable(&self.vm_fd)?;
|
||||
irq_fds.push(&r.irq_fd);
|
||||
}
|
||||
|
||||
Ok(irq_fds)
|
||||
}
|
||||
|
||||
fn disable_irq_fds(&self) -> Result<()> {
|
||||
for r in &self.interrupt_routes {
|
||||
r.disable(&self.vm_fd)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_kvm_routes(&self) -> Result<()> {
|
||||
let mut entry_vec: Vec<kvm_irq_routing_entry> = Vec::new();
|
||||
for route in self.interrupt_routes.iter() {
|
||||
@ -535,7 +551,7 @@ impl VfioPciDevice {
|
||||
|
||||
fn update_msi_capabilities(&mut self, offset: u64, data: &[u8]) -> Result<()> {
|
||||
match self.interrupt.update_msi(offset, data) {
|
||||
Some(InterruptUpdateAction::EnableMsi) => match self.irq_fds() {
|
||||
Some(InterruptUpdateAction::EnableMsi) => match self.enable_irq_fds() {
|
||||
Ok(fds) => {
|
||||
if let Err(e) = self.device.enable_msi(fds) {
|
||||
warn!("Could not enable MSI: {}", e);
|
||||
@ -544,6 +560,9 @@ impl VfioPciDevice {
|
||||
Err(e) => warn!("Could not get IRQ fds: {}", e),
|
||||
},
|
||||
Some(InterruptUpdateAction::DisableMsi) => {
|
||||
if let Err(e) = self.disable_irq_fds() {
|
||||
warn!("Could not disable MSI: {}", e);
|
||||
}
|
||||
if let Err(e) = self.device.disable_msi() {
|
||||
warn!("Could not disable MSI: {}", e);
|
||||
}
|
||||
@ -564,7 +583,7 @@ impl VfioPciDevice {
|
||||
|
||||
fn update_msix_capabilities(&mut self, offset: u64, data: &[u8]) {
|
||||
match self.interrupt.update_msix(offset, data) {
|
||||
Some(InterruptUpdateAction::EnableMsix) => match self.irq_fds() {
|
||||
Some(InterruptUpdateAction::EnableMsix) => match self.enable_irq_fds() {
|
||||
Ok(fds) => {
|
||||
if let Err(e) = self.device.enable_msix(fds) {
|
||||
warn!("Could not enable MSI-X: {}", e);
|
||||
@ -573,6 +592,9 @@ impl VfioPciDevice {
|
||||
Err(e) => warn!("Could not get IRQ fds: {}", e),
|
||||
},
|
||||
Some(InterruptUpdateAction::DisableMsix) => {
|
||||
if let Err(e) = self.disable_irq_fds() {
|
||||
warn!("Could not disable MSI: {}", e);
|
||||
}
|
||||
if let Err(e) = self.device.disable_msix() {
|
||||
warn!("Could not disable MSI-X: {}", e);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user