From nobody Sun Jul 13 20:59:11 2025 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1678213825986404.98136013273927; Tue, 7 Mar 2023 10:30:25 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZc2C-0006mk-V9; Tue, 07 Mar 2023 13:27:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZc24-0006hD-Iy for qemu-devel@nongnu.org; Tue, 07 Mar 2023 13:27:29 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZc1t-0005xu-9d for qemu-devel@nongnu.org; Tue, 07 Mar 2023 13:27:27 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pZc1n-006deC-Bg; Tue, 07 Mar 2023 18:27:11 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.96 #2 (Red Hat Linux)) id 1pZc1n-009e8h-0y; Tue, 07 Mar 2023 18:27:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=NmTq7xdswHQSe29JrCR0/eIaXBdiuGrCFOBx7jmSa9Y=; b=G5SUOmko1fipL6SDB2hu4ruoGS eW+Z8a2i4uMjcVHutfcbZBhulMuTBg2xj9mzOtwBLqAYYQVsmRhUPZgA6Nqm0vVvXGujfwEB0ycAf xR6+Bv1PKODyup3HH+4ZtQFr6PTKtAbDjiElsV4NeIOoyU4VaCXSLwk8JJ9P91GVywFguHdalmefi A/tHH4qSAlmWCdasOv7ocYXRlowDFuWxjqqMBMGUrMtBXCHqnNYF6OSLbX/AoyWECJCThLZD97NLL QdPN3dKR8s+VZofQYjpr8NJFrnW9f7n7nGvBawhggne6nZqV9Ipn4bfzz5hPrEPrIVRDU9C/7L+c1 sShbyWUw==; From: David Woodhouse To: Peter Maydell Cc: qemu-devel@nongnu.org, Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , Stefano Stabellini , vikram.garhwal@amd.com, Anthony Perard , xen-devel@lists.xenproject.org, Juan Quintela , "Dr . David Alan Gilbert" Subject: [PULL 09/27] hw/xen: Add evtchn operations to allow redirection to internal emulation Date: Tue, 7 Mar 2023 18:26:49 +0000 Message-Id: <20230307182707.2298618-10-dwmw2@infradead.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230307182707.2298618-1-dwmw2@infradead.org> References: <20230307182707.2298618-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+9298a7250c90fe94fbb7+7135+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1678213827213100001 From: David Woodhouse The existing implementation calling into the real libxenevtchn moves to a new file hw/xen/xen-operations.c, and is called via a function table which in a subsequent commit will also be able to invoke the emulated event channel support. Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- hw/9pfs/xen-9p-backend.c | 24 +++--- hw/i386/xen/xen-hvm.c | 27 ++++--- hw/xen/meson.build | 1 + hw/xen/xen-bus.c | 22 +++--- hw/xen/xen-legacy-backend.c | 8 +- hw/xen/xen-operations.c | 71 +++++++++++++++++ hw/xen/xen_pvdev.c | 12 +-- include/hw/xen/xen-bus.h | 1 + include/hw/xen/xen-legacy-backend.h | 1 + include/hw/xen/xen_backend_ops.h | 118 ++++++++++++++++++++++++++++ include/hw/xen/xen_common.h | 12 --- include/hw/xen/xen_pvdev.h | 1 + softmmu/globals.c | 1 + 13 files changed, 242 insertions(+), 57 deletions(-) create mode 100644 hw/xen/xen-operations.c create mode 100644 include/hw/xen/xen_backend_ops.h diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c index 65c4979c3c..864bdaf952 100644 --- a/hw/9pfs/xen-9p-backend.c +++ b/hw/9pfs/xen-9p-backend.c @@ -241,7 +241,7 @@ static void xen_9pfs_push_and_notify(V9fsPDU *pdu) xen_wmb(); =20 ring->inprogress =3D false; - xenevtchn_notify(ring->evtchndev, ring->local_port); + qemu_xen_evtchn_notify(ring->evtchndev, ring->local_port); =20 qemu_bh_schedule(ring->bh); } @@ -324,8 +324,8 @@ static void xen_9pfs_evtchn_event(void *opaque) Xen9pfsRing *ring =3D opaque; evtchn_port_t port; =20 - port =3D xenevtchn_pending(ring->evtchndev); - xenevtchn_unmask(ring->evtchndev, port); + port =3D qemu_xen_evtchn_pending(ring->evtchndev); + qemu_xen_evtchn_unmask(ring->evtchndev, port); =20 qemu_bh_schedule(ring->bh); } @@ -337,10 +337,10 @@ static void xen_9pfs_disconnect(struct XenLegacyDevic= e *xendev) =20 for (i =3D 0; i < xen_9pdev->num_rings; i++) { if (xen_9pdev->rings[i].evtchndev !=3D NULL) { - qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev= ), - NULL, NULL, NULL); - xenevtchn_unbind(xen_9pdev->rings[i].evtchndev, - xen_9pdev->rings[i].local_port); + qemu_set_fd_handler(qemu_xen_evtchn_fd(xen_9pdev->rings[i].evt= chndev), + NULL, NULL, NULL); + qemu_xen_evtchn_unbind(xen_9pdev->rings[i].evtchndev, + xen_9pdev->rings[i].local_port); xen_9pdev->rings[i].evtchndev =3D NULL; } } @@ -447,12 +447,12 @@ static int xen_9pfs_connect(struct XenLegacyDevice *x= endev) xen_9pdev->rings[i].inprogress =3D false; =20 =20 - xen_9pdev->rings[i].evtchndev =3D xenevtchn_open(NULL, 0); + xen_9pdev->rings[i].evtchndev =3D qemu_xen_evtchn_open(); if (xen_9pdev->rings[i].evtchndev =3D=3D NULL) { goto out; } - qemu_set_cloexec(xenevtchn_fd(xen_9pdev->rings[i].evtchndev)); - xen_9pdev->rings[i].local_port =3D xenevtchn_bind_interdomain + qemu_set_cloexec(qemu_xen_evtchn_fd(xen_9pdev->rings[i].evtchndev)= ); + xen_9pdev->rings[i].local_port =3D qemu_xen_evtchn_bind_interdomain (xen_9pdev->rings[i].evtchndev, xendev->dom, xen_9pdev->rings[i].evtchn); @@ -463,8 +463,8 @@ static int xen_9pfs_connect(struct XenLegacyDevice *xen= dev) goto out; } xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_po= rt); - qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), - xen_9pfs_evtchn_event, NULL, &xen_9pdev->rings[i]); + qemu_set_fd_handler(qemu_xen_evtchn_fd(xen_9pdev->rings[i].evtchnd= ev), + xen_9pfs_evtchn_event, NULL, &xen_9pdev->rings= [i]); } =20 xen_9pdev->security_model =3D xenstore_read_be_str(xendev, "security_m= odel"); diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index e5a1dd19f4..cb1d24f592 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -761,7 +761,7 @@ static ioreq_t *cpu_get_ioreq(XenIOState *state) int i; evtchn_port_t port; =20 - port =3D xenevtchn_pending(state->xce_handle); + port =3D qemu_xen_evtchn_pending(state->xce_handle); if (port =3D=3D state->bufioreq_local_port) { timer_mod(state->buffered_io_timer, BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIM= E)); @@ -780,7 +780,7 @@ static ioreq_t *cpu_get_ioreq(XenIOState *state) } =20 /* unmask the wanted port again */ - xenevtchn_unmask(state->xce_handle, port); + qemu_xen_evtchn_unmask(state->xce_handle, port); =20 /* get the io packet from shared memory */ state->send_vcpu =3D i; @@ -1147,7 +1147,7 @@ static void handle_buffered_io(void *opaque) BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIM= E)); } else { timer_del(state->buffered_io_timer); - xenevtchn_unmask(state->xce_handle, state->bufioreq_local_port); + qemu_xen_evtchn_unmask(state->xce_handle, state->bufioreq_local_po= rt); } } =20 @@ -1196,8 +1196,8 @@ static void cpu_handle_ioreq(void *opaque) } =20 req->state =3D STATE_IORESP_READY; - xenevtchn_notify(state->xce_handle, - state->ioreq_local_port[state->send_vcpu]); + qemu_xen_evtchn_notify(state->xce_handle, + state->ioreq_local_port[state->send_vcpu]); } } =20 @@ -1206,7 +1206,7 @@ static void xen_main_loop_prepare(XenIOState *state) int evtchn_fd =3D -1; =20 if (state->xce_handle !=3D NULL) { - evtchn_fd =3D xenevtchn_fd(state->xce_handle); + evtchn_fd =3D qemu_xen_evtchn_fd(state->xce_handle); } =20 state->buffered_io_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, handle_= buffered_io, @@ -1249,7 +1249,7 @@ static void xen_exit_notifier(Notifier *n, void *data) xenforeignmemory_unmap_resource(xen_fmem, state->fres); } =20 - xenevtchn_close(state->xce_handle); + qemu_xen_evtchn_close(state->xce_handle); xs_daemon_close(state->xenstore); } =20 @@ -1397,9 +1397,11 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryReg= ion **ram_memory) xen_pfn_t ioreq_pfn; XenIOState *state; =20 + setup_xen_backend_ops(); + state =3D g_new0(XenIOState, 1); =20 - state->xce_handle =3D xenevtchn_open(NULL, 0); + state->xce_handle =3D qemu_xen_evtchn_open(); if (state->xce_handle =3D=3D NULL) { perror("xen: event channel open"); goto err; @@ -1463,8 +1465,9 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegi= on **ram_memory) =20 /* FIXME: how about if we overflow the page here? */ for (i =3D 0; i < max_cpus; i++) { - rc =3D xenevtchn_bind_interdomain(state->xce_handle, xen_domid, - xen_vcpu_eport(state->shared_page,= i)); + rc =3D qemu_xen_evtchn_bind_interdomain(state->xce_handle, xen_dom= id, + xen_vcpu_eport(state->shared= _page, + i)); if (rc =3D=3D -1) { error_report("shared evtchn %d bind error %d", i, errno); goto err; @@ -1472,8 +1475,8 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegi= on **ram_memory) state->ioreq_local_port[i] =3D rc; } =20 - rc =3D xenevtchn_bind_interdomain(state->xce_handle, xen_domid, - state->bufioreq_remote_port); + rc =3D qemu_xen_evtchn_bind_interdomain(state->xce_handle, xen_domid, + state->bufioreq_remote_port); if (rc =3D=3D -1) { error_report("buffered evtchn bind error %d", errno); goto err; diff --git a/hw/xen/meson.build b/hw/xen/meson.build index ae0ace3046..f195bbd25c 100644 --- a/hw/xen/meson.build +++ b/hw/xen/meson.build @@ -5,6 +5,7 @@ softmmu_ss.add(when: ['CONFIG_XEN', xen], if_true: files( 'xen-legacy-backend.c', 'xen_devconfig.c', 'xen_pvdev.c', + 'xen-operations.c', )) =20 xen_specific_ss =3D ss.source_set() diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index df3f6b9ae0..d0b1ae93da 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -1095,12 +1095,12 @@ static bool xen_device_poll(void *opaque) static void xen_device_event(void *opaque) { XenEventChannel *channel =3D opaque; - unsigned long port =3D xenevtchn_pending(channel->xeh); + unsigned long port =3D qemu_xen_evtchn_pending(channel->xeh); =20 if (port =3D=3D channel->local_port) { xen_device_poll(channel); =20 - xenevtchn_unmask(channel->xeh, port); + qemu_xen_evtchn_unmask(channel->xeh, port); } } =20 @@ -1115,11 +1115,11 @@ void xen_device_set_event_channel_context(XenDevice= *xendev, } =20 if (channel->ctx) - aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, + aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),= true, NULL, NULL, NULL, NULL, NULL); =20 channel->ctx =3D ctx; - aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, + aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), tru= e, xen_device_event, NULL, xen_device_poll, NULL, chan= nel); } =20 @@ -1131,13 +1131,13 @@ XenEventChannel *xen_device_bind_event_channel(XenD= evice *xendev, XenEventChannel *channel =3D g_new0(XenEventChannel, 1); xenevtchn_port_or_error_t local_port; =20 - channel->xeh =3D xenevtchn_open(NULL, 0); + channel->xeh =3D qemu_xen_evtchn_open(); if (!channel->xeh) { error_setg_errno(errp, errno, "failed xenevtchn_open"); goto fail; } =20 - local_port =3D xenevtchn_bind_interdomain(channel->xeh, + local_port =3D qemu_xen_evtchn_bind_interdomain(channel->xeh, xendev->frontend_id, port); if (local_port < 0) { @@ -1160,7 +1160,7 @@ XenEventChannel *xen_device_bind_event_channel(XenDev= ice *xendev, =20 fail: if (channel->xeh) { - xenevtchn_close(channel->xeh); + qemu_xen_evtchn_close(channel->xeh); } =20 g_free(channel); @@ -1177,7 +1177,7 @@ void xen_device_notify_event_channel(XenDevice *xende= v, return; } =20 - if (xenevtchn_notify(channel->xeh, channel->local_port) < 0) { + if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) { error_setg_errno(errp, errno, "xenevtchn_notify failed"); } } @@ -1193,14 +1193,14 @@ void xen_device_unbind_event_channel(XenDevice *xen= dev, =20 QLIST_REMOVE(channel, list); =20 - aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, + aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), tru= e, NULL, NULL, NULL, NULL, NULL); =20 - if (xenevtchn_unbind(channel->xeh, channel->local_port) < 0) { + if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) { error_setg_errno(errp, errno, "xenevtchn_unbind failed"); } =20 - xenevtchn_close(channel->xeh); + qemu_xen_evtchn_close(channel->xeh); g_free(channel); } =20 diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c index afba71f6eb..9ce3dc204b 100644 --- a/hw/xen/xen-legacy-backend.c +++ b/hw/xen/xen-legacy-backend.c @@ -294,13 +294,13 @@ static struct XenLegacyDevice *xen_be_get_xendev(cons= t char *type, int dom, xendev->debug =3D debug; xendev->local_port =3D -1; =20 - xendev->evtchndev =3D xenevtchn_open(NULL, 0); + xendev->evtchndev =3D qemu_xen_evtchn_open(); if (xendev->evtchndev =3D=3D NULL) { xen_pv_printf(NULL, 0, "can't open evtchn device\n"); qdev_unplug(DEVICE(xendev), NULL); return NULL; } - qemu_set_cloexec(xenevtchn_fd(xendev->evtchndev)); + qemu_set_cloexec(qemu_xen_evtchn_fd(xendev->evtchndev)); =20 xen_pv_insert_xendev(xendev); =20 @@ -751,14 +751,14 @@ int xen_be_bind_evtchn(struct XenLegacyDevice *xendev) if (xendev->local_port !=3D -1) { return 0; } - xendev->local_port =3D xenevtchn_bind_interdomain + xendev->local_port =3D qemu_xen_evtchn_bind_interdomain (xendev->evtchndev, xendev->dom, xendev->remote_port); if (xendev->local_port =3D=3D -1) { xen_pv_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n"); return -1; } xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port); - qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), + qemu_set_fd_handler(qemu_xen_evtchn_fd(xendev->evtchndev), xen_pv_evtchn_event, NULL, xendev); return 0; } diff --git a/hw/xen/xen-operations.c b/hw/xen/xen-operations.c new file mode 100644 index 0000000000..1a959d89e8 --- /dev/null +++ b/hw/xen/xen-operations.c @@ -0,0 +1,71 @@ +/* + * QEMU Xen backend support: Operations for true Xen + * + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: David Woodhouse + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" + +#include "hw/xen/xen_backend_ops.h" +#include "hw/xen/xen_common.h" + +/* + * If we have new enough libxenctrl then we do not want/need these compat + * interfaces, despite what the user supplied cflags might say. They + * must be undefined before including xenctrl.h + */ +#undef XC_WANT_COMPAT_EVTCHN_API + +#include + +/* + * We don't support Xen prior to 4.2.0. + */ + +/* Xen 4.2 through 4.6 */ +#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40701 + +typedef xc_evtchn xenevtchn_handle; +typedef evtchn_port_or_error_t xenevtchn_port_or_error_t; + +#define xenevtchn_open(l, f) xc_evtchn_open(l, f); +#define xenevtchn_close(h) xc_evtchn_close(h) +#define xenevtchn_fd(h) xc_evtchn_fd(h) +#define xenevtchn_pending(h) xc_evtchn_pending(h) +#define xenevtchn_notify(h, p) xc_evtchn_notify(h, p) +#define xenevtchn_bind_interdomain(h, d, p) xc_evtchn_bind_interdomain(h, = d, p) +#define xenevtchn_unmask(h, p) xc_evtchn_unmask(h, p) +#define xenevtchn_unbind(h, p) xc_evtchn_unbind(h, p) + +#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >=3D 40701 */ + +#include + +#endif + +static xenevtchn_handle *libxenevtchn_backend_open(void) +{ + return xenevtchn_open(NULL, 0); +} + +struct evtchn_backend_ops libxenevtchn_backend_ops =3D { + .open =3D libxenevtchn_backend_open, + .close =3D xenevtchn_close, + .bind_interdomain =3D xenevtchn_bind_interdomain, + .unbind =3D xenevtchn_unbind, + .get_fd =3D xenevtchn_fd, + .notify =3D xenevtchn_notify, + .unmask =3D xenevtchn_unmask, + .pending =3D xenevtchn_pending, +}; + +void setup_xen_backend_ops(void) +{ + xen_evtchn_ops =3D &libxenevtchn_backend_ops; +} diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index 1a5177b354..86a2c8e567 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -238,14 +238,14 @@ void xen_pv_evtchn_event(void *opaque) struct XenLegacyDevice *xendev =3D opaque; evtchn_port_t port; =20 - port =3D xenevtchn_pending(xendev->evtchndev); + port =3D qemu_xen_evtchn_pending(xendev->evtchndev); if (port !=3D xendev->local_port) { xen_pv_printf(xendev, 0, "xenevtchn_pending returned %d (expected %d)\n", port, xendev->local_port); return; } - xenevtchn_unmask(xendev->evtchndev, port); + qemu_xen_evtchn_unmask(xendev->evtchndev, port); =20 if (xendev->ops->event) { xendev->ops->event(xendev); @@ -257,15 +257,15 @@ void xen_pv_unbind_evtchn(struct XenLegacyDevice *xen= dev) if (xendev->local_port =3D=3D -1) { return; } - qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL); - xenevtchn_unbind(xendev->evtchndev, xendev->local_port); + qemu_set_fd_handler(qemu_xen_evtchn_fd(xendev->evtchndev), NULL, NULL,= NULL); + qemu_xen_evtchn_unbind(xendev->evtchndev, xendev->local_port); xen_pv_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port= ); xendev->local_port =3D -1; } =20 int xen_pv_send_notify(struct XenLegacyDevice *xendev) { - return xenevtchn_notify(xendev->evtchndev, xendev->local_port); + return qemu_xen_evtchn_notify(xendev->evtchndev, xendev->local_port); } =20 /* ------------------------------------------------------------- */ @@ -306,7 +306,7 @@ void xen_pv_del_xendev(struct XenLegacyDevice *xendev) } =20 if (xendev->evtchndev !=3D NULL) { - xenevtchn_close(xendev->evtchndev); + qemu_xen_evtchn_close(xendev->evtchndev); } if (xendev->gnttabdev !=3D NULL) { xengnttab_close(xendev->gnttabdev); diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 4d966a2dbb..e21b83796e 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -8,6 +8,7 @@ #ifndef HW_XEN_BUS_H #define HW_XEN_BUS_H =20 +#include "hw/xen/xen_backend_ops.h" #include "hw/xen/xen_common.h" #include "hw/sysbus.h" #include "qemu/notify.h" diff --git a/include/hw/xen/xen-legacy-backend.h b/include/hw/xen/xen-legac= y-backend.h index e31cd3a068..06985b1f03 100644 --- a/include/hw/xen/xen-legacy-backend.h +++ b/include/hw/xen/xen-legacy-backend.h @@ -2,6 +2,7 @@ #define HW_XEN_LEGACY_BACKEND_H =20 #include "hw/xen/xen_common.h" +#include "hw/xen/xen_backend_ops.h" #include "hw/xen/xen_pvdev.h" #include "net/net.h" #include "qom/object.h" diff --git a/include/hw/xen/xen_backend_ops.h b/include/hw/xen/xen_backend_= ops.h new file mode 100644 index 0000000000..9605456e81 --- /dev/null +++ b/include/hw/xen/xen_backend_ops.h @@ -0,0 +1,118 @@ +/* + * QEMU Xen backend support + * + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: David Woodhouse + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef QEMU_XEN_BACKEND_OPS_H +#define QEMU_XEN_BACKEND_OPS_H + +/* + * For the time being, these operations map fairly closely to the API of + * the actual Xen libraries, e.g. libxenevtchn. As we complete the migrati= on + * from XenLegacyDevice back ends to the new XenDevice model, they may + * evolve to slightly higher-level APIs. + * + * The internal emulations do not emulate the Xen APIs entirely faithfully; + * only enough to be used by the Xen backend devices. For example, only one + * event channel can be bound to each handle, since that's sufficient for + * the device support (only the true Xen HVM backend uses more). And the + * behaviour of unmask() and pending() is different too because the device + * backends don't care. + */ + +typedef struct xenevtchn_handle xenevtchn_handle; +typedef int xenevtchn_port_or_error_t; +typedef uint32_t evtchn_port_t; + +struct evtchn_backend_ops { + xenevtchn_handle *(*open)(void); + int (*bind_interdomain)(xenevtchn_handle *xc, uint32_t domid, + evtchn_port_t guest_port); + int (*unbind)(xenevtchn_handle *xc, evtchn_port_t port); + int (*close)(struct xenevtchn_handle *xc); + int (*get_fd)(struct xenevtchn_handle *xc); + int (*notify)(struct xenevtchn_handle *xc, evtchn_port_t port); + int (*unmask)(struct xenevtchn_handle *xc, evtchn_port_t port); + int (*pending)(struct xenevtchn_handle *xc); +}; + +extern struct evtchn_backend_ops *xen_evtchn_ops; + +static inline xenevtchn_handle *qemu_xen_evtchn_open(void) +{ + if (!xen_evtchn_ops) { + return NULL; + } + return xen_evtchn_ops->open(); +} + +static inline int qemu_xen_evtchn_bind_interdomain(xenevtchn_handle *xc, + uint32_t domid, + evtchn_port_t guest_por= t) +{ + if (!xen_evtchn_ops) { + return -ENOSYS; + } + return xen_evtchn_ops->bind_interdomain(xc, domid, guest_port); +} + +static inline int qemu_xen_evtchn_unbind(xenevtchn_handle *xc, + evtchn_port_t port) +{ + if (!xen_evtchn_ops) { + return -ENOSYS; + } + return xen_evtchn_ops->unbind(xc, port); +} + +static inline int qemu_xen_evtchn_close(xenevtchn_handle *xc) +{ + if (!xen_evtchn_ops) { + return -ENOSYS; + } + return xen_evtchn_ops->close(xc); +} + +static inline int qemu_xen_evtchn_fd(xenevtchn_handle *xc) +{ + if (!xen_evtchn_ops) { + return -ENOSYS; + } + return xen_evtchn_ops->get_fd(xc); +} + +static inline int qemu_xen_evtchn_notify(xenevtchn_handle *xc, + evtchn_port_t port) +{ + if (!xen_evtchn_ops) { + return -ENOSYS; + } + return xen_evtchn_ops->notify(xc, port); +} + +static inline int qemu_xen_evtchn_unmask(xenevtchn_handle *xc, + evtchn_port_t port) +{ + if (!xen_evtchn_ops) { + return -ENOSYS; + } + return xen_evtchn_ops->unmask(xc, port); +} + +static inline int qemu_xen_evtchn_pending(xenevtchn_handle *xc) +{ + if (!xen_evtchn_ops) { + return -ENOSYS; + } + return xen_evtchn_ops->pending(xc); +} + +void setup_xen_backend_ops(void); + +#endif /* QEMU_XEN_BACKEND_OPS_H */ diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 9a13a756ae..34abd0a772 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -28,18 +28,7 @@ extern xc_interface *xen_xc; #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40701 =20 typedef xc_interface xenforeignmemory_handle; -typedef xc_evtchn xenevtchn_handle; typedef xc_gnttab xengnttab_handle; -typedef evtchn_port_or_error_t xenevtchn_port_or_error_t; - -#define xenevtchn_open(l, f) xc_evtchn_open(l, f); -#define xenevtchn_close(h) xc_evtchn_close(h) -#define xenevtchn_fd(h) xc_evtchn_fd(h) -#define xenevtchn_pending(h) xc_evtchn_pending(h) -#define xenevtchn_notify(h, p) xc_evtchn_notify(h, p) -#define xenevtchn_bind_interdomain(h, d, p) xc_evtchn_bind_interdomain(h, = d, p) -#define xenevtchn_unmask(h, p) xc_evtchn_unmask(h, p) -#define xenevtchn_unbind(h, p) xc_evtchn_unbind(h, p) =20 #define xengnttab_open(l, f) xc_gnttab_open(l, f) #define xengnttab_close(h) xc_gnttab_close(h) @@ -69,7 +58,6 @@ static inline void *xenforeignmemory_map(xc_interface *h,= uint32_t dom, =20 #else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >=3D 40701 */ =20 -#include #include #include =20 diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index 7cd4bc2b82..9c27b14764 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -1,6 +1,7 @@ #ifndef QEMU_HW_XEN_PVDEV_H #define QEMU_HW_XEN_PVDEV_H =20 +#include "hw/xen/xen_backend_ops.h" #include "hw/xen/xen_common.h" /* ------------------------------------------------------------- */ =20 diff --git a/softmmu/globals.c b/softmmu/globals.c index 0a4405614e..eb62739be1 100644 --- a/softmmu/globals.c +++ b/softmmu/globals.c @@ -65,3 +65,4 @@ bool qemu_uuid_set; uint32_t xen_domid; enum xen_mode xen_mode =3D XEN_DISABLED; bool xen_domid_restrict; +struct evtchn_backend_ops *xen_evtchn_ops; --=20 2.39.0