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@xxxxxxxxxx> --- 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(-) diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 3f1e84a..5bb3f08 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -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 diff --git a/tools/kvm/include/kvm/ioeventfd.h b/tools/kvm/include/kvm/ioeventfd.h index df01750..5e458be 100644 --- a/tools/kvm/include/kvm/ioeventfd.h +++ b/tools/kvm/include/kvm/ioeventfd.h @@ -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 diff --git a/tools/kvm/ioeventfd.c b/tools/kvm/ioeventfd.c index 3a240e4..37f9a63 100644 --- a/tools/kvm/ioeventfd.c +++ b/tools/kvm/ioeventfd.c @@ -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) diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index a7da8e8..56fa4ad 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -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); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html