From nobody Sun Apr 28 01:58:32 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1501580180405976.3320348412409; Tue, 1 Aug 2017 02:36:20 -0700 (PDT) Received: from localhost ([::1]:41386 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTb7-00006Z-Jw for importer@patchew.org; Tue, 01 Aug 2017 05:36:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38101) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTZJ-0007Gv-MO for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:34:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dcTZI-0001DW-SA for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:34:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46272) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dcTZG-0001BF-LX; Tue, 01 Aug 2017 05:34:22 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7FDFDC04B071; Tue, 1 Aug 2017 09:34:21 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-181.ams2.redhat.com [10.36.116.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id CF1826017B; Tue, 1 Aug 2017 09:34:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 7FDFDC04B071 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org, jean-philippe.brucker@arm.com Date: Tue, 1 Aug 2017 11:33:07 +0200 Message-Id: <1501579994-3320-2-git-send-email-eric.auger@redhat.com> In-Reply-To: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> References: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 01 Aug 2017 09:34: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 v3 1/8] 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: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, peterx@redhat.com, bharat.bhushan@nxp.com, christoffer.dall@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Update the script to update the virtio_iommu.h header. Signed-off-by: Eric Auger --- scripts/update-linux-headers.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers= .sh index 2f906c4..03f6712 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -134,6 +134,9 @@ EOF 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.5.5 From nobody Sun Apr 28 01:58:32 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1501580202545543.7897915733142; Tue, 1 Aug 2017 02:36:42 -0700 (PDT) Received: from localhost ([::1]:41388 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTbU-0000PG-JE for importer@patchew.org; Tue, 01 Aug 2017 05:36:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38160) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTZb-0007UF-10 for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:34:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dcTZZ-0001Zk-PW for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:34:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44160) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dcTZU-0001QL-Ei; Tue, 01 Aug 2017 05:34:36 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 42E8512E52D; Tue, 1 Aug 2017 09:34:35 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-181.ams2.redhat.com [10.36.116.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id DCEBA60186; Tue, 1 Aug 2017 09:34:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 42E8512E52D Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org, jean-philippe.brucker@arm.com Date: Tue, 1 Aug 2017 11:33:08 +0200 Message-Id: <1501579994-3320-3-git-send-email-eric.auger@redhat.com> In-Reply-To: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> References: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 01 Aug 2017 09:34:35 +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 v3 2/8] linux-headers: Update for virtio-iommu 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: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, peterx@redhat.com, bharat.bhushan@nxp.com, christoffer.dall@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This is a partial linux header update against Jean-Philippe's branch: git://linux-arm.org/linux-jpb.git virtio-iommu/base (unstable) Signed-off-by: Eric Auger --- include/standard-headers/linux/virtio_ids.h | 1 + include/standard-headers/linux/virtio_iommu.h | 142 ++++++++++++++++++++++= ++++ linux-headers/linux/virtio_iommu.h | 1 + 3 files changed, 144 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 6d5c3b2..934ed3d 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 61216 /* virtio IOMMU (temporary) */ =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 0000000..e139587 --- /dev/null +++ b/include/standard-headers/linux/virtio_iommu.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2017 ARM Ltd. + * + * This header is BSD licensed so anyone can use the definitions + * to implement compatible drivers/servers: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of ARM Ltd. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _LINUX_VIRTIO_IOMMU_H +#define _LINUX_VIRTIO_IOMMU_H + +/* Feature bits */ +#define VIRTIO_IOMMU_F_INPUT_RANGE 0 +#define VIRTIO_IOMMU_F_IOASID_BITS 1 +#define VIRTIO_IOMMU_F_MAP_UNMAP 2 +#define VIRTIO_IOMMU_F_BYPASS 3 + +QEMU_PACKED +struct virtio_iommu_config { + /* Supported page sizes */ + uint64_t page_sizes; + struct virtio_iommu_range { + uint64_t start; + uint64_t end; + } input_range; + uint8_t ioasid_bits; +}; + +/* 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 + +/* 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 + +QEMU_PACKED +struct virtio_iommu_req_head { + uint8_t type; + uint8_t reserved[3]; +}; + +QEMU_PACKED +struct virtio_iommu_req_tail { + uint8_t status; + uint8_t reserved[3]; +}; + +QEMU_PACKED +struct virtio_iommu_req_attach { + struct virtio_iommu_req_head head; + + uint32_t address_space; + uint32_t device; + uint32_t reserved; + + struct virtio_iommu_req_tail tail; +}; + +QEMU_PACKED +struct virtio_iommu_req_detach { + struct virtio_iommu_req_head head; + + uint32_t device; + uint32_t reserved; + + 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_MASK (VIRTIO_IOMMU_MAP_F_READ | \ + VIRTIO_IOMMU_MAP_F_WRITE | \ + VIRTIO_IOMMU_MAP_F_EXEC) + +QEMU_PACKED +struct virtio_iommu_req_map { + struct virtio_iommu_req_head head; + + uint32_t address_space; + uint32_t flags; + uint64_t virt_addr; + uint64_t phys_addr; + uint64_t size; + + struct virtio_iommu_req_tail tail; +}; + +QEMU_PACKED +struct virtio_iommu_req_unmap { + struct virtio_iommu_req_head head; + + uint32_t address_space; + uint32_t flags; + uint64_t virt_addr; + uint64_t size; + + struct virtio_iommu_req_tail tail; +}; + +union virtio_iommu_req { + struct virtio_iommu_req_head head; + + struct virtio_iommu_req_attach attach; + struct virtio_iommu_req_detach detach; + struct virtio_iommu_req_map map; + struct virtio_iommu_req_unmap unmap; +}; + +#endif diff --git a/linux-headers/linux/virtio_iommu.h b/linux-headers/linux/virti= o_iommu.h new file mode 100644 index 0000000..2dc4609 --- /dev/null +++ b/linux-headers/linux/virtio_iommu.h @@ -0,0 +1 @@ +#include "standard-headers/linux/virtio_iommu.h" --=20 2.5.5 From nobody Sun Apr 28 01:58:32 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1501580207582993.4001043395342; Tue, 1 Aug 2017 02:36:47 -0700 (PDT) Received: from localhost ([::1]:41389 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTba-0000Sy-3U for importer@patchew.org; Tue, 01 Aug 2017 05:36:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38191) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTZe-0007Wn-J4 for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:34:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dcTZc-0001ea-TG for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:34:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47446) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dcTZY-0001YH-V4; Tue, 01 Aug 2017 05:34:41 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D03158FF62; Tue, 1 Aug 2017 09:34:39 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-181.ams2.redhat.com [10.36.116.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9C47460176; Tue, 1 Aug 2017 09:34:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com D03158FF62 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org, jean-philippe.brucker@arm.com Date: Tue, 1 Aug 2017 11:33:09 +0200 Message-Id: <1501579994-3320-4-git-send-email-eric.auger@redhat.com> In-Reply-To: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> References: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 01 Aug 2017 09:34:40 +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 v3 3/8] 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: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, peterx@redhat.com, bharat.bhushan@nxp.com, christoffer.dall@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 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 --- 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 --- hw/virtio/Makefile.objs | 1 + hw/virtio/virtio-iommu.c | 248 +++++++++++++++++++++++++++++++++++= ++++ include/hw/virtio/virtio-iommu.h | 59 ++++++++++ 3 files changed, 308 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 765d363..8967a4a 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -6,6 +6,7 @@ common-obj-y +=3D virtio-mmio.o =20 obj-y +=3D virtio.o virtio-balloon.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 obj-y +=3D virtio-crypto.o obj-$(CONFIG_VIRTIO_PCI) +=3D virtio-crypto-pci.o diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c new file mode 100644 index 0000000..4570e19 --- /dev/null +++ b/hw/virtio/virtio-iommu.c @@ -0,0 +1,248 @@ +/* + * 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 "qapi-event.h" +#include "trace.h" + +#include "standard-headers/linux/virtio_ids.h" +#include + +#include "hw/virtio/virtio-bus.h" +#include "hw/virtio/virtio-access.h" +#include "hw/virtio/virtio-iommu.h" + +/* Max size */ +#define VIOMMU_DEFAULT_QUEUE_SIZE 256 + +static int virtio_iommu_handle_attach(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return -ENOENT; +} +static int virtio_iommu_handle_detach(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return -ENOENT; +} +static int virtio_iommu_handle_map(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return -ENOENT; +} +static int virtio_iommu_handle_unmap(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return -ENOENT; +} + +static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIOIOMMU *s =3D VIRTIO_IOMMU(vdev); + VirtQueueElement *elem; + struct virtio_iommu_req_head head; + struct virtio_iommu_req_tail tail; + unsigned int iov_cnt; + struct iovec *iov; + size_t sz; + + for (;;) { + elem =3D virtqueue_pop(vq, sizeof(VirtQueueElement)); + if (!elem) { + return; + } + + if (iov_size(elem->in_sg, elem->in_num) < sizeof(tail) || + iov_size(elem->out_sg, elem->out_num) < sizeof(head)) { + virtio_error(vdev, "virtio-iommu erroneous head or tail"); + virtqueue_detach_element(vq, elem, 0); + g_free(elem); + break; + } + + iov_cnt =3D elem->out_num; + iov =3D g_memdup(elem->out_sg, sizeof(struct iovec) * elem->out_nu= m); + sz =3D iov_to_buf(iov, iov_cnt, 0, &head, sizeof(head)); + if (sz !=3D sizeof(head)) { + tail.status =3D VIRTIO_IOMMU_S_UNSUPP; + } + qemu_mutex_lock(&s->mutex); + switch (head.type) { + case VIRTIO_IOMMU_T_ATTACH: + tail.status =3D virtio_iommu_handle_attach(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_DETACH: + tail.status =3D virtio_iommu_handle_detach(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_MAP: + tail.status =3D virtio_iommu_handle_map(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_UNMAP: + tail.status =3D virtio_iommu_handle_unmap(s, iov, iov_cnt); + break; + default: + tail.status =3D VIRTIO_IOMMU_S_UNSUPP; + } + qemu_mutex_unlock(&s->mutex); + + sz =3D iov_from_buf(elem->in_sg, elem->in_num, 0, + &tail, sizeof(tail)); + assert(sz =3D=3D sizeof(tail)); + + virtqueue_push(vq, elem, sizeof(tail)); + virtio_notify(vdev, vq); + g_free(elem); + } +} + +static void virtio_iommu_get_config(VirtIODevice *vdev, uint8_t *config_da= ta) +{ + VirtIOIOMMU *dev =3D VIRTIO_IOMMU(vdev); + + memcpy(config_data, &dev->config, sizeof(struct virtio_iommu_config)); +} + +static void virtio_iommu_set_config(VirtIODevice *vdev, + const uint8_t *config_data) +{ + VirtIOIOMMU *dev =3D VIRTIO_IOMMU(vdev); + struct virtio_iommu_config config; + + memcpy(&config, config_data, sizeof(struct virtio_iommu_config)); + + dev->config.page_sizes =3D le64_to_cpu(config.page_sizes); + dev->config.input_range.end =3D le64_to_cpu(config.input_range.end); +} + +static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f, + Error **errp) +{ + VirtIOIOMMU *dev =3D VIRTIO_IOMMU(vdev); + f |=3D dev->host_features; + virtio_add_feature(&f, VIRTIO_RING_F_EVENT_IDX); + virtio_add_feature(&f, VIRTIO_RING_F_INDIRECT_DESC); + virtio_add_feature(&f, VIRTIO_IOMMU_F_INPUT_RANGE); + virtio_add_feature(&f, VIRTIO_IOMMU_F_MAP_UNMAP); + return f; +} + +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->vq =3D virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, + virtio_iommu_handle_command); + + s->config.page_sizes =3D TARGET_PAGE_MASK; + s->config.input_range.end =3D -1UL; +} + +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) +{ +} + +static void virtio_iommu_set_status(VirtIODevice *vdev, uint8_t 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_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_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 0000000..6716cdb --- /dev/null +++ b/include/hw/virtio/virtio-iommu.h @@ -0,0 +1,59 @@ +/* + * 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 *vq; + struct virtio_iommu_config config; + uint32_t host_features; + GHashTable *as_by_busptr; + IOMMUPciBus *as_by_bus_num[IOMMU_PCI_BUS_MAX]; + GTree *address_spaces; + QemuMutex mutex; + GTree *devices; +} VirtIOIOMMU; + +#endif --=20 2.5.5 From nobody Sun Apr 28 01:58:32 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1501580349392676.6746696361705; Tue, 1 Aug 2017 02:39:09 -0700 (PDT) Received: from localhost ([::1]:41404 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTdr-0002Kn-WE for importer@patchew.org; Tue, 01 Aug 2017 05:39:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38268) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTZs-0007jh-LU for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dcTZr-0001vI-A3 for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49715) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dcTZm-0001pu-6c; Tue, 01 Aug 2017 05:34:54 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 149DB166A68; Tue, 1 Aug 2017 09:34:53 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-181.ams2.redhat.com [10.36.116.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2EEF36047A; Tue, 1 Aug 2017 09:34:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 149DB166A68 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org, jean-philippe.brucker@arm.com Date: Tue, 1 Aug 2017 11:33:10 +0200 Message-Id: <1501579994-3320-5-git-send-email-eric.auger@redhat.com> In-Reply-To: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> References: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 01 Aug 2017 09:34:53 +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 v3 4/8] 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: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, peterx@redhat.com, bharat.bhushan@nxp.com, christoffer.dall@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 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 --- hw/virtio/trace-events | 7 ++++ hw/virtio/virtio-iommu.c | 97 ++++++++++++++++++++++++++++++++++++++++++++= ++-- 2 files changed, 100 insertions(+), 4 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index e24d8fa..fba1da6 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -25,3 +25,10 @@ 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: %"PRIx64" num_pages: %d" + +# hw/virtio/virtio-iommu.c +# +virtio_iommu_attach(uint32_t as, uint32_t dev, uint32_t flags) "as=3D%d de= v=3D%d flags=3D%d" +virtio_iommu_detach(uint32_t dev, uint32_t flags) "dev=3D%d flags=3D%d" +virtio_iommu_map(uint32_t as, uint64_t phys_addr, uint64_t virt_addr, uint= 64_t size, uint32_t flags) "as=3D %d phys_addr=3D0x%"PRIx64" virt_addr=3D0x= %"PRIx64" size=3D0x%"PRIx64" flags=3D%d" +virtio_iommu_unmap(uint32_t as, uint64_t virt_addr, uint64_t size, uint32_= t reserved) "as=3D %d virt_addr=3D0x%"PRIx64" size=3D0x%"PRIx64" reserved= =3D%d" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 4570e19..6f5b71c 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -35,29 +35,118 @@ /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 =20 +static int virtio_iommu_attach(VirtIOIOMMU *s, + struct virtio_iommu_req_attach *req) +{ + uint32_t asid =3D le32_to_cpu(req->address_space); + uint32_t devid =3D le32_to_cpu(req->device); + uint32_t reserved =3D le32_to_cpu(req->reserved); + + trace_virtio_iommu_attach(asid, devid, reserved); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_detach(VirtIOIOMMU *s, + struct virtio_iommu_req_detach *req) +{ + uint32_t devid =3D le32_to_cpu(req->device); + uint32_t reserved =3D le32_to_cpu(req->reserved); + + trace_virtio_iommu_detach(devid, reserved); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_map(VirtIOIOMMU *s, + struct virtio_iommu_req_map *req) +{ + uint32_t asid =3D le32_to_cpu(req->address_space); + uint64_t phys_addr =3D le64_to_cpu(req->phys_addr); + uint64_t virt_addr =3D le64_to_cpu(req->virt_addr); + uint64_t size =3D le64_to_cpu(req->size); + uint32_t flags =3D le32_to_cpu(req->flags); + + trace_virtio_iommu_map(asid, phys_addr, virt_addr, size, flags); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_unmap(VirtIOIOMMU *s, + struct virtio_iommu_req_unmap *req) +{ + uint32_t asid =3D le32_to_cpu(req->address_space); + uint64_t virt_addr =3D le64_to_cpu(req->virt_addr); + uint64_t size =3D le64_to_cpu(req->size); + uint32_t flags =3D le32_to_cpu(req->flags); + + trace_virtio_iommu_unmap(asid, virt_addr, size, flags); + + 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.5.5 From nobody Sun Apr 28 01:58:32 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150158036682096.38430216607833; Tue, 1 Aug 2017 02:39:26 -0700 (PDT) Received: from localhost ([::1]:41405 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTe9-0002YA-GQ for importer@patchew.org; Tue, 01 Aug 2017 05:39:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38294) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTZy-0007oS-Ql for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dcTZv-00022T-HF for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:06 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44734) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dcTZq-0001tV-8a; Tue, 01 Aug 2017 05:34:58 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1B13C12E52C; Tue, 1 Aug 2017 09:34:57 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-181.ams2.redhat.com [10.36.116.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6AB556047A; Tue, 1 Aug 2017 09:34:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 1B13C12E52C Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org, jean-philippe.brucker@arm.com Date: Tue, 1 Aug 2017 11:33:11 +0200 Message-Id: <1501579994-3320-6-git-send-email-eric.auger@redhat.com> In-Reply-To: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> References: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 01 Aug 2017 09:34: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 v3 5/8] 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: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, peterx@redhat.com, bharat.bhushan@nxp.com, christoffer.dall@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 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 at that stage. Signed-off-by: Eric Auger --- 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 | 1 + hw/virtio/virtio-iommu.c | 117 +++++++++++++++++++++++++++++++++++= ++++ include/hw/virtio/virtio-iommu.h | 2 + 3 files changed, 120 insertions(+) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index fba1da6..341dbdf 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -32,3 +32,4 @@ virtio_iommu_attach(uint32_t as, uint32_t dev, uint32_t f= lags) "as=3D%d dev=3D%d fla virtio_iommu_detach(uint32_t dev, uint32_t flags) "dev=3D%d flags=3D%d" virtio_iommu_map(uint32_t as, uint64_t phys_addr, uint64_t virt_addr, uint= 64_t size, uint32_t flags) "as=3D %d phys_addr=3D0x%"PRIx64" virt_addr=3D0x= %"PRIx64" size=3D0x%"PRIx64" flags=3D%d" virtio_iommu_unmap(uint32_t as, uint64_t virt_addr, uint64_t size, uint32_= t reserved) "as=3D %d virt_addr=3D0x%"PRIx64" size=3D0x%"PRIx64" reserved= =3D%d" +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" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 6f5b71c..e663d9e 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -23,6 +23,7 @@ #include "hw/virtio/virtio.h" #include "sysemu/kvm.h" #include "qapi-event.h" +#include "qemu/error-report.h" #include "trace.h" =20 #include "standard-headers/linux/virtio_ids.h" @@ -35,6 +36,64 @@ /* 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; + uintptr_t key =3D (uintptr_t)bus; + IOMMUPciBus *sbus =3D g_hash_table_lookup(s->as_by_busptr, &key); + IOMMUDevice *sdev; + + if (!sbus) { + uintptr_t *new_key =3D g_malloc(sizeof(*new_key)); + + *new_key =3D (uintptr_t)bus; + sbus =3D g_malloc0(sizeof(IOMMUPciBus) + + sizeof(IOMMUDevice *) * IOMMU_PCI_DEVFN_MAX); + sbus->bus =3D bus; + g_hash_table_insert(s->as_by_busptr, new_key, 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; + + 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 void virtio_iommu_init_as(VirtIOIOMMU *s) +{ + PCIBus *pcibus =3D pci_find_primary_bus(); + + if (pcibus) { + pci_setup_iommu(pcibus, virtio_iommu_find_add_as, s); + } else { + error_report("No PCI bus, virtio-iommu is not registered"); + } +} + + static int virtio_iommu_attach(VirtIOIOMMU *s, struct virtio_iommu_req_attach *req) { @@ -208,6 +267,26 @@ static void virtio_iommu_handle_command(VirtIODevice *= vdev, VirtQueue *vq) } } =20 +static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr = addr, + IOMMUAccessFlags flag) +{ + 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); @@ -254,6 +333,21 @@ static const VMStateDescription vmstate_virtio_iommu_d= evice =3D { }, }; =20 +/***************************** + * Hash Table + *****************************/ + +static inline gboolean as_uint64_equal(gconstpointer v1, gconstpointer v2) +{ + return *((const uint64_t *)v1) =3D=3D *((const uint64_t *)v2); +} + +static inline guint as_uint64_hash(gconstpointer v) +{ + return (guint)*(const uint64_t *)v; +} + + static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); @@ -267,6 +361,13 @@ static void virtio_iommu_device_realize(DeviceState *d= ev, Error **errp) =20 s->config.page_sizes =3D TARGET_PAGE_MASK; s->config.input_range.end =3D -1UL; + + memset(s->as_by_bus_num, 0, sizeof(s->as_by_bus_num)); + s->as_by_busptr =3D g_hash_table_new_full(as_uint64_hash, + as_uint64_equal, + g_free, g_free); + + virtio_iommu_init_as(s); } =20 static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp) @@ -321,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, @@ -329,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 6716cdb..f9c988f 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.5.5 From nobody Sun Apr 28 01:58:32 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1501580410469371.74688944313584; Tue, 1 Aug 2017 02:40:10 -0700 (PDT) Received: from localhost ([::1]:41406 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTeq-000360-Vu for importer@patchew.org; Tue, 01 Aug 2017 05:40:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38409) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTa9-00081X-0l for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dcTa5-0002Nl-Na for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44898) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dcTZw-00022g-6s; Tue, 01 Aug 2017 05:35:04 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E49F910D9C6; Tue, 1 Aug 2017 09:35:02 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-181.ams2.redhat.com [10.36.116.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6F9966047A; Tue, 1 Aug 2017 09:34:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com E49F910D9C6 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org, jean-philippe.brucker@arm.com Date: Tue, 1 Aug 2017 11:33:12 +0200 Message-Id: <1501579994-3320-7-git-send-email-eric.auger@redhat.com> In-Reply-To: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> References: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 01 Aug 2017 09:35: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 v3 6/8] virtio-iommu: Implement the translation and commands 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: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, peterx@redhat.com, bharat.bhushan@nxp.com, christoffer.dall@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch adds the actual implementation for the translation routine and the virtio-iommu commands. Signed-off-by: Eric Auger --- v2 -> v3: - init the mutex - return VIRTIO_IOMMU_S_INVAL is reserved field is not null on attach/detach commands - on attach, when the device is already attached to an address space, detach it first instead of returning an error - remove nr_devices and use g_tree_ref/unref to destroy the as->mappings on last device detach - map/unmap: return NOENT instead of INVAL error if as does not exist - remove flags argument from attach/detach trace functions v1 -> v2: - fix compilation issue reported by autobuild system --- hw/virtio/trace-events | 10 +- hw/virtio/virtio-iommu.c | 232 +++++++++++++++++++++++++++++++++++++++++++= ++-- 2 files changed, 232 insertions(+), 10 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 341dbdf..8db3d91 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -28,8 +28,14 @@ virtio_balloon_to_target(uint64_t target, uint32_t num_p= ages) "balloon target: % =20 # hw/virtio/virtio-iommu.c # -virtio_iommu_attach(uint32_t as, uint32_t dev, uint32_t flags) "as=3D%d de= v=3D%d flags=3D%d" -virtio_iommu_detach(uint32_t dev, uint32_t flags) "dev=3D%d flags=3D%d" +virtio_iommu_attach(uint32_t as, uint32_t dev) "as=3D%d dev=3D%d" +virtio_iommu_detach(uint32_t dev) "dev=3D%d" virtio_iommu_map(uint32_t as, uint64_t phys_addr, uint64_t virt_addr, uint= 64_t size, uint32_t flags) "as=3D %d phys_addr=3D0x%"PRIx64" virt_addr=3D0x= %"PRIx64" size=3D0x%"PRIx64" flags=3D%d" virtio_iommu_unmap(uint32_t as, uint64_t virt_addr, uint64_t size, uint32_= t reserved) "as=3D %d virt_addr=3D0x%"PRIx64" size=3D0x%"PRIx64" reserved= =3D%d" 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_new_asid(uint32_t asid) "Allocate a new asid=3D%d" +virtio_iommu_new_devid(uint32_t devid) "Allocate a new devid=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_result(uint64_t virt_addr, uint64_t phys_addr, uint= 32_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 e663d9e..9217587 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -32,10 +32,36 @@ #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_as viommu_as; + +typedef struct viommu_mapping { + uint64_t virt_addr; + uint64_t phys_addr; + uint64_t size; + uint32_t flags; +} viommu_mapping; + +typedef struct viommu_interval { + uint64_t low; + uint64_t high; +} viommu_interval; + +typedef struct viommu_dev { + uint32_t id; + viommu_as *as; +} viommu_dev; + +struct viommu_as { + uint32_t id; + GTree *mappings; +}; + static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) { return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); @@ -93,6 +119,29 @@ static void virtio_iommu_init_as(VirtIOIOMMU *s) } } =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_dev(VirtIOIOMMU *s, viommu_dev *dev) +{ + viommu_as *as =3D dev->as; + + trace_virtio_iommu_detach(dev->id); + + g_tree_remove(s->devices, GUINT_TO_POINTER(dev->id)); + g_tree_unref(as->mappings); +} =20 static int virtio_iommu_attach(VirtIOIOMMU *s, struct virtio_iommu_req_attach *req) @@ -100,10 +149,42 @@ static int virtio_iommu_attach(VirtIOIOMMU *s, uint32_t asid =3D le32_to_cpu(req->address_space); uint32_t devid =3D le32_to_cpu(req->device); uint32_t reserved =3D le32_to_cpu(req->reserved); + viommu_as *as; + viommu_dev *dev; + + trace_virtio_iommu_attach(asid, devid); + + if (reserved) { + return VIRTIO_IOMMU_S_INVAL; + } + + dev =3D g_tree_lookup(s->devices, GUINT_TO_POINTER(devid)); + if (dev) { + /* + * the device is already attached to an address space, + * detach it first + */ + virtio_iommu_detach_dev(s, dev); + } =20 - trace_virtio_iommu_attach(asid, devid, reserved); + as =3D g_tree_lookup(s->address_spaces, GUINT_TO_POINTER(asid)); + if (!as) { + as =3D g_malloc0(sizeof(*as)); + as->id =3D asid; + as->mappings =3D g_tree_new_full((GCompareDataFunc)interval_cmp, + NULL, NULL, (GDestroyNotify)g_fre= e); + g_tree_insert(s->address_spaces, GUINT_TO_POINTER(asid), as); + trace_virtio_iommu_new_asid(asid); + } =20 - return VIRTIO_IOMMU_S_UNSUPP; + dev =3D g_malloc0(sizeof(*dev)); + dev->as =3D as; + dev->id =3D devid; + trace_virtio_iommu_new_devid(devid); + g_tree_insert(s->devices, GUINT_TO_POINTER(devid), dev); + g_tree_ref(as->mappings); + + return VIRTIO_IOMMU_S_OK; } =20 static int virtio_iommu_detach(VirtIOIOMMU *s, @@ -111,10 +192,20 @@ static int virtio_iommu_detach(VirtIOIOMMU *s, { uint32_t devid =3D le32_to_cpu(req->device); uint32_t reserved =3D le32_to_cpu(req->reserved); + viommu_dev *dev; + + if (reserved) { + return VIRTIO_IOMMU_S_INVAL; + } + + dev =3D g_tree_lookup(s->devices, GUINT_TO_POINTER(devid)); + if (!dev) { + return VIRTIO_IOMMU_S_INVAL; + } =20 - trace_virtio_iommu_detach(devid, reserved); + virtio_iommu_detach_dev(s, dev); =20 - return VIRTIO_IOMMU_S_UNSUPP; + return VIRTIO_IOMMU_S_OK; } =20 static int virtio_iommu_map(VirtIOIOMMU *s, @@ -125,10 +216,37 @@ static int virtio_iommu_map(VirtIOIOMMU *s, uint64_t virt_addr =3D le64_to_cpu(req->virt_addr); uint64_t size =3D le64_to_cpu(req->size); uint32_t flags =3D le32_to_cpu(req->flags); + viommu_as *as; + viommu_interval *interval; + viommu_mapping *mapping; + + interval =3D g_malloc0(sizeof(*interval)); + + interval->low =3D virt_addr; + interval->high =3D virt_addr + size - 1; + + as =3D g_tree_lookup(s->address_spaces, GUINT_TO_POINTER(asid)); + if (!as) { + return VIRTIO_IOMMU_S_NOENT; + } + + mapping =3D g_tree_lookup(as->mappings, (gpointer)interval); + if (mapping) { + g_free(interval); + return VIRTIO_IOMMU_S_INVAL; + } =20 trace_virtio_iommu_map(asid, phys_addr, virt_addr, size, flags); =20 - return VIRTIO_IOMMU_S_UNSUPP; + mapping =3D g_malloc0(sizeof(*mapping)); + mapping->virt_addr =3D virt_addr; + mapping->phys_addr =3D phys_addr; + mapping->size =3D size; + mapping->flags =3D flags; + + g_tree_insert(as->mappings, interval, mapping); + + return VIRTIO_IOMMU_S_OK; } =20 static int virtio_iommu_unmap(VirtIOIOMMU *s, @@ -138,10 +256,64 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s, uint64_t virt_addr =3D le64_to_cpu(req->virt_addr); uint64_t size =3D le64_to_cpu(req->size); uint32_t flags =3D le32_to_cpu(req->flags); + viommu_mapping *mapping; + viommu_interval interval; + viommu_as *as; =20 trace_virtio_iommu_unmap(asid, virt_addr, size, flags); =20 - return VIRTIO_IOMMU_S_UNSUPP; + as =3D g_tree_lookup(s->address_spaces, GUINT_TO_POINTER(asid)); + if (!as) { + error_report("%s: no as", __func__); + return VIRTIO_IOMMU_S_NOENT; + } + interval.low =3D virt_addr; + interval.high =3D virt_addr + size - 1; + + mapping =3D g_tree_lookup(as->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(as->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(as->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(as->mappings, (gpointer)¤t); + } else { + break; + } + if (interval.low >=3D interval.high) { + return VIRTIO_IOMMU_S_OK; + } else { + mapping =3D g_tree_lookup(as->mappings, (gpointer)&interval); + } + } + + if (mapping) { + error_report("****** %s: Unmap 0x%"PRIx64" size=3D0x%"PRIx64 + " from 0x%"PRIx64" size=3D0x%"PRIx64" is not supporte= d", + __func__, interval.low, size, + mapping->virt_addr, mapping->size); + } else { + error_report("****** %s: no mapping for [0x%"PRIx64",0x%"PRIx64"]", + __func__, interval.low, interval.high); + } + + return VIRTIO_IOMMU_S_INVAL; } =20 #define get_payload_size(req) (\ @@ -271,19 +443,46 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemo= ryRegion *mr, hwaddr addr, IOMMUAccessFlags flag) { IOMMUDevice *sdev =3D container_of(mr, IOMMUDevice, iommu_mr); + VirtIOIOMMU *s =3D sdev->viommu; uint32_t sid; + viommu_dev *dev; + viommu_mapping *mapping; + viommu_interval interval; + + 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, - .perm =3D IOMMU_NONE, + .addr_mask =3D (1 << 12) - 1, /* TODO */ + .perm =3D 3, }; =20 sid =3D virtio_iommu_get_sid(sdev); =20 trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag); + qemu_mutex_lock(&s->mutex); + + dev =3D g_tree_lookup(s->devices, GUINT_TO_POINTER(sid)); + if (!dev) { + /* device cannot be attached to another as */ + printf("%s sid=3D%d is not known!!\n", __func__, sid); + goto unlock; + } + + mapping =3D g_tree_lookup(dev->as->mappings, (gpointer)&interval); + if (!mapping) { + printf("%s no mapping for 0x%"PRIx64" for sid=3D%d\n", __func__, + addr, sid); + goto unlock; + } + entry.translated_addr =3D addr - mapping->virt_addr + mapping->phys_ad= dr, + trace_virtio_iommu_translate_result(addr, entry.translated_addr, sid); + +unlock: + qemu_mutex_unlock(&s->mutex); return entry; } =20 @@ -347,6 +546,12 @@ static inline guint as_uint64_hash(gconstpointer v) return (guint)*(const uint64_t *)v; } =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); +} =20 static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) { @@ -362,17 +567,28 @@ static void virtio_iommu_device_realize(DeviceState *= dev, Error **errp) s->config.page_sizes =3D TARGET_PAGE_MASK; s->config.input_range.end =3D -1UL; =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_full(as_uint64_hash, as_uint64_equal, g_free, g_free); =20 + s->address_spaces =3D g_tree_new_full((GCompareDataFunc)int_cmp, + NULL, NULL, (GDestroyNotify)g_fre= e); + s->devices =3D g_tree_new_full((GCompareDataFunc)int_cmp, + NULL, NULL, (GDestroyNotify)g_fre= e); + virtio_iommu_init_as(s); } =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->address_spaces); + g_tree_destroy(s->devices); =20 virtio_cleanup(vdev); } --=20 2.5.5 From nobody Sun Apr 28 01:58:32 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1501580507334592.9970084650698; Tue, 1 Aug 2017 02:41:47 -0700 (PDT) Received: from localhost ([::1]:41419 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTgP-0004OG-S5 for importer@patchew.org; Tue, 01 Aug 2017 05:41:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38534) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTaH-0008BC-I4 for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dcTaE-0002aF-AK for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52312) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dcTaC-0002Vz-3o; Tue, 01 Aug 2017 05:35:20 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 72CFC2861C8; Tue, 1 Aug 2017 09:35:18 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-181.ams2.redhat.com [10.36.116.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3F6C36017B; Tue, 1 Aug 2017 09:35:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 72CFC2861C8 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org, jean-philippe.brucker@arm.com Date: Tue, 1 Aug 2017 11:33:13 +0200 Message-Id: <1501579994-3320-8-git-send-email-eric.auger@redhat.com> In-Reply-To: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> References: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Tue, 01 Aug 2017 09:35:19 +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 v3 7/8] hw/arm/virt: Add 2.10 machine type 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: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, peterx@redhat.com, bharat.bhushan@nxp.com, christoffer.dall@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The new machine type allows virtio-iommu instantiation. Signed-off-by: Eric Auger --- a Veuillez saisir le message de validation pour vos modifications. Les lign= es --- hw/arm/virt.c | 24 ++++++++++++++++++++++-- include/hw/arm/virt.h | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 31739d7..93c4ab2 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1639,7 +1639,7 @@ static void machvirt_machine_init(void) } type_init(machvirt_machine_init); =20 -static void virt_2_9_instance_init(Object *obj) +static void virt_2_10_instance_init(Object *obj) { VirtMachineState *vms =3D VIRT_MACHINE(obj); VirtMachineClass *vmc =3D VIRT_MACHINE_GET_CLASS(vms); @@ -1699,10 +1699,30 @@ static void virt_2_9_instance_init(Object *obj) vms->irqmap =3D a15irqmap; } =20 +static void virt_machine_2_10_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(2, 10) + +#define VIRT_COMPAT_2_9 \ + HW_COMPAT_2_9 + +static void virt_2_9_instance_init(Object *obj) +{ + virt_2_10_instance_init(obj); +} + static void virt_machine_2_9_options(MachineClass *mc) { + VirtMachineClass *vmc =3D VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); + + virt_machine_2_10_options(mc); + SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_9); + + vmc->no_iommu =3D true; } -DEFINE_VIRT_MACHINE_AS_LATEST(2, 9) +DEFINE_VIRT_MACHINE(2, 9) + =20 #define VIRT_COMPAT_2_8 \ HW_COMPAT_2_8 diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 33b0ff3..ff27551 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -84,6 +84,7 @@ typedef struct { bool disallow_affinity_adjustment; bool no_its; bool no_pmu; + bool no_iommu; bool claim_edge_triggered_timers; } VirtMachineClass; =20 --=20 2.5.5 From nobody Sun Apr 28 01:58:32 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1501580489098891.5845265839122; Tue, 1 Aug 2017 02:41:29 -0700 (PDT) Received: from localhost ([::1]:41418 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTg7-000482-Bs for importer@patchew.org; Tue, 01 Aug 2017 05:41:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38561) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dcTaO-0008Gc-VD for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dcTaJ-0002hv-61 for qemu-devel@nongnu.org; Tue, 01 Aug 2017 05:35:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49012) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dcTaF-0002bV-Lg; Tue, 01 Aug 2017 05:35:23 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 908B9169366; Tue, 1 Aug 2017 09:35:22 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-181.ams2.redhat.com [10.36.116.181]) by smtp.corp.redhat.com (Postfix) with ESMTP id C896D60176; Tue, 1 Aug 2017 09:35:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 908B9169366 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org, jean-philippe.brucker@arm.com Date: Tue, 1 Aug 2017 11:33:14 +0200 Message-Id: <1501579994-3320-9-git-send-email-eric.auger@redhat.com> In-Reply-To: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> References: <1501579994-3320-1-git-send-email-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 01 Aug 2017 09:35:22 +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 v3 8/8] hw/arm/virt: Add virtio-iommu the virt board X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, peterx@redhat.com, bharat.bhushan@nxp.com, christoffer.dall@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The specific virtio-mmio node is inconditionally added on machine init while the binding between this latter and the PCIe host bridge is done on machine init done notifier, only if -device virtio-iommu-device was added to the qemu command line. Signed-off-by: Eric Auger --- --- hw/arm/virt.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++= ---- include/hw/arm/virt.h | 4 +++ 2 files changed, 89 insertions(+), 7 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 93c4ab2..9509399 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -52,6 +52,7 @@ #include "hw/arm/fdt.h" #include "hw/intc/arm_gic.h" #include "hw/intc/arm_gicv3_common.h" +#include "hw/virtio/virtio-iommu.h" #include "kvm_arm.h" #include "hw/smbios/smbios.h" #include "qapi/visitor.h" @@ -139,6 +140,7 @@ static const MemMapEntry a15memmap[] =3D { [VIRT_FW_CFG] =3D { 0x09020000, 0x00000018 }, [VIRT_GPIO] =3D { 0x09030000, 0x00001000 }, [VIRT_SECURE_UART] =3D { 0x09040000, 0x00001000 }, + [VIRT_SMMU] =3D { 0x09050000, 0x00000200 }, [VIRT_MMIO] =3D { 0x0a000000, 0x00000200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that siz= e */ [VIRT_PLATFORM_BUS] =3D { 0x0c000000, 0x02000000 }, @@ -159,6 +161,7 @@ static const int a15irqmap[] =3D { [VIRT_SECURE_UART] =3D 8, [VIRT_MMIO] =3D 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ [VIRT_GIC_V2M] =3D 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */ + [VIRT_SMMU] =3D 74, [VIRT_PLATFORM_BUS] =3D 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */ }; =20 @@ -991,7 +994,81 @@ static void create_pcie_irq_map(const VirtMachineState= *vms, 0x7 /* PCI irq */); } =20 -static void create_pcie(const VirtMachineState *vms, qemu_irq *pic) +static int bind_virtio_iommu_device(Object *obj, void *opaque) +{ + VirtMachineState *vms =3D (VirtMachineState *)opaque; + struct arm_boot_info *info =3D &vms->bootinfo; + int dtb_size; + void *fdt =3D info->get_dtb(info, &dtb_size); + Object *dev; + + dev =3D object_dynamic_cast(obj, TYPE_VIRTIO_IOMMU); + + if (!dev) { + /* Container, traverse it for children */ + return object_child_foreach(obj, bind_virtio_iommu_device, opaque); + } + + qemu_fdt_setprop_cells(fdt, vms->pcie_host_nodename, "iommu-map", + 0x0, vms->smmu_phandle, 0x0, 0x10000); + + return true; +} + +static +void virtio_iommu_notifier(Notifier *notifier, void *data) +{ + VirtMachineState *vms =3D container_of(notifier, VirtMachineState, + virtio_iommu_done); + VirtMachineClass *vmc =3D VIRT_MACHINE_GET_CLASS(vms); + Object *container; + + + if (vmc->no_iommu) { + return; + } + + container =3D container_get(qdev_get_machine(), "/peripheral"); + bind_virtio_iommu_device(container, vms); + container =3D container_get(qdev_get_machine(), "/peripheral-anon"); + bind_virtio_iommu_device(container, vms); +} + +static void create_virtio_iommu(VirtMachineState *vms, qemu_irq *pic) +{ + char *smmu; + const char compat[] =3D "virtio,mmio"; + int irq =3D vms->irqmap[VIRT_SMMU]; + hwaddr base =3D vms->memmap[VIRT_SMMU].base; + hwaddr size =3D vms->memmap[VIRT_SMMU].size; + VirtMachineClass *vmc =3D VIRT_MACHINE_GET_CLASS(vms); + + if (vmc->no_iommu) { + return; + } + + vms->smmu_phandle =3D qemu_fdt_alloc_phandle(vms->fdt); + + sysbus_create_simple("virtio-mmio", base, pic[irq]); + + smmu =3D g_strdup_printf("/virtio_mmio@%" PRIx64, base); + qemu_fdt_add_subnode(vms->fdt, smmu); + qemu_fdt_setprop(vms->fdt, smmu, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop_sized_cells(vms->fdt, smmu, "reg", 2, base, 2, size); + + qemu_fdt_setprop_cells(vms->fdt, smmu, "interrupts", + GIC_FDT_IRQ_TYPE_SPI, irq, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI); + + qemu_fdt_setprop(vms->fdt, smmu, "dma-coherent", NULL, 0); + qemu_fdt_setprop_cell(vms->fdt, smmu, "#iommu-cells", 1); + qemu_fdt_setprop_cell(vms->fdt, smmu, "phandle", vms->smmu_phandle); + g_free(smmu); + + vms->virtio_iommu_done.notify =3D virtio_iommu_notifier; + qemu_add_machine_init_done_notifier(&vms->virtio_iommu_done); +} + +static void create_pcie(VirtMachineState *vms, qemu_irq *pic) { hwaddr base_mmio =3D vms->memmap[VIRT_PCIE_MMIO].base; hwaddr size_mmio =3D vms->memmap[VIRT_PCIE_MMIO].size; @@ -1064,7 +1141,8 @@ static void create_pcie(const VirtMachineState *vms, = qemu_irq *pic) } } =20 - nodename =3D g_strdup_printf("/pcie@%" PRIx64, base); + vms->pcie_host_nodename =3D g_strdup_printf("/pcie@%" PRIx64, base); + nodename =3D vms->pcie_host_nodename; qemu_fdt_add_subnode(vms->fdt, nodename); qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "pci-host-ecam-generic"); @@ -1103,7 +1181,6 @@ static void create_pcie(const VirtMachineState *vms, = qemu_irq *pic) qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 1); create_pcie_irq_map(vms, vms->gic_phandle, irq, nodename); =20 - g_free(nodename); } =20 static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic) @@ -1448,16 +1525,16 @@ static void machvirt_init(MachineState *machine) =20 create_rtc(vms, pic); =20 - create_pcie(vms, pic); - - create_gpio(vms, pic); - /* Create mmio transports, so the user can create virtio backends * (which will be automatically plugged in to the transports). If * no backend is created the transport will just sit harmlessly idle. */ create_virtio_devices(vms, pic); =20 + create_pcie(vms, pic); + + create_gpio(vms, pic); + vms->fw_cfg =3D create_fw_cfg(vms, &address_space_memory); rom_set_fw(vms->fw_cfg); =20 @@ -1482,6 +1559,7 @@ static void machvirt_init(MachineState *machine) * Notifiers are executed in registration reverse order. */ create_platform_bus(vms, pic); + create_virtio_iommu(vms, pic); } =20 static bool virt_get_secure(Object *obj, Error **errp) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index ff27551..070cb39 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -59,6 +59,7 @@ enum { VIRT_GIC_V2M, VIRT_GIC_ITS, VIRT_GIC_REDIST, + VIRT_SMMU, VIRT_UART, VIRT_MMIO, VIRT_RTC, @@ -91,6 +92,7 @@ typedef struct { typedef struct { MachineState parent; Notifier machine_done; + Notifier virtio_iommu_done; FWCfgState *fw_cfg; bool secure; bool highmem; @@ -106,6 +108,8 @@ typedef struct { uint32_t clock_phandle; uint32_t gic_phandle; uint32_t msi_phandle; + uint32_t smmu_phandle; + char *pcie_host_nodename; int psci_conduit; } VirtMachineState; =20 --=20 2.5.5