From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 154176320180025.175551277843738; Fri, 9 Nov 2018 03:33:21 -0800 (PST) Received: from localhost ([::1]:33274 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL52O-00088t-Hg for importer@patchew.org; Fri, 09 Nov 2018 06:33:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45543) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL4zu-0006bJ-0A for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL4zs-0000Fv-CB for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:45 -0500 Received: from mx1.redhat.com ([209.132.183.28]:53378) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zk-0006uB-7y; Fri, 09 Nov 2018 06:30:36 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D8608C049E12; Fri, 9 Nov 2018 11:30:14 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 84B965C219; Fri, 9 Nov 2018 11:30:12 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:40 +0100 Message-Id: <20181109112957.10067-2-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Fri, 09 Nov 2018 11:30:15 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 01/18] update-linux-headers: Import virtio_iommu.h 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Update the script to update the virtio_iommu.h header. Signed-off-by: Eric Auger --- scripts/update-linux-headers.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers= .sh index 0a964fe240..55fd271a32 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -159,6 +159,9 @@ fi cat <$output/linux-headers/linux/virtio_config.h #include "standard-headers/linux/virtio_config.h" EOF +cat <$output/linux-headers/linux/virtio_iommu.h +#include "standard-headers/linux/virtio_iommu.h" +EOF cat <$output/linux-headers/linux/virtio_ring.h #include "standard-headers/linux/virtio_ring.h" EOF --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763582485942.4089056649804; Fri, 9 Nov 2018 03:39:42 -0800 (PST) Received: from localhost ([::1]:33311 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL58Q-00082x-BR for importer@patchew.org; Fri, 09 Nov 2018 06:39:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45497) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL4zs-0006Zf-Qu for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL4zq-00008v-Sk for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59212) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zZ-00071q-FX; Fri, 09 Nov 2018 06:30:27 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 706CF3084243; Fri, 9 Nov 2018 11:30:17 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 272945C219; Fri, 9 Nov 2018 11:30:14 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:41 +0100 Message-Id: <20181109112957.10067-3-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Fri, 09 Nov 2018 11:30:17 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 02/18] linux-headers: Partial update for virtio-iommu v0.8 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Partial sync against Jean-Philippe's branch: git://linux-arm.org/linux-jpb.git virtio-iommu/v0.8 Signed-off-by: Eric Auger --- include/standard-headers/linux/virtio_ids.h | 1 + include/standard-headers/linux/virtio_iommu.h | 159 ++++++++++++++++++ linux-headers/linux/virtio_iommu.h | 1 + 3 files changed, 161 insertions(+) create mode 100644 include/standard-headers/linux/virtio_iommu.h create mode 100644 linux-headers/linux/virtio_iommu.h diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard= -headers/linux/virtio_ids.h index 6d5c3b2d4f..cfe47c5d9a 100644 --- a/include/standard-headers/linux/virtio_ids.h +++ b/include/standard-headers/linux/virtio_ids.h @@ -43,5 +43,6 @@ #define VIRTIO_ID_INPUT 18 /* virtio input */ #define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */ #define VIRTIO_ID_CRYPTO 20 /* virtio crypto */ +#define VIRTIO_ID_IOMMU 23 /* virtio IOMMU */ =20 #endif /* _LINUX_VIRTIO_IDS_H */ diff --git a/include/standard-headers/linux/virtio_iommu.h b/include/standa= rd-headers/linux/virtio_iommu.h new file mode 100644 index 0000000000..0a40b21ea9 --- /dev/null +++ b/include/standard-headers/linux/virtio_iommu.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Virtio-iommu definition v0.8 + * + * Copyright (C) 2018 Arm Ltd. + */ +#ifndef _LINUX_VIRTIO_IOMMU_H +#define _LINUX_VIRTIO_IOMMU_H + +#include "standard-headers/linux/types.h" + +/* Feature bits */ +#define VIRTIO_IOMMU_F_INPUT_RANGE 0 +#define VIRTIO_IOMMU_F_DOMAIN_BITS 1 +#define VIRTIO_IOMMU_F_MAP_UNMAP 2 +#define VIRTIO_IOMMU_F_BYPASS 3 +#define VIRTIO_IOMMU_F_PROBE 4 + +struct virtio_iommu_config { + /* Supported page sizes */ + uint64_t page_size_mask; + /* Supported IOVA range */ + struct virtio_iommu_range { + uint64_t start; + uint64_t end; + } input_range; + /* Max domain ID size */ + uint8_t domain_bits; + uint8_t padding[3]; + /* Probe buffer size */ + uint32_t probe_size; +}; + +/* Request types */ +#define VIRTIO_IOMMU_T_ATTACH 0x01 +#define VIRTIO_IOMMU_T_DETACH 0x02 +#define VIRTIO_IOMMU_T_MAP 0x03 +#define VIRTIO_IOMMU_T_UNMAP 0x04 +#define VIRTIO_IOMMU_T_PROBE 0x05 + +/* Status types */ +#define VIRTIO_IOMMU_S_OK 0x00 +#define VIRTIO_IOMMU_S_IOERR 0x01 +#define VIRTIO_IOMMU_S_UNSUPP 0x02 +#define VIRTIO_IOMMU_S_DEVERR 0x03 +#define VIRTIO_IOMMU_S_INVAL 0x04 +#define VIRTIO_IOMMU_S_RANGE 0x05 +#define VIRTIO_IOMMU_S_NOENT 0x06 +#define VIRTIO_IOMMU_S_FAULT 0x07 + +struct virtio_iommu_req_head { + uint8_t type; + uint8_t reserved[3]; +}; + +struct virtio_iommu_req_tail { + uint8_t status; + uint8_t reserved[3]; +}; + +struct virtio_iommu_req_attach { + struct virtio_iommu_req_head head; + uint32_t domain; + uint32_t endpoint; + uint8_t reserved[8]; + struct virtio_iommu_req_tail tail; +}; + +struct virtio_iommu_req_detach { + struct virtio_iommu_req_head head; + uint32_t domain; + uint32_t endpoint; + uint8_t reserved[8]; + struct virtio_iommu_req_tail tail; +}; + +#define VIRTIO_IOMMU_MAP_F_READ (1 << 0) +#define VIRTIO_IOMMU_MAP_F_WRITE (1 << 1) +#define VIRTIO_IOMMU_MAP_F_EXEC (1 << 2) +#define VIRTIO_IOMMU_MAP_F_MMIO (1 << 3) + +#define VIRTIO_IOMMU_MAP_F_MASK (VIRTIO_IOMMU_MAP_F_READ | \ + VIRTIO_IOMMU_MAP_F_WRITE | \ + VIRTIO_IOMMU_MAP_F_EXEC | \ + VIRTIO_IOMMU_MAP_F_MMIO) + +struct virtio_iommu_req_map { + struct virtio_iommu_req_head head; + uint32_t domain; + uint64_t virt_start; + uint64_t virt_end; + uint64_t phys_start; + uint32_t flags; + struct virtio_iommu_req_tail tail; +}; + +struct virtio_iommu_req_unmap { + struct virtio_iommu_req_head head; + uint32_t domain; + uint64_t virt_start; + uint64_t virt_end; + uint8_t reserved[4]; + struct virtio_iommu_req_tail tail; +}; + +#define VIRTIO_IOMMU_PROBE_T_NONE 0 +#define VIRTIO_IOMMU_PROBE_T_RESV_MEM 1 + +#define VIRTIO_IOMMU_PROBE_T_MASK 0xfff + +struct virtio_iommu_probe_property { + uint16_t type; + uint16_t length; +}; + +#define VIRTIO_IOMMU_RESV_MEM_T_RESERVED 0 +#define VIRTIO_IOMMU_RESV_MEM_T_MSI 1 + +struct virtio_iommu_probe_resv_mem { + struct virtio_iommu_probe_property head; + uint8_t subtype; + uint8_t reserved[3]; + uint64_t start; + uint64_t end; +}; + +struct virtio_iommu_req_probe { + struct virtio_iommu_req_head head; + uint32_t endpoint; + uint8_t reserved[64]; + + uint8_t properties[]; + + /* + * Tail follows the variable-length properties array. No padding, + * property lengths are all aligned on 8 bytes. + */ +}; + +/* Fault types */ +#define VIRTIO_IOMMU_FAULT_R_UNKNOWN 0 +#define VIRTIO_IOMMU_FAULT_R_DOMAIN 1 +#define VIRTIO_IOMMU_FAULT_R_MAPPING 2 + +#define VIRTIO_IOMMU_FAULT_F_READ (1 << 0) +#define VIRTIO_IOMMU_FAULT_F_WRITE (1 << 1) +#define VIRTIO_IOMMU_FAULT_F_EXEC (1 << 2) +#define VIRTIO_IOMMU_FAULT_F_ADDRESS (1 << 8) + +struct virtio_iommu_fault { + uint8_t reason; + uint8_t reserved[3]; + uint32_t flags; + uint32_t endpoint; + uint8_t reserved2[4]; + uint64_t address; +}; + +#endif diff --git a/linux-headers/linux/virtio_iommu.h b/linux-headers/linux/virti= o_iommu.h new file mode 100644 index 0000000000..2dc4609c16 --- /dev/null +++ b/linux-headers/linux/virtio_iommu.h @@ -0,0 +1 @@ +#include "standard-headers/linux/virtio_iommu.h" --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763604995749.1824004903546; Fri, 9 Nov 2018 03:40:04 -0800 (PST) Received: from localhost ([::1]:33313 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL58t-0008Ry-KC for importer@patchew.org; Fri, 09 Nov 2018 06:40:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45724) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL500-0006hA-Um for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL4zv-0000Ss-E0 for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36252) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zk-00077I-93; Fri, 09 Nov 2018 06:30:37 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 04871811D3; Fri, 9 Nov 2018 11:30:20 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id B666A5C219; Fri, 9 Nov 2018 11:30:17 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:42 +0100 Message-Id: <20181109112957.10067-4-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 09 Nov 2018 11:30:20 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 03/18] virtio-iommu: Add skeleton 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patchs adds the skeleton for the virtio-iommu device. Signed-off-by: Eric Auger --- v7 -> v8: - expose VIRTIO_IOMMU_F_BYPASS and VIRTIO_F_VERSION_1 features - set_config dummy implementation + tracing - add trace in get_features - set the features on realize() and store the acked ones - remove inclusion of linux/virtio_iommu.h v6 -> v7: - removed qapi-event.h include - add primary_bus and associated property v4 -> v5: - use the new v0.5 terminology (domain, endpoint) - add the event virtqueue v3 -> v4: - use page_size_mask instead of page_sizes - added set_features() - added some traces (reset, set_status, set_features) - empty virtio_iommu_set_config() as the driver MUST NOT write to device configuration fields - add get_config trace v2 -> v3: - rebase on 2.10-rc0, ie. use IOMMUMemoryRegion and remove iommu_ops. - advertise VIRTIO_IOMMU_F_MAP_UNMAP feature - page_sizes set to TARGET_PAGE_SIZE Conflicts: hw/virtio/trace-events --- hw/virtio/Makefile.objs | 1 + hw/virtio/trace-events | 9 + hw/virtio/virtio-iommu.c | 273 +++++++++++++++++++++++++++++++ include/hw/virtio/virtio-iommu.h | 62 +++++++ 4 files changed, 345 insertions(+) create mode 100644 hw/virtio/virtio-iommu.c create mode 100644 include/hw/virtio/virtio-iommu.h diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index 1b2799cfd8..49eba67a54 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -10,6 +10,7 @@ obj-$(CONFIG_VIRTIO_CRYPTO) +=3D virtio-crypto.o obj-$(call land,$(CONFIG_VIRTIO_CRYPTO),$(CONFIG_VIRTIO_PCI)) +=3D virtio-= crypto-pci.o =20 obj-$(CONFIG_LINUX) +=3D vhost.o vhost-backend.o vhost-user.o +obj-$(CONFIG_LINUX) +=3D virtio-iommu.o obj-$(CONFIG_VHOST_VSOCK) +=3D vhost-vsock.o endif =20 diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 07bcbe9e85..84da904d8b 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -46,3 +46,12 @@ virtio_balloon_handle_output(const char *name, uint64_t = gpa) "section name: %s g virtio_balloon_get_config(uint32_t num_pages, uint32_t actual) "num_pages:= %d actual: %d" virtio_balloon_set_config(uint32_t actual, uint32_t oldactual) "actual: %d= oldactual: %d" virtio_balloon_to_target(uint64_t target, uint32_t num_pages) "balloon tar= get: 0x%"PRIx64" num_pages: %d" + +# hw/virtio/virtio-iommu.c +# +virtio_iommu_device_reset(void) "reset!" +virtio_iommu_get_features(uint64_t features) "device supports features=3D0= x%"PRIx64 +virtio_iommu_set_features(uint64_t features) "features accepted by the dri= ver =3D0x%"PRIx64 +virtio_iommu_device_status(uint8_t status) "driver status =3D %d" +virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t = end, uint8_t domain_bits, uint32_t probe_size) "page_size_mask=3D0x%"PRIx64= " start=3D0x%"PRIx64" end=3D0x%"PRIx64" domain_bits=3D%d probe_size=3D0x%x" +virtio_iommu_set_config(uint64_t page_size_mask, uint64_t start, uint64_t = end, uint8_t domain_bits, uint32_t probe_size) "page_size_mask=3D0x%"PRIx64= " start=3D0x%"PRIx64" end=3D0x%"PRIx64" domain_bits=3D%d probe_size=3D0x%x" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c new file mode 100644 index 0000000000..cf7dee128a --- /dev/null +++ b/hw/virtio/virtio-iommu.c @@ -0,0 +1,273 @@ +/* + * virtio-iommu device + * + * Copyright (c) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License f= or + * more details. + * + * You should have received a copy of the GNU General Public License along= with + * this program. If not, see . + * + */ + +#include "qemu/osdep.h" +#include "qemu/iov.h" +#include "qemu-common.h" +#include "hw/virtio/virtio.h" +#include "sysemu/kvm.h" +#include "trace.h" + +#include "standard-headers/linux/virtio_ids.h" + +#include "hw/virtio/virtio-bus.h" +#include "hw/virtio/virtio-access.h" +#include "hw/virtio/virtio-iommu.h" + +/* Max size */ +#define VIOMMU_DEFAULT_QUEUE_SIZE 256 + +static int virtio_iommu_handle_attach(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return -ENOENT; +} +static int virtio_iommu_handle_detach(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return -ENOENT; +} +static int virtio_iommu_handle_map(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return -ENOENT; +} +static int virtio_iommu_handle_unmap(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return -ENOENT; +} + +static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIOIOMMU *s =3D VIRTIO_IOMMU(vdev); + VirtQueueElement *elem; + struct virtio_iommu_req_head head; + struct virtio_iommu_req_tail tail; + unsigned int iov_cnt; + struct iovec *iov; + size_t sz; + + for (;;) { + elem =3D virtqueue_pop(vq, sizeof(VirtQueueElement)); + if (!elem) { + return; + } + + if (iov_size(elem->in_sg, elem->in_num) < sizeof(tail) || + iov_size(elem->out_sg, elem->out_num) < sizeof(head)) { + virtio_error(vdev, "virtio-iommu erroneous head or tail"); + virtqueue_detach_element(vq, elem, 0); + g_free(elem); + break; + } + + iov_cnt =3D elem->out_num; + iov =3D g_memdup(elem->out_sg, sizeof(struct iovec) * elem->out_nu= m); + sz =3D iov_to_buf(iov, iov_cnt, 0, &head, sizeof(head)); + if (sz !=3D sizeof(head)) { + tail.status =3D VIRTIO_IOMMU_S_UNSUPP; + } + qemu_mutex_lock(&s->mutex); + switch (head.type) { + case VIRTIO_IOMMU_T_ATTACH: + tail.status =3D virtio_iommu_handle_attach(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_DETACH: + tail.status =3D virtio_iommu_handle_detach(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_MAP: + tail.status =3D virtio_iommu_handle_map(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_UNMAP: + tail.status =3D virtio_iommu_handle_unmap(s, iov, iov_cnt); + break; + default: + tail.status =3D VIRTIO_IOMMU_S_UNSUPP; + } + qemu_mutex_unlock(&s->mutex); + + sz =3D iov_from_buf(elem->in_sg, elem->in_num, 0, + &tail, sizeof(tail)); + assert(sz =3D=3D sizeof(tail)); + + virtqueue_push(vq, elem, sizeof(tail)); + virtio_notify(vdev, vq); + g_free(elem); + } +} + +static void virtio_iommu_get_config(VirtIODevice *vdev, uint8_t *config_da= ta) +{ + VirtIOIOMMU *dev =3D VIRTIO_IOMMU(vdev); + struct virtio_iommu_config *config =3D &dev->config; + + trace_virtio_iommu_get_config(config->page_size_mask, + config->input_range.start, + config->input_range.end, + config->domain_bits, + config->probe_size); + memcpy(config_data, &dev->config, sizeof(struct virtio_iommu_config)); +} + +static void virtio_iommu_set_config(VirtIODevice *vdev, + const uint8_t *config_data) +{ + struct virtio_iommu_config config; + + memcpy(&config, config_data, sizeof(struct virtio_iommu_config)); + trace_virtio_iommu_set_config(config.page_size_mask, + config.input_range.start, + config.input_range.end, + config.domain_bits, + config.probe_size); +} + +static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f, + Error **errp) +{ + VirtIOIOMMU *dev =3D VIRTIO_IOMMU(vdev); + + f |=3D dev->features; + trace_virtio_iommu_get_features(f); + return f; +} + +static void virtio_iommu_set_features(VirtIODevice *vdev, uint64_t val) +{ + VirtIOIOMMU *dev =3D VIRTIO_IOMMU(vdev); + + dev->acked_features =3D val; + trace_virtio_iommu_set_features(dev->acked_features); +} + +static int virtio_iommu_post_load_device(void *opaque, int version_id) +{ + return 0; +} + +static const VMStateDescription vmstate_virtio_iommu_device =3D { + .name =3D "virtio-iommu-device", + .version_id =3D 1, + .minimum_version_id =3D 1, + .post_load =3D virtio_iommu_post_load_device, + .fields =3D (VMStateField[]) { + VMSTATE_END_OF_LIST() + }, +}; + +static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) +{ + VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); + VirtIOIOMMU *s =3D VIRTIO_IOMMU(dev); + + virtio_init(vdev, "virtio-iommu", VIRTIO_ID_IOMMU, + sizeof(struct virtio_iommu_config)); + + s->req_vq =3D virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, + virtio_iommu_handle_command); + s->event_vq =3D virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, NULL= ); + + s->config.page_size_mask =3D TARGET_PAGE_MASK; + s->config.input_range.end =3D -1UL; + s->config.domain_bits =3D 32; + + virtio_add_feature(&s->features, VIRTIO_RING_F_EVENT_IDX); + virtio_add_feature(&s->features, VIRTIO_RING_F_INDIRECT_DESC); + virtio_add_feature(&s->features, VIRTIO_F_VERSION_1); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_INPUT_RANGE); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_DOMAIN_BITS); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS); +} + +static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp) +{ + VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); + + virtio_cleanup(vdev); +} + +static void virtio_iommu_device_reset(VirtIODevice *vdev) +{ + trace_virtio_iommu_device_reset(); +} + +static void virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status) +{ + trace_virtio_iommu_device_status(status); +} + +static void virtio_iommu_instance_init(Object *obj) +{ +} + +static const VMStateDescription vmstate_virtio_iommu =3D { + .name =3D "virtio-iommu", + .minimum_version_id =3D 1, + .version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_VIRTIO_DEVICE, + VMSTATE_END_OF_LIST() + }, +}; + +static Property virtio_iommu_properties[] =3D { + DEFINE_PROP_LINK("primary-bus", VirtIOIOMMU, primary_bus, "PCI", PCIBu= s *), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_iommu_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + VirtioDeviceClass *vdc =3D VIRTIO_DEVICE_CLASS(klass); + + dc->props =3D virtio_iommu_properties; + dc->vmsd =3D &vmstate_virtio_iommu; + + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + vdc->realize =3D virtio_iommu_device_realize; + vdc->unrealize =3D virtio_iommu_device_unrealize; + vdc->reset =3D virtio_iommu_device_reset; + vdc->get_config =3D virtio_iommu_get_config; + vdc->set_config =3D virtio_iommu_set_config; + vdc->get_features =3D virtio_iommu_get_features; + vdc->set_features =3D virtio_iommu_set_features; + vdc->set_status =3D virtio_iommu_set_status; + vdc->vmsd =3D &vmstate_virtio_iommu_device; +} + +static const TypeInfo virtio_iommu_info =3D { + .name =3D TYPE_VIRTIO_IOMMU, + .parent =3D TYPE_VIRTIO_DEVICE, + .instance_size =3D sizeof(VirtIOIOMMU), + .instance_init =3D virtio_iommu_instance_init, + .class_init =3D virtio_iommu_class_init, +}; + +static void virtio_register_types(void) +{ + type_register_static(&virtio_iommu_info); +} + +type_init(virtio_register_types) diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-io= mmu.h new file mode 100644 index 0000000000..4d47b6abeb --- /dev/null +++ b/include/hw/virtio/virtio-iommu.h @@ -0,0 +1,62 @@ +/* + * virtio-iommu device + * + * Copyright (c) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License f= or + * more details. + * + * You should have received a copy of the GNU General Public License along= with + * this program. If not, see . + * + */ + +#ifndef QEMU_VIRTIO_IOMMU_H +#define QEMU_VIRTIO_IOMMU_H + +#include "standard-headers/linux/virtio_iommu.h" +#include "hw/virtio/virtio.h" +#include "hw/pci/pci.h" + +#define TYPE_VIRTIO_IOMMU "virtio-iommu-device" +#define VIRTIO_IOMMU(obj) \ + OBJECT_CHECK(VirtIOIOMMU, (obj), TYPE_VIRTIO_IOMMU) + +#define IOMMU_PCI_BUS_MAX 256 +#define IOMMU_PCI_DEVFN_MAX 256 + +typedef struct IOMMUDevice { + void *viommu; + PCIBus *bus; + int devfn; + IOMMUMemoryRegion iommu_mr; + AddressSpace as; +} IOMMUDevice; + +typedef struct IOMMUPciBus { + PCIBus *bus; + IOMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically allo= c */ +} IOMMUPciBus; + +typedef struct VirtIOIOMMU { + VirtIODevice parent_obj; + VirtQueue *req_vq; + VirtQueue *event_vq; + struct virtio_iommu_config config; + uint64_t features; + uint64_t acked_features; + GHashTable *as_by_busptr; + IOMMUPciBus *as_by_bus_num[IOMMU_PCI_BUS_MAX]; + PCIBus *primary_bus; + GTree *domains; + QemuMutex mutex; + GTree *endpoints; +} VirtIOIOMMU; + +#endif --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763725989514.5175164075179; Fri, 9 Nov 2018 03:42:05 -0800 (PST) Received: from localhost ([::1]:33330 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5Aq-0001lb-Kf for importer@patchew.org; Fri, 09 Nov 2018 06:42:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45727) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL500-0006hB-Vl for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL4zw-0000XW-JF for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41546) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zo-0007OT-NO; Fri, 09 Nov 2018 06:30:42 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 871DF30821ED; Fri, 9 Nov 2018 11:30:24 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 46D475C219; Fri, 9 Nov 2018 11:30:20 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:43 +0100 Message-Id: <20181109112957.10067-5-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 09 Nov 2018 11:30:24 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 04/18] virtio-iommu: Decode the command payload 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch adds the command payload decoding and introduces the functions that will do the actual command handling. Those functions are not yet implemented. Signed-off-by: Eric Auger --- v7 -> v8: - handle new domain parameter in detach - remove reserved checks v5 -> v6: - change map/unmap semantics (remove size) v4 -> v5: - adopt new v0.5 terminology v3 -> v4: - no flags field anymore in struct virtio_iommu_req_unmap - test reserved on attach/detach, change trace proto - rebase on v2.10.0. --- hw/virtio/trace-events | 4 ++ hw/virtio/virtio-iommu.c | 95 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 84da904d8b..e6177ca0e4 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -55,3 +55,7 @@ virtio_iommu_set_features(uint64_t features) "features ac= cepted by the driver =3D0 virtio_iommu_device_status(uint8_t status) "driver status =3D %d" virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t = end, uint8_t domain_bits, uint32_t probe_size) "page_size_mask=3D0x%"PRIx64= " start=3D0x%"PRIx64" end=3D0x%"PRIx64" domain_bits=3D%d probe_size=3D0x%x" virtio_iommu_set_config(uint64_t page_size_mask, uint64_t start, uint64_t = end, uint8_t domain_bits, uint32_t probe_size) "page_size_mask=3D0x%"PRIx64= " start=3D0x%"PRIx64" end=3D0x%"PRIx64" domain_bits=3D%d probe_size=3D0x%x" +virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "domain=3D%d endpo= int=3D%d" +virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=3D%d endpo= int=3D%d" +virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_en= d, uint64_t phys_start, uint32_t flags) "domain=3D%d virt_start=3D0x%"PRIx6= 4" virt_end=3D0x%"PRIx64 " phys_start=3D0x%"PRIx64" flags=3D%d" +virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_= end) "domain=3D%d virt_start=3D0x%"PRIx64" virt_end=3D0x%"PRIx64 diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index cf7dee128a..5346440c51 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -33,29 +33,116 @@ /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 =20 +static int virtio_iommu_attach(VirtIOIOMMU *s, + struct virtio_iommu_req_attach *req) +{ + uint32_t domain_id =3D le32_to_cpu(req->domain); + uint32_t ep_id =3D le32_to_cpu(req->endpoint); + + trace_virtio_iommu_attach(domain_id, ep_id); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_detach(VirtIOIOMMU *s, + struct virtio_iommu_req_detach *req) +{ + uint32_t domain_id =3D le32_to_cpu(req->domain); + uint32_t ep_id =3D le32_to_cpu(req->endpoint); + + trace_virtio_iommu_detach(domain_id, ep_id); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_map(VirtIOIOMMU *s, + struct virtio_iommu_req_map *req) +{ + uint32_t domain_id =3D le32_to_cpu(req->domain); + uint64_t phys_start =3D le64_to_cpu(req->phys_start); + uint64_t virt_start =3D le64_to_cpu(req->virt_start); + uint64_t virt_end =3D le64_to_cpu(req->virt_end); + uint32_t flags =3D le32_to_cpu(req->flags); + + trace_virtio_iommu_map(domain_id, virt_start, virt_end, phys_start, fl= ags); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_unmap(VirtIOIOMMU *s, + struct virtio_iommu_req_unmap *req) +{ + uint32_t domain_id =3D le32_to_cpu(req->domain); + uint64_t virt_start =3D le64_to_cpu(req->virt_start); + uint64_t virt_end =3D le64_to_cpu(req->virt_end); + + trace_virtio_iommu_unmap(domain_id, virt_start, virt_end); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +#define get_payload_size(req) (\ +sizeof((req)) - sizeof(struct virtio_iommu_req_tail)) + static int virtio_iommu_handle_attach(VirtIOIOMMU *s, struct iovec *iov, unsigned int iov_cnt) { - return -ENOENT; + struct virtio_iommu_req_attach req; + size_t sz, payload_sz; + + payload_sz =3D get_payload_size(req); + + sz =3D iov_to_buf(iov, iov_cnt, 0, &req, payload_sz); + if (sz !=3D payload_sz) { + return VIRTIO_IOMMU_S_INVAL; + } + return virtio_iommu_attach(s, &req); } static int virtio_iommu_handle_detach(VirtIOIOMMU *s, struct iovec *iov, unsigned int iov_cnt) { - return -ENOENT; + struct virtio_iommu_req_detach req; + size_t sz, payload_sz; + + payload_sz =3D get_payload_size(req); + + sz =3D iov_to_buf(iov, iov_cnt, 0, &req, payload_sz); + if (sz !=3D payload_sz) { + return VIRTIO_IOMMU_S_INVAL; + } + return virtio_iommu_detach(s, &req); } static int virtio_iommu_handle_map(VirtIOIOMMU *s, struct iovec *iov, unsigned int iov_cnt) { - return -ENOENT; + struct virtio_iommu_req_map req; + size_t sz, payload_sz; + + payload_sz =3D get_payload_size(req); + + sz =3D iov_to_buf(iov, iov_cnt, 0, &req, payload_sz); + if (sz !=3D payload_sz) { + return VIRTIO_IOMMU_S_INVAL; + } + return virtio_iommu_map(s, &req); } static int virtio_iommu_handle_unmap(VirtIOIOMMU *s, struct iovec *iov, unsigned int iov_cnt) { - return -ENOENT; + struct virtio_iommu_req_unmap req; + size_t sz, payload_sz; + + payload_sz =3D get_payload_size(req); + + sz =3D iov_to_buf(iov, iov_cnt, 0, &req, payload_sz); + if (sz !=3D payload_sz) { + return VIRTIO_IOMMU_S_INVAL; + } + return virtio_iommu_unmap(s, &req); } =20 static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763300410597.5385759439625; Fri, 9 Nov 2018 03:35:00 -0800 (PST) Received: from localhost ([::1]:33281 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL53z-0002gt-7T for importer@patchew.org; Fri, 09 Nov 2018 06:34:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45633) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL4zw-0006eW-86 for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL4zt-0000MG-IB for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:48 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55016) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zk-0007nt-BC; Fri, 09 Nov 2018 06:30:38 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0410AC058CA9; Fri, 9 Nov 2018 11:30:32 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id C75FB5C21F; Fri, 9 Nov 2018 11:30:24 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:44 +0100 Message-Id: <20181109112957.10067-6-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 09 Nov 2018 11:30:32 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 05/18] virtio-iommu: Add the iommu regions 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch initializes the iommu memory regions so that PCIe end point transactions get translated. The translation function is not yet implemented though. Signed-off-by: Eric Auger --- v6 -> v7: - use primary_bus - rebase on new translate proto featuring iommu_idx v5 -> v6: - include qapi/error.h - fix g_hash_table_lookup key in virtio_iommu_find_add_as v4 -> v5: - use PCI bus handle as a key - use get_primary_pci_bus() callback v3 -> v4: - add trace_virtio_iommu_init_iommu_mr v2 -> v3: - use IOMMUMemoryRegion - iommu mr name built with BDF - rename smmu_get_sid into virtio_iommu_get_sid and use PCI_BUILD_BDF --- hw/virtio/trace-events | 2 + hw/virtio/virtio-iommu.c | 94 ++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-iommu.h | 2 + 3 files changed, 98 insertions(+) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index e6177ca0e4..9270b0463e 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -59,3 +59,5 @@ virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "= domain=3D%d endpoint=3D%d" virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=3D%d endpo= int=3D%d" virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_en= d, uint64_t phys_start, uint32_t flags) "domain=3D%d virt_start=3D0x%"PRIx6= 4" virt_end=3D0x%"PRIx64 " phys_start=3D0x%"PRIx64" flags=3D%d" virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_= end) "domain=3D%d virt_start=3D0x%"PRIx64" virt_end=3D0x%"PRIx64 +virtio_iommu_translate(const char *name, uint32_t rid, uint64_t iova, int = flag) "mr=3D%s rid=3D%d addr=3D0x%"PRIx64" flag=3D%d" +virtio_iommu_init_iommu_mr(char *iommu_mr) "init %s" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 5346440c51..2043623b30 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -22,6 +22,10 @@ #include "qemu-common.h" #include "hw/virtio/virtio.h" #include "sysemu/kvm.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "hw/i386/pc.h" +#include "hw/arm/virt.h" #include "trace.h" =20 #include "standard-headers/linux/virtio_ids.h" @@ -33,6 +37,50 @@ /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 =20 +static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) +{ + return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); +} + +static AddressSpace *virtio_iommu_find_add_as(PCIBus *bus, void *opaque, + int devfn) +{ + VirtIOIOMMU *s =3D opaque; + IOMMUPciBus *sbus =3D g_hash_table_lookup(s->as_by_busptr, bus); + IOMMUDevice *sdev; + + if (!sbus) { + sbus =3D g_malloc0(sizeof(IOMMUPciBus) + + sizeof(IOMMUDevice *) * IOMMU_PCI_DEVFN_MAX); + sbus->bus =3D bus; + g_hash_table_insert(s->as_by_busptr, bus, sbus); + } + + sdev =3D sbus->pbdev[devfn]; + if (!sdev) { + char *name =3D g_strdup_printf("%s-%d-%d", + TYPE_VIRTIO_IOMMU_MEMORY_REGION, + pci_bus_num(bus), devfn); + sdev =3D sbus->pbdev[devfn] =3D g_malloc0(sizeof(IOMMUDevice)); + + sdev->viommu =3D s; + sdev->bus =3D bus; + sdev->devfn =3D devfn; + + trace_virtio_iommu_init_iommu_mr(name); + + memory_region_init_iommu(&sdev->iommu_mr, sizeof(sdev->iommu_mr), + TYPE_VIRTIO_IOMMU_MEMORY_REGION, + OBJECT(s), name, + UINT64_MAX); + address_space_init(&sdev->as, + MEMORY_REGION(&sdev->iommu_mr), TYPE_VIRTIO_IOM= MU); + } + + return &sdev->as; + +} + static int virtio_iommu_attach(VirtIOIOMMU *s, struct virtio_iommu_req_attach *req) { @@ -204,6 +252,27 @@ static void virtio_iommu_handle_command(VirtIODevice *= vdev, VirtQueue *vq) } } =20 +static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr = addr, + IOMMUAccessFlags flag, + int iommu_idx) +{ + IOMMUDevice *sdev =3D container_of(mr, IOMMUDevice, iommu_mr); + uint32_t sid; + + IOMMUTLBEntry entry =3D { + .target_as =3D &address_space_memory, + .iova =3D addr, + .translated_addr =3D addr, + .addr_mask =3D ~(hwaddr)0, + .perm =3D IOMMU_NONE, + }; + + sid =3D virtio_iommu_get_sid(sdev); + + trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag); + return entry; +} + static void virtio_iommu_get_config(VirtIODevice *vdev, uint8_t *config_da= ta) { VirtIOIOMMU *dev =3D VIRTIO_IOMMU(vdev); @@ -286,6 +355,15 @@ static void virtio_iommu_device_realize(DeviceState *d= ev, Error **errp) virtio_add_feature(&s->features, VIRTIO_IOMMU_F_DOMAIN_BITS); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS); + + memset(s->as_by_bus_num, 0, sizeof(s->as_by_bus_num)); + s->as_by_busptr =3D g_hash_table_new(NULL, NULL); + + if (s->primary_bus) { + pci_setup_iommu(s->primary_bus, virtio_iommu_find_add_as, s); + } else { + error_setg(errp, "VIRTIO-IOMMU is not attached to any PCI bus!"); + } } =20 static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp) @@ -344,6 +422,14 @@ static void virtio_iommu_class_init(ObjectClass *klass= , void *data) vdc->vmsd =3D &vmstate_virtio_iommu_device; } =20 +static void virtio_iommu_memory_region_class_init(ObjectClass *klass, + void *data) +{ + IOMMUMemoryRegionClass *imrc =3D IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate =3D virtio_iommu_translate; +} + static const TypeInfo virtio_iommu_info =3D { .name =3D TYPE_VIRTIO_IOMMU, .parent =3D TYPE_VIRTIO_DEVICE, @@ -352,9 +438,17 @@ static const TypeInfo virtio_iommu_info =3D { .class_init =3D virtio_iommu_class_init, }; =20 +static const TypeInfo virtio_iommu_memory_region_info =3D { + .parent =3D TYPE_IOMMU_MEMORY_REGION, + .name =3D TYPE_VIRTIO_IOMMU_MEMORY_REGION, + .class_init =3D virtio_iommu_memory_region_class_init, +}; + + static void virtio_register_types(void) { type_register_static(&virtio_iommu_info); + type_register_static(&virtio_iommu_memory_region_info); } =20 type_init(virtio_register_types) diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-io= mmu.h index 4d47b6abeb..f55f48d304 100644 --- a/include/hw/virtio/virtio-iommu.h +++ b/include/hw/virtio/virtio-iommu.h @@ -28,6 +28,8 @@ #define VIRTIO_IOMMU(obj) \ OBJECT_CHECK(VirtIOIOMMU, (obj), TYPE_VIRTIO_IOMMU) =20 +#define TYPE_VIRTIO_IOMMU_MEMORY_REGION "virtio-iommu-memory-region" + #define IOMMU_PCI_BUS_MAX 256 #define IOMMU_PCI_DEVFN_MAX 256 =20 --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763336004252.43952156635942; Fri, 9 Nov 2018 03:35:36 -0800 (PST) Received: from localhost ([::1]:33284 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL54Y-00038M-Qk for importer@patchew.org; Fri, 09 Nov 2018 06:35:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45785) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL503-0006jj-35 for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL501-0000wt-0V for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:55 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59318) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zq-0007vk-Px; Fri, 09 Nov 2018 06:30:43 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 98126308428B; Fri, 9 Nov 2018 11:30:34 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4DCD05C219; Fri, 9 Nov 2018 11:30:32 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:45 +0100 Message-Id: <20181109112957.10067-7-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Fri, 09 Nov 2018 11:30:34 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 06/18] virtio-iommu: Endpoint and domains structs and helpers 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch introduce domain and endpoint internal datatypes. Both are stored in RB trees. The domain owns a list of endpoints attached to it. Helpers to get/put end points and domains are introduced. get() helpers will become static in subsequent patches. Signed-off-by: Eric Auger --- v6 -> v7: - on virtio_iommu_find_add_as the bus number computation may not be finalized yet so we cannot register the EPs at that time. Hence, let's remove the get_endpoint and also do not use the bus number for building the memory region name string (only used for debug though). v4 -> v5: - initialize as->endpoint_list v3 -> v4: - new separate patch --- hw/virtio/trace-events | 4 ++ hw/virtio/virtio-iommu.c | 125 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 9270b0463e..4b15086872 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -61,3 +61,7 @@ virtio_iommu_map(uint32_t domain_id, uint64_t virt_start,= uint64_t virt_end, uin virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_= end) "domain=3D%d virt_start=3D0x%"PRIx64" virt_end=3D0x%"PRIx64 virtio_iommu_translate(const char *name, uint32_t rid, uint64_t iova, int = flag) "mr=3D%s rid=3D%d addr=3D0x%"PRIx64" flag=3D%d" virtio_iommu_init_iommu_mr(char *iommu_mr) "init %s" +virtio_iommu_get_endpoint(uint32_t ep_id) "Alloc endpoint=3D%d" +virtio_iommu_put_endpoint(uint32_t ep_id) "Free endpoint=3D%d" +virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=3D%d" +virtio_iommu_put_domain(uint32_t domain_id) "Free domain=3D%d" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 2043623b30..e4014a8800 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -33,20 +33,124 @@ #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-access.h" #include "hw/virtio/virtio-iommu.h" +#include "hw/pci/pci_bus.h" +#include "hw/pci/pci.h" =20 /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 =20 +typedef struct viommu_domain { + uint32_t id; + GTree *mappings; + QLIST_HEAD(, viommu_endpoint) endpoint_list; +} viommu_domain; + +typedef struct viommu_endpoint { + uint32_t id; + viommu_domain *domain; + QLIST_ENTRY(viommu_endpoint) next; + VirtIOIOMMU *viommu; +} viommu_endpoint; + +typedef struct viommu_interval { + uint64_t low; + uint64_t high; +} viommu_interval; + static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) { return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); } =20 +static gint interval_cmp(gconstpointer a, gconstpointer b, gpointer user_d= ata) +{ + viommu_interval *inta =3D (viommu_interval *)a; + viommu_interval *intb =3D (viommu_interval *)b; + + if (inta->high <=3D intb->low) { + return -1; + } else if (intb->high <=3D inta->low) { + return 1; + } else { + return 0; + } +} + +static void virtio_iommu_detach_endpoint_from_domain(viommu_endpoint *ep) +{ + QLIST_REMOVE(ep, next); + ep->domain =3D NULL; +} + +viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id); +viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id) +{ + viommu_endpoint *ep; + + ep =3D g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id)); + if (ep) { + return ep; + } + ep =3D g_malloc0(sizeof(*ep)); + ep->id =3D ep_id; + ep->viommu =3D s; + trace_virtio_iommu_get_endpoint(ep_id); + g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep); + return ep; +} + +static void virtio_iommu_put_endpoint(gpointer data) +{ + viommu_endpoint *ep =3D (viommu_endpoint *)data; + + if (ep->domain) { + virtio_iommu_detach_endpoint_from_domain(ep); + g_tree_unref(ep->domain->mappings); + } + + trace_virtio_iommu_put_endpoint(ep->id); + g_free(ep); +} + +viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id); +viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id) +{ + viommu_domain *domain; + + domain =3D g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id)); + if (domain) { + return domain; + } + domain =3D g_malloc0(sizeof(*domain)); + domain->id =3D domain_id; + domain->mappings =3D g_tree_new_full((GCompareDataFunc)interval_cmp, + NULL, (GDestroyNotify)g_free, + (GDestroyNotify)g_free); + g_tree_insert(s->domains, GUINT_TO_POINTER(domain_id), domain); + QLIST_INIT(&domain->endpoint_list); + trace_virtio_iommu_get_domain(domain_id); + return domain; +} + +static void virtio_iommu_put_domain(gpointer data) +{ + viommu_domain *domain =3D (viommu_domain *)data; + viommu_endpoint *iter, *tmp; + + QLIST_FOREACH_SAFE(iter, &domain->endpoint_list, next, tmp) { + virtio_iommu_detach_endpoint_from_domain(iter); + } + g_tree_destroy(domain->mappings); + trace_virtio_iommu_put_domain(domain->id); + g_free(domain); +} + static AddressSpace *virtio_iommu_find_add_as(PCIBus *bus, void *opaque, int devfn) { VirtIOIOMMU *s =3D opaque; IOMMUPciBus *sbus =3D g_hash_table_lookup(s->as_by_busptr, bus); + static uint32_t mr_index; IOMMUDevice *sdev; =20 if (!sbus) { @@ -60,7 +164,7 @@ static AddressSpace *virtio_iommu_find_add_as(PCIBus *bu= s, void *opaque, if (!sdev) { char *name =3D g_strdup_printf("%s-%d-%d", TYPE_VIRTIO_IOMMU_MEMORY_REGION, - pci_bus_num(bus), devfn); + mr_index++, devfn); sdev =3D sbus->pbdev[devfn] =3D g_malloc0(sizeof(IOMMUDevice)); =20 sdev->viommu =3D s; @@ -75,6 +179,7 @@ static AddressSpace *virtio_iommu_find_add_as(PCIBus *bu= s, void *opaque, UINT64_MAX); address_space_init(&sdev->as, MEMORY_REGION(&sdev->iommu_mr), TYPE_VIRTIO_IOM= MU); + g_free(name); } =20 return &sdev->as; @@ -332,6 +437,13 @@ static const VMStateDescription vmstate_virtio_iommu_d= evice =3D { }, }; =20 +static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data) +{ + uint ua =3D GPOINTER_TO_UINT(a); + uint ub =3D GPOINTER_TO_UINT(b); + return (ua > ub) - (ua < ub); +} + static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); @@ -356,6 +468,8 @@ static void virtio_iommu_device_realize(DeviceState *de= v, Error **errp) virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS); =20 + qemu_mutex_init(&s->mutex); + memset(s->as_by_bus_num, 0, sizeof(s->as_by_bus_num)); s->as_by_busptr =3D g_hash_table_new(NULL, NULL); =20 @@ -364,11 +478,20 @@ static void virtio_iommu_device_realize(DeviceState *= dev, Error **errp) } else { error_setg(errp, "VIRTIO-IOMMU is not attached to any PCI bus!"); } + + s->domains =3D g_tree_new_full((GCompareDataFunc)int_cmp, + NULL, NULL, virtio_iommu_put_domain); + s->endpoints =3D g_tree_new_full((GCompareDataFunc)int_cmp, + NULL, NULL, virtio_iommu_put_endpoint); } =20 static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp) { VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); + VirtIOIOMMU *s =3D VIRTIO_IOMMU(dev); + + g_tree_destroy(s->domains); + g_tree_destroy(s->endpoints); =20 virtio_cleanup(vdev); } --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763239339443.5453568534531; Fri, 9 Nov 2018 03:33:59 -0800 (PST) Received: from localhost ([::1]:33278 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL52w-0000Wm-C5 for importer@patchew.org; Fri, 09 Nov 2018 06:33:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45733) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL501-0006hE-0f for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL4zw-0000V8-0d for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38908) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zr-000876-1i; Fri, 09 Nov 2018 06:30:43 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2444289AE6; Fri, 9 Nov 2018 11:30:37 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC3B15C219; Fri, 9 Nov 2018 11:30:34 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:46 +0100 Message-Id: <20181109112957.10067-8-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 09 Nov 2018 11:30:37 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 07/18] virtio-iommu: Implement attach/detach command 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch implements the endpoint attach/detach to/from a domain. Signed-off-by: Eric Auger --- --- hw/virtio/virtio-iommu.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index e4014a8800..bd245ea979 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -82,8 +82,8 @@ static void virtio_iommu_detach_endpoint_from_domain(viom= mu_endpoint *ep) ep->domain =3D NULL; } =20 -viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id); -viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id) +static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, + uint32_t ep_id) { viommu_endpoint *ep; =20 @@ -112,8 +112,8 @@ static void virtio_iommu_put_endpoint(gpointer data) g_free(ep); } =20 -viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id); -viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id) +static viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, + uint32_t domain_id) { viommu_domain *domain; =20 @@ -191,10 +191,27 @@ static int virtio_iommu_attach(VirtIOIOMMU *s, { uint32_t domain_id =3D le32_to_cpu(req->domain); uint32_t ep_id =3D le32_to_cpu(req->endpoint); + viommu_domain *domain; + viommu_endpoint *ep; =20 trace_virtio_iommu_attach(domain_id, ep_id); =20 - return VIRTIO_IOMMU_S_UNSUPP; + ep =3D virtio_iommu_get_endpoint(s, ep_id); + if (ep->domain) { + /* + * the device is already attached to a domain, + * detach it first + */ + virtio_iommu_detach_endpoint_from_domain(ep); + } + + domain =3D virtio_iommu_get_domain(s, domain_id); + QLIST_INSERT_HEAD(&domain->endpoint_list, ep, next); + + ep->domain =3D domain; + g_tree_ref(domain->mappings); + + return VIRTIO_IOMMU_S_OK; } =20 static int virtio_iommu_detach(VirtIOIOMMU *s, @@ -202,10 +219,21 @@ static int virtio_iommu_detach(VirtIOIOMMU *s, { uint32_t domain_id =3D le32_to_cpu(req->domain); uint32_t ep_id =3D le32_to_cpu(req->endpoint); + viommu_endpoint *ep; =20 trace_virtio_iommu_detach(domain_id, ep_id); =20 - return VIRTIO_IOMMU_S_UNSUPP; + ep =3D g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id)); + if (!ep) { + return VIRTIO_IOMMU_S_NOENT; + } + + if (!ep->domain) { + return VIRTIO_IOMMU_S_INVAL; + } + + virtio_iommu_detach_endpoint_from_domain(ep); + return VIRTIO_IOMMU_S_OK; } =20 static int virtio_iommu_map(VirtIOIOMMU *s, --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763429917391.22475124127664; Fri, 9 Nov 2018 03:37:09 -0800 (PST) Received: from localhost ([::1]:33300 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL55z-0004L6-OI for importer@patchew.org; Fri, 09 Nov 2018 06:37:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45729) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL500-0006hD-VY for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL4zw-0000Xu-Nh for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:53538) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zq-0008UF-S7; Fri, 09 Nov 2018 06:30:43 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9AB03C034E18; Fri, 9 Nov 2018 11:30:41 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6BF585C21F; Fri, 9 Nov 2018 11:30:37 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:47 +0100 Message-Id: <20181109112957.10067-9-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Fri, 09 Nov 2018 11:30:41 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 08/18] virtio-iommu: Implement map/unmap 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch implements virtio_iommu_map/unmap. Signed-off-by: Eric Auger --- v5 -> v6: - use new v0.6 fields - replace error_report by qemu_log_mask v3 -> v4: - implement unmap semantics as specified in v0.4 --- hw/virtio/trace-events | 3 ++ hw/virtio/virtio-iommu.c | 94 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 4b15086872..b3c5c2604e 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -65,3 +65,6 @@ virtio_iommu_get_endpoint(uint32_t ep_id) "Alloc endpoint= =3D%d" virtio_iommu_put_endpoint(uint32_t ep_id) "Free endpoint=3D%d" virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=3D%d" virtio_iommu_put_domain(uint32_t domain_id) "Free domain=3D%d" +virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t nex= t_low, uint64_t next_high) "Unmap left [0x%"PRIx64",0x%"PRIx64"], new inter= val=3D[0x%"PRIx64",0x%"PRIx64"]" +virtio_iommu_unmap_right_interval(uint64_t low, uint64_t high, uint64_t ne= xt_low, uint64_t next_high) "Unmap right [0x%"PRIx64",0x%"PRIx64"], new int= erval=3D[0x%"PRIx64",0x%"PRIx64"]" +virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc [0= x%"PRIx64",0x%"PRIx64"]" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index bd245ea979..1a1ed4d3d3 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -18,6 +18,7 @@ */ =20 #include "qemu/osdep.h" +#include "qemu/log.h" #include "qemu/iov.h" #include "qemu-common.h" #include "hw/virtio/virtio.h" @@ -57,6 +58,13 @@ typedef struct viommu_interval { uint64_t high; } viommu_interval; =20 +typedef struct viommu_mapping { + uint64_t virt_addr; + uint64_t phys_addr; + uint64_t size; + uint32_t flags; +} viommu_mapping; + static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) { return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); @@ -244,10 +252,37 @@ static int virtio_iommu_map(VirtIOIOMMU *s, uint64_t virt_start =3D le64_to_cpu(req->virt_start); uint64_t virt_end =3D le64_to_cpu(req->virt_end); uint32_t flags =3D le32_to_cpu(req->flags); + viommu_domain *domain; + viommu_interval *interval; + viommu_mapping *mapping; + + interval =3D g_malloc0(sizeof(*interval)); + + interval->low =3D virt_start; + interval->high =3D virt_end; + + domain =3D g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id)); + if (!domain) { + return VIRTIO_IOMMU_S_NOENT; + } + + mapping =3D g_tree_lookup(domain->mappings, (gpointer)interval); + if (mapping) { + g_free(interval); + return VIRTIO_IOMMU_S_INVAL; + } =20 trace_virtio_iommu_map(domain_id, virt_start, virt_end, phys_start, fl= ags); =20 - return VIRTIO_IOMMU_S_UNSUPP; + mapping =3D g_malloc0(sizeof(*mapping)); + mapping->virt_addr =3D virt_start; + mapping->phys_addr =3D phys_start; + mapping->size =3D virt_end - virt_start + 1; + mapping->flags =3D flags; + + g_tree_insert(domain->mappings, interval, mapping); + + return VIRTIO_IOMMU_S_OK; } =20 static int virtio_iommu_unmap(VirtIOIOMMU *s, @@ -256,10 +291,65 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s, uint32_t domain_id =3D le32_to_cpu(req->domain); uint64_t virt_start =3D le64_to_cpu(req->virt_start); uint64_t virt_end =3D le64_to_cpu(req->virt_end); + uint64_t size =3D virt_end - virt_start + 1; + viommu_mapping *mapping; + viommu_interval interval; + viommu_domain *domain; =20 trace_virtio_iommu_unmap(domain_id, virt_start, virt_end); =20 - return VIRTIO_IOMMU_S_UNSUPP; + domain =3D g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id)); + if (!domain) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: no domain\n", __func__); + return VIRTIO_IOMMU_S_NOENT; + } + interval.low =3D virt_start; + interval.high =3D virt_end; + + mapping =3D g_tree_lookup(domain->mappings, (gpointer)(&interval)); + + while (mapping) { + viommu_interval current; + uint64_t low =3D mapping->virt_addr; + uint64_t high =3D mapping->virt_addr + mapping->size - 1; + + current.low =3D low; + current.high =3D high; + + if (low =3D=3D interval.low && size >=3D mapping->size) { + g_tree_remove(domain->mappings, (gpointer)(¤t)); + interval.low =3D high + 1; + trace_virtio_iommu_unmap_left_interval(current.low, current.hi= gh, + interval.low, interval.high); + } else if (high =3D=3D interval.high && size >=3D mapping->size) { + trace_virtio_iommu_unmap_right_interval(current.low, current.h= igh, + interval.low, interval.high); + g_tree_remove(domain->mappings, (gpointer)(¤t)); + interval.high =3D low - 1; + } else if (low > interval.low && high < interval.high) { + trace_virtio_iommu_unmap_inc_interval(current.low, current.hig= h); + g_tree_remove(domain->mappings, (gpointer)(¤t)); + } else { + break; + } + if (interval.low >=3D interval.high) { + return VIRTIO_IOMMU_S_OK; + } else { + mapping =3D g_tree_lookup(domain->mappings, (gpointer)(&interv= al)); + } + } + + if (mapping) { + qemu_log_mask(LOG_GUEST_ERROR, + "****** %s: Unmap 0x%"PRIx64" size=3D0x%"PRIx64 + " from 0x%"PRIx64" size=3D0x%"PRIx64" is not supporte= d\n", + __func__, interval.low, size, + mapping->virt_addr, mapping->size); + } else { + return VIRTIO_IOMMU_S_OK; + } + + return VIRTIO_IOMMU_S_INVAL; } =20 #define get_payload_size(req) (\ --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763878280973.5369888569899; Fri, 9 Nov 2018 03:44:38 -0800 (PST) Received: from localhost ([::1]:33346 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5DJ-00061p-2T for importer@patchew.org; Fri, 09 Nov 2018 06:44:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45809) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL503-0006kc-Vi for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL502-00014W-NQ for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:30:55 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55126) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL4zz-0000jV-5k; Fri, 09 Nov 2018 06:30:51 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 64AD4C0669B0; Fri, 9 Nov 2018 11:30:50 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 267AF5C219; Fri, 9 Nov 2018 11:30:41 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:48 +0100 Message-Id: <20181109112957.10067-10-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 09 Nov 2018 11:30:50 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 09/18] virtio-iommu: Implement translate 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch implements the translate callback Signed-off-by: Eric Auger --- v6 -> v7: - implemented bypass-mode v5 -> v6: - replace error_report by qemu_log_mask v4 -> v5: - check the device domain is not NULL - s/printf/error_report - set flags to IOMMU_NONE in case of all translation faults --- hw/virtio/trace-events | 1 + hw/virtio/virtio-iommu.c | 57 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index b3c5c2604e..1f0e143b55 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -68,3 +68,4 @@ virtio_iommu_put_domain(uint32_t domain_id) "Free domain= =3D%d" virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t nex= t_low, uint64_t next_high) "Unmap left [0x%"PRIx64",0x%"PRIx64"], new inter= val=3D[0x%"PRIx64",0x%"PRIx64"]" virtio_iommu_unmap_right_interval(uint64_t low, uint64_t high, uint64_t ne= xt_low, uint64_t next_high) "Unmap right [0x%"PRIx64",0x%"PRIx64"], new int= erval=3D[0x%"PRIx64",0x%"PRIx64"]" virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc [0= x%"PRIx64",0x%"PRIx64"]" +virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_= t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=3D%d" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 1a1ed4d3d3..281d6d69c9 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -480,19 +480,74 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemo= ryRegion *mr, hwaddr addr, int iommu_idx) { IOMMUDevice *sdev =3D container_of(mr, IOMMUDevice, iommu_mr); + VirtIOIOMMU *s =3D sdev->viommu; uint32_t sid; + viommu_endpoint *ep; + viommu_mapping *mapping; + viommu_interval interval; + bool bypass_allowed; + + interval.low =3D addr; + interval.high =3D addr + 1; =20 IOMMUTLBEntry entry =3D { .target_as =3D &address_space_memory, .iova =3D addr, .translated_addr =3D addr, - .addr_mask =3D ~(hwaddr)0, + .addr_mask =3D (1 << ctz32(s->config.page_size_mask)) - 1, .perm =3D IOMMU_NONE, }; =20 + bypass_allowed =3D virtio_has_feature(s->acked_features, + VIRTIO_IOMMU_F_BYPASS); + sid =3D virtio_iommu_get_sid(sdev); =20 trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag); + qemu_mutex_lock(&s->mutex); + + ep =3D g_tree_lookup(s->endpoints, GUINT_TO_POINTER(sid)); + if (!ep) { + if (!bypass_allowed) { + error_report("%s sid=3D%d is not known!!", __func__, sid); + } else { + entry.perm =3D flag; + } + goto unlock; + } + + if (!ep->domain) { + if (!bypass_allowed) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s %02x:%02x.%01x not attached to any domain\n", + __func__, PCI_BUS_NUM(sid), PCI_SLOT(sid), PCI_F= UNC(sid)); + } else { + entry.perm =3D flag; + } + goto unlock; + } + + mapping =3D g_tree_lookup(ep->domain->mappings, (gpointer)(&interval)); + if (!mapping) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s no mapping for 0x%"PRIx64" for sid=3D%d\n", + __func__, addr, sid); + goto unlock; + } + + if (((flag & IOMMU_RO) && !(mapping->flags & VIRTIO_IOMMU_MAP_F_READ))= || + ((flag & IOMMU_WO) && !(mapping->flags & VIRTIO_IOMMU_MAP_F_WRITE)= )) { + qemu_log_mask(LOG_GUEST_ERROR, + "Permission error on 0x%"PRIx64"(%d): allowed=3D%d\n= ", + addr, flag, mapping->flags); + goto unlock; + } + entry.translated_addr =3D addr - mapping->virt_addr + mapping->phys_ad= dr; + entry.perm =3D flag; + trace_virtio_iommu_translate_out(addr, entry.translated_addr, sid); + +unlock: + qemu_mutex_unlock(&s->mutex); return entry; } =20 --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763693574598.3793759508635; Fri, 9 Nov 2018 03:41:33 -0800 (PST) Received: from localhost ([::1]:33329 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5AK-0001OX-5x for importer@patchew.org; Fri, 09 Nov 2018 06:41:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45992) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50C-0006uG-RZ for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL506-0001G8-2n for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:04 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38974) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL501-0000xs-R2; Fri, 09 Nov 2018 06:30:54 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E858B87621; Fri, 9 Nov 2018 11:30:52 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id A86BE5C219; Fri, 9 Nov 2018 11:30:50 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:49 +0100 Message-Id: <20181109112957.10067-11-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 09 Nov 2018 11:30:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 10/18] virtio-iommu: Implement probe request 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch implements the PROBE request. At the moment, no reserved regions are returned as none are registered per device. Only a NONE property is returned. Signed-off-by: Eric Auger --- v7 -> v8: - adapt to removal of value filed in virtio_iommu_probe_property v6 -> v7: - adapt to the change in virtio_iommu_probe_resv_mem fields - use get_endpoint() instead of directly checking the EP was registered. v4 -> v5: - initialize bufstate.error to false - add cpu_to_le64(size) --- hw/virtio/trace-events | 2 + hw/virtio/virtio-iommu.c | 189 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 189 insertions(+), 2 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 1f0e143b55..19824c3e91 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -69,3 +69,5 @@ virtio_iommu_unmap_left_interval(uint64_t low, uint64_t h= igh, uint64_t next_low, virtio_iommu_unmap_right_interval(uint64_t low, uint64_t high, uint64_t ne= xt_low, uint64_t next_high) "Unmap right [0x%"PRIx64",0x%"PRIx64"], new int= erval=3D[0x%"PRIx64",0x%"PRIx64"]" virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc [0= x%"PRIx64",0x%"PRIx64"]" virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_= t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=3D%d" +virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t = start, uint64_t end, uint32_t flags, size_t filled) "dev=3D %d, subtype=3D%= d start=3D0x%"PRIx64" end=3D0x%"PRIx64" flags=3D%d filled=3D0x%lx" +virtio_iommu_fill_none_property(uint32_t devid) "devid=3D%d" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 281d6d69c9..6164b5a7d1 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -39,6 +39,11 @@ =20 /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 +#define VIOMMU_PROBE_SIZE 512 + +#define SUPPORTED_PROBE_PROPERTIES (\ + VIRTIO_IOMMU_PROBE_T_NONE | \ + VIRTIO_IOMMU_PROBE_T_RESV_MEM) =20 typedef struct viommu_domain { uint32_t id; @@ -51,6 +56,7 @@ typedef struct viommu_endpoint { viommu_domain *domain; QLIST_ENTRY(viommu_endpoint) next; VirtIOIOMMU *viommu; + GTree *reserved_regions; } viommu_endpoint; =20 typedef struct viommu_interval { @@ -65,6 +71,13 @@ typedef struct viommu_mapping { uint32_t flags; } viommu_mapping; =20 +typedef struct viommu_property_buffer { + viommu_endpoint *endpoint; + size_t filled; + uint8_t *start; + bool error; +} viommu_property_buffer; + static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) { return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); @@ -104,6 +117,9 @@ static viommu_endpoint *virtio_iommu_get_endpoint(VirtI= OIOMMU *s, ep->viommu =3D s; trace_virtio_iommu_get_endpoint(ep_id); g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep); + ep->reserved_regions =3D g_tree_new_full((GCompareDataFunc)interval_cm= p, + NULL, (GDestroyNotify)g_free, + (GDestroyNotify)g_free); return ep; } =20 @@ -117,6 +133,7 @@ static void virtio_iommu_put_endpoint(gpointer data) } =20 trace_virtio_iommu_put_endpoint(ep->id); + g_tree_destroy(ep->reserved_regions); g_free(ep); } =20 @@ -352,6 +369,138 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s, return VIRTIO_IOMMU_S_INVAL; } =20 +/** + * virtio_iommu_fill_resv_mem_prop - Add a RESV_MEM probe + * property into the probe request buffer + * + * @key: interval handle + * @value: handle to the reserved memory region + * @data: handle to the probe request buffer state + */ +static gboolean virtio_iommu_fill_resv_mem_prop(gpointer key, + gpointer value, + gpointer data) +{ + struct virtio_iommu_probe_resv_mem *resv =3D + (struct virtio_iommu_probe_resv_mem *)value; + struct virtio_iommu_probe_property *prop; + struct virtio_iommu_probe_resv_mem *current; + viommu_property_buffer *bufstate =3D (viommu_property_buffer *)data; + size_t size =3D sizeof(*resv), total_size; + uint8_t *prop_value; + + total_size =3D size + sizeof(*prop); + + if (bufstate->filled + total_size >=3D VIOMMU_PROBE_SIZE) { + bufstate->error =3D true; + /* get the traversal stopped by returning true */ + return true; + } + prop =3D (struct virtio_iommu_probe_property *) + (bufstate->start + bufstate->filled); + prop->type =3D cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM) & + VIRTIO_IOMMU_PROBE_T_MASK; + prop->length =3D cpu_to_le16(size); + + prop_value =3D (uint8_t *)prop + 4; + current =3D (struct virtio_iommu_probe_resv_mem *)prop_value; + *current =3D *resv; + bufstate->filled +=3D total_size; + trace_virtio_iommu_fill_resv_property(bufstate->endpoint->id, + resv->subtype, resv->start, + resv->end, resv->subtype, + bufstate->filled); + return false; +} + +static int virtio_iommu_fill_none_prop(viommu_property_buffer *bufstate) +{ + struct virtio_iommu_probe_property *prop; + + prop =3D (struct virtio_iommu_probe_property *) + (bufstate->start + bufstate->filled); + prop->type =3D cpu_to_le16(VIRTIO_IOMMU_PROBE_T_NONE) + & VIRTIO_IOMMU_PROBE_T_MASK; + prop->length =3D 0; + bufstate->filled +=3D sizeof(*prop); + trace_virtio_iommu_fill_none_property(bufstate->endpoint->id); + return 0; +} + +static int virtio_iommu_fill_property(int type, + viommu_property_buffer *bufstate) +{ + int ret =3D -ENOSPC; + + if (bufstate->filled + 4 >=3D VIOMMU_PROBE_SIZE) { + /* Even the property header cannot be filled */ + bufstate->error =3D true; + goto out; + } + + switch (type) { + case VIRTIO_IOMMU_PROBE_T_NONE: + ret =3D virtio_iommu_fill_none_prop(bufstate); + break; + case VIRTIO_IOMMU_PROBE_T_RESV_MEM: + { + viommu_endpoint *ep =3D bufstate->endpoint; + + g_tree_foreach(ep->reserved_regions, + virtio_iommu_fill_resv_mem_prop, + bufstate); + if (!bufstate->error) { + ret =3D 0; + } + break; + } + default: + ret =3D -ENOENT; + break; + } +out: + if (ret) { + error_report("%s property of type=3D%d could not be filled (%d)," + " remaining size =3D 0x%lx", + __func__, type, ret, bufstate->filled); + } + return ret; +} + +/** + * virtio_iommu_probe - Fill the probe request buffer with all + * the properties the device is able to return and add a NONE + * property at the end. + */ +static int virtio_iommu_probe(VirtIOIOMMU *s, + struct virtio_iommu_req_probe *req, + uint8_t *buf) +{ + uint32_t ep_id =3D le32_to_cpu(req->endpoint); + int16_t prop_types =3D SUPPORTED_PROBE_PROPERTIES, type; + viommu_property_buffer bufstate; + viommu_endpoint *ep; + int ret; + + ep =3D virtio_iommu_get_endpoint(s, ep_id); + + bufstate.start =3D buf; + bufstate.filled =3D 0; + bufstate.error =3D false; + bufstate.endpoint =3D ep; + + while ((type =3D ctz32(prop_types)) !=3D 32) { + ret =3D virtio_iommu_fill_property(1 << type, &bufstate); + if (ret) { + break; + } + prop_types &=3D ~(1 << type); + } + virtio_iommu_fill_property(VIRTIO_IOMMU_PROBE_T_NONE, &bufstate); + + return VIRTIO_IOMMU_S_OK; +} + #define get_payload_size(req) (\ sizeof((req)) - sizeof(struct virtio_iommu_req_tail)) =20 @@ -416,6 +565,24 @@ static int virtio_iommu_handle_unmap(VirtIOIOMMU *s, return virtio_iommu_unmap(s, &req); } =20 +static int virtio_iommu_handle_probe(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt, + uint8_t *buf) +{ + struct virtio_iommu_req_probe req; + size_t sz, payload_sz; + + payload_sz =3D sizeof(req); + + sz =3D iov_to_buf(iov, iov_cnt, 0, &req, payload_sz); + if (sz !=3D payload_sz) { + return VIRTIO_IOMMU_S_INVAL; + } + + return virtio_iommu_probe(s, &req, buf); +} + static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) { VirtIOIOMMU *s =3D VIRTIO_IOMMU(vdev); @@ -460,16 +627,32 @@ static void virtio_iommu_handle_command(VirtIODevice = *vdev, VirtQueue *vq) case VIRTIO_IOMMU_T_UNMAP: tail.status =3D virtio_iommu_handle_unmap(s, iov, iov_cnt); break; + case VIRTIO_IOMMU_T_PROBE: + { + struct virtio_iommu_req_tail *ptail; + uint8_t *buf =3D g_malloc0(s->config.probe_size + sizeof(tail)= ); + + ptail =3D (struct virtio_iommu_req_tail *) + (buf + s->config.probe_size); + ptail->status =3D virtio_iommu_handle_probe(s, iov, iov_cnt, b= uf); + + sz =3D iov_from_buf(elem->in_sg, elem->in_num, 0, + buf, s->config.probe_size + sizeof(tail)); + g_free(buf); + assert(sz =3D=3D s->config.probe_size + sizeof(tail)); + goto push; + } default: tail.status =3D VIRTIO_IOMMU_S_UNSUPP; } - qemu_mutex_unlock(&s->mutex); =20 sz =3D iov_from_buf(elem->in_sg, elem->in_num, 0, &tail, sizeof(tail)); assert(sz =3D=3D sizeof(tail)); =20 - virtqueue_push(vq, elem, sizeof(tail)); +push: + qemu_mutex_unlock(&s->mutex); + virtqueue_push(vq, elem, sz); virtio_notify(vdev, vq); g_free(elem); } @@ -632,6 +815,7 @@ static void virtio_iommu_device_realize(DeviceState *de= v, Error **errp) s->config.page_size_mask =3D TARGET_PAGE_MASK; s->config.input_range.end =3D -1UL; s->config.domain_bits =3D 32; + s->config.probe_size =3D VIOMMU_PROBE_SIZE; =20 virtio_add_feature(&s->features, VIRTIO_RING_F_EVENT_IDX); virtio_add_feature(&s->features, VIRTIO_RING_F_INDIRECT_DESC); @@ -640,6 +824,7 @@ static void virtio_iommu_device_realize(DeviceState *de= v, Error **errp) virtio_add_feature(&s->features, VIRTIO_IOMMU_F_DOMAIN_BITS); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_PROBE); =20 qemu_mutex_init(&s->mutex); =20 --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 154176352090389.90118358290044; Fri, 9 Nov 2018 03:38:40 -0800 (PST) Received: from localhost ([::1]:33309 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL57X-0006aT-HZ for importer@patchew.org; Fri, 09 Nov 2018 06:38:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45990) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50C-0006uE-RS for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL506-0001Ji-WF for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:04 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51608) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL504-00018v-DW; Fri, 09 Nov 2018 06:30:56 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 80049308339D; Fri, 9 Nov 2018 11:30:55 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 396BD5C219; Fri, 9 Nov 2018 11:30:53 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:50 +0100 Message-Id: <20181109112957.10067-12-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Fri, 09 Nov 2018 11:30:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 11/18] virtio-iommu: Add an msi_bypass property 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" In case the msi_bypass property is set, it means we need to register the IOAPIC MSI window as a reserved region: 0xFEE00000 - 0xFEEFFFFF. Signed-off-by: Eric Auger --- --- hw/virtio/virtio-iommu.c | 52 ++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-iommu.h | 1 + 2 files changed, 53 insertions(+) diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 6164b5a7d1..e6ad8a0c61 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -41,6 +41,9 @@ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 #define VIOMMU_PROBE_SIZE 512 =20 +#define IOAPIC_RANGE_START (0xfee00000) +#define IOAPIC_RANGE_SIZE (0x100000) + #define SUPPORTED_PROBE_PROPERTIES (\ VIRTIO_IOMMU_PROBE_T_NONE | \ VIRTIO_IOMMU_PROBE_T_RESV_MEM) @@ -103,6 +106,25 @@ static void virtio_iommu_detach_endpoint_from_domain(v= iommu_endpoint *ep) ep->domain =3D NULL; } =20 +static void virtio_iommu_register_resv_region(viommu_endpoint *ep, + uint8_t subtype, + uint64_t start, uint64_t end) +{ + viommu_interval *interval; + struct virtio_iommu_probe_resv_mem *reg; + + interval =3D g_malloc0(sizeof(*interval)); + interval->low =3D start; + interval->high =3D end; + + reg =3D g_malloc0(sizeof(*reg)); + reg->subtype =3D subtype; + reg->start =3D cpu_to_le64(start); + reg->end =3D cpu_to_le64(end); + + g_tree_insert(ep->reserved_regions, interval, reg); +} + static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id) { @@ -120,6 +142,12 @@ static viommu_endpoint *virtio_iommu_get_endpoint(Virt= IOIOMMU *s, ep->reserved_regions =3D g_tree_new_full((GCompareDataFunc)interval_cm= p, NULL, (GDestroyNotify)g_free, (GDestroyNotify)g_free); + if (s->msi_bypass) { + virtio_iommu_register_resv_region(ep, VIRTIO_IOMMU_RESV_MEM_T_MSI, + IOAPIC_RANGE_START, + IOAPIC_RANGE_SIZE); + } + return ep; } =20 @@ -864,8 +892,32 @@ static void virtio_iommu_set_status(VirtIODevice *vdev= , uint8_t status) trace_virtio_iommu_device_status(status); } =20 +static bool virtio_iommu_get_msi_bypass(Object *obj, Error **errp) +{ + VirtIOIOMMU *s =3D VIRTIO_IOMMU(obj); + + return s->msi_bypass; +} + +static void virtio_iommu_set_msi_bypass(Object *obj, bool value, Error **e= rrp) +{ + VirtIOIOMMU *s =3D VIRTIO_IOMMU(obj); + + s->msi_bypass =3D value; +} + static void virtio_iommu_instance_init(Object *obj) { + VirtIOIOMMU *s =3D VIRTIO_IOMMU(obj); + + object_property_add_bool(obj, "msi_bypass", virtio_iommu_get_msi_bypas= s, + virtio_iommu_set_msi_bypass, NULL); + object_property_set_description(obj, "msi_bypass", + "Indicates whether msis are bypassed b= y " + "the IOMMU. Default is YES", + NULL); + + s->msi_bypass =3D true; } =20 static const VMStateDescription vmstate_virtio_iommu =3D { diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-io= mmu.h index f55f48d304..56c8b4e57f 100644 --- a/include/hw/virtio/virtio-iommu.h +++ b/include/hw/virtio/virtio-iommu.h @@ -59,6 +59,7 @@ typedef struct VirtIOIOMMU { GTree *domains; QemuMutex mutex; GTree *endpoints; + bool msi_bypass; } VirtIOIOMMU; =20 #endif --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763833319141.02561962832192; Fri, 9 Nov 2018 03:43:53 -0800 (PST) Received: from localhost ([::1]:33344 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5Ca-0005Qk-5x for importer@patchew.org; Fri, 09 Nov 2018 06:43:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46066) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50I-0006y6-9F for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL50G-0001x0-9T for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58664) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL506-0001Gf-Si; Fri, 09 Nov 2018 06:30:59 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0BAE27AE95; Fri, 9 Nov 2018 11:30:58 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id C431D5C219; Fri, 9 Nov 2018 11:30:55 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:51 +0100 Message-Id: <20181109112957.10067-13-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 09 Nov 2018 11:30:58 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 12/18] virtio-iommu: Implement fault reporting 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The event queue allows to report asynchronous errors. The translate function now injects faults when relevant. Signed-off-by: Eric Auger --- hw/virtio/trace-events | 1 + hw/virtio/virtio-iommu.c | 67 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 19824c3e91..053a07b3fc 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -71,3 +71,4 @@ virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t hi= gh) "Unmap inc [0x%"PRI virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_= t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=3D%d" virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t = start, uint64_t end, uint32_t flags, size_t filled) "dev=3D %d, subtype=3D%= d start=3D0x%"PRIx64" end=3D0x%"PRIx64" flags=3D%d filled=3D0x%lx" virtio_iommu_fill_none_property(uint32_t devid) "devid=3D%d" +virtio_iommu_report_fault(uint8_t reason, uint32_t flags, uint32_t endpoin= t, uint64_t addr) "FAULT reason=3D%d flags=3D%d endpoint=3D%d address =3D0x= %"PRIx64 diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index e6ad8a0c61..e5ab3db834 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -686,17 +686,63 @@ push: } } =20 +static void virtio_iommu_report_fault(VirtIOIOMMU *viommu, uint8_t reason, + uint32_t flags, uint32_t endpoint, + uint64_t address) +{ + VirtIODevice *vdev =3D &viommu->parent_obj; + VirtQueue *vq =3D viommu->event_vq; + struct virtio_iommu_fault fault; + VirtQueueElement *elem; + size_t sz; + + memset(&fault, 0, sizeof(fault)); + fault.reason =3D reason; + fault.flags =3D flags; + fault.endpoint =3D endpoint; + fault.address =3D address; + + for (;;) { + elem =3D virtqueue_pop(vq, sizeof(VirtQueueElement)); + + if (!elem) { + virtio_error(vdev, + "no buffer available in event queue to report eve= nt"); + return; + } + + if (iov_size(elem->in_sg, elem->in_num) < sizeof(fault)) { + virtio_error(vdev, "error buffer of wrong size"); + virtqueue_detach_element(vq, elem, 0); + g_free(elem); + continue; + } + break; + } + /* we have a buffer to fill in */ + sz =3D iov_from_buf(elem->in_sg, elem->in_num, 0, + &fault, sizeof(fault)); + assert(sz =3D=3D sizeof(fault)); + + trace_virtio_iommu_report_fault(reason, flags, endpoint, address); + virtqueue_push(vq, elem, sz); + virtio_notify(vdev, vq); + g_free(elem); + +} + static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr = addr, IOMMUAccessFlags flag, int iommu_idx) { IOMMUDevice *sdev =3D container_of(mr, IOMMUDevice, iommu_mr); VirtIOIOMMU *s =3D sdev->viommu; - uint32_t sid; + uint32_t sid, flags; viommu_endpoint *ep; viommu_mapping *mapping; viommu_interval interval; bool bypass_allowed; + bool read_fault, write_fault; =20 interval.low =3D addr; interval.high =3D addr + 1; @@ -721,6 +767,8 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemory= Region *mr, hwaddr addr, if (!ep) { if (!bypass_allowed) { error_report("%s sid=3D%d is not known!!", __func__, sid); + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_UNKNOWN, + 0, sid, 0); } else { entry.perm =3D flag; } @@ -732,6 +780,8 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemory= Region *mr, hwaddr addr, qemu_log_mask(LOG_GUEST_ERROR, "%s %02x:%02x.%01x not attached to any domain\n", __func__, PCI_BUS_NUM(sid), PCI_SLOT(sid), PCI_F= UNC(sid)); + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_DOMAIN, + 0, sid, 0); } else { entry.perm =3D flag; } @@ -743,14 +793,25 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemo= ryRegion *mr, hwaddr addr, qemu_log_mask(LOG_GUEST_ERROR, "%s no mapping for 0x%"PRIx64" for sid=3D%d\n", __func__, addr, sid); + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING, + 0, sid, addr); goto unlock; } =20 - if (((flag & IOMMU_RO) && !(mapping->flags & VIRTIO_IOMMU_MAP_F_READ))= || - ((flag & IOMMU_WO) && !(mapping->flags & VIRTIO_IOMMU_MAP_F_WRITE)= )) { + read_fault =3D (flag & IOMMU_RO) && + !(mapping->flags & VIRTIO_IOMMU_MAP_F_READ); + write_fault =3D (flag & IOMMU_WO) && + !(mapping->flags & VIRTIO_IOMMU_MAP_F_WRITE); + + flags =3D read_fault ? VIRTIO_IOMMU_FAULT_F_READ : 0; + flags |=3D write_fault ? VIRTIO_IOMMU_FAULT_F_WRITE : 0; + if (flags) { qemu_log_mask(LOG_GUEST_ERROR, "Permission error on 0x%"PRIx64"(%d): allowed=3D%d\n= ", addr, flag, mapping->flags); + flags |=3D VIRTIO_IOMMU_FAULT_F_ADDRESS; + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING, + flags, sid, addr); goto unlock; } entry.translated_addr =3D addr - mapping->virt_addr + mapping->phys_ad= dr; --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763813022483.8608961274899; Fri, 9 Nov 2018 03:43:33 -0800 (PST) Received: from localhost ([::1]:33338 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5CC-0004Up-55 for importer@patchew.org; Fri, 09 Nov 2018 06:43:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46065) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50I-0006y5-9K for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL50G-0001xt-CR for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41750) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL509-0001Th-GV; Fri, 09 Nov 2018 06:31:01 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A3128300238D; Fri, 9 Nov 2018 11:31:00 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 553F85C22F; Fri, 9 Nov 2018 11:30:58 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:52 +0100 Message-Id: <20181109112957.10067-14-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 09 Nov 2018 11:31:00 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 13/18] virtio_iommu: Handle reserved regions in translation process 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When translating an address we need to check if it belongs to a reserved virtual address range. If it does, there are 2 cases: - it belongs to a RESERVED region: the guest should neither use this address in a MAP not instruct the end-point to DMA on them. We report an error - It belongs to an MSI region: we bypass the translation. Signed-off-by: Eric Auger --- hw/virtio/virtio-iommu.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index e5ab3db834..c88aecf18f 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -743,6 +743,7 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemory= Region *mr, hwaddr addr, viommu_interval interval; bool bypass_allowed; bool read_fault, write_fault; + struct virtio_iommu_probe_resv_mem *reg; =20 interval.low =3D addr; interval.high =3D addr + 1; @@ -775,6 +776,21 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemor= yRegion *mr, hwaddr addr, goto unlock; } =20 + reg =3D g_tree_lookup(ep->reserved_regions, (gpointer)(&interval)); + if (reg) { + switch (reg->subtype) { + case VIRTIO_IOMMU_RESV_MEM_T_MSI: + entry.perm =3D flag; + break; + case VIRTIO_IOMMU_RESV_MEM_T_RESERVED: + default: + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING, + 0, sid, addr); + break; + } + goto unlock; + } + if (!ep->domain) { if (!bypass_allowed) { qemu_log_mask(LOG_GUEST_ERROR, --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763949065513.4402508385921; Fri, 9 Nov 2018 03:45:49 -0800 (PST) Received: from localhost ([::1]:33358 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5EO-0006wG-JL for importer@patchew.org; Fri, 09 Nov 2018 06:45:44 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46226) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50R-00073P-Px for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL50Q-0002m4-Hd for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:19 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40488) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL50K-0002EX-5o; Fri, 09 Nov 2018 06:31:12 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 064DC30BF470; Fri, 9 Nov 2018 11:31:11 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id EBDDF5C219; Fri, 9 Nov 2018 11:31:00 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:53 +0100 Message-Id: <20181109112957.10067-15-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 09 Nov 2018 11:31:11 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 14/18] virtio-iommu-pci: Add virtio iommu pci support 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch adds virtio-iommu-pci, which is the pci proxy for the virtio-iommu device. Signed-off-by: Eric Auger --- hw/virtio/virtio-pci.c | 50 ++++++++++++++++++++++++++++++++++++++++++ hw/virtio/virtio-pci.h | 14 ++++++++++++ include/hw/pci/pci.h | 1 + qdev-monitor.c | 1 + 4 files changed, 66 insertions(+) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index a954799267..45b294b34d 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -2342,6 +2342,55 @@ static const TypeInfo virtio_balloon_pci_info =3D { .class_init =3D virtio_balloon_pci_class_init, }; =20 +/* virtio-iommu-pci */ + +static Property virtio_iommu_pci_properties[] =3D { + DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **err= p) +{ + VirtIOIOMMUPCI *dev =3D VIRTIO_IOMMU_PCI(vpci_dev); + DeviceState *vdev =3D DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus)); + object_property_set_link(OBJECT(dev), + OBJECT(pci_get_bus(&vpci_dev->pci_dev)), + "primary-bus", errp); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_iommu_pci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + VirtioPCIClass *k =3D VIRTIO_PCI_CLASS(klass); + PCIDeviceClass *pcidev_k =3D PCI_DEVICE_CLASS(klass); + k->realize =3D virtio_iommu_pci_realize; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + dc->props =3D virtio_iommu_pci_properties; + pcidev_k->vendor_id =3D PCI_VENDOR_ID_REDHAT_QUMRANET; + pcidev_k->device_id =3D PCI_DEVICE_ID_VIRTIO_IOMMU; + pcidev_k->revision =3D VIRTIO_PCI_ABI_VERSION; + pcidev_k->class_id =3D PCI_CLASS_OTHERS; +} + +static void virtio_iommu_pci_instance_init(Object *obj) +{ + VirtIOIOMMUPCI *dev =3D VIRTIO_IOMMU_PCI(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_IOMMU); +} + +static const TypeInfo virtio_iommu_pci_info =3D { + .name =3D TYPE_VIRTIO_IOMMU_PCI, + .parent =3D TYPE_VIRTIO_PCI, + .instance_size =3D sizeof(VirtIOIOMMUPCI), + .instance_init =3D virtio_iommu_pci_instance_init, + .class_init =3D virtio_iommu_pci_class_init, +}; + /* virtio-serial-pci */ =20 static void virtio_serial_pci_realize(VirtIOPCIProxy *vpci_dev, Error **er= rp) @@ -2712,6 +2761,7 @@ static void virtio_pci_register_types(void) #endif type_register_static(&virtio_scsi_pci_info); type_register_static(&virtio_balloon_pci_info); + type_register_static(&virtio_iommu_pci_info); type_register_static(&virtio_serial_pci_info); type_register_static(&virtio_net_pci_info); #ifdef CONFIG_VHOST_SCSI diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index 813082b0d7..a17100b4a0 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -26,6 +26,7 @@ #include "hw/virtio/virtio-input.h" #include "hw/virtio/virtio-gpu.h" #include "hw/virtio/virtio-crypto.h" +#include "hw/virtio/virtio-iommu.h" #include "hw/virtio/vhost-user-scsi.h" #if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX) #include "hw/virtio/vhost-user-blk.h" @@ -57,6 +58,7 @@ typedef struct VirtIOInputHostPCI VirtIOInputHostPCI; typedef struct VirtIOGPUPCI VirtIOGPUPCI; typedef struct VHostVSockPCI VHostVSockPCI; typedef struct VirtIOCryptoPCI VirtIOCryptoPCI; +typedef struct VirtIOIOMMUPCI VirtIOIOMMUPCI; =20 /* virtio-pci-bus */ =20 @@ -363,6 +365,18 @@ struct VirtIOInputHIDPCI { VirtIOInputHID vdev; }; =20 +/* + * * virtio-iommu-pci: This extends VirtioPCIProxy. + * */ +#define TYPE_VIRTIO_IOMMU_PCI "virtio-iommu-pci" +#define VIRTIO_IOMMU_PCI(obj) \ + OBJECT_CHECK(VirtIOIOMMUPCI, (obj), TYPE_VIRTIO_IOMMU_PCI) + +struct VirtIOIOMMUPCI { + VirtIOPCIProxy parent_obj; + VirtIOIOMMU vdev; +}; + #ifdef CONFIG_LINUX =20 #define TYPE_VIRTIO_INPUT_HOST_PCI "virtio-input-host-pci" diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index e6514bba23..a01fd4d2e1 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -85,6 +85,7 @@ extern bool pci_available; #define PCI_DEVICE_ID_VIRTIO_RNG 0x1005 #define PCI_DEVICE_ID_VIRTIO_9P 0x1009 #define PCI_DEVICE_ID_VIRTIO_VSOCK 0x1012 +#define PCI_DEVICE_ID_VIRTIO_IOMMU 0x1013 =20 #define PCI_VENDOR_ID_REDHAT 0x1b36 #define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001 diff --git a/qdev-monitor.c b/qdev-monitor.c index 07147c63bf..4f1ae056da 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -62,6 +62,7 @@ static const QDevAlias qdev_alias_table[] =3D { { "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_S390X }, { "virtio-input-host-pci", "virtio-input-host", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X }, + { "virtio-iommu-pci", "virtio-iommu", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X= }, { "virtio-keyboard-ccw", "virtio-keyboard", QEMU_ARCH_S390X }, { "virtio-keyboard-pci", "virtio-keyboard", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X }, --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763536380236.7599474329569; Fri, 9 Nov 2018 03:38:56 -0800 (PST) Received: from localhost ([::1]:33310 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL57n-0007LB-5C for importer@patchew.org; Fri, 09 Nov 2018 06:38:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46217) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50R-00073I-LP for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL50Q-0002ks-Eb for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:19 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34994) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL50M-0002Su-Ll; Fri, 09 Nov 2018 06:31:15 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 918473098453; Fri, 9 Nov 2018 11:31:13 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4E2DE5C21F; Fri, 9 Nov 2018 11:31:11 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:54 +0100 Message-Id: <20181109112957.10067-16-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 09 Nov 2018 11:31:13 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 15/18] hw/arm/virt: Add virtio-iommu to the virt board 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Both the virtio-iommu device and its dedicated mmio transport get instantiated when requested. Signed-off-by: Eric Auger --- v6 -> v7: - align to the smmu instantiation code v4 -> v5: - VirtMachineClass no_iommu added in this patch - Use object_resolve_path_type --- hw/arm/virt.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index a2b8d8f7c2..f2994c4359 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -29,6 +29,7 @@ */ =20 #include "qemu/osdep.h" +#include "monitor/qdev.h" #include "qapi/error.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" @@ -49,6 +50,7 @@ #include "qemu/bitops.h" #include "qemu/error-report.h" #include "hw/pci-host/gpex.h" +#include "hw/virtio/virtio-pci.h" #include "hw/arm/sysbus-fdt.h" #include "hw/platform-bus.h" #include "hw/arm/fdt.h" @@ -59,6 +61,7 @@ #include "qapi/visitor.h" #include "standard-headers/linux/input.h" #include "hw/arm/smmuv3.h" +#include "hw/virtio/virtio-iommu.h" =20 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ @@ -1085,6 +1088,33 @@ static void create_smmu(const VirtMachineState *vms,= qemu_irq *pic, g_free(node); } =20 +static void create_virtio_iommu(VirtMachineState *vms, + const char *pciehb_nodename, PCIBus *bus) +{ + const char compat[] =3D "virtio,pci-iommu"; + uint16_t bdf =3D 0x8; /* 00:01.0 */ + DeviceState *dev; + char *node; + + dev =3D qdev_create(BUS(bus), TYPE_VIRTIO_IOMMU_PCI); + object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal); + + node =3D g_strdup_printf("%s/virtio_iommu@%d", pciehb_nodename, bdf); + qemu_fdt_add_subnode(vms->fdt, node); + qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", + 1, bdf << 8 /* phys.hi */, + 1, 0 /* phys.mid */, + 1, 0 /* phys.lo */, + 1, 0 /* size.hi */, + 1, 0 /* size.low */); + + qemu_fdt_setprop_cell(vms->fdt, node, "#iommu-cells", 1); + qemu_fdt_setprop_cell(vms->fdt, node, "phandle", vms->iommu_phandle); + g_free(node); +} + + static void create_pcie(VirtMachineState *vms, qemu_irq *pic) { hwaddr base_mmio =3D vms->memmap[VIRT_PCIE_MMIO].base; @@ -1205,10 +1235,22 @@ static void create_pcie(VirtMachineState *vms, qemu= _irq *pic) if (vms->iommu) { vms->iommu_phandle =3D qemu_fdt_alloc_phandle(vms->fdt); =20 - create_smmu(vms, pic, pci->bus); + switch (vms->iommu) { + case VIRT_IOMMU_SMMUV3: + create_smmu(vms, pic, pci->bus); + qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map", + 0x0, vms->iommu_phandle, 0x0, 0x10000); + break; + case VIRT_IOMMU_VIRTIO: + create_virtio_iommu(vms, nodename, pci->bus); + qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map", + 0x0, vms->iommu_phandle, 0x0, 0x8, + 0x9, vms->iommu_phandle, 0x9, 0xfff7); + break; + default: + g_assert_not_reached(); + } =20 - qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map", - 0x0, vms->iommu_phandle, 0x0, 0x10000); } =20 g_free(nodename); --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541763999340922.7291338097896; Fri, 9 Nov 2018 03:46:39 -0800 (PST) Received: from localhost ([::1]:33365 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5FG-0007ae-6t for importer@patchew.org; Fri, 09 Nov 2018 06:46:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46343) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50b-00079V-Mx for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL50U-0003Dt-5J for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:28 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51790) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL50P-0002cl-29; Fri, 09 Nov 2018 06:31:18 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 24B54308339B; Fri, 9 Nov 2018 11:31:16 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id D68915C220; Fri, 9 Nov 2018 11:31:13 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:55 +0100 Message-Id: <20181109112957.10067-17-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Fri, 09 Nov 2018 11:31:16 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 16/18] hw/arm/virt-acpi-build: Introduce fill_iort_idmap helper 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" To avoid code duplication, let's introduce an helper that fills one IORT ID mappings array index. Signed-off-by: Eric Auger --- v8: new --- hw/arm/virt-acpi-build.c | 43 ++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 5785fb697c..ec7c4835fe 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -396,6 +396,17 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, uns= igned xsdt_tbl_offset) return rsdp_table; } =20 +static inline void +fill_iort_idmap(AcpiIortIdMapping *idmap, int i, + uint32_t input_base, uint32_t id_count, + uint32_t output_base, uint32_t output_reference) +{ + idmap[i].input_base =3D cpu_to_le32(input_base); + idmap[i].id_count =3D cpu_to_le32(id_count); + idmap[i].output_base =3D cpu_to_le32(output_base); + idmap[i].output_reference =3D cpu_to_le32(output_reference); +} + static void build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { @@ -453,13 +464,12 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) smmu->gerr_gsiv =3D cpu_to_le32(irq + 2); smmu->sync_gsiv =3D cpu_to_le32(irq + 3); =20 - /* Identity RID mapping covering the whole input RID range */ - idmap =3D &smmu->id_mapping_array[0]; - idmap->input_base =3D 0; - idmap->id_count =3D cpu_to_le32(0xFFFF); - idmap->output_base =3D 0; - /* output IORT node is the ITS group node (the first node) */ - idmap->output_reference =3D cpu_to_le32(iort_node_offset); + /* + * Identity RID mapping covering the whole input RID range. + * The output IORT node is the ITS group node (the first node). + */ + fill_iort_idmap(smmu->id_mapping_array, 0, 0, 0xffff, 0, + iort_node_offset); } =20 /* Root Complex Node */ @@ -477,18 +487,17 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) rc->memory_properties.memory_flags =3D 0x3; /* CCA =3D CPM =3D DCAS = =3D 1 */ rc->pci_segment_number =3D 0; /* MCFG pci_segment */ =20 - /* Identity RID mapping covering the whole input RID range */ - idmap =3D &rc->id_mapping_array[0]; - idmap->input_base =3D 0; - idmap->id_count =3D cpu_to_le32(0xFFFF); - idmap->output_base =3D 0; - if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3) { - /* output IORT node is the smmuv3 node */ - idmap->output_reference =3D cpu_to_le32(smmu_offset); + /* Identity RID mapping and output IORT node is the iommu node */ + fill_iort_idmap(rc->id_mapping_array, 0, 0, 0xFFFF, 0, + smmu_offset); } else { - /* output IORT node is the ITS group node (the first node) */ - idmap->output_reference =3D cpu_to_le32(iort_node_offset); + /* + * Identity RID mapping and the output IORT node is the ITS group + * node (the first node). + */ + fill_iort_idmap(rc->id_mapping_array, 0, 0, 0xFFFF, 0, + iort_node_offset); } =20 /* --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541764159165616.8069594707046; Fri, 9 Nov 2018 03:49:19 -0800 (PST) Received: from localhost ([::1]:33380 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5Hp-00034W-Qc for importer@patchew.org; Fri, 09 Nov 2018 06:49:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46378) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50f-0007BB-Ek for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL50b-0003kV-JV for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:32 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38948) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL50R-0002qX-Ol; Fri, 09 Nov 2018 06:31:20 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AFA4E307D91D; Fri, 9 Nov 2018 11:31:18 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6CC305C219; Fri, 9 Nov 2018 11:31:16 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:56 +0100 Message-Id: <20181109112957.10067-18-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 09 Nov 2018 11:31:18 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 17/18] hw/arm/virt-acpi-build: Add virtio-iommu node in IORT table 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch builds the virtio-iommu node in the ACPI IORT table. The RID space of the root complex, which spans 0x0-0x10000 maps to streamid space 0x0-0x10000 in the virtio-iommu which in turn maps to deviceid space 0x0-0x10000 in the ITS group. The iommu RID (0x8) is excluded as described in virtio-iommu specification. Signed-off-by: Eric Auger --- v7 -> v8: - exclude the iommu RID (0x8) in the root complex ID mapping --- hw/arm/virt-acpi-build.c | 49 ++++++++++++++++++++++++++++++------- include/hw/acpi/acpi-defs.h | 21 +++++++++++++++- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index ec7c4835fe..4e62731aaf 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -414,14 +414,14 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) AcpiIortIdMapping *idmap; AcpiIortItsGroup *its; AcpiIortTable *iort; - AcpiIortSmmu3 *smmu; - size_t node_size, iort_node_offset, iort_length, smmu_offset =3D 0; + size_t node_size, iort_node_offset, iort_length, iommu_offset =3D 0; AcpiIortRC *rc; + int nb_rc_idmappings =3D 1; =20 iort =3D acpi_data_push(table_data, sizeof(*iort)); =20 - if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3) { - nb_nodes =3D 3; /* RC, ITS, SMMUv3 */ + if (vms->iommu) { + nb_nodes =3D 3; /* RC, ITS, IOMMU */ } else { nb_nodes =3D 2; /* RC, ITS */ } @@ -446,10 +446,10 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) its->identifiers[0] =3D 0; /* MADT translation_id */ =20 if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3) { + AcpiIortSmmu3 *smmu; int irq =3D vms->irqmap[VIRT_SMMU]; =20 - /* SMMUv3 node */ - smmu_offset =3D iort_node_offset + node_size; + iommu_offset =3D iort_node_offset + node_size; node_size =3D sizeof(*smmu) + sizeof(*idmap); iort_length +=3D node_size; smmu =3D acpi_data_push(table_data, node_size); @@ -470,16 +470,38 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) */ fill_iort_idmap(smmu->id_mapping_array, 0, 0, 0xffff, 0, iort_node_offset); + } else if (vms->iommu =3D=3D VIRT_IOMMU_VIRTIO) { + AcpiIortPVIommuPCI *iommu; + + nb_rc_idmappings =3D 2; + iommu_offset =3D iort_node_offset + node_size; + node_size =3D sizeof(*iommu) + 2 * sizeof(*idmap); + iort_length +=3D node_size; + iommu =3D acpi_data_push(table_data, node_size); + + iommu->type =3D ACPI_IORT_NODE_PARAVIRT; + iommu->length =3D cpu_to_le16(node_size); + iommu->mapping_count =3D cpu_to_le32(2); + iommu->mapping_offset =3D cpu_to_le32(sizeof(*iommu)); + iommu->devid =3D cpu_to_le32(0x8); + iommu->model =3D cpu_to_le32(ACPI_IORT_NODE_PV_VIRTIO_IOMMU_PCI); + + /* + * Identity RID mapping covering the whole input RID range + * output IORT node is the ITS group node (the first node) + */ + fill_iort_idmap(iommu->id_mapping_array, 0, 0, 0xffff, 0, + iort_node_offset); } =20 /* Root Complex Node */ - node_size =3D sizeof(*rc) + sizeof(*idmap); + node_size =3D sizeof(*rc) + nb_rc_idmappings * sizeof(*idmap); iort_length +=3D node_size; rc =3D acpi_data_push(table_data, node_size); =20 rc->type =3D ACPI_IORT_NODE_PCI_ROOT_COMPLEX; rc->length =3D cpu_to_le16(node_size); - rc->mapping_count =3D cpu_to_le32(1); + rc->mapping_count =3D cpu_to_le32(nb_rc_idmappings); rc->mapping_offset =3D cpu_to_le32(sizeof(*rc)); =20 /* fully coherent device */ @@ -490,7 +512,16 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vir= tMachineState *vms) if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3) { /* Identity RID mapping and output IORT node is the iommu node */ fill_iort_idmap(rc->id_mapping_array, 0, 0, 0xFFFF, 0, - smmu_offset); + iommu_offset); + } else if (vms->iommu =3D=3D VIRT_IOMMU_VIRTIO) { + /* + * Identity mapping with the IOMMU RID (0x8) excluded. The output + * IORT node is the iommu node. + */ + fill_iort_idmap(rc->id_mapping_array, 0, 0, 0x8, 0, + iommu_offset); + fill_iort_idmap(rc->id_mapping_array, 1, 0x9, 0xFFF7, 0x9, + iommu_offset); } else { /* * Identity RID mapping and the output IORT node is the ITS group diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index af8e023968..b14aa95dc1 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -601,7 +601,8 @@ enum { ACPI_IORT_NODE_NAMED_COMPONENT =3D 0x01, ACPI_IORT_NODE_PCI_ROOT_COMPLEX =3D 0x02, ACPI_IORT_NODE_SMMU =3D 0x03, - ACPI_IORT_NODE_SMMU_V3 =3D 0x04 + ACPI_IORT_NODE_SMMU_V3 =3D 0x04, + ACPI_IORT_NODE_PARAVIRT =3D 0x80 }; =20 struct AcpiIortIdMapping { @@ -628,6 +629,24 @@ struct AcpiIortItsGroup { } QEMU_PACKED; typedef struct AcpiIortItsGroup AcpiIortItsGroup; =20 +struct AcpiIortPVIommuPCI { + ACPI_IORT_NODE_HEADER_DEF + uint32_t devid; + uint8_t reserved2[12]; + uint32_t model; + uint32_t flags; + uint8_t reserved3[16]; + AcpiIortIdMapping id_mapping_array[0]; +} QEMU_PACKED; +typedef struct AcpiIortPVIommuPCI AcpiIortPVIommuPCI; + +enum { + ACPI_IORT_NODE_PV_VIRTIO_IOMMU =3D 0x0, + ACPI_IORT_NODE_PV_VIRTIO_IOMMU_PCI =3D 0x1, +}; + +#define ACPI_IORT_NODE_PV_CACHE_COHERENT (1 << 0) + struct AcpiIortSmmu3 { ACPI_IORT_NODE_HEADER_DEF uint64_t base_address; --=20 2.17.2 From nobody Sat May 4 12:24:50 2024 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541764036824177.82583433020727; Fri, 9 Nov 2018 03:47:16 -0800 (PST) Received: from localhost ([::1]:33369 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5Fp-00080y-GW for importer@patchew.org; Fri, 09 Nov 2018 06:47:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46454) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL50y-0007Op-Ne for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL50t-00051p-J1 for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:31:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46038) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL50Y-0003Pj-Sz; Fri, 09 Nov 2018 06:31:27 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8F629307CDC9; Fri, 9 Nov 2018 11:31:23 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-55.ams2.redhat.com [10.36.116.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id EC9255C21F; Fri, 9 Nov 2018 11:31:18 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, jean-philippe.brucker@arm.com Date: Fri, 9 Nov 2018 12:29:57 +0100 Message-Id: <20181109112957.10067-19-eric.auger@redhat.com> In-Reply-To: <20181109112957.10067-1-eric.auger@redhat.com> References: <20181109112957.10067-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Fri, 09 Nov 2018 11:31:23 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v8 18/18] hw/arm/virt: Allow virtio-iommu instantiation 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: tn@semihalf.com, kevin.tian@intel.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The virtio-iommu now can be instantiated by adding the virt machine option "-M virt,iommu=3Dvirtio" Signed-off-by: Eric Auger --- hw/arm/virt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index f2994c4359..d2080a1ba9 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1710,6 +1710,8 @@ static char *virt_get_iommu(Object *obj, Error **errp) return g_strdup("none"); case VIRT_IOMMU_SMMUV3: return g_strdup("smmuv3"); + case VIRT_IOMMU_VIRTIO: + return g_strdup("virtio"); default: g_assert_not_reached(); } @@ -1721,11 +1723,13 @@ static void virt_set_iommu(Object *obj, const char = *value, Error **errp) =20 if (!strcmp(value, "smmuv3")) { vms->iommu =3D VIRT_IOMMU_SMMUV3; + } else if (!strcmp(value, "virtio")) { + vms->iommu =3D VIRT_IOMMU_VIRTIO; } else if (!strcmp(value, "none")) { vms->iommu =3D VIRT_IOMMU_NONE; } else { error_setg(errp, "Invalid iommu value"); - error_append_hint(errp, "Valid values are none, smmuv3.\n"); + error_append_hint(errp, "Valid values are none, smmuv3, virtio.\n"= ); } } =20 @@ -1901,7 +1905,7 @@ static void virt_3_1_instance_init(Object *obj) object_property_add_str(obj, "iommu", virt_get_iommu, virt_set_iommu, = NULL); object_property_set_description(obj, "iommu", "Set the IOMMU type. " - "Valid values are none and smmuv3", + "Valid values are none, smmuv3, virtio= ", NULL); =20 vms->memmap =3D a15memmap; --=20 2.17.2