From patchwork Mon Nov 27 07:27:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergiy Kibrik X-Patchwork-Id: 13469247 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 72B78C4167B for ; Mon, 27 Nov 2023 07:29:15 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.641630.1000358 (Exim 4.92) (envelope-from ) id 1r7W3E-000587-KF; Mon, 27 Nov 2023 07:29:04 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 641630.1000358; Mon, 27 Nov 2023 07:29:04 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7W3E-000580-Hf; Mon, 27 Nov 2023 07:29:04 +0000 Received: by outflank-mailman (input) for mailman id 641630; Mon, 27 Nov 2023 07:29:03 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7W3D-0004kO-BF for xen-devel@lists.xenproject.org; Mon, 27 Nov 2023 07:29:03 +0000 Received: from pb-smtp21.pobox.com (pb-smtp21.pobox.com [173.228.157.53]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id a1998854-8cf6-11ee-9b0e-b553b5be7939; Mon, 27 Nov 2023 08:29:01 +0100 (CET) Received: from pb-smtp21.pobox.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id 0EDD41A518; Mon, 27 Nov 2023 02:28:59 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from pb-smtp21.sea.icgroup.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id 064691A517; Mon, 27 Nov 2023 02:28:59 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from localhost (unknown [188.163.75.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pb-smtp21.pobox.com (Postfix) with ESMTPSA id B2C721A516; Mon, 27 Nov 2023 02:28:55 -0500 (EST) (envelope-from sakib@darkstar.site) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a1998854-8cf6-11ee-9b0e-b553b5be7939 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=pobox.com; h=from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; s=sasl; bh=JxaNh5W5NVw14x6LTlh4LsUYY sXdhWV9cMoMNLEDhSM=; b=jqHc+rVh38HE5GawOxoTPLHXqGIuJB5IUfFZjkvlk QrKYYmSPtTgyO/nyWGDxNynmNVNDRmyij8vh+9KYzm8bozxS9T4J8X8Ue/JcRWZd vm9YB1UmiR9FGHbrURTvFaTOM+tc09UIwMbS7Q6bWRWLHP6JsFDI7P8qAMqUrPZo lw= From: Sergiy Kibrik To: xen-devel@lists.xenproject.org, Julien Grall Cc: Oleksandr Tyshchenko , Stefano Stabellini , Volodymyr Babchuk , Stewart Hildebrand , Juergen Gross , Wei Liu , Anthony PERARD , Sergiy Kibrik Subject: [RFC PATCH v1 1/5] libxl: Pass max_vcpus to Qemu in case of PVH domain (Arm) as well Date: Mon, 27 Nov 2023 09:27:50 +0200 Message-Id: <20231127072754.4045254-2-Sergiy_Kibrik@epam.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> References: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> MIME-Version: 1.0 X-Pobox-Relay-ID: 9F4C56C2-8CF6-11EE-888E-A19503B9AAD1-90055647!pb-smtp21.pobox.com From: Oleksandr Tyshchenko The number of vCPUs used for the IOREQ configuration (machine->smp.cpus) should really match the system value as for each vCPU we setup a dedicated evtchn for the communication with Xen at the runtime. This is needed for the IOREQ to be properly configured and work if the involved domain has more than one vCPU assigned. Note that Qemu should set mc->max_cpus to GUEST_MAX_VCPUS in xen_arm_machine_class_init(). Signed-off-by: Oleksandr Tyshchenko Signed-off-by: Sergiy Kibrik --- tools/libs/light/libxl_dm.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c index 14b593110f..0b2548d35b 100644 --- a/tools/libs/light/libxl_dm.c +++ b/tools/libs/light/libxl_dm.c @@ -1553,18 +1553,6 @@ static int libxl__build_device_model_args_new(libxl__gc *gc, if (!libxl__acpi_defbool_val(b_info)) { flexarray_append(dm_args, "-no-acpi"); } - if (b_info->max_vcpus > 1) { - flexarray_append(dm_args, "-smp"); - if (b_info->avail_vcpus.size) { - int nr_set_cpus = 0; - nr_set_cpus = libxl_bitmap_count_set(&b_info->avail_vcpus); - - flexarray_append(dm_args, GCSPRINTF("%d,maxcpus=%d", - nr_set_cpus, - b_info->max_vcpus)); - } else - flexarray_append(dm_args, GCSPRINTF("%d", b_info->max_vcpus)); - } for (i = 0; i < num_nics; i++) { if (nics[i].nictype == LIBXL_NIC_TYPE_VIF_IOEMU) { char *smac = GCSPRINTF(LIBXL_MAC_FMT, @@ -1800,6 +1788,22 @@ static int libxl__build_device_model_args_new(libxl__gc *gc, for (i = 0; b_info->extra && b_info->extra[i] != NULL; i++) flexarray_append(dm_args, b_info->extra[i]); + if (b_info->type == LIBXL_DOMAIN_TYPE_HVM || + b_info->type == LIBXL_DOMAIN_TYPE_PVH) { + if (b_info->max_vcpus > 1) { + flexarray_append(dm_args, "-smp"); + if (b_info->avail_vcpus.size) { + int nr_set_cpus = 0; + nr_set_cpus = libxl_bitmap_count_set(&b_info->avail_vcpus); + + flexarray_append(dm_args, GCSPRINTF("%d,maxcpus=%d", + nr_set_cpus, + b_info->max_vcpus)); + } else + flexarray_append(dm_args, GCSPRINTF("%d", b_info->max_vcpus)); + } + } + flexarray_append(dm_args, "-machine"); switch (b_info->type) { case LIBXL_DOMAIN_TYPE_PVH: From patchwork Mon Nov 27 07:27:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergiy Kibrik X-Patchwork-Id: 13469248 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E778CC4167B for ; Mon, 27 Nov 2023 07:29:17 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.641632.1000369 (Exim 4.92) (envelope-from ) id 1r7W3K-0005Sa-SR; Mon, 27 Nov 2023 07:29:10 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 641632.1000369; Mon, 27 Nov 2023 07:29:10 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7W3K-0005ST-PY; Mon, 27 Nov 2023 07:29:10 +0000 Received: by outflank-mailman (input) for mailman id 641632; Mon, 27 Nov 2023 07:29:09 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7W3J-0004kO-2v for xen-devel@lists.xenproject.org; Mon, 27 Nov 2023 07:29:09 +0000 Received: from pb-smtp21.pobox.com (pb-smtp21.pobox.com [173.228.157.53]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id a553287b-8cf6-11ee-9b0e-b553b5be7939; Mon, 27 Nov 2023 08:29:06 +0100 (CET) Received: from pb-smtp21.pobox.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id 7EF7C1A51D; Mon, 27 Nov 2023 02:29:05 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from pb-smtp21.sea.icgroup.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id 776291A51C; Mon, 27 Nov 2023 02:29:05 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from localhost (unknown [188.163.75.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pb-smtp21.pobox.com (Postfix) with ESMTPSA id 128D41A51B; Mon, 27 Nov 2023 02:29:02 -0500 (EST) (envelope-from sakib@darkstar.site) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a553287b-8cf6-11ee-9b0e-b553b5be7939 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=pobox.com; h=from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; s=sasl; bh=9JyQs8aYabTMI9rypcTcqg0D+ zlsuPF150pLvMUKNLw=; b=DCK0JzAdWuHs1rJw6rdFhZXTTx+y09Sde575U9o9D c1vo+MFHq4+UipolP1yjlwaL3SNujaTI9u78ApAaTYtTJlDPgG9iWz3CfHNf8p+j RRoiTImhqgE3GQ/dVeeJDQQpHN4BFtys47iFD92c7bw9HMClp5w3ujuFblKwUz81 /c= From: Sergiy Kibrik To: xen-devel@lists.xenproject.org, Julien Grall Cc: Oleksandr Tyshchenko , Stefano Stabellini , Volodymyr Babchuk , Stewart Hildebrand , Juergen Gross , Bertrand Marquis , Michal Orzel , Sergiy Kibrik Subject: [RFC PATCH v1 2/5] xen/public: arch-arm: reserve resources for virtio-pci Date: Mon, 27 Nov 2023 09:27:51 +0200 Message-Id: <20231127072754.4045254-3-Sergiy_Kibrik@epam.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> References: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> MIME-Version: 1.0 X-Pobox-Relay-ID: A314BB46-8CF6-11EE-98F6-A19503B9AAD1-90055647!pb-smtp21.pobox.com From: Oleksandr Tyshchenko In order to enable more use-cases such as having multiple device-models (Qemu) running in different backend domains which provide virtio-pci devices for the same guest, we allocate and expose one PCI host bridge for every virtio backend domain for that guest. For that purpose we reserve separate virtio-pci resources (memory and SPI range for Legacy PCI interrupts) for up to 8 possible PCI host bridges (to be aligned with MAX_NR_IOREQ_SERVERS) and allocate one host bridge per backend domain. We'll need at most 32 interrupts (INTA..INTD legacy PCI interrupts per each of 8 host bridges), and at most 32MB of memory (since as it was observed virtio-pci devices use up to 16KB each, this can be different for physical PCI devices ofc). The details of PCI host bridge (including its host_id) are to be written to dedicated Xenstore node for the device-model to retrieve. Signed-off-by: Oleksandr Tyshchenko Signed-off-by: Sergiy Kibrik --- xen/include/public/arch-arm.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index a25e87dbda..caa4e92b55 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -466,6 +466,28 @@ typedef uint64_t xen_callback_t; #define GUEST_VPCI_MEM_ADDR xen_mk_ullong(0x23000000) #define GUEST_VPCI_MEM_SIZE xen_mk_ullong(0x10000000) +/* + * 8 MB is reserved for virtio-pci configuration space based on calculation + * 8 bridges x 32 devices x 8 functions x 4 KB = 8 MB + */ +#define GUEST_VIRTIO_PCI_ECAM_BASE xen_mk_ullong(0x33000000) +#define GUEST_VIRTIO_PCI_TOTAL_ECAM_SIZE xen_mk_ullong(0x00800000) +#define GUEST_VIRTIO_PCI_HOST_ECAM_SIZE xen_mk_ullong(0x00100000) + +/* 32 MB is reserved for virtio-pci memory based on calculation + * 8 bridges x 32 devices x 8 functions x 16 KB per virtio-pci device = 32 MB + */ +#define GUEST_VIRTIO_PCI_ADDR_TYPE_MEM xen_mk_ullong(0x02000000) +#define GUEST_VIRTIO_PCI_MEM_ADDR xen_mk_ullong(0x33800000) +#define GUEST_VIRTIO_PCI_MEM_SIZE xen_mk_ullong(0x02000000) + +/* 32 MB is reserved for virtio-pci Prefetch memory based on calculation + * 8 bridges x 32 devices x 8 functions x 16 KB per virtio-pci device = 32 MB + */ +#define GUEST_VIRTIO_PCI_ADDR_TYPE_PREFETCH_MEM xen_mk_ullong(0x42000000) +#define GUEST_VIRTIO_PCI_PREFETCH_MEM_ADDR xen_mk_ullong(0x35800000) +#define GUEST_VIRTIO_PCI_PREFETCH_MEM_SIZE xen_mk_ullong(0x02000000) + /* * 16MB == 4096 pages reserved for guest to use as a region to map its * grant table in. @@ -515,6 +537,10 @@ typedef uint64_t xen_callback_t; #define GUEST_VIRTIO_MMIO_SPI_FIRST 33 #define GUEST_VIRTIO_MMIO_SPI_LAST 43 +/* 8 bridges x 4 #INTA..#INTD interrupts = 32 SPIs to reserve for virtio-pci */ +#define GUEST_VIRTIO_PCI_SPI_FIRST 44 +#define GUEST_VIRTIO_PCI_SPI_LAST 76 + /* PSCI functions */ #define PSCI_cpu_suspend 0 #define PSCI_cpu_off 1 From patchwork Mon Nov 27 07:27:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergiy Kibrik X-Patchwork-Id: 13469249 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1B02BC4167B for ; Mon, 27 Nov 2023 07:29:28 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.641633.1000379 (Exim 4.92) (envelope-from ) id 1r7W3S-0005pS-7z; Mon, 27 Nov 2023 07:29:18 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 641633.1000379; Mon, 27 Nov 2023 07:29:18 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7W3S-0005pJ-53; Mon, 27 Nov 2023 07:29:18 +0000 Received: by outflank-mailman (input) for mailman id 641633; Mon, 27 Nov 2023 07:29:17 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7W3R-0005Pb-GN for xen-devel@lists.xenproject.org; Mon, 27 Nov 2023 07:29:17 +0000 Received: from pb-smtp21.pobox.com (pb-smtp21.pobox.com [173.228.157.53]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id a927e4ff-8cf6-11ee-98e2-6d05b1d4d9a1; Mon, 27 Nov 2023 08:29:14 +0100 (CET) Received: from pb-smtp21.pobox.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id D12B61A520; Mon, 27 Nov 2023 02:29:11 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from pb-smtp21.sea.icgroup.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id B6CE61A51F; Mon, 27 Nov 2023 02:29:11 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from localhost (unknown [188.163.75.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pb-smtp21.pobox.com (Postfix) with ESMTPSA id 0A6921A51E; Mon, 27 Nov 2023 02:29:07 -0500 (EST) (envelope-from sakib@darkstar.site) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a927e4ff-8cf6-11ee-98e2-6d05b1d4d9a1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=pobox.com; h=from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; s=sasl; bh=CbeTAHYGk50C0Qkwb6apv4tsO 0V8YdHsdOnMVLhr/r0=; b=xWhj6BPsp3N9S19K57k/v1fh2zscMH5AGetvd+XPU FOm5uFAueJTD6M/C7Q22wu71dw0Ro8C49TpAdCY7J78Hqo/rJ2D/u9vc98l+4O4O wg1ptGK4eQT0lzz+V02jYv9xyFDy6w+XLXlEzOZxDs6ZTVmvA836rkuF2pbgRCEv i4= From: Sergiy Kibrik To: xen-devel@lists.xenproject.org, Julien Grall Cc: Oleksandr Tyshchenko , Stefano Stabellini , Volodymyr Babchuk , Stewart Hildebrand , Juergen Gross , Wei Liu , Anthony PERARD , Sergiy Kibrik Subject: [RFC PATCH v1 3/5] libxl/arm: Add basic virtio-pci support Date: Mon, 27 Nov 2023 09:27:52 +0200 Message-Id: <20231127072754.4045254-4-Sergiy_Kibrik@epam.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> References: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> MIME-Version: 1.0 X-Pobox-Relay-ID: A6A2B34E-8CF6-11EE-8C37-A19503B9AAD1-90055647!pb-smtp21.pobox.com From: Oleksandr Tyshchenko Introduce new transport mechanism "pci" for the Virtio device and update parsing and configuration logic accordingly. In order to enable more use-cases such as having multiple device-models (Qemu) running in different backend domains which provide virtio-pci devices for the same guest, we allocate and expose one PCI host bridge for every virtio backend domain for that guest. Also extend PCI Host bridge DT node exposed to the guest by adding bindings for Legacy PCI interrupts (#INTA - #INTD). Signed-off-by: Oleksandr Tyshchenko Signed-off-by: Sergiy Kibrik --- docs/man/xl.cfg.5.pod.in | 9 +- tools/libs/light/libxl_arm.c | 287 ++++++++++++++++++++++++++++-- tools/libs/light/libxl_create.c | 18 +- tools/libs/light/libxl_dm.c | 70 ++++++++ tools/libs/light/libxl_internal.h | 5 + tools/libs/light/libxl_types.idl | 34 +++- tools/libs/light/libxl_virtio.c | 98 +++++++--- tools/xl/xl_parse.c | 36 ++++ 8 files changed, 507 insertions(+), 50 deletions(-) diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in index 2e234b450e..0fba750815 100644 --- a/docs/man/xl.cfg.5.pod.in +++ b/docs/man/xl.cfg.5.pod.in @@ -1616,8 +1616,13 @@ hexadecimal format, without the "0x" prefix and all in lower case, like =item B -Specifies the transport mechanism for the Virtio device, only "mmio" is -supported for now. +Specifies the transport mechanism for the Virtio device, both "mmio" and "pci" +are supported. This option is mandatory. + +=item B + +The Virtio device with transport "pci" must be identified by its B. +See L for more details about the format for B. =item B diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c index 1539191774..4789ee08d2 100644 --- a/tools/libs/light/libxl_arm.c +++ b/tools/libs/light/libxl_arm.c @@ -20,6 +20,11 @@ */ #define VIRTIO_MMIO_DEV_SIZE xen_mk_ullong(0x200) +#define VIRTIO_PCI_HOST_MEM_SIZE xen_mk_ullong(0x400000) +#define VIRTIO_PCI_HOST_PREFETCH_MEM_SIZE xen_mk_ullong(0x400000) +#define VIRTIO_PCI_HOST_NUM_SPIS 4 +#define VIRTIO_PCI_MAX_HOSTS 8 + static uint64_t alloc_virtio_mmio_base(libxl__gc *gc, uint64_t *virtio_mmio_base) { uint64_t base = *virtio_mmio_base; @@ -80,14 +85,101 @@ static const char *gicv_to_string(libxl_gic_version gic_version) } } +static int alloc_virtio_pci_host(libxl__gc *gc, + uint32_t backend_domid, + uint32_t *host_id, + unsigned int *num_hosts, + libxl_virtio_pci_host *hosts) +{ + unsigned int i; + + BUILD_BUG_ON(VIRTIO_PCI_MAX_HOSTS != + GUEST_VIRTIO_PCI_TOTAL_ECAM_SIZE / GUEST_VIRTIO_PCI_HOST_ECAM_SIZE); + BUILD_BUG_ON(VIRTIO_PCI_MAX_HOSTS != + GUEST_VIRTIO_PCI_MEM_SIZE / VIRTIO_PCI_HOST_MEM_SIZE); + BUILD_BUG_ON(VIRTIO_PCI_MAX_HOSTS != + GUEST_VIRTIO_PCI_PREFETCH_MEM_SIZE / VIRTIO_PCI_HOST_PREFETCH_MEM_SIZE); + BUILD_BUG_ON(VIRTIO_PCI_MAX_HOSTS != + (GUEST_VIRTIO_PCI_SPI_LAST - GUEST_VIRTIO_PCI_SPI_FIRST) / VIRTIO_PCI_HOST_NUM_SPIS); + + if (*num_hosts > VIRTIO_PCI_MAX_HOSTS) + return ERROR_INVAL; + + for (i = 0; i < *num_hosts; i++) { + if (hosts[i].backend_domid == backend_domid) { + *host_id = hosts[i].id; + + LOG(DEBUG, "Reuse host #%u: " + "ECAM: 0x%"PRIx64"-0x%"PRIx64" " + "MEM: 0x%"PRIx64"-0x%"PRIx64" " + "PREFETCH_MEM: 0x%"PRIx64"-0x%"PRIx64" " + "IRQ: %u-%u", + hosts[i].id, + hosts[i].ecam_base, + hosts[i].ecam_base + hosts[i].ecam_size - 1, + hosts[i].mem_base, + hosts[i].mem_base + hosts[i].mem_size - 1, + hosts[i].prefetch_mem_base, + hosts[i].prefetch_mem_base + hosts[i].prefetch_mem_size - 1, + hosts[i].irq_first, + hosts[i].irq_first + hosts[i].num_irqs - 1); + + return 0; + } + } + + if (i == VIRTIO_PCI_MAX_HOSTS) { + LOG(ERROR, "Ran out of reserved resources for virtio-pci host\n"); + return ERROR_FAIL; + } + + hosts[i].backend_domid = backend_domid; + hosts[i].id = i; + hosts[i].ecam_base = GUEST_VIRTIO_PCI_ECAM_BASE + + i * GUEST_VIRTIO_PCI_HOST_ECAM_SIZE; + hosts[i].ecam_size = GUEST_VIRTIO_PCI_HOST_ECAM_SIZE; + hosts[i].mem_base = GUEST_VIRTIO_PCI_MEM_ADDR + + i * VIRTIO_PCI_HOST_MEM_SIZE; + hosts[i].mem_size = VIRTIO_PCI_HOST_MEM_SIZE; + hosts[i].prefetch_mem_base = GUEST_VIRTIO_PCI_PREFETCH_MEM_ADDR + + i * VIRTIO_PCI_HOST_PREFETCH_MEM_SIZE; + hosts[i].prefetch_mem_size = VIRTIO_PCI_HOST_PREFETCH_MEM_SIZE; + hosts[i].irq_first = GUEST_VIRTIO_PCI_SPI_FIRST + + i * VIRTIO_PCI_HOST_NUM_SPIS; + hosts[i].num_irqs = VIRTIO_PCI_HOST_NUM_SPIS; + + *host_id = hosts[i].id; + + (*num_hosts)++; + + LOG(DEBUG, "Allocate host #%u: " + "ECAM: 0x%"PRIx64"-0x%"PRIx64" " + "MEM: 0x%"PRIx64"-0x%"PRIx64" " + "PREFETCH_MEM: 0x%"PRIx64"-0x%"PRIx64" " + "IRQ: %u-%u", + hosts[i].id, + hosts[i].ecam_base, + hosts[i].ecam_base + hosts[i].ecam_size - 1, + hosts[i].mem_base, + hosts[i].mem_base + hosts[i].mem_size - 1, + hosts[i].prefetch_mem_base, + hosts[i].prefetch_mem_base + hosts[i].prefetch_mem_size - 1, + hosts[i].irq_first, + hosts[i].irq_first + hosts[i].num_irqs - 1); + + return 0; +} + int libxl__arch_domain_prepare_config(libxl__gc *gc, libxl_domain_config *d_config, struct xen_domctl_createdomain *config) { uint32_t nr_spis = 0; unsigned int i; - uint32_t vuart_irq, virtio_irq = 0; - bool vuart_enabled = false, virtio_enabled = false; + uint32_t vuart_irq, virtio_mmio_irq_last, virtio_pci_irq_last = 0; + bool vuart_enabled = false, virtio_mmio_enabled = false; + unsigned int num_virtio_pci_hosts = 0; + libxl_virtio_pci_host virtio_pci_hosts[VIRTIO_PCI_MAX_HOSTS] = {0}; uint64_t virtio_mmio_base = GUEST_VIRTIO_MMIO_BASE; uint32_t virtio_mmio_irq = GUEST_VIRTIO_MMIO_SPI_FIRST; int rc; @@ -118,11 +210,17 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, for (i = 0; i < d_config->num_virtios; i++) { libxl_device_virtio *virtio = &d_config->virtios[i]; - if (virtio->transport != LIBXL_VIRTIO_TRANSPORT_MMIO) - continue; - - rc = alloc_virtio_mmio_params(gc, &virtio->base, &virtio->irq, - &virtio_mmio_base, &virtio_mmio_irq); + if (virtio->transport != LIBXL_VIRTIO_TRANSPORT_MMIO) { + rc = alloc_virtio_pci_host(gc, + virtio->backend_domid, + &virtio->u.pci.host_id, + &num_virtio_pci_hosts, + virtio_pci_hosts); + } else { + rc = alloc_virtio_mmio_params(gc, &virtio->u.mmio.base, + &virtio->u.mmio.irq, + &virtio_mmio_base, &virtio_mmio_irq); + } if (rc) return rc; @@ -134,14 +232,25 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, * The resulting "nr_spis" needs to cover the highest possible SPI. */ if (virtio_mmio_irq != GUEST_VIRTIO_MMIO_SPI_FIRST) { - virtio_enabled = true; + virtio_mmio_enabled = true; /* * Assumes that "virtio_mmio_irq" is the highest allocated irq, which is * updated from alloc_virtio_mmio_irq() currently. */ - virtio_irq = virtio_mmio_irq - 1; - nr_spis = max(nr_spis, virtio_irq - 32 + 1); + virtio_mmio_irq_last = virtio_mmio_irq - 1; + nr_spis = max(nr_spis, virtio_mmio_irq_last - 32 + 1); + } + + if (num_virtio_pci_hosts) { + libxl_virtio_pci_host *host = &virtio_pci_hosts[num_virtio_pci_hosts - 1]; + + /* + * Assumes that latest allocated host contains the highest allocated + * irq range. + */ + virtio_pci_irq_last = host->irq_first + host->num_irqs - 1; + nr_spis = max(nr_spis, virtio_pci_irq_last - 32 + 1); } for (i = 0; i < d_config->b_info.num_irqs; i++) { @@ -164,10 +273,14 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, } /* The same check as for vpl011 */ - if (virtio_enabled && - (irq >= GUEST_VIRTIO_MMIO_SPI_FIRST && irq <= virtio_irq)) { + if (virtio_mmio_enabled && + (irq >= GUEST_VIRTIO_MMIO_SPI_FIRST && irq <= virtio_mmio_irq_last)) { LOG(ERROR, "Physical IRQ %u conflicting with Virtio MMIO IRQ range\n", irq); return ERROR_FAIL; + } else if (num_virtio_pci_hosts && + (irq >= GUEST_VIRTIO_PCI_SPI_FIRST && irq <= virtio_pci_irq_last)) { + LOG(ERROR, "Physical IRQ %u conflicting with Virtio PCI IRQ range\n", irq); + return ERROR_FAIL; } if (irq < 32) @@ -179,6 +292,14 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, nr_spis = spi + 1; } + if (num_virtio_pci_hosts) { + d_config->b_info.num_virtio_pci_hosts = num_virtio_pci_hosts; + d_config->b_info.virtio_pci_hosts = libxl__calloc(NOGC, + num_virtio_pci_hosts, sizeof(*d_config->b_info.virtio_pci_hosts)); + memcpy(d_config->b_info.virtio_pci_hosts, virtio_pci_hosts, + sizeof(*d_config->b_info.virtio_pci_hosts) * num_virtio_pci_hosts); + } + LOG(DEBUG, "Configure the domain"); config->arch.nr_spis = nr_spis; @@ -908,6 +1029,130 @@ static int make_vpci_node(libxl__gc *gc, void *fdt, return 0; } +#define PCI_IRQ_MAP_MIN_STRIDE 8 + +static int create_virtio_pci_irq_map(libxl__gc *gc, void *fdt, + libxl_virtio_pci_host *host) +{ + uint32_t *full_irq_map, *irq_map; + size_t len; + unsigned int slot, pin; + int res, cells; + + res = fdt_property_cell(fdt, "#interrupt-cells", 1); + if (res) return res; + + /* assume GIC node to be present, due to + * make_gicv2_node()/make_gicv3_node() get called earlier + */ + res = fdt_node_offset_by_phandle(fdt, GUEST_PHANDLE_GIC); + if (res < 0) + return res; + + res = fdt_address_cells(fdt, res); + /* handle case of make_gicv2_node() setting #address-cells to 0 */ + if (res == -FDT_ERR_BADNCELLS) + res = 0; + else if (res < 0) + return res; + + cells = res; + len = sizeof(uint32_t) * host->num_irqs * host->num_irqs * + (PCI_IRQ_MAP_MIN_STRIDE + cells); + irq_map = full_irq_map = libxl__malloc(gc, len); + + for (slot = 0; slot < host->num_irqs; slot++) { + for (pin = 0; pin < host->num_irqs; pin++) { + uint32_t irq = host->irq_first + ((pin + slot) % host->num_irqs); + unsigned int i = 0; + + /* PCI address (3 cells) */ + irq_map[i++] = cpu_to_fdt32(PCI_DEVFN(slot, 0) << 8); + irq_map[i++] = cpu_to_fdt32(0); + irq_map[i++] = cpu_to_fdt32(0); + + /* PCI interrupt (1 cell) */ + irq_map[i++] = cpu_to_fdt32(pin + 1); + + /* GIC phandle (1 cell) */ + irq_map[i++] = cpu_to_fdt32(GUEST_PHANDLE_GIC); + + /* GIC unit address, set 0 because vgic itself handles vpci IRQs */ + for (int c = cells; c--; irq_map[i++] = cpu_to_fdt32(0)); + + /* GIC interrupt (3 cells) */ + irq_map[i++] = cpu_to_fdt32(0); /* SPI */ + irq_map[i++] = cpu_to_fdt32(irq - 32); + irq_map[i++] = cpu_to_fdt32(DT_IRQ_TYPE_LEVEL_HIGH); + + irq_map += PCI_IRQ_MAP_MIN_STRIDE + cells; + } + } + + res = fdt_property(fdt, "interrupt-map", full_irq_map, len); + if (res) return res; + + res = fdt_property_values(gc, fdt, "interrupt-map-mask", 4, + PCI_DEVFN(3, 0) << 8, 0, 0, 0x7); + if (res) return res; + + return 0; +} + +/* TODO Consider reusing make_vpci_node() */ +static int make_virtio_pci_node(libxl__gc *gc, void *fdt, + libxl_virtio_pci_host *host, + libxl_domain_config *d_config) +{ + int res; + const char *name = GCSPRINTF("pcie@%"PRIx64, host->ecam_base); + + res = fdt_begin_node(fdt, name); + if (res) return res; + + res = fdt_property_compat(gc, fdt, 1, "pci-host-ecam-generic"); + if (res) return res; + + res = fdt_property_string(fdt, "device_type", "pci"); + if (res) return res; + + res = fdt_property_regs(gc, fdt, GUEST_ROOT_ADDRESS_CELLS, + GUEST_ROOT_SIZE_CELLS, 1, host->ecam_base, host->ecam_size); + if (res) return res; + + res = fdt_property_values(gc, fdt, "bus-range", 2, 0, 0); + if (res) return res; + + res = fdt_property_cell(fdt, "#address-cells", 3); + if (res) return res; + + res = fdt_property_cell(fdt, "#size-cells", 2); + if (res) return res; + + res = fdt_property_string(fdt, "status", "okay"); + if (res) return res; + + res = fdt_property_vpci_ranges(gc, fdt, GUEST_ROOT_ADDRESS_CELLS, + GUEST_ROOT_SIZE_CELLS, 2, + GUEST_VIRTIO_PCI_ADDR_TYPE_MEM, host->mem_base, host->mem_size, + GUEST_VIRTIO_PCI_ADDR_TYPE_PREFETCH_MEM, host->prefetch_mem_base, + host->prefetch_mem_size); + if (res) return res; + + /* The same property as for virtio-mmio device */ + res = fdt_property(fdt, "dma-coherent", NULL, 0); + if (res) return res; + + /* Legacy PCI interrupts (#INTA - #INTD) */ + res = create_virtio_pci_irq_map(gc, fdt, host); + if (res) return res; + + res = fdt_end_node(fdt); + if (res) return res; + + return 0; +} + static int make_xen_iommu_node(libxl__gc *gc, void *fdt) { int res; @@ -1384,20 +1629,26 @@ next_resize: for (i = 0; i < d_config->num_virtios; i++) { libxl_device_virtio *virtio = &d_config->virtios[i]; - if (virtio->transport != LIBXL_VIRTIO_TRANSPORT_MMIO) - continue; - if (libxl_defbool_val(virtio->grant_usage)) iommu_needed = true; - FDT( make_virtio_mmio_node_device(gc, fdt, virtio->base, - virtio->irq, virtio->type, + if (virtio->transport != LIBXL_VIRTIO_TRANSPORT_MMIO) + continue; + + FDT( make_virtio_mmio_node_device(gc, fdt, virtio->u.mmio.base, + virtio->u.mmio.irq, virtio->type, virtio->backend_domid, libxl_defbool_val(virtio->grant_usage)) ); } + for (i = 0; i < d_config->b_info.num_virtio_pci_hosts; i++) { + libxl_virtio_pci_host *host = &d_config->b_info.virtio_pci_hosts[i]; + + FDT( make_virtio_pci_node(gc, fdt, host, d_config) ); + } + /* - * The iommu node should be created only once for all virtio-mmio + * The iommu node should be created only once for all virtio * devices. */ if (iommu_needed) diff --git a/tools/libs/light/libxl_create.c b/tools/libs/light/libxl_create.c index ce1d431103..22b4fa40cc 100644 --- a/tools/libs/light/libxl_create.c +++ b/tools/libs/light/libxl_create.c @@ -1273,8 +1273,9 @@ int libxl__domain_config_setdefault(libxl__gc *gc, } for (i = 0; i < d_config->num_virtios; i++) { - ret = libxl__virtio_devtype.set_default(gc, domid, - &d_config->virtios[i], false); + libxl_device_virtio *virtio = &d_config->virtios[i]; + + ret = libxl__virtio_devtype.set_default(gc, domid, virtio, false); if (ret) { LOGD(ERROR, domid, "Unable to set virtio defaults for device %d", i); goto error_out; @@ -1770,6 +1771,19 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, for (i = 0; i < d_config->num_virtios; i++) libxl__device_add(gc, domid, &libxl__virtio_devtype, &d_config->virtios[i]); + /* + * This should be done before spawning device model, but after + * the creation of "device-model" directory in Xenstore. + */ + for (i = 0; i < d_config->b_info.num_virtio_pci_hosts; i++) { + libxl_virtio_pci_host *host = &d_config->b_info.virtio_pci_hosts[i]; + + ret = libxl__save_dm_virtio_pci_host(gc, domid, host); + if (ret) { + LOGD(ERROR, domid, "Unable to save virtio_pci_host for device model"); + goto error_out; + } + } switch (d_config->c_info.type) { case LIBXL_DOMAIN_TYPE_HVM: diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c index 0b2548d35b..4e9391fc08 100644 --- a/tools/libs/light/libxl_dm.c +++ b/tools/libs/light/libxl_dm.c @@ -3375,6 +3375,76 @@ static void device_model_postconfig_done(libxl__egc *egc, dmss->callback(egc, dmss, rc); } +int libxl__save_dm_virtio_pci_host(libxl__gc *gc, + uint32_t domid, + libxl_virtio_pci_host *host) +{ + const char *dm_path; + char **dir; + xs_transaction_t t = XBT_NULL; + unsigned int n; + int rc; + + dm_path = GCSPRINTF("/local/domain/%d/device-model", host->backend_domid); + + dir = libxl__xs_directory(gc, XBT_NULL, dm_path, &n); + if (!dir) + return ERROR_INVAL; + + dm_path = DEVICE_MODEL_XS_PATH(gc, host->backend_domid, domid, "/virtio_pci_host"); + + for (;;) { + rc = libxl__xs_transaction_start(gc, &t); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/id", dm_path), + GCSPRINTF("%u", host->id)); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/ecam_base", dm_path), + GCSPRINTF("%#"PRIx64, host->ecam_base)); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/ecam_size", dm_path), + GCSPRINTF("%#"PRIx64, host->ecam_size)); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/mem_base", dm_path), + GCSPRINTF("%#"PRIx64, host->mem_base)); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/mem_size", dm_path), + GCSPRINTF("%#"PRIx64, host->mem_size)); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/prefetch_mem_base", dm_path), + GCSPRINTF("%#"PRIx64, host->prefetch_mem_base)); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/prefetch_mem_size", dm_path), + GCSPRINTF("%#"PRIx64, host->prefetch_mem_size)); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/irq_first", dm_path), + GCSPRINTF("%u", host->irq_first)); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/num_irqs", dm_path), + GCSPRINTF("%u", host->num_irqs)); + if (rc) goto out; + + rc = libxl__xs_transaction_commit(gc, &t); + if (!rc) break; + if (rc < 0) goto out; + } + + return 0; + +out: + libxl__xs_transaction_abort(gc, &t); + return rc; +} + void libxl__spawn_qdisk_backend(libxl__egc *egc, libxl__dm_spawn_state *dmss) { STATE_AO_GC(dmss->spawn.ao); diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index d5732d1c37..75d370d739 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -4199,6 +4199,11 @@ _hidden void libxl__spawn_qdisk_backend(libxl__egc *egc, libxl__dm_spawn_state *dmss); _hidden int libxl__destroy_qdisk_backend(libxl__gc *gc, uint32_t domid); + +_hidden int libxl__save_dm_virtio_pci_host(libxl__gc *gc, + uint32_t domid, + libxl_virtio_pci_host *host); + /*----- Domain creation -----*/ diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index 7d8bd5d216..a86c601994 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -281,6 +281,7 @@ libxl_vkb_backend = Enumeration("vkb_backend", [ libxl_virtio_transport = Enumeration("virtio_transport", [ (0, "UNKNOWN"), (1, "MMIO"), + (2, "PCI"), ]) libxl_passthrough = Enumeration("passthrough", [ @@ -558,6 +559,19 @@ libxl_altp2m_mode = Enumeration("altp2m_mode", [ (3, "limited"), ], init_val = "LIBXL_ALTP2M_MODE_DISABLED") +libxl_virtio_pci_host = Struct("virtio_pci_host", [ + ("backend_domid", libxl_domid), + ("id", uint32), + ("ecam_base", uint64), + ("ecam_size", uint64), + ("mem_base", uint64), + ("mem_size", uint64), + ("prefetch_mem_base", uint64), + ("prefetch_mem_size", uint64), + ("irq_first", uint32), + ("num_irqs", uint32), + ]) + libxl_domain_build_info = Struct("domain_build_info",[ ("max_vcpus", integer), ("avail_vcpus", libxl_bitmap), @@ -631,6 +645,7 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("apic", libxl_defbool), ("dm_restrict", libxl_defbool), ("tee", libxl_tee_type), + ("virtio_pci_hosts", Array(libxl_virtio_pci_host, "num_virtio_pci_hosts")), ("u", KeyedUnion(None, libxl_domain_type, "type", [("hvm", Struct(None, [("firmware", string), ("bios", libxl_bios_type), @@ -764,13 +779,22 @@ libxl_device_virtio = Struct("device_virtio", [ ("backend_domid", libxl_domid), ("backend_domname", string), ("type", string), - ("transport", libxl_virtio_transport), + ("u", KeyedUnion(None, libxl_virtio_transport, "transport", + [("unknown", None), + # Note that virtio-mmio parameters (irq and base) are for internal + # use by libxl and can't be modified. + ("mmio", Struct(None, [("irq", uint32), + ("base", uint64), + ])), + ("pci", Struct(None, [("func", uint8), + ("dev", uint8), + ("bus", uint8), + ("domain", uint16), + ("host_id", uint32), + ])), + ])), ("grant_usage", libxl_defbool), ("devid", libxl_devid), - # Note that virtio-mmio parameters (irq and base) are for internal - # use by libxl and can't be modified. - ("irq", uint32), - ("base", uint64) ]) libxl_device_disk = Struct("device_disk", [ diff --git a/tools/libs/light/libxl_virtio.c b/tools/libs/light/libxl_virtio.c index e5e321adc5..8062423c75 100644 --- a/tools/libs/light/libxl_virtio.c +++ b/tools/libs/light/libxl_virtio.c @@ -57,8 +57,21 @@ static int libxl__set_xenstore_virtio(libxl__gc *gc, uint32_t domid, { const char *transport = libxl_virtio_transport_to_string(virtio->transport); - flexarray_append_pair(back, "irq", GCSPRINTF("%u", virtio->irq)); - flexarray_append_pair(back, "base", GCSPRINTF("%#"PRIx64, virtio->base)); + if (virtio->transport == LIBXL_VIRTIO_TRANSPORT_MMIO) { + flexarray_append_pair(back, "irq", GCSPRINTF("%u", virtio->u.mmio.irq)); + flexarray_append_pair(back, "base", GCSPRINTF("%#"PRIx64, virtio->u.mmio.base)); + } else { + /* + * TODO: + * Probably we will also need to store PCI Host bridge details (irq and + * mem ranges) this particular PCI device belongs to if emulator cannot + * or should not rely on what is described at include/public/arch-arm.h + */ + flexarray_append_pair(back, "bdf", GCSPRINTF("%04x:%02x:%02x.%01x", + virtio->u.pci.domain, virtio->u.pci.bus, + virtio->u.pci.dev, virtio->u.pci.func)); + flexarray_append_pair(back, "host_id", GCSPRINTF("%u", virtio->u.pci.host_id)); + } flexarray_append_pair(back, "type", GCSPRINTF("%s", virtio->type)); flexarray_append_pair(back, "transport", GCSPRINTF("%s", transport)); flexarray_append_pair(back, "grant_usage", @@ -84,33 +97,72 @@ static int libxl__virtio_from_xenstore(libxl__gc *gc, const char *libxl_path, rc = libxl__backendpath_parse_domid(gc, be_path, &virtio->backend_domid); if (rc) goto out; - rc = libxl__xs_read_checked(gc, XBT_NULL, - GCSPRINTF("%s/irq", be_path), &tmp); - if (rc) goto out; - - if (tmp) { - virtio->irq = strtoul(tmp, NULL, 0); + tmp = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/transport", be_path)); + if (!tmp) { + LOG(ERROR, "Missing xenstore node %s/transport", be_path); + rc = ERROR_INVAL; + goto out; } - tmp = NULL; - rc = libxl__xs_read_checked(gc, XBT_NULL, - GCSPRINTF("%s/base", be_path), &tmp); - if (rc) goto out; + rc = libxl_virtio_transport_from_string(tmp, &virtio->transport); + if (rc) { + LOG(ERROR, "Unable to parse xenstore node %s/transport", be_path); + goto out; + } - if (tmp) { - virtio->base = strtoul(tmp, NULL, 0); + if (virtio->transport != LIBXL_VIRTIO_TRANSPORT_MMIO && + virtio->transport != LIBXL_VIRTIO_TRANSPORT_PCI) { + LOG(ERROR, "Unexpected transport for virtio"); + rc = ERROR_INVAL; + goto out; } - tmp = NULL; - rc = libxl__xs_read_checked(gc, XBT_NULL, - GCSPRINTF("%s/transport", be_path), &tmp); - if (rc) goto out; + if (virtio->transport == LIBXL_VIRTIO_TRANSPORT_MMIO) { + tmp = NULL; + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/irq", be_path), &tmp); + if (rc) goto out; - if (tmp) { - if (!strcmp(tmp, "mmio")) { - virtio->transport = LIBXL_VIRTIO_TRANSPORT_MMIO; - } else { - return ERROR_INVAL; + if (tmp) { + virtio->u.mmio.irq = strtoul(tmp, NULL, 0); + } + + tmp = NULL; + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/base", be_path), &tmp); + if (rc) goto out; + + if (tmp) { + virtio->u.mmio.base = strtoul(tmp, NULL, 0); + } + } else { + unsigned int domain, bus, dev, func; + + tmp = NULL; + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/bdf", be_path), &tmp); + if (rc) goto out; + + if (tmp) { + if (sscanf(tmp, "%04x:%02x:%02x.%01x", + &domain, &bus, &dev, &func) != 4) { + rc = ERROR_INVAL; + goto out; + } + + virtio->u.pci.domain = domain; + virtio->u.pci.bus = bus; + virtio->u.pci.dev = dev; + virtio->u.pci.func = func; + } + + tmp = NULL; + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/host_id", be_path), &tmp); + if (rc) goto out; + + if (tmp) { + virtio->u.pci.host_id = strtoul(tmp, NULL, 0); } } diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index ed983200c3..4544ce2307 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1217,6 +1217,24 @@ static int parse_virtio_config(libxl_device_virtio *virtio, char *token) if (rc) return rc; } else if (MATCH_OPTION("grant_usage", token, oparg)) { libxl_defbool_set(&virtio->grant_usage, strtoul(oparg, NULL, 0)); + } else if (MATCH_OPTION("bdf", token, oparg)) { + /* + * TODO: + * We pretend that we are ordinary PCI device to reuse BDF parsing + * logic. This needs to be properly reused by adjusting parse_bdf(). + */ + libxl_device_pci pci; + + rc = xlu_pci_parse_bdf(NULL, &pci, oparg); + if (rc) { + fprintf(stderr, "Unable to parse BDF `%s' for virtio-pci\n", oparg); + return -1; + } + + virtio->u.pci.domain = pci.domain; + virtio->u.pci.bus = pci.bus; + virtio->u.pci.dev = pci.dev; + virtio->u.pci.func = pci.func; } else { fprintf(stderr, "Unknown string \"%s\" in virtio spec\n", token); return -1; @@ -1238,6 +1256,7 @@ static void parse_virtio_list(const XLU_Config *config, while ((item = xlu_cfg_get_listitem(virtios, entry)) != NULL) { libxl_device_virtio *virtio; char *p; + bool bdf_present = false; virtio = ARRAY_EXTEND_INIT(d_config->virtios, d_config->num_virtios, libxl_device_virtio_init); @@ -1260,6 +1279,8 @@ static void parse_virtio_list(const XLU_Config *config, strcat(str, p2); p = str; } + } else if (MATCH_OPTION("bdf", p, oparg)) { + bdf_present = true; } rc = parse_virtio_config(virtio, p); @@ -1270,6 +1291,21 @@ static void parse_virtio_list(const XLU_Config *config, p = strtok(NULL, ","); } + if (virtio->transport == LIBXL_VIRTIO_TRANSPORT_UNKNOWN) { + fprintf(stderr, "Unspecified transport for virtio\n"); + rc = ERROR_FAIL; goto out; + } + + if (virtio->transport == LIBXL_VIRTIO_TRANSPORT_PCI && + !bdf_present) { + fprintf(stderr, "BDF must be specified for virtio-pci\n"); + rc = ERROR_FAIL; goto out; + } else if (virtio->transport == LIBXL_VIRTIO_TRANSPORT_MMIO && + bdf_present) { + fprintf(stderr, "BDF must not be specified for virtio-mmio\n"); + rc = ERROR_FAIL; goto out; + } + entry++; free(buf); } From patchwork Mon Nov 27 07:32:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergiy Kibrik X-Patchwork-Id: 13469252 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D3D79C4167B for ; Mon, 27 Nov 2023 07:34:42 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.641645.1000389 (Exim 4.92) (envelope-from ) id 1r7W8T-0007xh-11; Mon, 27 Nov 2023 07:34:29 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 641645.1000389; Mon, 27 Nov 2023 07:34:28 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7W8S-0007xa-TG; Mon, 27 Nov 2023 07:34:28 +0000 Received: by outflank-mailman (input) for mailman id 641645; Mon, 27 Nov 2023 07:34:27 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7W8R-0007xT-Cu for xen-devel@lists.xenproject.org; Mon, 27 Nov 2023 07:34:27 +0000 Received: from pb-smtp21.pobox.com (pb-smtp21.pobox.com [173.228.157.53]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 63b25de3-8cf7-11ee-98e2-6d05b1d4d9a1; Mon, 27 Nov 2023 08:34:26 +0100 (CET) Received: from pb-smtp21.pobox.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id 62F701A588; Mon, 27 Nov 2023 02:34:24 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from pb-smtp21.sea.icgroup.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id 5A3391A586; Mon, 27 Nov 2023 02:34:24 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from localhost (unknown [188.163.75.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pb-smtp21.pobox.com (Postfix) with ESMTPSA id E7D621A585; Mon, 27 Nov 2023 02:34:20 -0500 (EST) (envelope-from sakib@darkstar.site) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 63b25de3-8cf7-11ee-98e2-6d05b1d4d9a1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=pobox.com; h=from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; s=sasl; bh=F3YC9QsVnSSuRXfmGqVQj/is4 CeJzEOPdZWm5MoPMAk=; b=ePUv65SniNxzAG8cD18UU4fzCVBq0E3UPLwcXQp3D eWpixnPBs9YvRVtDVM1APsisMh1AB8cOeWDSRsbYa0bGHOY50DSUhaymCAzscVlw gk+U6f0yeQzQUdDAgvwi4AcUPqjER4N2DH08Jwog8vf2ABnoMhbWcwGC1LeBk+7C mg= From: Sergiy Kibrik To: xen-devel@lists.xenproject.org, Julien Grall Cc: Oleksandr Tyshchenko , Stefano Stabellini , Volodymyr Babchuk , Stewart Hildebrand , Juergen Gross , Wei Liu , Anthony PERARD , Sergiy Kibrik Subject: [RFC PATCH v1 4/5] libxl/arm: Reuse generic PCI-IOMMU bindings for virtio-pci devices Date: Mon, 27 Nov 2023 09:32:20 +0200 Message-Id: <20231127073221.4046427-1-Sergiy_Kibrik@epam.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> References: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> MIME-Version: 1.0 X-Pobox-Relay-ID: 6124FFEC-8CF7-11EE-B321-A19503B9AAD1-90055647!pb-smtp21.pobox.com From: Oleksandr Tyshchenko Use the same "xen-grant-dma" device concept for the PCI devices behind device-tree based PCI Host controller, but with one modification. Unlike for platform devices, we cannot use generic IOMMU bindings (iommus property), as we need to support more flexible configuration. The problem is that PCI devices under the single PCI Host controller may have the backends running in different Xen domains and thus have different endpoints ID (backend domains ID). Reuse generic PCI-IOMMU bindings (iommu-map/iommu-map-mask properties) which allows us to describe relationship between PCI devices and backend domains ID properly. Linux guest is already able to deal with generic PCI-IOMMU bindings (see Linux drivers/xen/grant-dma-ops.c for details). According to Linux: - Documentation/devicetree/bindings/pci/pci-iommu.txt - Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml Signed-off-by: Oleksandr Tyshchenko Signed-off-by: Sergiy Kibrik --- tools/libs/light/libxl_arm.c | 64 ++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c index 4789ee08d2..c1e39d688a 100644 --- a/tools/libs/light/libxl_arm.c +++ b/tools/libs/light/libxl_arm.c @@ -1030,6 +1030,7 @@ static int make_vpci_node(libxl__gc *gc, void *fdt, } #define PCI_IRQ_MAP_MIN_STRIDE 8 +#define PCI_IOMMU_MAP_STRIDE 4 static int create_virtio_pci_irq_map(libxl__gc *gc, void *fdt, libxl_virtio_pci_host *host) @@ -1099,6 +1100,65 @@ static int create_virtio_pci_irq_map(libxl__gc *gc, void *fdt, return 0; } +/* XXX Consider reusing libxl__realloc() to avoid an extra loop */ +static int create_virtio_pci_iommu_map(libxl__gc *gc, void *fdt, + libxl_virtio_pci_host *host, + libxl_domain_config *d_config) +{ + uint32_t *full_iommu_map, *iommu_map; + unsigned int i, len, ntranslated = 0; + int res; + + for (i = 0; i < d_config->num_virtios; i++) { + libxl_device_virtio *virtio = &d_config->virtios[i]; + + if (libxl_defbool_val(virtio->grant_usage) && + virtio->transport == LIBXL_VIRTIO_TRANSPORT_PCI && + virtio->u.pci.host_id == host->id) { + ntranslated++; + } + } + + if (!ntranslated) + return 0; + + len = ntranslated * sizeof(uint32_t) * PCI_IOMMU_MAP_STRIDE; + full_iommu_map = libxl__malloc(gc, len); + iommu_map = full_iommu_map; + + /* See Linux Documentation/devicetree/bindings/pci/pci-iommu.txt */ + for (i = 0; i < d_config->num_virtios; i++) { + libxl_device_virtio *virtio = &d_config->virtios[i]; + + if (libxl_defbool_val(virtio->grant_usage) && + virtio->transport == LIBXL_VIRTIO_TRANSPORT_PCI && + virtio->u.pci.host_id == host->id) { + uint16_t bdf = (virtio->u.pci.bus << 8) | + (virtio->u.pci.dev << 3) | virtio->u.pci.func; + unsigned int j = 0; + + /* rid_base (1 cell) */ + iommu_map[j++] = cpu_to_fdt32(bdf); + + /* iommu_phandle (1 cell) */ + iommu_map[j++] = cpu_to_fdt32(GUEST_PHANDLE_IOMMU); + + /* iommu_base (1 cell) */ + iommu_map[j++] = cpu_to_fdt32(virtio->backend_domid); + + /* length (1 cell) */ + iommu_map[j++] = cpu_to_fdt32(1 << 3); + + iommu_map += PCI_IOMMU_MAP_STRIDE; + } + } + + res = fdt_property(fdt, "iommu-map", full_iommu_map, len); + if (res) return res; + + return 0; +} + /* TODO Consider reusing make_vpci_node() */ static int make_virtio_pci_node(libxl__gc *gc, void *fdt, libxl_virtio_pci_host *host, @@ -1147,6 +1207,10 @@ static int make_virtio_pci_node(libxl__gc *gc, void *fdt, res = create_virtio_pci_irq_map(gc, fdt, host); if (res) return res; + /* xen,grant-dma bindings */ + res = create_virtio_pci_iommu_map(gc, fdt, host, d_config); + if (res) return res; + res = fdt_end_node(fdt); if (res) return res; From patchwork Mon Nov 27 07:32:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergiy Kibrik X-Patchwork-Id: 13469253 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 412A8C4167B for ; Mon, 27 Nov 2023 07:38:13 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.641647.1000398 (Exim 4.92) (envelope-from ) id 1r7WBv-0001An-EO; Mon, 27 Nov 2023 07:38:03 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 641647.1000398; Mon, 27 Nov 2023 07:38:03 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7WBv-0001Ag-BD; Mon, 27 Nov 2023 07:38:03 +0000 Received: by outflank-mailman (input) for mailman id 641647; Mon, 27 Nov 2023 07:38:01 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1r7WBt-00019G-TV for xen-devel@lists.xenproject.org; Mon, 27 Nov 2023 07:38:01 +0000 Received: from pb-smtp21.pobox.com (pb-smtp21.pobox.com [173.228.157.53]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id e36b66e6-8cf7-11ee-98e2-6d05b1d4d9a1; Mon, 27 Nov 2023 08:38:00 +0100 (CET) Received: from pb-smtp21.pobox.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id 1C7EE1A5A6; Mon, 27 Nov 2023 02:37:59 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from pb-smtp21.sea.icgroup.com (unknown [127.0.0.1]) by pb-smtp21.pobox.com (Postfix) with ESMTP id 13B171A5A5; Mon, 27 Nov 2023 02:37:59 -0500 (EST) (envelope-from sakib@darkstar.site) Received: from localhost (unknown [188.163.75.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pb-smtp21.pobox.com (Postfix) with ESMTPSA id A0B661A5A4; Mon, 27 Nov 2023 02:37:54 -0500 (EST) (envelope-from sakib@darkstar.site) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: e36b66e6-8cf7-11ee-98e2-6d05b1d4d9a1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=pobox.com; h=from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; s=sasl; bh=/Z6kaeEKawpzWl9Eo1m8IbkY5 KCnWj8r3LTFolwrXyg=; b=CgYzO7Qbsw3D7wjBW12uiZp86cQ3nJuYdPlOr68+G eTVZjOJYaLoy4LRWeCtPI5pJOiR6nOhRtVdTkZuWPttAc5fvDqTVA5KUjxAQVSt9 IYzit7HhTfuojt70/VlwVRhl4VpRqB4PPYVoCNLZCXzbZpGefy7ADE5stpLl3W6X bg= From: Sergiy Kibrik To: xen-devel@lists.xenproject.org, Julien Grall Cc: Oleksandr Tyshchenko , Stefano Stabellini , Volodymyr Babchuk , Stewart Hildebrand , Juergen Gross , Wei Liu , Anthony PERARD , Sergiy Kibrik Subject: [RFC PATCH v1 5/5] libxl: Add "backend_type" property for the Virtio devices Date: Mon, 27 Nov 2023 09:32:21 +0200 Message-Id: <20231127073221.4046427-2-Sergiy_Kibrik@epam.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231127073221.4046427-1-Sergiy_Kibrik@epam.com> References: <20231127072754.4045254-1-Sergiy_Kibrik@epam.com> <20231127073221.4046427-1-Sergiy_Kibrik@epam.com> MIME-Version: 1.0 X-Pobox-Relay-ID: E085CC4E-8CF7-11EE-9B4A-A19503B9AAD1-90055647!pb-smtp21.pobox.com From: Oleksandr Tyshchenko Introduce new configuration option "backend_type" for the Virtio devices in order to specify backend implementation to use. There are two possible values "qemu" (default) and "standalone". If backend is in Qemu (backend_type=qemu) and Qemu runs in toolstack domain (backend=Domain-0) then Qemu will be launched automatically at the guest creation time. For this to work implement "dm_needed" callback. Please note, there is no support for Qemu in other domains for the time being, so the combination of "backend=DomD" and "backend_type=qemu" just won't work. Qemu configuration for Virtio devices should be described via "device_model_args" property. Signed-off-by: Oleksandr Tyshchenko Signed-off-by: Sergiy Kibrik Reviewed-by: Juergen Gross --- docs/man/xl.cfg.5.pod.in | 9 +++++++++ tools/libs/light/libxl_types.idl | 7 +++++++ tools/libs/light/libxl_virtio.c | 29 ++++++++++++++++++++++++++++- tools/xl/xl_parse.c | 3 +++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in index 0fba750815..592aad1d1e 100644 --- a/docs/man/xl.cfg.5.pod.in +++ b/docs/man/xl.cfg.5.pod.in @@ -1624,6 +1624,15 @@ are supported. This option is mandatory. The Virtio device with transport "pci" must be identified by its B. See L for more details about the format for B. +=item B + +Specifies the software implementation of the backend implementation to use. +This option doesn't affect the guest's view of the Virtio device. + +Both "qemu" and "standalone" are supported. The only difference is +that for the former the toolstack assists with configuring and launching +the device-model. If this option is missing, then "qemu" value will be used. + =item B If this option is B, the Xen grants are always enabled. diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index a86c601994..13b8ade41c 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -284,6 +284,12 @@ libxl_virtio_transport = Enumeration("virtio_transport", [ (2, "PCI"), ]) +libxl_virtio_backend = Enumeration("virtio_backend", [ + (0, "UNKNOWN"), + (1, "QEMU"), + (2, "STANDALONE"), + ]) + libxl_passthrough = Enumeration("passthrough", [ (0, "default"), (1, "disabled"), @@ -778,6 +784,7 @@ libxl_device_vkb = Struct("device_vkb", [ libxl_device_virtio = Struct("device_virtio", [ ("backend_domid", libxl_domid), ("backend_domname", string), + ("backend_type", libxl_virtio_backend), ("type", string), ("u", KeyedUnion(None, libxl_virtio_transport, "transport", [("unknown", None), diff --git a/tools/libs/light/libxl_virtio.c b/tools/libs/light/libxl_virtio.c index 8062423c75..339a2006f0 100644 --- a/tools/libs/light/libxl_virtio.c +++ b/tools/libs/light/libxl_virtio.c @@ -32,9 +32,20 @@ static int libxl__device_virtio_setdefault(libxl__gc *gc, uint32_t domid, libxl_defbool_setdefault(&virtio->grant_usage, virtio->backend_domid != LIBXL_TOOLSTACK_DOMID); + if (virtio->backend_type == LIBXL_VIRTIO_BACKEND_UNKNOWN) + virtio->backend_type = LIBXL_VIRTIO_BACKEND_QEMU; + return 0; } +static int libxl__device_virtio_dm_needed(void *e, unsigned domid) +{ + libxl_device_virtio *elem = e; + + return elem->backend_type == LIBXL_VIRTIO_BACKEND_QEMU && + elem->backend_domid == domid; +} + static int libxl__device_from_virtio(libxl__gc *gc, uint32_t domid, libxl_device_virtio *virtio, libxl__device *device) @@ -55,7 +66,8 @@ static int libxl__set_xenstore_virtio(libxl__gc *gc, uint32_t domid, flexarray_t *back, flexarray_t *front, flexarray_t *ro_front) { - const char *transport = libxl_virtio_transport_to_string(virtio->transport); + const char *transport = libxl_virtio_transport_to_string(virtio->transport), + *backend = libxl_virtio_backend_to_string(virtio->backend_type); if (virtio->transport == LIBXL_VIRTIO_TRANSPORT_MMIO) { flexarray_append_pair(back, "irq", GCSPRINTF("%u", virtio->u.mmio.irq)); @@ -74,6 +86,7 @@ static int libxl__set_xenstore_virtio(libxl__gc *gc, uint32_t domid, } flexarray_append_pair(back, "type", GCSPRINTF("%s", virtio->type)); flexarray_append_pair(back, "transport", GCSPRINTF("%s", transport)); + flexarray_append_pair(back, "backend_type", GCSPRINTF("%s", backend)); flexarray_append_pair(back, "grant_usage", libxl_defbool_val(virtio->grant_usage) ? "1" : "0"); @@ -166,6 +179,19 @@ static int libxl__virtio_from_xenstore(libxl__gc *gc, const char *libxl_path, } } + tmp = NULL; + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/backend_type", be_path), &tmp); + if (rc) goto out; + + if (tmp) { + rc = libxl_virtio_backend_from_string(tmp, &virtio->backend_type); + if (rc) { + LOG(ERROR, "Unable to parse xenstore node %s/backend_type", be_path); + goto out; + } + } + tmp = NULL; rc = libxl__xs_read_checked(gc, XBT_NULL, GCSPRINTF("%s/grant_usage", be_path), &tmp); @@ -200,6 +226,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(virtio) #define libxl_device_virtio_compare NULL DEFINE_DEVICE_TYPE_STRUCT(virtio, VIRTIO, virtios, + .dm_needed = libxl__device_virtio_dm_needed, .set_xenstore_config = (device_set_xenstore_config_fn_t) libxl__set_xenstore_virtio, .from_xenstore = (device_from_xenstore_fn_t)libxl__virtio_from_xenstore, diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 4544ce2307..234cef5f7e 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1215,6 +1215,9 @@ static int parse_virtio_config(libxl_device_virtio *virtio, char *token) } else if (MATCH_OPTION("transport", token, oparg)) { rc = libxl_virtio_transport_from_string(oparg, &virtio->transport); if (rc) return rc; + } else if (MATCH_OPTION("backend_type", token, oparg)) { + rc = libxl_virtio_backend_from_string(oparg, &virtio->backend_type); + if (rc) return rc; } else if (MATCH_OPTION("grant_usage", token, oparg)) { libxl_defbool_set(&virtio->grant_usage, strtoul(oparg, NULL, 0)); } else if (MATCH_OPTION("bdf", token, oparg)) {