diff mbox

[kvmtool,2/3] ioeventfd: Don't register on the PIO bus if the arch doesn't support it

Message ID 20180404175354.4887-2-jean-philippe.brucker@arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jean-Philippe Brucker April 4, 2018, 5:53 p.m. UTC
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: a508ea95f954 ("virtio/pci: Use port I/O for configuration registers by default")
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
 arm/include/arm-common/kvm-arch.h |  2 ++
 include/kvm/ioeventfd.h           |  1 +
 ioeventfd.c                       | 13 +++++++++----
 mips/include/kvm/kvm-arch.h       |  2 ++
 powerpc/include/kvm/kvm-arch.h    |  2 ++
 x86/include/kvm/kvm-arch.h        |  2 ++
 6 files changed, 18 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h
index c83c45fc2041..b9d486d5eac2 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -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
diff --git a/include/kvm/ioeventfd.h b/include/kvm/ioeventfd.h
index bb1f78de9b57..a1cb8410ed14 100644
--- a/include/kvm/ioeventfd.h
+++ b/include/kvm/ioeventfd.h
@@ -16,6 +16,7 @@  struct ioevent {
 	void			*fn_ptr;
 	int			fd;
 	u64			datamatch;
+	u32			flags;
 
 	struct list_head	list;
 };
diff --git a/ioeventfd.c b/ioeventfd.c
index 186ac703e365..14453b82899d 100644
--- a/ioeventfd.c
+++ b/ioeventfd.c
@@ -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);
diff --git a/mips/include/kvm/kvm-arch.h b/mips/include/kvm/kvm-arch.h
index 97bbf3474e9e..fdc09d830263 100644
--- a/mips/include/kvm/kvm-arch.h
+++ b/mips/include/kvm/kvm-arch.h
@@ -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>
diff --git a/powerpc/include/kvm/kvm-arch.h b/powerpc/include/kvm/kvm-arch.h
index fdd518f07555..8126b96cb66a 100644
--- a/powerpc/include/kvm/kvm-arch.h
+++ b/powerpc/include/kvm/kvm-arch.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;
diff --git a/x86/include/kvm/kvm-arch.h b/x86/include/kvm/kvm-arch.h
index 50b3bfb459dd..bfdd3438a9de 100644
--- a/x86/include/kvm/kvm-arch.h
+++ b/x86/include/kvm/kvm-arch.h
@@ -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 {