From nobody Fri May 3 00:19:22 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 1542908222739913.0980740357189; Thu, 22 Nov 2018 09:37:02 -0800 (PST) Received: from localhost ([::1]:48382 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsuT-0006Bf-JJ for importer@patchew.org; Thu, 22 Nov 2018 12:37:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48819) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsaQ-0004og-Lb for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsaN-0005di-0f for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:18 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38996) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaC-0005SS-Pj; Thu, 22 Nov 2018 12:16:06 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7EE8E3084026; Thu, 22 Nov 2018 17:15:57 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id B878D60610; Thu, 22 Nov 2018 17:15:52 +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: Thu, 22 Nov 2018 18:15:22 +0100 Message-Id: <20181122171538.12359-2-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Thu, 22 Nov 2018 17:15:57 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 01/17] 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 Tested-by: Bharat Bhushan --- 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 Fri May 3 00:19:22 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 1542908346494766.9451342466483; Thu, 22 Nov 2018 09:39:06 -0800 (PST) Received: from localhost ([::1]:48434 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPswT-0008TD-FP for importer@patchew.org; Thu, 22 Nov 2018 12:39:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsaX-0004vY-RW for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsaQ-0005iW-MS for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:24 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42178) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaI-0005TR-Ow; Thu, 22 Nov 2018 12:16:12 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0B3E5300126C; Thu, 22 Nov 2018 17:16:00 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id C389D60610; Thu, 22 Nov 2018 17:15:57 +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: Thu, 22 Nov 2018 18:15:23 +0100 Message-Id: <20181122171538.12359-3-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Thu, 22 Nov 2018 17:16:00 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 02/17] 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 Tested-by: Bharat Bhushan --- 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 Fri May 3 00:19:22 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 1542908472946875.3816929096786; Thu, 22 Nov 2018 09:41:12 -0800 (PST) Received: from localhost ([::1]:48482 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsyV-0002JZ-Ss for importer@patchew.org; Thu, 22 Nov 2018 12:41:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49140) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsae-00052i-Pa for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsaa-0005zx-Pt for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:32 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46832) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaG-0005Uw-Pu; Thu, 22 Nov 2018 12:16:10 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 97BB43138BAB; Thu, 22 Nov 2018 17:16:02 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5451260610; Thu, 22 Nov 2018 17:16: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: Thu, 22 Nov 2018 18:15:24 +0100 Message-Id: <20181122171538.12359-4-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Thu, 22 Nov 2018 17:16:02 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 03/17] 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 Tested-by: Bharat Bhushan --- v8 -> v9: - properly initialize tail 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..d8894f047b --- /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 =3D {}; + 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 Fri May 3 00:19:22 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 1542908058064764.6037120559167; Thu, 22 Nov 2018 09:34:18 -0800 (PST) Received: from localhost ([::1]:48366 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsrj-0004Mx-Ho for importer@patchew.org; Thu, 22 Nov 2018 12:34:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48817) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsaQ-0004oe-KY for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsaN-0005e6-Cm for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:18 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48552) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaE-0005VN-Qs; Thu, 22 Nov 2018 12:16:08 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2C4F4308339C; Thu, 22 Nov 2018 17:16:05 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id E154660920; Thu, 22 Nov 2018 17:16:02 +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: Thu, 22 Nov 2018 18:15:25 +0100 Message-Id: <20181122171538.12359-5-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Thu, 22 Nov 2018 17:16:05 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 04/17] 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 Tested-by: Bharat Bhushan --- 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 d8894f047b..fc95751c40 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 Fri May 3 00:19:22 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 1542907393680834.0661289520651; Thu, 22 Nov 2018 09:23:13 -0800 (PST) Received: from localhost ([::1]:48150 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsgw-0002Ff-EE for importer@patchew.org; Thu, 22 Nov 2018 12:23:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49135) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsae-00052b-Kv for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsaa-0005zu-Pq for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:32 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44054) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaM-0005bZ-Sc; Thu, 22 Nov 2018 12:16:15 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2C95FC057F2A; Thu, 22 Nov 2018 17:16:13 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 788B360923; Thu, 22 Nov 2018 17:16:05 +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: Thu, 22 Nov 2018 18:15:26 +0100 Message-Id: <20181122171538.12359-6-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 22 Nov 2018 17:16:13 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 05/17] 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 Tested-by: Bharat Bhushan --- 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 fc95751c40..dead062baf 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 Fri May 3 00:19:22 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 1542908568964413.69408128457644; Thu, 22 Nov 2018 09:42:48 -0800 (PST) Received: from localhost ([::1]:48510 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPszy-0003Ki-L6 for importer@patchew.org; Thu, 22 Nov 2018 12:42:42 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49292) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsao-0005B2-76 for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsae-000667-JX for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36994) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaS-0005k7-Ku; Thu, 22 Nov 2018 12:16:22 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9091280F8D; Thu, 22 Nov 2018 17:16:18 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7711860610; Thu, 22 Nov 2018 17:16: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: Thu, 22 Nov 2018 18:15:27 +0100 Message-Id: <20181122171538.12359-7-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 22 Nov 2018 17:16:18 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 06/17] 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 Tested-by: Bharat Bhushan --- 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 dead062baf..1b9c3ba416 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 Fri May 3 00:19:22 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 1542907582990861.3072740777584; Thu, 22 Nov 2018 09:26:22 -0800 (PST) Received: from localhost ([::1]:48246 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPskA-0005hd-0L for importer@patchew.org; Thu, 22 Nov 2018 12:26:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49282) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsan-0005AE-10 for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsae-00065b-HU for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42412) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaU-0005qL-Rk; Thu, 22 Nov 2018 12:16:24 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 25C6389AEF; Thu, 22 Nov 2018 17:16:21 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id D9EF360610; Thu, 22 Nov 2018 17:16: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: Thu, 22 Nov 2018 18:15:28 +0100 Message-Id: <20181122171538.12359-8-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 22 Nov 2018 17:16:21 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 07/17] 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 Tested-by: Bharat Bhushan --- --- 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 1b9c3ba416..5c231f865c 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 Fri May 3 00:19:22 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 1542907511573143.28296018087167; Thu, 22 Nov 2018 09:25:11 -0800 (PST) Received: from localhost ([::1]:48181 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsix-0004dX-9J for importer@patchew.org; Thu, 22 Nov 2018 12:25:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49368) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsb0-0005Lw-N6 for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsat-0006HJ-9n for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39126) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaY-0005u3-SK; Thu, 22 Nov 2018 12:16:28 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B651030014CF; Thu, 22 Nov 2018 17:16:23 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6F5A660610; Thu, 22 Nov 2018 17:16:21 +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: Thu, 22 Nov 2018 18:15:29 +0100 Message-Id: <20181122171538.12359-9-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Thu, 22 Nov 2018 17:16:23 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 08/17] 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 Tested-by: Bharat Bhushan --- 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 5c231f865c..23f7dc6f7f 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 Fri May 3 00:19:22 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 1542907675780145.39365503270574; Thu, 22 Nov 2018 09:27:55 -0800 (PST) Received: from localhost ([::1]:48285 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsld-0006qC-Rb for importer@patchew.org; Thu, 22 Nov 2018 12:27:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49371) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsb0-0005Lx-Nx for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsav-0006IC-5z for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:16:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34919) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsae-0005xR-Pj; Thu, 22 Nov 2018 12:16:34 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 490AA88E6A; Thu, 22 Nov 2018 17:16:26 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 06EA160610; Thu, 22 Nov 2018 17:16:23 +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: Thu, 22 Nov 2018 18:15:30 +0100 Message-Id: <20181122171538.12359-10-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 22 Nov 2018 17:16:26 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 09/17] 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 Tested-by: Bharat Bhushan --- 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 23f7dc6f7f..af90413b37 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 Fri May 3 00:19:22 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 1542908654601631.1907937127681; Thu, 22 Nov 2018 09:44:14 -0800 (PST) Received: from localhost ([::1]:48523 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPt1O-0004z3-UF for importer@patchew.org; Thu, 22 Nov 2018 12:44:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49629) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsb9-0005TL-Jl for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsb4-0006Wl-HF for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56048) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsaj-0006Bk-D9; Thu, 22 Nov 2018 12:16:37 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5D4B59F733; Thu, 22 Nov 2018 17:16:36 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 919AA60610; Thu, 22 Nov 2018 17:16:26 +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: Thu, 22 Nov 2018 18:15:31 +0100 Message-Id: <20181122171538.12359-11-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 22 Nov 2018 17:16:36 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 10/17] 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 Tested-by: Bharat Bhushan --- v8 -> v9: - fix filling of properties (changes induced by v0.7 -> v0.8 spec evolution) 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 | 181 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 181 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 af90413b37..4fc43494d9 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -39,6 +39,10 @@ =20 /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 +#define VIOMMU_PROBE_SIZE 512 + +#define SUPPORTED_PROBE_PROPERTIES (\ + 1 << VIRTIO_IOMMU_PROBE_T_RESV_MEM) =20 typedef struct viommu_domain { uint32_t id; @@ -51,6 +55,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 +70,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 +116,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 +132,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 +368,131 @@ 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_resv_mem *buf_prop; + viommu_property_buffer *bufstate =3D (viommu_property_buffer *)data; + size_t prop_size =3D sizeof(*resv); + + if (bufstate->filled + prop_size >=3D VIOMMU_PROBE_SIZE) { + bufstate->error =3D true; + /* get the traversal stopped by returning true */ + return true; + } + buf_prop =3D (struct virtio_iommu_probe_resv_mem *) + (bufstate->start + bufstate->filled); + *buf_prop =3D *resv; + + bufstate->filled +=3D prop_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; +} + +/* Fill the properties[] buffer with properties of type @type */ +static int virtio_iommu_fill_property(int type, + viommu_property_buffer *bufstate) +{ + int ret =3D -ENOSPC; + + if (bufstate->filled + sizeof(struct virtio_iommu_probe_property) + >=3D VIOMMU_PROBE_SIZE) { + /* no space left for the header */ + 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(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 +557,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 +619,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 +807,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 +816,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 Fri May 3 00:19:22 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 1542907963480426.292132951809; Thu, 22 Nov 2018 09:32:43 -0800 (PST) Received: from localhost ([::1]:48349 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsqD-00032j-Dl for importer@patchew.org; Thu, 22 Nov 2018 12:32:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49792) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsbE-0005XO-7c for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsbB-0006l2-4h for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:08 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52862) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsb1-0006GN-EE; Thu, 22 Nov 2018 12:16:55 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AC96D31256BE; Thu, 22 Nov 2018 17:16:42 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id A606360610; Thu, 22 Nov 2018 17:16:36 +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: Thu, 22 Nov 2018 18:15:32 +0100 Message-Id: <20181122171538.12359-12-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Thu, 22 Nov 2018 17:16:42 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 11/17] virtio-iommu: Expose the IOAPIC MSI reserved region when relevant 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" We introduce a new msi_bypass field which indicates whether the IOAPIC MSI window [0xFEE00000 - 0xFEEFFFFF] must be exposed as a reserved region. By default the field is set to true at instantiation time. Later on we will introduce a property at virtio pci proxy level to turn it off. Signed-off-by: Eric Auger Tested-by: Bharat Bhushan --- v8 -> v9: - pass IOAPIC_RANGE_END to virtio_iommu_register_resv_region - take into account the change in the struct virtio_iommu_probe_resv_mem definition - We just introduce the field here. A property will be introduced later on at pci proxy level. --- hw/virtio/virtio-iommu.c | 36 ++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-iommu.h | 1 + 2 files changed, 37 insertions(+) diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 4fc43494d9..324518c300 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_END (0xfeefffff) + #define SUPPORTED_PROBE_PROPERTIES (\ 1 << VIRTIO_IOMMU_PROBE_T_RESV_MEM) =20 @@ -102,6 +105,30 @@ 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 *resv_reg_prop; + size_t prop_size =3D sizeof(struct virtio_iommu_probe_resv_mem); + size_t value_size =3D prop_size - + sizeof(struct virtio_iommu_probe_property); + + interval =3D g_malloc0(sizeof(*interval)); + interval->low =3D start; + interval->high =3D end; + + resv_reg_prop =3D g_malloc0(prop_size); + resv_reg_prop->head.type =3D VIRTIO_IOMMU_PROBE_T_RESV_MEM; + resv_reg_prop->head.length =3D cpu_to_le64(value_size); + resv_reg_prop->subtype =3D cpu_to_le64(subtype); + resv_reg_prop->start =3D cpu_to_le64(start); + resv_reg_prop->end =3D cpu_to_le64(end); + + g_tree_insert(ep->reserved_regions, interval, resv_reg_prop); +} + static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id) { @@ -119,6 +146,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_END); + } + return ep; } =20 @@ -858,6 +891,9 @@ static void virtio_iommu_set_status(VirtIODevice *vdev,= uint8_t status) =20 static void virtio_iommu_instance_init(Object *obj) { + VirtIOIOMMU *s =3D VIRTIO_IOMMU(obj); + + 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 Fri May 3 00:19:22 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 1542907306136897.1034023639827; Thu, 22 Nov 2018 09:21:46 -0800 (PST) Received: from localhost ([::1]:48146 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsfW-0001BW-NX for importer@patchew.org; Thu, 22 Nov 2018 12:21:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49829) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsbF-0005ZE-Px for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsbD-0006qJ-IA for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:09 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58614) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsb1-0006Gs-Np; Thu, 22 Nov 2018 12:16:55 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 40A9FA048B; Thu, 22 Nov 2018 17:16:45 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id F128160610; Thu, 22 Nov 2018 17:16:42 +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: Thu, 22 Nov 2018 18:15:33 +0100 Message-Id: <20181122171538.12359-13-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 22 Nov 2018 17:16:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 12/17] 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 Tested-by: Bharat Bhushan --- 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 324518c300..1246dd6bdf 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -683,17 +683,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; @@ -718,6 +764,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; } @@ -729,6 +777,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; } @@ -740,14 +790,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 Fri May 3 00:19:22 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 1542907763458115.6048224263618; Thu, 22 Nov 2018 09:29:23 -0800 (PST) Received: from localhost ([::1]:48293 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsn4-0000c1-DO for importer@patchew.org; Thu, 22 Nov 2018 12:29:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49751) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsbD-0005WK-26 for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsb9-0006hg-Nl for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:07 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56102) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsb0-0006Hq-Tz; Thu, 22 Nov 2018 12:16:55 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CF0A110DE3; Thu, 22 Nov 2018 17:16:47 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 894D560920; Thu, 22 Nov 2018 17:16:45 +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: Thu, 22 Nov 2018 18:15:34 +0100 Message-Id: <20181122171538.12359-14-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 22 Nov 2018 17:16:47 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 13/17] 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 Tested-by: Bharat Bhushan --- 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 1246dd6bdf..2ec01f3b9e 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -740,6 +740,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; @@ -772,6 +773,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 Fri May 3 00:19:22 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 1542908282308635.2868796169814; Thu, 22 Nov 2018 09:38:02 -0800 (PST) Received: from localhost ([::1]:48418 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsvR-0006sp-C2 for importer@patchew.org; Thu, 22 Nov 2018 12:38:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49813) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsbF-0005YA-0U for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsbC-0006oF-Kj for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:08 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47140) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsb2-0006Qg-MM; Thu, 22 Nov 2018 12:16:56 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 90D443138BB9; Thu, 22 Nov 2018 17:16:55 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 22B2C60920; Thu, 22 Nov 2018 17:16:47 +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: Thu, 22 Nov 2018 18:15:35 +0100 Message-Id: <20181122171538.12359-15-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Thu, 22 Nov 2018 17:16:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 14/17] 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 Tested-by: Bharat Bhushan --- v8 -> v9: - add the msi-bypass property --- hw/virtio/virtio-pci.c | 51 ++++++++++++++++++++++++++++++++++++++++++ hw/virtio/virtio-pci.h | 14 ++++++++++++ include/hw/pci/pci.h | 1 + qdev-monitor.c | 1 + 4 files changed, 67 insertions(+) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index a954799267..cdd18afe9e 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -2342,6 +2342,56 @@ 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_BOOL("msi-bypass", VirtIOIOMMUPCI, vdev.msi_bypass, true), + 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 +2762,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 Fri May 3 00:19:22 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 1542908137019929.4567951036566; Thu, 22 Nov 2018 09:35:37 -0800 (PST) Received: from localhost ([::1]:48368 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPst0-0005C9-IP for importer@patchew.org; Thu, 22 Nov 2018 12:35:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49854) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsbH-0005aW-1O for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsbE-0006sk-TP for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:11 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47250) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsb8-0006dl-Py; Thu, 22 Nov 2018 12:17:03 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 413DCC049D79; Thu, 22 Nov 2018 17:17:01 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id D75D96061E; Thu, 22 Nov 2018 17:16: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: Thu, 22 Nov 2018 18:15:36 +0100 Message-Id: <20181122171538.12359-16-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 22 Nov 2018 17:17:01 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 15/17] hw/arm/virt: Add the virtio-iommu device tree mappings 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" Adds the "virtio,pci-iommu" node in the host bridge node and the RID mapping, excluding the IOMMU RID. Signed-off-by: Eric Auger Reviewed-by: Bharat Bhushan Tested-by: Bharat Bhushan --- v8 -> v9: - disable msi-bypass property - addition of the subnode is handled is the hotplug handler and IOMMU RID is notimposed anymore 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 | 57 +++++++++++++++++++++++++++++++++++++------ include/hw/arm/virt.h | 2 ++ 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index a2b8d8f7c2..b2bbb0ef49 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, Error **errp) +{ + const char compat[] =3D "virtio,pci-iommu"; + uint16_t bdf =3D vms->virtio_iommu_bdf; + char *node; + + vms->iommu_phandle =3D qemu_fdt_alloc_phandle(vms->fdt); + + node =3D g_strdup_printf("%s/virtio_iommu@%d", vms->pciehb_nodename, b= df); + 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); + + qemu_fdt_setprop_cells(vms->fdt, vms->pciehb_nodename, "iommu-map", + 0x0, vms->iommu_phandle, 0x0, bdf, + bdf + 1, vms->iommu_phandle, bdf + 1, 0xffff - = bdf); +} + static void create_pcie(VirtMachineState *vms, qemu_irq *pic) { hwaddr base_mmio =3D vms->memmap[VIRT_PCIE_MMIO].base; @@ -1162,7 +1192,7 @@ static void create_pcie(VirtMachineState *vms, qemu_i= rq *pic) } } =20 - nodename =3D g_strdup_printf("/pcie@%" PRIx64, base); + nodename =3D vms->pciehb_nodename =3D g_strdup_printf("/pcie@%" PRIx64= , base); qemu_fdt_add_subnode(vms->fdt, nodename); qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "pci-host-ecam-generic"); @@ -1205,13 +1235,17 @@ 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; + default: + g_assert_not_reached(); + } =20 - qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map", - 0x0, vms->iommu_phandle, 0x0, 0x10000); } - - g_free(nodename); } =20 static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic) @@ -1736,12 +1770,21 @@ static void virt_machine_device_plug_cb(HotplugHand= ler *hotplug_dev, SYS_BUS_DEVICE(dev)); } } + if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { + PCIDevice *pdev =3D PCI_DEVICE(dev); + + vms->iommu =3D VIRT_IOMMU_VIRTIO; + vms->virtio_iommu_bdf =3D pci_get_bdf(pdev); + object_property_set_bool(OBJECT(dev), false, "msi-bypass", errp); + create_virtio_iommu(vms, errp); + } } =20 static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *mach= ine, DeviceState *dev) { - if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) { + if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE) || + object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { return HOTPLUG_HANDLER(machine); } =20 diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 4cc57a7ef6..c330f6f4b7 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -115,7 +115,9 @@ typedef struct { bool virt; int32_t gic_version; VirtIOMMUType iommu; + uint16_t virtio_iommu_bdf; struct arm_boot_info bootinfo; + char *pciehb_nodename; const MemMapEntry *memmap; const int *irqmap; int smp_cpus; --=20 2.17.2 From nobody Fri May 3 00:19:22 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 1542907909931213.84456769266114; Thu, 22 Nov 2018 09:31:49 -0800 (PST) Received: from localhost ([::1]:48313 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPspQ-0002S5-Md for importer@patchew.org; Thu, 22 Nov 2018 12:31:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49901) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsbK-0005dJ-5s for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsbH-0006wn-AB for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:14 -0500 Received: from mx1.redhat.com ([209.132.183.28]:6707) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsbB-0006if-8F; Thu, 22 Nov 2018 12:17:05 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CB5D53084026; Thu, 22 Nov 2018 17:17:03 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 86A416061E; Thu, 22 Nov 2018 17:17:01 +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: Thu, 22 Nov 2018 18:15:37 +0100 Message-Id: <20181122171538.12359-17-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Thu, 22 Nov 2018 17:17:03 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 16/17] 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 Tested-by: Bharat Bhushan --- 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 Fri May 3 00:19:22 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 154290749350565.90526161913408; Thu, 22 Nov 2018 09:24:53 -0800 (PST) Received: from localhost ([::1]:48170 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsib-0004IH-K2 for importer@patchew.org; Thu, 22 Nov 2018 12:24:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49941) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPsbM-0005fd-9h for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPsbK-00072U-D8 for qemu-devel@nongnu.org; Thu, 22 Nov 2018 12:17:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58670) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPsbD-0006oP-Sq; Thu, 22 Nov 2018 12:17:08 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6453F234; Thu, 22 Nov 2018 17:17:06 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1CD6C6061E; Thu, 22 Nov 2018 17:17:03 +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: Thu, 22 Nov 2018 18:15:38 +0100 Message-Id: <20181122171538.12359-18-eric.auger@redhat.com> In-Reply-To: <20181122171538.12359-1-eric.auger@redhat.com> References: <20181122171538.12359-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 22 Nov 2018 17:17:06 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v9 17/17] 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 is excluded as described in virtio-iommu specification. Signed-off-by: Eric Auger Tested-by: Bharat Bhushan --- v8 -> v9: - iommu RID is not fixed anymore v7 -> v8: - exclude the iommu RID (0x8) in the root complex ID mapping --- hw/arm/virt-acpi-build.c | 50 ++++++++++++++++++++++++++++++------- include/hw/acpi/acpi-defs.h | 21 +++++++++++++++- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index ec7c4835fe..0e621f6551 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) + 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(vms->virtio_iommu_bdf); + 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,17 @@ 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, vms->virtio_iommu_bdf,= 0, + iommu_offset); + fill_iort_idmap(rc->id_mapping_array, 1, vms->virtio_iommu_bdf + 1, + 0xFFFF - vms->virtio_iommu_bdf, + vms->virtio_iommu_bdf + 1, 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