Commit ed83730f authored by Jean-Philippe Brucker's avatar Jean-Philippe Brucker Committed by Will Deacon
Browse files

ioeventfd: Don't register on the PIO bus if the arch doesn't support it

virtio/pci.c registers a notification ioeventfd on both PIO and MMIO
buses. But architectures other than x86 cannot differentiate MMIO from
PIO traps, and the kernel always calls kvm_io_bus_read/write with
KVM_MMIO_BUS as argument.

As a result kvmtool's ioeventfd isn't used with virtio PCI, because the
kernel can't find it and all accesses to the doorbell return to
userspace. To fix it, don't set the PIO flag if the architecture doesn't
support it.

Fixes: a508ea95

 ("virtio/pci: Use port I/O for configuration registers by default")
Signed-off-by: default avatarJean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 5e9dd852
......@@ -32,6 +32,8 @@
#define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE)
#define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA
#define KVM_IOEVENTFD_HAS_PIO 0
/*
* On a GICv3 there must be one redistributor per vCPU.
* The value here is the size for one, we multiply this at runtime with
......
......@@ -16,6 +16,7 @@ struct ioevent {
void *fn_ptr;
int fd;
u64 datamatch;
u32 flags;
struct list_head list;
};
......
......@@ -145,7 +145,12 @@ int ioeventfd__add_event(struct ioevent *ioevent, int flags)
.flags = KVM_IOEVENTFD_FLAG_DATAMATCH,
};
if (flags & IOEVENTFD_FLAG_PIO)
/*
* For architectures that don't recognize PIO accesses, always register
* on the MMIO bus. Otherwise PIO accesses will cause returns to
* userspace.
*/
if (KVM_IOEVENTFD_HAS_PIO && flags & IOEVENTFD_FLAG_PIO)
kvm_ioevent.flags |= KVM_IOEVENTFD_FLAG_PIO;
r = ioctl(ioevent->fn_kvm->vm_fd, KVM_IOEVENTFD, &kvm_ioevent);
......@@ -167,6 +172,7 @@ int ioeventfd__add_event(struct ioevent *ioevent, int flags)
}
}
ioevent->flags = kvm_ioevent.flags;
list_add_tail(&new_ioevent->list, &used_ioevents);
return 0;
......@@ -199,9 +205,8 @@ int ioeventfd__del_event(u64 addr, u64 datamatch)
.addr = ioevent->io_addr,
.len = ioevent->io_len,
.datamatch = ioevent->datamatch,
.flags = KVM_IOEVENTFD_FLAG_PIO
| KVM_IOEVENTFD_FLAG_DEASSIGN
| KVM_IOEVENTFD_FLAG_DATAMATCH,
.flags = ioevent->flags
| KVM_IOEVENTFD_FLAG_DEASSIGN,
};
ioctl(ioevent->fn_kvm->vm_fd, KVM_IOEVENTFD, &kvm_ioevent);
......
......@@ -32,6 +32,8 @@
*/
#define KVM_VM_TYPE 1
#define KVM_IOEVENTFD_HAS_PIO 0
#define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI
#include <stdbool.h>
......
......@@ -46,6 +46,8 @@
#define KVM_VM_TYPE 0
#define KVM_IOEVENTFD_HAS_PIO 0
#define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI
struct spapr_phb;
......
......@@ -28,6 +28,8 @@
#define KVM_VM_TYPE 0
#define KVM_IOEVENTFD_HAS_PIO 1
#define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI
struct kvm_arch {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment