From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42241) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZIEDI-0003o0-H6 for qemu-devel@nongnu.org; Thu, 23 Jul 2015 06:58:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZIEDD-0004aP-3V for qemu-devel@nongnu.org; Thu, 23 Jul 2015 06:58:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59936) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZIEDC-0004Zr-V6 for qemu-devel@nongnu.org; Thu, 23 Jul 2015 06:58:51 -0400 From: Stefan Hajnoczi Date: Thu, 23 Jul 2015 11:58:47 +0100 Message-Id: <1437649127-21839-1-git-send-email-stefanha@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [RFC] memory: emulate ioeventfd List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini , marcandre.lureau@gmail.com, Stefan Hajnoczi , "Michael S. Tsirkin" The ioeventfd mechanism is used by vhost, dataplane, and virtio-pci to turn guest MMIO/PIO writes into eventfd file descriptor events. This allows arbitrary threads to be notified when the guest writes to a specific MMIO/PIO address. qtest and TCG do not support ioeventfd because memory writes are not checked against registered ioeventfds in QEMU. This patch implements this in memory_region_dispatch_read() so qtest can use ioeventfd. This patch is suboptimal because the -machine accel=3Dkvm case now duplicates ioeventfd matching in QEMU userspace. If kvm.ko didn't match and we exited to userspace, then matching in QEMU userspace will fail too. Signed-off-by: Stefan Hajnoczi --- memory.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) Marc-Andr=C3=A9 asked about this patch so I'm sending it now. This is a first step to making qtest work with vhost. I haven't tested i= t. Not sure about irqfd either. Perhaps some work is necessary to make irqf= d work, but I think QEMU already implements that (at least in the virtio-pc= i case). diff --git a/memory.c b/memory.c index 0acebb1..407fec4 100644 --- a/memory.c +++ b/memory.c @@ -1146,6 +1146,32 @@ MemTxResult memory_region_dispatch_read(MemoryRegi= on *mr, return r; } =20 +/* Return true if an ioeventfd was signalled */ +static bool memory_region_dispatch_write_ioeventfds(MemoryRegion *mr, + hwaddr addr, + uint64_t data, + unsigned size, + MemTxAttrs attrs) +{ + MemoryRegionIoeventfd ioeventfd =3D { + .addr =3D addrrange_make(int128_make64(addr), int128_make64(size= )), + .data =3D data, + }; + unsigned i; + + for (i =3D 0; i < mr->ioeventfd_nb; i++) { + ioeventfd.match_data =3D mr->ioeventfds[i].match_data; + ioeventfd.e =3D mr->ioeventfds[i].e; + + if (memory_region_ioeventfd_equal(ioeventfd, mr->ioeventfds[i]))= { + event_notifier_set(ioeventfd.e); + return true; + } + } + + return false; +} + MemTxResult memory_region_dispatch_write(MemoryRegion *mr, hwaddr addr, uint64_t data, @@ -1159,6 +1185,10 @@ MemTxResult memory_region_dispatch_write(MemoryReg= ion *mr, =20 adjust_endianness(mr, &data, size); =20 + if (memory_region_dispatch_write_ioeventfds(mr, addr, data, size, at= trs)) { + return MEMTX_OK; + } + if (mr->ops->write) { return access_with_adjusted_size(addr, &data, size, mr->ops->impl.min_access_size, --=20 2.4.3