From nobody Thu Nov 6 19:39:03 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1542814499475187.4243975299977; Wed, 21 Nov 2018 07:34:59 -0800 (PST) Received: from localhost ([::1]:39819 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPUWj-0005x1-7J for importer@patchew.org; Wed, 21 Nov 2018 10:34:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52515) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPURM-0001iL-9o for qemu-devel@nongnu.org; Wed, 21 Nov 2018 10:29:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPURE-0007iU-MA for qemu-devel@nongnu.org; Wed, 21 Nov 2018 10:29:18 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:57320) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPUR2-0007ZM-EO; Wed, 21 Nov 2018 10:29:00 -0500 X-IronPort-AV: E=Sophos;i="5.56,261,1539648000"; d="scan'208";a="71207534" From: Paul Durrant To: , , Date: Wed, 21 Nov 2018 15:12:07 +0000 Message-ID: <20181121151211.15997-15-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181121151211.15997-1-paul.durrant@citrix.com> References: <20181121151211.15997-1-paul.durrant@citrix.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions... X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anthony Perard , Kevin Wolf , Paul Durrant , Stefano Stabellini , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ...and wire in the dataplane. This patch adds the remaining code to make the xen-qdisk XenDevice functional. The parameters that a block frontend expects to find are populated in the backend xenstore area, and the 'ring-ref' and 'event-channel' values specified in the frontend xenstore area are mapped/bound and used to set up the dataplane. Signed-off-by: Paul Durrant --- Cc: Stefano Stabellini Cc: Anthony Perard Cc: Kevin Wolf Cc: Max Reitz --- hw/block/xen-qdisk.c | 140 +++++++++++++++++++++++++++++++++++++++++= ++++ hw/xen/xen-bus.c | 12 ++-- include/hw/xen/xen-bus.h | 8 +++ include/hw/xen/xen-qdisk.h | 12 ++++ 4 files changed, 166 insertions(+), 6 deletions(-) diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c index 35f7b70480..8c88393832 100644 --- a/hw/block/xen-qdisk.c +++ b/hw/block/xen-qdisk.c @@ -9,6 +9,10 @@ #include "qapi/visitor.h" #include "hw/hw.h" #include "hw/xen/xen-qdisk.h" +#include "sysemu/blockdev.h" +#include "sysemu/block-backend.h" +#include "sysemu/iothread.h" +#include "dataplane/xen-qdisk.h" #include "trace.h" =20 static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp) @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev, Error *= *errp) { XenQdiskDevice *qdiskdev =3D XEN_QDISK_DEVICE(xendev); XenQdiskVdev *vdev =3D &qdiskdev->vdev; + BlockConf *conf =3D &qdiskdev->conf; + DriveInfo *dinfo; + bool is_cdrom; + unsigned int info; + int64_t size; =20 if (!vdev->valid) { error_setg(errp, "vdev property not set"); @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev, Error= **errp) } =20 trace_xen_qdisk_realize(vdev->disk, vdev->partition); + + if (!conf->blk) { + error_setg(errp, "drive property not set"); + return; + } + + if (!blk_is_inserted(conf->blk)) { + error_setg(errp, "device needs media, but drive is empty"); + return; + } + + if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf->blk), + false, errp)) { + return; + } + + if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) { + return; + } + + dinfo =3D blk_legacy_dinfo(conf->blk); + is_cdrom =3D (dinfo && dinfo->media_cd); + + blkconf_blocksizes(conf); + + if (conf->logical_block_size > conf->physical_block_size) { + error_setg( + errp, "logical_block_size > physical_block_size not supported"= ); + return; + } + + blk_set_guest_block_size(conf->blk, conf->logical_block_size); + + if (conf->discard_granularity > 0) { + xen_device_backend_printf(xendev, "feature-discard", "%u", 1); + } + + xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1); + xen_device_backend_printf(xendev, "max-ring-page-order", "%u", + qdiskdev->max_ring_page_order); + + info =3D blk_is_read_only(conf->blk) ? VDISK_READONLY : 0; + info |=3D is_cdrom ? VDISK_CDROM : 0; + + xen_device_backend_printf(xendev, "info", "%u", info); + + xen_device_frontend_printf(xendev, "virtual-device", "%u", + vdev->number); + xen_device_frontend_printf(xendev, "device-type", "%s", + is_cdrom ? "cdrom" : "disk"); + + size =3D blk_getlength(conf->blk); + xen_device_backend_printf(xendev, "sector-size", "%u", + conf->logical_block_size); + xen_device_backend_printf(xendev, "sectors", "%lu", + size / conf->logical_block_size); + + qdiskdev->dataplane =3D xen_qdisk_dataplane_create(xendev, conf, + qdiskdev->iothread); } =20 static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp) { XenQdiskVdev *vdev =3D &qdiskdev->vdev; + XenDevice *xendev =3D XEN_DEVICE(qdiskdev); + unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol; + char *str; =20 trace_xen_qdisk_connect(vdev->disk, vdev->partition); + + if (xen_device_frontend_scanf(xendev, "ring-page-order", "%u", + &order) !=3D 1) { + nr_ring_ref =3D 1; + ring_ref =3D g_new(unsigned int, nr_ring_ref); + + if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", + &ring_ref[0]) !=3D 1) { + error_setg(errp, "failed to read ring-ref"); + return; + } + } else if (order <=3D qdiskdev->max_ring_page_order) { + unsigned int i; + + nr_ring_ref =3D 1 << order; + ring_ref =3D g_new(unsigned int, nr_ring_ref); + + for (i =3D 0; i < nr_ring_ref; i++) { + const char *key =3D g_strdup_printf("ring-ref%u", i); + + if (xen_device_frontend_scanf(xendev, key, "%u", + &ring_ref[i]) !=3D 1) { + error_setg(errp, "failed to read %s", key); + g_free((gpointer)key); + return; + } + + g_free((gpointer)key); + } + } else { + error_setg(errp, "invalid ring-page-order (%d)", order); + return; + } + + if (xen_device_frontend_scanf(xendev, "event-channel", "%u", + &event_channel) !=3D 1) { + error_setg(errp, "failed to read event-channel"); + return; + } + + if (xen_device_frontend_scanf(xendev, "protocol", "%ms", + &str) !=3D 1) { + protocol =3D BLKIF_PROTOCOL_NATIVE; + } else { + if (strcmp(str, XEN_IO_PROTO_ABI_X86_32) =3D=3D 0) { + protocol =3D BLKIF_PROTOCOL_X86_32; + } else if (strcmp(str, XEN_IO_PROTO_ABI_X86_64) =3D=3D 0) { + protocol =3D BLKIF_PROTOCOL_X86_64; + } else { + protocol =3D BLKIF_PROTOCOL_NATIVE; + } + + free(str); + } + + xen_qdisk_dataplane_start(qdiskdev->dataplane, ring_ref, nr_ring_ref, + event_channel, protocol); + + g_free(ring_ref); } =20 static void xen_qdisk_disconnect(XenQdiskDevice *qdiskdev, Error **errp) @@ -44,6 +174,8 @@ static void xen_qdisk_disconnect(XenQdiskDevice *qdiskde= v, Error **errp) XenQdiskVdev *vdev =3D &qdiskdev->vdev; =20 trace_xen_qdisk_disconnect(vdev->disk, vdev->partition); + + xen_qdisk_dataplane_stop(qdiskdev->dataplane); } =20 static void xen_qdisk_frontend_changed(XenDevice *xendev, @@ -93,6 +225,9 @@ static void xen_qdisk_unrealize(XenDevice *xendev, Error= **errp) trace_xen_qdisk_unrealize(vdev->disk, vdev->partition); =20 xen_qdisk_disconnect(qdiskdev, &error_fatal); + + xen_qdisk_dataplane_destroy(qdiskdev->dataplane); + qdiskdev->dataplane =3D NULL; } =20 static char *disk_to_vbd_name(unsigned int disk) @@ -289,6 +424,11 @@ const PropertyInfo xen_qdisk_prop_vdev =3D { static Property xen_qdisk_props[] =3D { DEFINE_PROP("vdev", XenQdiskDevice, vdev, xen_qdisk_prop_vdev, XenQdiskVdev), + DEFINE_BLOCK_PROPERTIES(XenQdiskDevice, conf), + DEFINE_PROP_UINT32("max-ring-page-order", XenQdiskDevice, + max_ring_page_order, 4), + DEFINE_PROP_LINK("iothread", XenQdiskDevice, iothread, TYPE_IOTHREAD, + IOThread *), DEFINE_PROP_END_OF_LIST() }; =20 diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index 64c8af54b0..c4b253103f 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -217,8 +217,8 @@ static const TypeInfo xen_bus_type_info =3D { .class_init =3D xen_bus_class_init, }; =20 -static void xen_device_backend_printf(XenDevice *xendev, const char *key, - const char *fmt, ...) +void xen_device_backend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); va_list ap; @@ -305,8 +305,8 @@ static void xen_device_backend_destroy(XenDevice *xende= v) g_free(xendev->backend_path); } =20 -static void xen_device_frontend_printf(XenDevice *xendev, const char *key, - const char *fmt, ...) +void xen_device_frontend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); va_list ap; @@ -318,8 +318,8 @@ static void xen_device_frontend_printf(XenDevice *xende= v, const char *key, va_end(ap); } =20 -static int xen_device_frontend_scanf(XenDevice *xendev, const char *key, - const char *fmt, ...) +int xen_device_frontend_scanf(XenDevice *xendev, const char *key, + const char *fmt, ...) { XenBus *xenbus =3D XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); va_list ap; diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 386f6bfc93..d931e01268 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -82,6 +82,14 @@ void xen_device_backend_set_state(XenDevice *xendev, enum xenbus_state state); enum xenbus_state xen_device_backend_get_state(XenDevice *xendev); =20 +void xen_device_backend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...); + +void xen_device_frontend_printf(XenDevice *xendev, const char *key, + const char *fmt, ...); +int xen_device_frontend_scanf(XenDevice *xendev, const char *key, + const char *fmt, ...); + void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, Error **errp); void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs, diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h index ade0866037..d7dd2bf0ee 100644 --- a/include/hw/xen/xen-qdisk.h +++ b/include/hw/xen/xen-qdisk.h @@ -6,7 +6,15 @@ #ifndef HW_XEN_QDISK_H #define HW_XEN_QDISK_H =20 +#include "hw/xen/xen.h" #include "hw/xen/xen-bus.h" +#include "hw/block/block.h" +#include "hw/block/xen_blkif.h" +#include "hw/block/dataplane/xen-qdisk.h" +#include "sysemu/blockdev.h" +#include "sysemu/iothread.h" +#include "sysemu/block-backend.h" +#include "sysemu/iothread.h" =20 typedef enum XenQdiskVdevType { XEN_QDISK_VDEV_TYPE_DP, @@ -33,6 +41,10 @@ typedef struct XenQdiskDevice XenQdiskDevice; struct XenQdiskDevice { XenDevice xendev; XenQdiskVdev vdev; + BlockConf conf; + unsigned int max_ring_page_order; + IOThread *iothread; + XenQdiskDataPlane *dataplane; }; =20 #endif /* HW_XEN_QDISK_H */ --=20 2.11.0