From nobody Wed Nov 5 15:38:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.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 1496851667186858.6500120691974; Wed, 7 Jun 2017 09:07:47 -0700 (PDT) Received: from localhost ([::1]:44953 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdUn-0003V1-KZ for importer@patchew.org; Wed, 07 Jun 2017 12:07:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50410) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdP2-0005sq-6J for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:01:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIdP1-0007yj-Ci for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:01:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54410) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIdOz-0007yA-15; Wed, 07 Jun 2017 12:01:45 -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 8CF133D974; Wed, 7 Jun 2017 16:01:43 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id E1FF0189A9; Wed, 7 Jun 2017 16:01:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8CF133D974 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=pass smtp.mailfrom=eric.auger@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8CF133D974 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: Wed, 7 Jun 2017 18:01:20 +0200 Message-Id: <1496851287-9428-2-git-send-email-eric.auger@redhat.com> In-Reply-To: <1496851287-9428-1-git-send-email-eric.auger@redhat.com> References: <1496851287-9428-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]); Wed, 07 Jun 2017 16:01:44 +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 v2 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, bharat.bhushan@nxp.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, robin.murphy@arm.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 Wed Nov 5 15:38:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.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 1496851622763751.3882673713977; Wed, 7 Jun 2017 09:07:02 -0700 (PDT) Received: from localhost ([::1]:44948 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdU5-0002oQ-6W for importer@patchew.org; Wed, 07 Jun 2017 12:07:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50443) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdP9-0005yJ-9q for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:01:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIdP8-0007zz-5r for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:01:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55980) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIdP3-0007z6-2f; Wed, 07 Jun 2017 12:01:49 -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 DF517C04B93B; Wed, 7 Jun 2017 16:01:47 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id E956C7D958; Wed, 7 Jun 2017 16:01:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com DF517C04B93B Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=eric.auger@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com DF517C04B93B 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: Wed, 7 Jun 2017 18:01:21 +0200 Message-Id: <1496851287-9428-3-git-send-email-eric.auger@redhat.com> In-Reply-To: <1496851287-9428-1-git-send-email-eric.auger@redhat.com> References: <1496851287-9428-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.31]); Wed, 07 Jun 2017 16:01:48 +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 v2 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, bharat.bhushan@nxp.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, robin.murphy@arm.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 Wed Nov 5 15:38:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.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 1496851556700922.1252346556262; Wed, 7 Jun 2017 09:05:56 -0700 (PDT) Received: from localhost ([::1]:44942 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdSv-0001o8-Um for importer@patchew.org; Wed, 07 Jun 2017 12:05:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50573) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdPP-0006KE-Du for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIdPJ-000843-U6 for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46914) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIdPE-00082H-7K; Wed, 07 Jun 2017 12:02:00 -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 F060283F3D; Wed, 7 Jun 2017 16:01:58 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 41DEB189A9; Wed, 7 Jun 2017 16:01:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com F060283F3D 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=pass smtp.mailfrom=eric.auger@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com F060283F3D 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: Wed, 7 Jun 2017 18:01:22 +0200 Message-Id: <1496851287-9428-4-git-send-email-eric.auger@redhat.com> In-Reply-To: <1496851287-9428-1-git-send-email-eric.auger@redhat.com> References: <1496851287-9428-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]); Wed, 07 Jun 2017 16:01:59 +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 v2 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, bharat.bhushan@nxp.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, robin.murphy@arm.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 --- hw/virtio/Makefile.objs | 1 + hw/virtio/virtio-iommu.c | 247 +++++++++++++++++++++++++++++++++++= ++++ include/hw/virtio/virtio-iommu.h | 60 ++++++++++ 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..86129ef --- /dev/null +++ b/hw/virtio/virtio-iommu.c @@ -0,0 +1,247 @@ +/* + * 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); + 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 ~((1ULL << 12) - 1); + 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..2259413 --- /dev/null +++ b/include/hw/virtio/virtio-iommu.h @@ -0,0 +1,60 @@ +/* + * 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; + MemoryRegion 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; + MemoryRegionIOMMUOps iommu_ops; + 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 Wed Nov 5 15:38:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.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 1496851900910451.9075379710837; Wed, 7 Jun 2017 09:11:40 -0700 (PDT) Received: from localhost ([::1]:44979 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdYZ-0007PA-6K for importer@patchew.org; Wed, 07 Jun 2017 12:11:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50650) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdPY-0006RJ-CX for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIdPS-000868-0x for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51552) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIdPI-00083T-8X; Wed, 07 Jun 2017 12:02: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 102181766AD; Wed, 7 Jun 2017 16:02:03 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 52B1E5C46E; Wed, 7 Jun 2017 16:01:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 102181766AD 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=pass smtp.mailfrom=eric.auger@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 102181766AD 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: Wed, 7 Jun 2017 18:01:23 +0200 Message-Id: <1496851287-9428-5-git-send-email-eric.auger@redhat.com> In-Reply-To: <1496851287-9428-1-git-send-email-eric.auger@redhat.com> References: <1496851287-9428-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]); Wed, 07 Jun 2017 16:02: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 v2 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, bharat.bhushan@nxp.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, robin.murphy@arm.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 86129ef..ea1caa7 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 Wed Nov 5 15:38:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.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 14968517781188.381714061664638; Wed, 7 Jun 2017 09:09:38 -0700 (PDT) Received: from localhost ([::1]:44960 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdWa-0005af-C6 for importer@patchew.org; Wed, 07 Jun 2017 12:09:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50622) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdPV-0006Pl-Dx for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIdPU-00086Y-6y for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45608) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIdPN-00084j-F4; Wed, 07 Jun 2017 12:02:09 -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 43D2CDC8F4; Wed, 7 Jun 2017 16:02:08 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6646F5C46E; Wed, 7 Jun 2017 16:02:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 43D2CDC8F4 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=eric.auger@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 43D2CDC8F4 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: Wed, 7 Jun 2017 18:01:24 +0200 Message-Id: <1496851287-9428-6-git-send-email-eric.auger@redhat.com> In-Reply-To: <1496851287-9428-1-git-send-email-eric.auger@redhat.com> References: <1496851287-9428-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.38]); Wed, 07 Jun 2017 16:02:08 +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 v2 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, bharat.bhushan@nxp.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, robin.murphy@arm.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 --- hw/virtio/trace-events | 1 + hw/virtio/virtio-iommu.c | 97 ++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 98 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 ea1caa7..902c779 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,59 @@ /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 =20 +static inline uint16_t smmu_get_sid(IOMMUDevice *dev) +{ + return ((pci_bus_num(dev->bus) & 0xff) << 8) | 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) { + 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, OBJECT(s), + &s->iommu_ops, TYPE_VIRTIO_IOMMU, + UINT64_MAX); + address_space_init(&sdev->as, &sdev->iommu_mr, TYPE_VIRTIO_IOMMU); + } + + 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 +262,26 @@ static void virtio_iommu_handle_command(VirtIODevice *= vdev, VirtQueue *vq) } } =20 +static IOMMUTLBEntry virtio_iommu_translate(MemoryRegion *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 smmu_get_sid(sdev); + + trace_virtio_iommu_translate(mr->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); @@ -253,6 +327,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); @@ -266,6 +355,14 @@ static void virtio_iommu_device_realize(DeviceState *d= ev, Error **errp) =20 s->config.page_sizes =3D ~((1ULL << 12) - 1); s->config.input_range.end =3D -1UL; + + s->iommu_ops.translate =3D virtio_iommu_translate; + 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) --=20 2.5.5 From nobody Wed Nov 5 15:38:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.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 149685173623985.15488006680687; Wed, 7 Jun 2017 09:08:56 -0700 (PDT) Received: from localhost ([::1]:44958 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdVu-0004gN-BT for importer@patchew.org; Wed, 07 Jun 2017 12:08:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50760) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdPf-0006ae-7B for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIdPd-00089Q-HC for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52026) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIdPZ-00087o-Fq; Wed, 07 Jun 2017 12:02:21 -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 3CE7A33458E; Wed, 7 Jun 2017 16:02:20 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 98EC55C46E; Wed, 7 Jun 2017 16:02:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3CE7A33458E Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=eric.auger@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3CE7A33458E 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: Wed, 7 Jun 2017 18:01:25 +0200 Message-Id: <1496851287-9428-7-git-send-email-eric.auger@redhat.com> In-Reply-To: <1496851287-9428-1-git-send-email-eric.auger@redhat.com> References: <1496851287-9428-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.29]); Wed, 07 Jun 2017 16:02:20 +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 v2 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, bharat.bhushan@nxp.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, robin.murphy@arm.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 --- v1 -> v2: - fix compilation issue reported by autobuild system --- hw/virtio/trace-events | 6 ++ hw/virtio/virtio-iommu.c | 202 +++++++++++++++++++++++++++++++++++++++++++= ++-- 2 files changed, 202 insertions(+), 6 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 341dbdf..9196b63 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -33,3 +33,9 @@ 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" +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 902c779..cd188fc 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -32,10 +32,37 @@ #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; + uint32_t nr_devices; + GTree *mappings; +}; + static inline uint16_t smmu_get_sid(IOMMUDevice *dev) { return ((pci_bus_num(dev->bus) & 0xff) << 8) | dev->devfn; @@ -88,6 +115,19 @@ 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; + } +} =20 static int virtio_iommu_attach(VirtIOIOMMU *s, struct virtio_iommu_req_attach *req) @@ -95,10 +135,34 @@ 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; =20 trace_virtio_iommu_attach(asid, devid, reserved); =20 - return VIRTIO_IOMMU_S_UNSUPP; + dev =3D g_tree_lookup(s->devices, GUINT_TO_POINTER(devid)); + if (dev) { + return -1; + } + + 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); + } + + dev =3D g_malloc0(sizeof(*dev)); + dev->as =3D as; + dev->id =3D devid; + as->nr_devices++; + trace_virtio_iommu_new_devid(devid); + g_tree_insert(s->devices, GUINT_TO_POINTER(devid), dev); + + return VIRTIO_IOMMU_S_OK; } =20 static int virtio_iommu_detach(VirtIOIOMMU *s, @@ -106,10 +170,13 @@ 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); + int ret; =20 trace_virtio_iommu_detach(devid, reserved); =20 - return VIRTIO_IOMMU_S_UNSUPP; + ret =3D g_tree_remove(s->devices, GUINT_TO_POINTER(devid)); + + return ret ? VIRTIO_IOMMU_S_OK : VIRTIO_IOMMU_S_INVAL; } =20 static int virtio_iommu_map(VirtIOIOMMU *s, @@ -120,10 +187,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_INVAL; + } + + 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, @@ -133,10 +227,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_INVAL; + } + 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) (\ @@ -266,19 +414,46 @@ static IOMMUTLBEntry virtio_iommu_translate(MemoryReg= ion *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 smmu_get_sid(sdev); =20 trace_virtio_iommu_translate(mr->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 @@ -341,6 +516,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,12 +543,21 @@ static void virtio_iommu_device_realize(DeviceState *= dev, Error **errp) 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 Wed Nov 5 15:38:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.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 1496851984356608.8492893407517; Wed, 7 Jun 2017 09:13:04 -0700 (PDT) Received: from localhost ([::1]:44987 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdZt-0000Pa-0L for importer@patchew.org; Wed, 07 Jun 2017 12:13:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50869) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdPm-0006hv-Pv for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIdPm-0008Cw-08 for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56054) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIdPd-00089D-Ff; Wed, 07 Jun 2017 12:02:25 -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 415DB3DBE6; Wed, 7 Jun 2017 16:02:24 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 91E4E7D509; Wed, 7 Jun 2017 16:02:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 415DB3DBE6 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=pass smtp.mailfrom=eric.auger@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 415DB3DBE6 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: Wed, 7 Jun 2017 18:01:26 +0200 Message-Id: <1496851287-9428-8-git-send-email-eric.auger@redhat.com> In-Reply-To: <1496851287-9428-1-git-send-email-eric.auger@redhat.com> References: <1496851287-9428-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]); Wed, 07 Jun 2017 16:02:24 +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 v2 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, bharat.bhushan@nxp.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, robin.murphy@arm.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 010f724..6eb0d2a 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 Wed Nov 5 15:38:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.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 1496852068839210.7342666228825; Wed, 7 Jun 2017 09:14:28 -0700 (PDT) Received: from localhost ([::1]:44992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdbF-0001MW-5v for importer@patchew.org; Wed, 07 Jun 2017 12:14:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50886) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIdPn-0006ip-KE for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIdPm-0008D5-D5 for qemu-devel@nongnu.org; Wed, 07 Jun 2017 12:02:35 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46802) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIdPh-0008AZ-Mb; Wed, 07 Jun 2017 12:02:29 -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 8738DDC8E0; Wed, 7 Jun 2017 16:02:28 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-222.ams2.redhat.com [10.36.116.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 94F74189A9; Wed, 7 Jun 2017 16:02:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8738DDC8E0 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=eric.auger@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8738DDC8E0 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: Wed, 7 Jun 2017 18:01:27 +0200 Message-Id: <1496851287-9428-9-git-send-email-eric.auger@redhat.com> In-Reply-To: <1496851287-9428-1-git-send-email-eric.auger@redhat.com> References: <1496851287-9428-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.38]); Wed, 07 Jun 2017 16:02:28 +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 v2 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, bharat.bhushan@nxp.com, marc.zyngier@arm.com, tn@semihalf.com, will.deacon@arm.com, drjones@redhat.com, robin.murphy@arm.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 6eb0d2a..6bcfbcd 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