@@ -126,7 +126,7 @@ ifeq ($(ARCH),x86)
endif
# POWER/ppc: Actually only support ppc64 currently.
ifeq ($(uname_M), ppc64)
- DEFINES += -DCONFIG_PPC
+ DEFINES += -DCONFIG_PPC -DCONFIG_NO_IOEVENTFDS
OBJS += powerpc/ioport.o
OBJS += powerpc/irq.o
OBJS += powerpc/kvm.o
@@ -4,6 +4,7 @@
#include <linux/types.h>
#include <linux/list.h>
#include <sys/eventfd.h>
+#include <stdbool.h>
struct kvm;
@@ -21,7 +22,7 @@ struct ioevent {
void ioeventfd__init(void);
void ioeventfd__start(void);
-void ioeventfd__add_event(struct ioevent *ioevent);
+bool ioeventfd__add_event(struct ioevent *ioevent);
void ioeventfd__del_event(u64 addr, u64 datamatch);
#endif
@@ -26,7 +26,7 @@ void ioeventfd__init(void)
die("Failed creating epoll fd");
}
-void ioeventfd__add_event(struct ioevent *ioevent)
+bool ioeventfd__add_event(struct ioevent *ioevent)
{
struct kvm_ioeventfd kvm_ioevent;
struct epoll_event epoll_event;
@@ -48,8 +48,13 @@ void ioeventfd__add_event(struct ioevent *ioevent)
.flags = KVM_IOEVENTFD_FLAG_PIO | KVM_IOEVENTFD_FLAG_DATAMATCH,
};
- if (ioctl(ioevent->fn_kvm->vm_fd, KVM_IOEVENTFD, &kvm_ioevent) != 0)
- die("Failed creating new ioeventfd");
+ if (ioctl(ioevent->fn_kvm->vm_fd, KVM_IOEVENTFD, &kvm_ioevent) != 0) {
+ /* Not all KVM implementations may support KVM_IOEVENTFD,
+ * so be graceful.
+ */
+ free(new_ioevent);
+ return false;
+ }
epoll_event = (struct epoll_event) {
.events = EPOLLIN,
@@ -60,6 +65,7 @@ void ioeventfd__add_event(struct ioevent *ioevent)
die("Failed assigning new event to the epoll fd");
list_add_tail(&new_ioevent->list, &used_ioevents);
+ return true;
}
void ioeventfd__del_event(u64 addr, u64 datamatch)
@@ -7,6 +7,7 @@
#include "kvm/virtio.h"
#include "kvm/ioeventfd.h"
#include "kvm/virtio-trans.h"
+#include "kvm/util.h"
#include <linux/virtio_pci.h>
#include <linux/byteorder.h>
@@ -50,7 +51,17 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtra
.fd = eventfd(0, 0),
};
- ioeventfd__add_event(&ioevent);
+ if (!ioeventfd__add_event(&ioevent)) {
+#ifndef CONFIG_NO_IOEVENTFDS
+ /*
+ * ioevents aren't supported on all KVM implementations, so we
+ * expect this to fail -- don't need to be verbose about it!
+ * For virtio-pci, this is fine. It catches the IO accesses
+ * anyway, so still works (but slower).
+ */
+ pr_warning("Failed creating new ioeventfd");
+#endif
+ }
if (vtrans->virtio_ops->notify_vq_eventfd)
vtrans->virtio_ops->notify_vq_eventfd(kvm, vpci->dev, vq, ioevent.fd);
Some KVM implementations (e.g. PPC) don't yet support ioeventfds, so don't bomb out/die. virtio-pci is able to function if it instead uses normal IO port notification. Signed-off-by: Matt Evans <matt@ozlabs.org> --- tools/kvm/Makefile | 2 +- tools/kvm/include/kvm/ioeventfd.h | 3 ++- tools/kvm/ioeventfd.c | 12 +++++++++--- tools/kvm/virtio/pci.c | 13 ++++++++++++- 4 files changed, 24 insertions(+), 6 deletions(-)