From patchwork Tue Jul 30 17:21:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066299 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 053D613B1 for ; Tue, 30 Jul 2019 17:23:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DC1A828848 for ; Tue, 30 Jul 2019 17:23:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CE01428856; Tue, 30 Jul 2019 17:23:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7764228653 for ; Tue, 30 Jul 2019 17:23:00 +0000 (UTC) Received: from localhost ([::1]:34822 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVpz-0000sj-TM for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:22:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60696) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVpR-0007xI-F9 for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVpQ-0000WD-IN for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57540) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVpO-0000Uh-LV; Tue, 30 Jul 2019 13:22:22 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7DFFBC04BD40; Tue, 30 Jul 2019 17:22:21 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id B19E760C62; Tue, 30 Jul 2019 17:21:55 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:23 +0200 Message-Id: <20190730172137.23114-2-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 30 Jul 2019 17:22:21 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 01/15] update-linux-headers: Import virtio_iommu.h X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 f76d77363b..7805291ca0 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -175,6 +175,9 @@ fi cat <$output/linux-headers/linux/virtio_config.h #include "standard-headers/linux/virtio_config.h" EOF +cat <$output/linux-headers/linux/virtio_iommu.h +#include "standard-headers/linux/virtio_iommu.h" +EOF cat <$output/linux-headers/linux/virtio_ring.h #include "standard-headers/linux/virtio_ring.h" EOF From patchwork Tue Jul 30 17:21:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066303 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 51F3C1395 for ; Tue, 30 Jul 2019 17:23:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 33571285FB for ; Tue, 30 Jul 2019 17:23:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2683C1FE84; Tue, 30 Jul 2019 17:23:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.1 required=2.0 tests=BAYES_00,FUZZY_XPILL, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 802A91FE84 for ; Tue, 30 Jul 2019 17:23:26 +0000 (UTC) Received: from localhost ([::1]:34830 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqP-000212-TN for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:23:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60827) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVpf-0008Pp-U2 for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVpc-0000iN-Mq for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54017) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVpU-0000ZK-Ii; Tue, 30 Jul 2019 13:22:28 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 76B5530A884E; Tue, 30 Jul 2019 17:22:27 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id C2E4C60BEC; Tue, 30 Jul 2019 17:22:21 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:24 +0200 Message-Id: <20190730172137.23114-3-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Tue, 30 Jul 2019 17:22:27 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 02/15] linux-headers: update against 5.3-rc2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Sync headers against 5.3-rc2 (commit 2a11c76e5301) Signed-off-by: Eric Auger --- include/standard-headers/asm-x86/bootparam.h | 2 + include/standard-headers/asm-x86/kvm_para.h | 3 + include/standard-headers/linux/ethtool.h | 2 + include/standard-headers/linux/pci_regs.h | 4 + include/standard-headers/linux/virtio_ids.h | 1 + include/standard-headers/linux/virtio_iommu.h | 165 ++++++++++++++++++ include/standard-headers/linux/virtio_pmem.h | 6 +- linux-headers/asm-arm/kvm.h | 12 ++ linux-headers/asm-arm/unistd-common.h | 2 + linux-headers/asm-arm64/kvm.h | 17 ++ linux-headers/asm-generic/mman-common.h | 15 +- linux-headers/asm-generic/mman.h | 10 +- linux-headers/asm-generic/unistd.h | 8 +- linux-headers/asm-mips/unistd_n32.h | 1 + linux-headers/asm-mips/unistd_n64.h | 1 + linux-headers/asm-mips/unistd_o32.h | 1 + linux-headers/asm-powerpc/mman.h | 6 +- linux-headers/asm-powerpc/unistd_32.h | 1 + linux-headers/asm-powerpc/unistd_64.h | 1 + linux-headers/asm-s390/unistd_32.h | 2 + linux-headers/asm-s390/unistd_64.h | 2 + linux-headers/asm-x86/kvm.h | 28 ++- linux-headers/asm-x86/unistd_32.h | 2 + linux-headers/asm-x86/unistd_64.h | 2 + linux-headers/asm-x86/unistd_x32.h | 2 + linux-headers/linux/kvm.h | 11 +- linux-headers/linux/psp-sev.h | 5 +- linux-headers/linux/virtio_iommu.h | 1 + 28 files changed, 278 insertions(+), 35 deletions(-) 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/asm-x86/bootparam.h b/include/standard-headers/asm-x86/bootparam.h index 67d4f0119f..a6f7cf535e 100644 --- a/include/standard-headers/asm-x86/bootparam.h +++ b/include/standard-headers/asm-x86/bootparam.h @@ -29,6 +29,8 @@ #define XLF_EFI_HANDOVER_32 (1<<2) #define XLF_EFI_HANDOVER_64 (1<<3) #define XLF_EFI_KEXEC (1<<4) +#define XLF_5LEVEL (1<<5) +#define XLF_5LEVEL_ENABLED (1<<6) #endif /* _ASM_X86_BOOTPARAM_H */ diff --git a/include/standard-headers/asm-x86/kvm_para.h b/include/standard-headers/asm-x86/kvm_para.h index 35cd8d651f..90604a8fb7 100644 --- a/include/standard-headers/asm-x86/kvm_para.h +++ b/include/standard-headers/asm-x86/kvm_para.h @@ -29,6 +29,8 @@ #define KVM_FEATURE_PV_TLB_FLUSH 9 #define KVM_FEATURE_ASYNC_PF_VMEXIT 10 #define KVM_FEATURE_PV_SEND_IPI 11 +#define KVM_FEATURE_POLL_CONTROL 12 +#define KVM_FEATURE_PV_SCHED_YIELD 13 #define KVM_HINTS_REALTIME 0 @@ -47,6 +49,7 @@ #define MSR_KVM_ASYNC_PF_EN 0x4b564d02 #define MSR_KVM_STEAL_TIME 0x4b564d03 #define MSR_KVM_PV_EOI_EN 0x4b564d04 +#define MSR_KVM_POLL_CONTROL 0x4b564d05 struct kvm_steal_time { uint64_t steal; diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h index 9b9919a8f6..16d0eeea86 100644 --- a/include/standard-headers/linux/ethtool.h +++ b/include/standard-headers/linux/ethtool.h @@ -1483,6 +1483,8 @@ enum ethtool_link_mode_bit_indices { ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT = 64, ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT = 65, ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT = 66, + ETHTOOL_LINK_MODE_100baseT1_Full_BIT = 67, + ETHTOOL_LINK_MODE_1000baseT1_Full_BIT = 68, /* must be last entry */ __ETHTOOL_LINK_MODE_MASK_NBITS diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index 27164769d1..f28e562d7c 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -528,6 +528,7 @@ #define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1 */ #define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003 /* LNKCAP2 SLS Vector bit 2 */ #define PCI_EXP_LNKCAP_SLS_16_0GB 0x00000004 /* LNKCAP2 SLS Vector bit 3 */ +#define PCI_EXP_LNKCAP_SLS_32_0GB 0x00000005 /* LNKCAP2 SLS Vector bit 4 */ #define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ #define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ @@ -556,6 +557,7 @@ #define PCI_EXP_LNKSTA_CLS_5_0GB 0x0002 /* Current Link Speed 5.0GT/s */ #define PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 /* Current Link Speed 8.0GT/s */ #define PCI_EXP_LNKSTA_CLS_16_0GB 0x0004 /* Current Link Speed 16.0GT/s */ +#define PCI_EXP_LNKSTA_CLS_32_0GB 0x0005 /* Current Link Speed 32.0GT/s */ #define PCI_EXP_LNKSTA_NLW 0x03f0 /* Negotiated Link Width */ #define PCI_EXP_LNKSTA_NLW_X1 0x0010 /* Current Link Width x1 */ #define PCI_EXP_LNKSTA_NLW_X2 0x0020 /* Current Link Width x2 */ @@ -661,6 +663,7 @@ #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5GT/s */ #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */ #define PCI_EXP_LNKCAP2_SLS_16_0GB 0x00000010 /* Supported Speed 16GT/s */ +#define PCI_EXP_LNKCAP2_SLS_32_0GB 0x00000020 /* Supported Speed 32GT/s */ #define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100 /* Crosslink supported */ #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ #define PCI_EXP_LNKCTL2_TLS 0x000f @@ -668,6 +671,7 @@ #define PCI_EXP_LNKCTL2_TLS_5_0GT 0x0002 /* Supported Speed 5GT/s */ #define PCI_EXP_LNKCTL2_TLS_8_0GT 0x0003 /* Supported Speed 8GT/s */ #define PCI_EXP_LNKCTL2_TLS_16_0GT 0x0004 /* Supported Speed 16GT/s */ +#define PCI_EXP_LNKCTL2_TLS_32_0GT 0x0005 /* Supported Speed 32GT/s */ #define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52 /* v2 endpoints with link end here */ #define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */ diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h index 32b2f94d1f..348fd0176f 100644 --- a/include/standard-headers/linux/virtio_ids.h +++ b/include/standard-headers/linux/virtio_ids.h @@ -43,6 +43,7 @@ #define VIRTIO_ID_INPUT 18 /* virtio input */ #define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */ #define VIRTIO_ID_CRYPTO 20 /* virtio crypto */ +#define VIRTIO_ID_IOMMU 23 /* virtio IOMMU */ #define VIRTIO_ID_PMEM 27 /* virtio pmem */ #endif /* _LINUX_VIRTIO_IDS_H */ diff --git a/include/standard-headers/linux/virtio_iommu.h b/include/standard-headers/linux/virtio_iommu.h new file mode 100644 index 0000000000..b9443b83a1 --- /dev/null +++ b/include/standard-headers/linux/virtio_iommu.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Virtio-iommu definition v0.12 + * + * Copyright (C) 2019 Arm Ltd. + */ +#ifndef _LINUX_VIRTIO_IOMMU_H +#define _LINUX_VIRTIO_IOMMU_H + +#include "standard-headers/linux/types.h" + +/* Feature bits */ +#define VIRTIO_IOMMU_F_INPUT_RANGE 0 +#define VIRTIO_IOMMU_F_DOMAIN_RANGE 1 +#define VIRTIO_IOMMU_F_MAP_UNMAP 2 +#define VIRTIO_IOMMU_F_BYPASS 3 +#define VIRTIO_IOMMU_F_PROBE 4 +#define VIRTIO_IOMMU_F_MMIO 5 + +struct virtio_iommu_range_64 { + uint64_t start; + uint64_t end; +}; + +struct virtio_iommu_range_32 { + uint32_t start; + uint32_t end; +}; + +struct virtio_iommu_config { + /* Supported page sizes */ + uint64_t page_size_mask; + /* Supported IOVA range */ + struct virtio_iommu_range_64 input_range; + /* Max domain ID size */ + struct virtio_iommu_range_32 domain_range; + /* Probe buffer size */ + uint32_t probe_size; +}; + +/* Request types */ +#define VIRTIO_IOMMU_T_ATTACH 0x01 +#define VIRTIO_IOMMU_T_DETACH 0x02 +#define VIRTIO_IOMMU_T_MAP 0x03 +#define VIRTIO_IOMMU_T_UNMAP 0x04 +#define VIRTIO_IOMMU_T_PROBE 0x05 + +/* Status types */ +#define VIRTIO_IOMMU_S_OK 0x00 +#define VIRTIO_IOMMU_S_IOERR 0x01 +#define VIRTIO_IOMMU_S_UNSUPP 0x02 +#define VIRTIO_IOMMU_S_DEVERR 0x03 +#define VIRTIO_IOMMU_S_INVAL 0x04 +#define VIRTIO_IOMMU_S_RANGE 0x05 +#define VIRTIO_IOMMU_S_NOENT 0x06 +#define VIRTIO_IOMMU_S_FAULT 0x07 +#define VIRTIO_IOMMU_S_NOMEM 0x08 + +struct virtio_iommu_req_head { + uint8_t type; + uint8_t reserved[3]; +}; + +struct virtio_iommu_req_tail { + uint8_t status; + uint8_t reserved[3]; +}; + +struct virtio_iommu_req_attach { + struct virtio_iommu_req_head head; + uint32_t domain; + uint32_t endpoint; + uint8_t reserved[8]; + struct virtio_iommu_req_tail tail; +}; + +struct virtio_iommu_req_detach { + struct virtio_iommu_req_head head; + uint32_t domain; + uint32_t endpoint; + uint8_t reserved[8]; + struct virtio_iommu_req_tail tail; +}; + +#define VIRTIO_IOMMU_MAP_F_READ (1 << 0) +#define VIRTIO_IOMMU_MAP_F_WRITE (1 << 1) +#define VIRTIO_IOMMU_MAP_F_MMIO (1 << 2) + +#define VIRTIO_IOMMU_MAP_F_MASK (VIRTIO_IOMMU_MAP_F_READ | \ + VIRTIO_IOMMU_MAP_F_WRITE | \ + VIRTIO_IOMMU_MAP_F_MMIO) + +struct virtio_iommu_req_map { + struct virtio_iommu_req_head head; + uint32_t domain; + uint64_t virt_start; + uint64_t virt_end; + uint64_t phys_start; + uint32_t flags; + struct virtio_iommu_req_tail tail; +}; + +struct virtio_iommu_req_unmap { + struct virtio_iommu_req_head head; + uint32_t domain; + uint64_t virt_start; + uint64_t virt_end; + uint8_t reserved[4]; + struct virtio_iommu_req_tail tail; +}; + +#define VIRTIO_IOMMU_PROBE_T_NONE 0 +#define VIRTIO_IOMMU_PROBE_T_RESV_MEM 1 + +#define VIRTIO_IOMMU_PROBE_T_MASK 0xfff + +struct virtio_iommu_probe_property { + uint16_t type; + uint16_t length; +}; + +#define VIRTIO_IOMMU_RESV_MEM_T_RESERVED 0 +#define VIRTIO_IOMMU_RESV_MEM_T_MSI 1 + +struct virtio_iommu_probe_resv_mem { + struct virtio_iommu_probe_property head; + uint8_t subtype; + uint8_t reserved[3]; + uint64_t start; + uint64_t end; +}; + +struct virtio_iommu_req_probe { + struct virtio_iommu_req_head head; + uint32_t endpoint; + uint8_t reserved[64]; + + uint8_t properties[]; + + /* + * Tail follows the variable-length properties array. No padding, + * property lengths are all aligned on 8 bytes. + */ +}; + +/* Fault types */ +#define VIRTIO_IOMMU_FAULT_R_UNKNOWN 0 +#define VIRTIO_IOMMU_FAULT_R_DOMAIN 1 +#define VIRTIO_IOMMU_FAULT_R_MAPPING 2 + +#define VIRTIO_IOMMU_FAULT_F_READ (1 << 0) +#define VIRTIO_IOMMU_FAULT_F_WRITE (1 << 1) +#define VIRTIO_IOMMU_FAULT_F_EXEC (1 << 2) +#define VIRTIO_IOMMU_FAULT_F_ADDRESS (1 << 8) + +struct virtio_iommu_fault { + uint8_t reason; + uint8_t reserved[3]; + uint32_t flags; + uint32_t endpoint; + uint8_t reserved2[4]; + uint64_t address; +}; + +#endif diff --git a/include/standard-headers/linux/virtio_pmem.h b/include/standard-headers/linux/virtio_pmem.h index 7e3d43b121..fc029de798 100644 --- a/include/standard-headers/linux/virtio_pmem.h +++ b/include/standard-headers/linux/virtio_pmem.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause */ /* * Definitions for virtio-pmem devices. * @@ -7,8 +7,8 @@ * Author(s): Pankaj Gupta */ -#ifndef _UAPI_LINUX_VIRTIO_PMEM_H -#define _UAPI_LINUX_VIRTIO_PMEM_H +#ifndef _LINUX_VIRTIO_PMEM_H +#define _LINUX_VIRTIO_PMEM_H #include "standard-headers/linux/types.h" #include "standard-headers/linux/virtio_ids.h" diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h index e1f8b74558..dfccc47092 100644 --- a/linux-headers/asm-arm/kvm.h +++ b/linux-headers/asm-arm/kvm.h @@ -214,6 +214,18 @@ struct kvm_vcpu_events { #define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \ KVM_REG_ARM_FW | ((r) & 0xffff)) #define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1 KVM_REG_ARM_FW_REG(1) + /* Higher values mean better protection. */ +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL 0 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL 1 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED 2 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 KVM_REG_ARM_FW_REG(2) + /* Higher values mean better protection. */ +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL 0 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN 1 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL 2 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4) /* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 diff --git a/linux-headers/asm-arm/unistd-common.h b/linux-headers/asm-arm/unistd-common.h index 27a9b6da27..eb5d361b11 100644 --- a/linux-headers/asm-arm/unistd-common.h +++ b/linux-headers/asm-arm/unistd-common.h @@ -388,5 +388,7 @@ #define __NR_fsconfig (__NR_SYSCALL_BASE + 431) #define __NR_fsmount (__NR_SYSCALL_BASE + 432) #define __NR_fspick (__NR_SYSCALL_BASE + 433) +#define __NR_pidfd_open (__NR_SYSCALL_BASE + 434) +#define __NR_clone3 (__NR_SYSCALL_BASE + 435) #endif /* _ASM_ARM_UNISTD_COMMON_H */ diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h index 2431ec35a9..a95d3a4203 100644 --- a/linux-headers/asm-arm64/kvm.h +++ b/linux-headers/asm-arm64/kvm.h @@ -229,6 +229,16 @@ struct kvm_vcpu_events { #define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ KVM_REG_ARM_FW | ((r) & 0xffff)) #define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1 KVM_REG_ARM_FW_REG(1) +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL 0 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL 1 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED 2 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 KVM_REG_ARM_FW_REG(2) +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL 0 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN 1 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL 2 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4) /* SVE registers */ #define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT) @@ -260,6 +270,13 @@ struct kvm_vcpu_events { KVM_REG_SIZE_U256 | \ ((i) & (KVM_ARM64_SVE_MAX_SLICES - 1))) +/* + * Register values for KVM_REG_ARM64_SVE_ZREG(), KVM_REG_ARM64_SVE_PREG() and + * KVM_REG_ARM64_SVE_FFR() are represented in memory in an endianness- + * invariant layout which differs from the layout used for the FPSIMD + * V-registers on big-endian systems: see sigcontext.h for more explanation. + */ + #define KVM_ARM64_SVE_VQ_MIN __SVE_VQ_MIN #define KVM_ARM64_SVE_VQ_MAX __SVE_VQ_MAX diff --git a/linux-headers/asm-generic/mman-common.h b/linux-headers/asm-generic/mman-common.h index abd238d0f7..63b1f506ea 100644 --- a/linux-headers/asm-generic/mman-common.h +++ b/linux-headers/asm-generic/mman-common.h @@ -19,15 +19,18 @@ #define MAP_TYPE 0x0f /* Mask for type of mapping */ #define MAP_FIXED 0x10 /* Interpret addr exactly */ #define MAP_ANONYMOUS 0x20 /* don't use a file */ -#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED -# define MAP_UNINITIALIZED 0x4000000 /* For anonymous mmap, memory could be uninitialized */ -#else -# define MAP_UNINITIALIZED 0x0 /* Don't support this flag */ -#endif -/* 0x0100 - 0x80000 flags are defined in asm-generic/mman.h */ +/* 0x0100 - 0x4000 flags are defined in asm-generic/mman.h */ +#define MAP_POPULATE 0x008000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x010000 /* do not block on IO */ +#define MAP_STACK 0x020000 /* give out an address that is best suited for process/thread stacks */ +#define MAP_HUGETLB 0x040000 /* create a huge page mapping */ +#define MAP_SYNC 0x080000 /* perform synchronous page faults for the mapping */ #define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */ +#define MAP_UNINITIALIZED 0x4000000 /* For anonymous mmap, memory could be + * uninitialized */ + /* * Flags for mlock */ diff --git a/linux-headers/asm-generic/mman.h b/linux-headers/asm-generic/mman.h index 653687d977..57e8195d0b 100644 --- a/linux-headers/asm-generic/mman.h +++ b/linux-headers/asm-generic/mman.h @@ -9,13 +9,11 @@ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ #define MAP_LOCKED 0x2000 /* pages are locked */ #define MAP_NORESERVE 0x4000 /* don't check for reservations */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ -#define MAP_HUGETLB 0x40000 /* create a huge page mapping */ -#define MAP_SYNC 0x80000 /* perform synchronous page faults for the mapping */ -/* Bits [26:31] are reserved, see mman-common.h for MAP_HUGETLB usage */ +/* + * Bits [26:31] are reserved, see asm-generic/hugetlb_encode.h + * for MAP_HUGETLB usage + */ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h index a87904daf1..1be0e798e3 100644 --- a/linux-headers/asm-generic/unistd.h +++ b/linux-headers/asm-generic/unistd.h @@ -844,9 +844,15 @@ __SYSCALL(__NR_fsconfig, sys_fsconfig) __SYSCALL(__NR_fsmount, sys_fsmount) #define __NR_fspick 433 __SYSCALL(__NR_fspick, sys_fspick) +#define __NR_pidfd_open 434 +__SYSCALL(__NR_pidfd_open, sys_pidfd_open) +#ifdef __ARCH_WANT_SYS_CLONE3 +#define __NR_clone3 435 +__SYSCALL(__NR_clone3, sys_clone3) +#endif #undef __NR_syscalls -#define __NR_syscalls 434 +#define __NR_syscalls 436 /* * 32 bit systems traditionally used different diff --git a/linux-headers/asm-mips/unistd_n32.h b/linux-headers/asm-mips/unistd_n32.h index fb988de900..7dffe8e34e 100644 --- a/linux-headers/asm-mips/unistd_n32.h +++ b/linux-headers/asm-mips/unistd_n32.h @@ -363,6 +363,7 @@ #define __NR_fsconfig (__NR_Linux + 431) #define __NR_fsmount (__NR_Linux + 432) #define __NR_fspick (__NR_Linux + 433) +#define __NR_pidfd_open (__NR_Linux + 434) #endif /* _ASM_MIPS_UNISTD_N32_H */ diff --git a/linux-headers/asm-mips/unistd_n64.h b/linux-headers/asm-mips/unistd_n64.h index 17359163c9..f4592d6fc5 100644 --- a/linux-headers/asm-mips/unistd_n64.h +++ b/linux-headers/asm-mips/unistd_n64.h @@ -339,6 +339,7 @@ #define __NR_fsconfig (__NR_Linux + 431) #define __NR_fsmount (__NR_Linux + 432) #define __NR_fspick (__NR_Linux + 433) +#define __NR_pidfd_open (__NR_Linux + 434) #endif /* _ASM_MIPS_UNISTD_N64_H */ diff --git a/linux-headers/asm-mips/unistd_o32.h b/linux-headers/asm-mips/unistd_o32.h index 83c8d8fb83..04c6728352 100644 --- a/linux-headers/asm-mips/unistd_o32.h +++ b/linux-headers/asm-mips/unistd_o32.h @@ -409,6 +409,7 @@ #define __NR_fsconfig (__NR_Linux + 431) #define __NR_fsmount (__NR_Linux + 432) #define __NR_fspick (__NR_Linux + 433) +#define __NR_pidfd_open (__NR_Linux + 434) #endif /* _ASM_MIPS_UNISTD_O32_H */ diff --git a/linux-headers/asm-powerpc/mman.h b/linux-headers/asm-powerpc/mman.h index 1c2b3fca05..8db7c2a3be 100644 --- a/linux-headers/asm-powerpc/mman.h +++ b/linux-headers/asm-powerpc/mman.h @@ -21,15 +21,11 @@ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ + #define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ #define MCL_FUTURE 0x4000 /* lock all additions to address space */ #define MCL_ONFAULT 0x8000 /* lock all pages that are faulted in */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ -#define MAP_HUGETLB 0x40000 /* create a huge page mapping */ - /* Override any generic PKEY permission defines */ #define PKEY_DISABLE_EXECUTE 0x4 #undef PKEY_ACCESS_MASK diff --git a/linux-headers/asm-powerpc/unistd_32.h b/linux-headers/asm-powerpc/unistd_32.h index 04cb2d3e61..2af478a7fe 100644 --- a/linux-headers/asm-powerpc/unistd_32.h +++ b/linux-headers/asm-powerpc/unistd_32.h @@ -416,6 +416,7 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 +#define __NR_pidfd_open 434 #endif /* _ASM_POWERPC_UNISTD_32_H */ diff --git a/linux-headers/asm-powerpc/unistd_64.h b/linux-headers/asm-powerpc/unistd_64.h index b1e6921490..4d76f18222 100644 --- a/linux-headers/asm-powerpc/unistd_64.h +++ b/linux-headers/asm-powerpc/unistd_64.h @@ -388,6 +388,7 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 +#define __NR_pidfd_open 434 #endif /* _ASM_POWERPC_UNISTD_64_H */ diff --git a/linux-headers/asm-s390/unistd_32.h b/linux-headers/asm-s390/unistd_32.h index 941853f3e9..7cce3ee296 100644 --- a/linux-headers/asm-s390/unistd_32.h +++ b/linux-headers/asm-s390/unistd_32.h @@ -406,5 +406,7 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 +#define __NR_pidfd_open 434 +#define __NR_clone3 435 #endif /* _ASM_S390_UNISTD_32_H */ diff --git a/linux-headers/asm-s390/unistd_64.h b/linux-headers/asm-s390/unistd_64.h index 90271d7f82..2371ff1e7a 100644 --- a/linux-headers/asm-s390/unistd_64.h +++ b/linux-headers/asm-s390/unistd_64.h @@ -354,5 +354,7 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 +#define __NR_pidfd_open 434 +#define __NR_clone3 435 #endif /* _ASM_S390_UNISTD_64_H */ diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index 6e7dd792e4..503d3f42da 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -378,23 +378,24 @@ struct kvm_sync_regs { struct kvm_vcpu_events events; }; -#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0) -#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1) -#define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) -#define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3) +#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0) +#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1) +#define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) +#define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3) +#define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT (1 << 4) #define KVM_STATE_NESTED_FORMAT_VMX 0 -#define KVM_STATE_NESTED_FORMAT_SVM 1 +#define KVM_STATE_NESTED_FORMAT_SVM 1 /* unused */ #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 #define KVM_STATE_NESTED_EVMCS 0x00000004 -#define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 - #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 +#define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 + struct kvm_vmx_nested_state_data { __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; @@ -432,4 +433,17 @@ struct kvm_nested_state { } data; }; +/* for KVM_CAP_PMU_EVENT_FILTER */ +struct kvm_pmu_event_filter { + __u32 action; + __u32 nevents; + __u32 fixed_counter_bitmap; + __u32 flags; + __u32 pad[4]; + __u64 events[0]; +}; + +#define KVM_PMU_EVENT_ALLOW 0 +#define KVM_PMU_EVENT_DENY 1 + #endif /* _ASM_X86_KVM_H */ diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h index 57bb48854c..e8ebec1cdc 100644 --- a/linux-headers/asm-x86/unistd_32.h +++ b/linux-headers/asm-x86/unistd_32.h @@ -424,5 +424,7 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 +#define __NR_pidfd_open 434 +#define __NR_clone3 435 #endif /* _ASM_X86_UNISTD_32_H */ diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h index fe6aa0688a..a2f863d549 100644 --- a/linux-headers/asm-x86/unistd_64.h +++ b/linux-headers/asm-x86/unistd_64.h @@ -346,5 +346,7 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 +#define __NR_pidfd_open 434 +#define __NR_clone3 435 #endif /* _ASM_X86_UNISTD_64_H */ diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h index 09cca49ba7..4cdc67d848 100644 --- a/linux-headers/asm-x86/unistd_x32.h +++ b/linux-headers/asm-x86/unistd_x32.h @@ -299,6 +299,8 @@ #define __NR_fsconfig (__X32_SYSCALL_BIT + 431) #define __NR_fsmount (__X32_SYSCALL_BIT + 432) #define __NR_fspick (__X32_SYSCALL_BIT + 433) +#define __NR_pidfd_open (__X32_SYSCALL_BIT + 434) +#define __NR_clone3 (__X32_SYSCALL_BIT + 435) #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) #define __NR_ioctl (__X32_SYSCALL_BIT + 514) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index c8423e760c..9cf351919c 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -116,7 +116,7 @@ struct kvm_irq_level { * ACPI gsi notion of irq. * For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47.. * For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23.. - * For ARM: See Documentation/virtual/kvm/api.txt + * For ARM: See Documentation/virt/kvm/api.txt */ union { __u32 irq; @@ -696,9 +696,11 @@ struct kvm_ioeventfd { #define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) #define KVM_X86_DISABLE_EXITS_HLT (1 << 1) #define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) +#define KVM_X86_DISABLE_EXITS_CSTATE (1 << 3) #define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ KVM_X86_DISABLE_EXITS_HLT | \ - KVM_X86_DISABLE_EXITS_PAUSE) + KVM_X86_DISABLE_EXITS_PAUSE | \ + KVM_X86_DISABLE_EXITS_CSTATE) /* for KVM_ENABLE_CAP */ struct kvm_enable_cap { @@ -993,6 +995,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_SVE 170 #define KVM_CAP_ARM_PTRAUTH_ADDRESS 171 #define KVM_CAP_ARM_PTRAUTH_GENERIC 172 +#define KVM_CAP_PMU_EVENT_FILTER 173 #ifdef KVM_CAP_IRQ_ROUTING @@ -1083,7 +1086,7 @@ struct kvm_xen_hvm_config { * * KVM_IRQFD_FLAG_RESAMPLE indicates resamplefd is valid and specifies * the irqfd to operate in resampling mode for level triggered interrupt - * emulation. See Documentation/virtual/kvm/api.txt. + * emulation. See Documentation/virt/kvm/api.txt. */ #define KVM_IRQFD_FLAG_RESAMPLE (1 << 1) @@ -1327,6 +1330,8 @@ struct kvm_s390_ucas_mapping { #define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info) /* Available with KVM_CAP_PPC_GET_CPU_CHAR */ #define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char) +/* Available with KVM_CAP_PMU_EVENT_FILTER */ +#define KVM_SET_PMU_EVENT_FILTER _IOW(KVMIO, 0xb2, struct kvm_pmu_event_filter) /* ioctl for vm fd */ #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h index 36bbe17d8f..34c39690c0 100644 --- a/linux-headers/linux/psp-sev.h +++ b/linux-headers/linux/psp-sev.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* * Userspace interface for AMD Secure Encrypted Virtualization (SEV) * platform management commands. @@ -7,10 +8,6 @@ * Author: Brijesh Singh * * SEV API specification is available at: https://developer.amd.com/sev/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __PSP_SEV_USER_H__ diff --git a/linux-headers/linux/virtio_iommu.h b/linux-headers/linux/virtio_iommu.h new file mode 100644 index 0000000000..2dc4609c16 --- /dev/null +++ b/linux-headers/linux/virtio_iommu.h @@ -0,0 +1 @@ +#include "standard-headers/linux/virtio_iommu.h" From patchwork Tue Jul 30 17:21:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066311 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4ED9B1395 for ; Tue, 30 Jul 2019 17:25:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D5F11FFBD for ; Tue, 30 Jul 2019 17:25:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1E7D0285CE; Tue, 30 Jul 2019 17:25:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 14EA9205A8 for ; Tue, 30 Jul 2019 17:25:35 +0000 (UTC) Received: from localhost ([::1]:34868 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVsU-0006pI-DR for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:25:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60836) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVpg-0008SX-PG for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVpe-0000kB-Oy for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:40 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55406) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVpZ-0000fN-Ts; Tue, 30 Jul 2019 13:22:34 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA0B530BD1D6; Tue, 30 Jul 2019 17:22:32 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8967D60C47; Tue, 30 Jul 2019 17:22:27 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:25 +0200 Message-Id: <20190730172137.23114-4-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Tue, 30 Jul 2019 17:22:33 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 03/15] virtio-iommu: Add skeleton X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patchs adds the skeleton for the virtio-iommu device. Signed-off-by: Eric Auger --- v9 -> v10: - expose VIRTIO_IOMMU_F_MMIO feature - s/domain_bits/domain_range struct - change error codes - enforce unmigratable - Kconfig v7 -> v8: - expose VIRTIO_IOMMU_F_BYPASS and VIRTIO_F_VERSION_1 features - set_config dummy implementation + tracing - add trace in get_features - set the features on realize() and store the acked ones - remove inclusion of linux/virtio_iommu.h v6 -> v7: - removed qapi-event.h include - add primary_bus and associated property v4 -> v5: - use the new v0.5 terminology (domain, endpoint) - add the event virtqueue v3 -> v4: - use page_size_mask instead of page_sizes - added set_features() - added some traces (reset, set_status, set_features) - empty virtio_iommu_set_config() as the driver MUST NOT write to device configuration fields - add get_config trace v2 -> v3: - rebase on 2.10-rc0, ie. use IOMMUMemoryRegion and remove iommu_ops. - advertise VIRTIO_IOMMU_F_MAP_UNMAP feature - page_sizes set to TARGET_PAGE_SIZE Conflicts: hw/virtio/trace-events --- hw/virtio/Kconfig | 5 + hw/virtio/Makefile.objs | 1 + hw/virtio/trace-events | 8 + hw/virtio/virtio-iommu.c | 267 +++++++++++++++++++++++++++++++ include/hw/virtio/virtio-iommu.h | 62 +++++++ 5 files changed, 343 insertions(+) create mode 100644 hw/virtio/virtio-iommu.c create mode 100644 include/hw/virtio/virtio-iommu.h diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig index 3724ff8bac..a30107b439 100644 --- a/hw/virtio/Kconfig +++ b/hw/virtio/Kconfig @@ -6,6 +6,11 @@ config VIRTIO_RNG default y depends on VIRTIO +config VIRTIO_IOMMU + bool + default y + depends on VIRTIO + config VIRTIO_PCI bool default y if PCI_DEVICES diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index 964ce78607..f42e4dd94f 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -14,6 +14,7 @@ obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o obj-$(call land,$(CONFIG_VIRTIO_CRYPTO),$(CONFIG_VIRTIO_PCI)) += virtio-crypto-pci.o obj-$(CONFIG_VIRTIO_PMEM) += virtio-pmem.o common-obj-$(call land,$(CONFIG_VIRTIO_PMEM),$(CONFIG_VIRTIO_PCI)) += virtio-pmem-pci.o +obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o ifeq ($(CONFIG_VIRTIO_PCI),y) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index e28ba48da6..f7dac39213 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -53,3 +53,11 @@ virtio_mmio_write_offset(uint64_t offset, uint64_t value) "virtio_mmio_write off virtio_mmio_guest_page(uint64_t size, int shift) "guest page size 0x%" PRIx64 " shift %d" virtio_mmio_queue_write(uint64_t value, int max_size) "mmio_queue write 0x%" PRIx64 " max %d" virtio_mmio_setting_irq(int level) "virtio_mmio setting IRQ %d" + +# hw/virtio/virtio-iommu.c +virtio_iommu_device_reset(void) "reset!" +virtio_iommu_get_features(uint64_t features) "device supports features=0x%"PRIx64 +virtio_iommu_set_features(uint64_t features) "features accepted by the driver =0x%"PRIx64 +virtio_iommu_device_status(uint8_t status) "driver status = %d" +virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_range, uint32_t probe_size) "page_size_mask=0x%"PRIx64" start=0x%"PRIx64" end=0x%"PRIx64" domain_range=%d probe_size=0x%x" +virtio_iommu_set_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_range, uint32_t probe_size) "page_size_mask=0x%"PRIx64" start=0x%"PRIx64" end=0x%"PRIx64" domain_bits=%d probe_size=0x%x" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c new file mode 100644 index 0000000000..f239954396 --- /dev/null +++ b/hw/virtio/virtio-iommu.c @@ -0,0 +1,267 @@ +/* + * 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 for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + */ + +#include "qemu/osdep.h" +#include "qemu/iov.h" +#include "qemu-common.h" +#include "hw/virtio/virtio.h" +#include "sysemu/kvm.h" +#include "trace.h" + +#include "standard-headers/linux/virtio_ids.h" + +#include "hw/virtio/virtio-bus.h" +#include "hw/virtio/virtio-access.h" +#include "hw/virtio/virtio-iommu.h" + +/* Max size */ +#define VIOMMU_DEFAULT_QUEUE_SIZE 256 + +static int virtio_iommu_handle_attach(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return VIRTIO_IOMMU_S_UNSUPP; +} +static int virtio_iommu_handle_detach(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return VIRTIO_IOMMU_S_UNSUPP; +} +static int virtio_iommu_handle_map(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return VIRTIO_IOMMU_S_UNSUPP; +} +static int virtio_iommu_handle_unmap(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt) +{ + return VIRTIO_IOMMU_S_UNSUPP; +} + +static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIOIOMMU *s = VIRTIO_IOMMU(vdev); + struct virtio_iommu_req_head head; + struct virtio_iommu_req_tail tail; + VirtQueueElement *elem; + unsigned int iov_cnt; + struct iovec *iov; + size_t sz; + + for (;;) { + elem = 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 bad head/tail size"); + virtqueue_detach_element(vq, elem, 0); + g_free(elem); + break; + } + + iov_cnt = elem->out_num; + iov = g_memdup(elem->out_sg, sizeof(struct iovec) * elem->out_num); + sz = iov_to_buf(iov, iov_cnt, 0, &head, sizeof(head)); + if (unlikely(sz != sizeof(head))) { + tail.status = VIRTIO_IOMMU_S_DEVERR; + goto out; + } + qemu_mutex_lock(&s->mutex); + switch (head.type) { + case VIRTIO_IOMMU_T_ATTACH: + tail.status = virtio_iommu_handle_attach(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_DETACH: + tail.status = virtio_iommu_handle_detach(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_MAP: + tail.status = virtio_iommu_handle_map(s, iov, iov_cnt); + break; + case VIRTIO_IOMMU_T_UNMAP: + tail.status = virtio_iommu_handle_unmap(s, iov, iov_cnt); + break; + default: + tail.status = VIRTIO_IOMMU_S_UNSUPP; + } + qemu_mutex_unlock(&s->mutex); + +out: + sz = iov_from_buf(elem->in_sg, elem->in_num, 0, + &tail, sizeof(tail)); + assert(sz == 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_data) +{ + VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev); + struct virtio_iommu_config *config = &dev->config; + + trace_virtio_iommu_get_config(config->page_size_mask, + config->input_range.start, + config->input_range.end, + config->domain_range.end, + config->probe_size); + memcpy(config_data, &dev->config, sizeof(struct virtio_iommu_config)); +} + +static void virtio_iommu_set_config(VirtIODevice *vdev, + const uint8_t *config_data) +{ + struct virtio_iommu_config config; + + memcpy(&config, config_data, sizeof(struct virtio_iommu_config)); + trace_virtio_iommu_set_config(config.page_size_mask, + config.input_range.start, + config.input_range.end, + config.domain_range.end, + config.probe_size); +} + +static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f, + Error **errp) +{ + VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev); + + f |= dev->features; + trace_virtio_iommu_get_features(f); + return f; +} + +static void virtio_iommu_set_features(VirtIODevice *vdev, uint64_t val) +{ + VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev); + + dev->acked_features = val; + trace_virtio_iommu_set_features(dev->acked_features); +} + +static const VMStateDescription vmstate_virtio_iommu_device = { + .name = "virtio-iommu-device", + .unmigratable = 1, +}; + +static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOIOMMU *s = VIRTIO_IOMMU(dev); + + virtio_init(vdev, "virtio-iommu", VIRTIO_ID_IOMMU, + sizeof(struct virtio_iommu_config)); + + s->req_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, + virtio_iommu_handle_command); + s->event_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, NULL); + + s->config.page_size_mask = TARGET_PAGE_MASK; + s->config.input_range.end = -1UL; + s->config.domain_range.start = 0; + s->config.domain_range.end = 32; + + virtio_add_feature(&s->features, VIRTIO_RING_F_EVENT_IDX); + virtio_add_feature(&s->features, VIRTIO_RING_F_INDIRECT_DESC); + virtio_add_feature(&s->features, VIRTIO_F_VERSION_1); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_INPUT_RANGE); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_DOMAIN_RANGE); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MMIO); +} + +static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + + virtio_cleanup(vdev); +} + +static void virtio_iommu_device_reset(VirtIODevice *vdev) +{ + trace_virtio_iommu_device_reset(); +} + +static void virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status) +{ + trace_virtio_iommu_device_status(status); +} + +static void virtio_iommu_instance_init(Object *obj) +{ +} + +static const VMStateDescription vmstate_virtio_iommu = { + .name = "virtio-iommu", + .minimum_version_id = 1, + .version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_VIRTIO_DEVICE, + VMSTATE_END_OF_LIST() + }, +}; + +static Property virtio_iommu_properties[] = { + DEFINE_PROP_LINK("primary-bus", VirtIOIOMMU, primary_bus, "PCI", PCIBus *), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_iommu_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + + dc->props = virtio_iommu_properties; + dc->vmsd = &vmstate_virtio_iommu; + + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + vdc->realize = virtio_iommu_device_realize; + vdc->unrealize = virtio_iommu_device_unrealize; + vdc->reset = virtio_iommu_device_reset; + vdc->get_config = virtio_iommu_get_config; + vdc->set_config = virtio_iommu_set_config; + vdc->get_features = virtio_iommu_get_features; + vdc->set_features = virtio_iommu_set_features; + vdc->set_status = virtio_iommu_set_status; + vdc->vmsd = &vmstate_virtio_iommu_device; +} + +static const TypeInfo virtio_iommu_info = { + .name = TYPE_VIRTIO_IOMMU, + .parent = TYPE_VIRTIO_DEVICE, + .instance_size = sizeof(VirtIOIOMMU), + .instance_init = virtio_iommu_instance_init, + .class_init = 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-iommu.h new file mode 100644 index 0000000000..4d47b6abeb --- /dev/null +++ b/include/hw/virtio/virtio-iommu.h @@ -0,0 +1,62 @@ +/* + * virtio-iommu device + * + * Copyright (c) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * 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 alloc */ +} IOMMUPciBus; + +typedef struct VirtIOIOMMU { + VirtIODevice parent_obj; + VirtQueue *req_vq; + VirtQueue *event_vq; + struct virtio_iommu_config config; + uint64_t features; + uint64_t acked_features; + GHashTable *as_by_busptr; + IOMMUPciBus *as_by_bus_num[IOMMU_PCI_BUS_MAX]; + PCIBus *primary_bus; + GTree *domains; + QemuMutex mutex; + GTree *endpoints; +} VirtIOIOMMU; + +#endif From patchwork Tue Jul 30 17:21:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066319 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 49A7C13B1 for ; Tue, 30 Jul 2019 17:27:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 27382285D4 for ; Tue, 30 Jul 2019 17:27:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 183EE283AD; Tue, 30 Jul 2019 17:27:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 92BFF283AD for ; Tue, 30 Jul 2019 17:27:52 +0000 (UTC) Received: from localhost ([::1]:34910 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVuh-0003MT-Qf for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:27:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60868) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVpl-0000Fu-9H for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVpk-0000oz-0e for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50713) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVph-0000mV-7X; Tue, 30 Jul 2019 13:22:41 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 752E6A96F2; Tue, 30 Jul 2019 17:22:40 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0D52A60BE5; Tue, 30 Jul 2019 17:22:32 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:26 +0200 Message-Id: <20190730172137.23114-5-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 30 Jul 2019 17:22:40 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 04/15] virtio-iommu: Decode the command payload X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- v9 -> v10: - make virtio_iommu_handle_* more compact and remove get_payload_size v7 -> v8: - handle new domain parameter in detach - remove reserved checks v5 -> v6: - change map/unmap semantics (remove size) v4 -> v5: - adopt new v0.5 terminology v3 -> v4: - no flags field anymore in struct virtio_iommu_req_unmap - test reserved on attach/detach, change trace proto - rebase on v2.10.0. --- hw/virtio/trace-events | 4 ++ hw/virtio/virtio-iommu.c | 81 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index f7dac39213..c7276116e7 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -61,3 +61,7 @@ virtio_iommu_set_features(uint64_t features) "features accepted by the driver =0 virtio_iommu_device_status(uint8_t status) "driver status = %d" virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_range, uint32_t probe_size) "page_size_mask=0x%"PRIx64" start=0x%"PRIx64" end=0x%"PRIx64" domain_range=%d probe_size=0x%x" virtio_iommu_set_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_range, uint32_t probe_size) "page_size_mask=0x%"PRIx64" start=0x%"PRIx64" end=0x%"PRIx64" domain_bits=%d probe_size=0x%x" +virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d" +virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d" +virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start, uint32_t flags) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 " phys_start=0x%"PRIx64" flags=%d" +virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index f239954396..658249c81e 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -33,29 +33,102 @@ /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 +static int virtio_iommu_attach(VirtIOIOMMU *s, + struct virtio_iommu_req_attach *req) +{ + uint32_t domain_id = le32_to_cpu(req->domain); + uint32_t ep_id = le32_to_cpu(req->endpoint); + + trace_virtio_iommu_attach(domain_id, ep_id); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_detach(VirtIOIOMMU *s, + struct virtio_iommu_req_detach *req) +{ + uint32_t domain_id = le32_to_cpu(req->domain); + uint32_t ep_id = le32_to_cpu(req->endpoint); + + trace_virtio_iommu_detach(domain_id, ep_id); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_map(VirtIOIOMMU *s, + struct virtio_iommu_req_map *req) +{ + uint32_t domain_id = le32_to_cpu(req->domain); + uint64_t phys_start = le64_to_cpu(req->phys_start); + uint64_t virt_start = le64_to_cpu(req->virt_start); + uint64_t virt_end = le64_to_cpu(req->virt_end); + uint32_t flags = le32_to_cpu(req->flags); + + trace_virtio_iommu_map(domain_id, virt_start, virt_end, phys_start, flags); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_unmap(VirtIOIOMMU *s, + struct virtio_iommu_req_unmap *req) +{ + uint32_t domain_id = le32_to_cpu(req->domain); + uint64_t virt_start = le64_to_cpu(req->virt_start); + uint64_t virt_end = le64_to_cpu(req->virt_end); + + trace_virtio_iommu_unmap(domain_id, virt_start, virt_end); + + return VIRTIO_IOMMU_S_UNSUPP; +} + +static int virtio_iommu_iov_to_req(struct iovec *iov, + unsigned int iov_cnt, + void *req, size_t req_sz) +{ + size_t sz, payload_sz = req_sz - sizeof(struct virtio_iommu_req_tail); + + sz = iov_to_buf(iov, iov_cnt, 0, req, payload_sz); + if (unlikely(sz != payload_sz)) { + return VIRTIO_IOMMU_S_INVAL; + } + return 0; +} + static int virtio_iommu_handle_attach(VirtIOIOMMU *s, struct iovec *iov, unsigned int iov_cnt) { - return VIRTIO_IOMMU_S_UNSUPP; + struct virtio_iommu_req_attach req; + int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req)); + + return ret ? ret : virtio_iommu_attach(s, &req); } static int virtio_iommu_handle_detach(VirtIOIOMMU *s, struct iovec *iov, unsigned int iov_cnt) { - return VIRTIO_IOMMU_S_UNSUPP; + struct virtio_iommu_req_detach req; + int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req)); + + return ret ? ret : virtio_iommu_detach(s, &req); } static int virtio_iommu_handle_map(VirtIOIOMMU *s, struct iovec *iov, unsigned int iov_cnt) { - return VIRTIO_IOMMU_S_UNSUPP; + struct virtio_iommu_req_map req; + int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req)); + + return ret ? ret : virtio_iommu_map(s, &req); } static int virtio_iommu_handle_unmap(VirtIOIOMMU *s, struct iovec *iov, unsigned int iov_cnt) { - return VIRTIO_IOMMU_S_UNSUPP; + struct virtio_iommu_req_unmap req; + int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req)); + + return ret ? ret : virtio_iommu_unmap(s, &req); } static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) From patchwork Tue Jul 30 17:21:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066301 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 300DD1395 for ; Tue, 30 Jul 2019 17:23:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1145428874 for ; Tue, 30 Jul 2019 17:23:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0506B28862; Tue, 30 Jul 2019 17:23:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7007D205A8 for ; Tue, 30 Jul 2019 17:23:24 +0000 (UTC) Received: from localhost ([::1]:34828 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqN-0001vM-Md for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:23:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60920) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVpr-0000WT-7o for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVpp-0000th-RP for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48685) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVpm-0000qh-NF; Tue, 30 Jul 2019 13:22:46 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E8D703086211; Tue, 30 Jul 2019 17:22:45 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id C6B6860BE5; Tue, 30 Jul 2019 17:22:40 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:27 +0200 Message-Id: <20190730172137.23114-6-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Tue, 30 Jul 2019 17:22:46 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 05/15] virtio-iommu: Add the iommu regions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch initializes the iommu memory regions so that PCIe end point transactions get translated. The translation function is not yet implemented though. Signed-off-by: Eric Auger --- v9 -> v10: - remove pc/virt machine headers - virtio_iommu_find_add_as: mr_index introduced in that patch and name properly freed v6 -> v7: - use primary_bus - rebase on new translate proto featuring iommu_idx v5 -> v6: - include qapi/error.h - fix g_hash_table_lookup key in virtio_iommu_find_add_as v4 -> v5: - use PCI bus handle as a key - use get_primary_pci_bus() callback v3 -> v4: - add trace_virtio_iommu_init_iommu_mr v2 -> v3: - use IOMMUMemoryRegion - iommu mr name built with BDF - rename smmu_get_sid into virtio_iommu_get_sid and use PCI_BUILD_BDF --- hw/virtio/trace-events | 2 + hw/virtio/virtio-iommu.c | 92 ++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-iommu.h | 2 + 3 files changed, 96 insertions(+) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index c7276116e7..b32169d56c 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -65,3 +65,5 @@ virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d" virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d" virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start, uint32_t flags) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 " phys_start=0x%"PRIx64" flags=%d" virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 +virtio_iommu_translate(const char *name, uint32_t rid, uint64_t iova, int flag) "mr=%s rid=%d addr=0x%"PRIx64" flag=%d" +virtio_iommu_init_iommu_mr(char *iommu_mr) "init %s" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 658249c81e..1610e2f773 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -22,6 +22,8 @@ #include "qemu-common.h" #include "hw/virtio/virtio.h" #include "sysemu/kvm.h" +#include "qapi/error.h" +#include "qemu/error-report.h" #include "trace.h" #include "standard-headers/linux/virtio_ids.h" @@ -33,6 +35,50 @@ /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 +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 = opaque; + IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, bus); + static uint32_t mr_index; + IOMMUDevice *sdev; + + if (!sbus) { + sbus = g_malloc0(sizeof(IOMMUPciBus) + + sizeof(IOMMUDevice *) * IOMMU_PCI_DEVFN_MAX); + sbus->bus = bus; + g_hash_table_insert(s->as_by_busptr, bus, sbus); + } + + sdev = sbus->pbdev[devfn]; + if (!sdev) { + char *name = g_strdup_printf("%s-%d-%d", + TYPE_VIRTIO_IOMMU_MEMORY_REGION, + mr_index++, devfn); + sdev = sbus->pbdev[devfn] = g_malloc0(sizeof(IOMMUDevice)); + + sdev->viommu = s; + sdev->bus = bus; + sdev->devfn = devfn; + + trace_virtio_iommu_init_iommu_mr(name); + + memory_region_init_iommu(&sdev->iommu_mr, sizeof(sdev->iommu_mr), + TYPE_VIRTIO_IOMMU_MEMORY_REGION, + OBJECT(s), name, + UINT64_MAX); + address_space_init(&sdev->as, + MEMORY_REGION(&sdev->iommu_mr), TYPE_VIRTIO_IOMMU); + g_free(name); + } + return &sdev->as; +} + static int virtio_iommu_attach(VirtIOIOMMU *s, struct virtio_iommu_req_attach *req) { @@ -192,6 +238,27 @@ out: } } +static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, + IOMMUAccessFlags flag, + int iommu_idx) +{ + IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr); + uint32_t sid; + + IOMMUTLBEntry entry = { + .target_as = &address_space_memory, + .iova = addr, + .translated_addr = addr, + .addr_mask = ~(hwaddr)0, + .perm = IOMMU_NONE, + }; + + sid = 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_data) { VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev); @@ -266,6 +333,15 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MMIO); + + memset(s->as_by_bus_num, 0, sizeof(s->as_by_bus_num)); + s->as_by_busptr = g_hash_table_new(NULL, NULL); + + if (s->primary_bus) { + pci_setup_iommu(s->primary_bus, virtio_iommu_find_add_as, s); + } else { + error_setg(errp, "VIRTIO-IOMMU is not attached to any PCI bus!"); + } } static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp) @@ -324,6 +400,14 @@ static void virtio_iommu_class_init(ObjectClass *klass, void *data) vdc->vmsd = &vmstate_virtio_iommu_device; } +static void virtio_iommu_memory_region_class_init(ObjectClass *klass, + void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = virtio_iommu_translate; +} + static const TypeInfo virtio_iommu_info = { .name = TYPE_VIRTIO_IOMMU, .parent = TYPE_VIRTIO_DEVICE, @@ -332,9 +416,17 @@ static const TypeInfo virtio_iommu_info = { .class_init = virtio_iommu_class_init, }; +static const TypeInfo virtio_iommu_memory_region_info = { + .parent = TYPE_IOMMU_MEMORY_REGION, + .name = TYPE_VIRTIO_IOMMU_MEMORY_REGION, + .class_init = 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); } type_init(virtio_register_types) diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h index 4d47b6abeb..f55f48d304 100644 --- a/include/hw/virtio/virtio-iommu.h +++ b/include/hw/virtio/virtio-iommu.h @@ -28,6 +28,8 @@ #define VIRTIO_IOMMU(obj) \ OBJECT_CHECK(VirtIOIOMMU, (obj), TYPE_VIRTIO_IOMMU) +#define TYPE_VIRTIO_IOMMU_MEMORY_REGION "virtio-iommu-memory-region" + #define IOMMU_PCI_BUS_MAX 256 #define IOMMU_PCI_DEVFN_MAX 256 From patchwork Tue Jul 30 17:21:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066309 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3268D1395 for ; Tue, 30 Jul 2019 17:25:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 14C41205AD for ; Tue, 30 Jul 2019 17:25:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 08E5826E54; Tue, 30 Jul 2019 17:25:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 68C1428815 for ; Tue, 30 Jul 2019 17:25:03 +0000 (UTC) Received: from localhost ([::1]:34866 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVry-0006DV-SN for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:25:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60953) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVpw-0000ng-Kg for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVpv-0000xM-8T for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:22:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46156) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVps-0000uv-2C; Tue, 30 Jul 2019 13:22:52 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5B220882EA; Tue, 30 Jul 2019 17:22:51 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4A0DC60BF7; Tue, 30 Jul 2019 17:22:46 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:28 +0200 Message-Id: <20190730172137.23114-7-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 30 Jul 2019 17:22:51 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 06/15] virtio-iommu: Endpoint and domains structs and helpers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch introduce domain and endpoint internal datatypes. Both are stored in RB trees. The domain owns a list of endpoints attached to it. Helpers to get/put end points and domains are introduced. get() helpers will become static in subsequent patches. Signed-off-by: Eric Auger Reviewed-by: Bharat Bhushan --- v9 -> v10: - added Bharat's R-b v6 -> v7: - on virtio_iommu_find_add_as the bus number computation may not be finalized yet so we cannot register the EPs at that time. Hence, let's remove the get_endpoint and also do not use the bus number for building the memory region name string (only used for debug though). v4 -> v5: - initialize as->endpoint_list v3 -> v4: - new separate patch --- hw/virtio/trace-events | 4 ++ hw/virtio/virtio-iommu.c | 121 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index b32169d56c..a373bdebb3 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -67,3 +67,7 @@ virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end, uin virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 virtio_iommu_translate(const char *name, uint32_t rid, uint64_t iova, int flag) "mr=%s rid=%d addr=0x%"PRIx64" flag=%d" virtio_iommu_init_iommu_mr(char *iommu_mr) "init %s" +virtio_iommu_get_endpoint(uint32_t ep_id) "Alloc endpoint=%d" +virtio_iommu_put_endpoint(uint32_t ep_id) "Free endpoint=%d" +virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=%d" +virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 1610e2f773..77dccecc0a 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -31,15 +31,118 @@ #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" /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 +typedef struct viommu_domain { + uint32_t id; + GTree *mappings; + QLIST_HEAD(, viommu_endpoint) endpoint_list; +} viommu_domain; + +typedef struct viommu_endpoint { + uint32_t id; + viommu_domain *domain; + QLIST_ENTRY(viommu_endpoint) next; + VirtIOIOMMU *viommu; +} viommu_endpoint; + +typedef struct viommu_interval { + uint64_t low; + uint64_t high; +} viommu_interval; + static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) { return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); } +static gint interval_cmp(gconstpointer a, gconstpointer b, gpointer user_data) +{ + viommu_interval *inta = (viommu_interval *)a; + viommu_interval *intb = (viommu_interval *)b; + + if (inta->high <= intb->low) { + return -1; + } else if (intb->high <= inta->low) { + return 1; + } else { + return 0; + } +} + +static void virtio_iommu_detach_endpoint_from_domain(viommu_endpoint *ep) +{ + QLIST_REMOVE(ep, next); + ep->domain = NULL; +} + +viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id); +viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id) +{ + viommu_endpoint *ep; + + ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id)); + if (ep) { + return ep; + } + ep = g_malloc0(sizeof(*ep)); + ep->id = ep_id; + ep->viommu = s; + trace_virtio_iommu_get_endpoint(ep_id); + g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep); + return ep; +} + +static void virtio_iommu_put_endpoint(gpointer data) +{ + viommu_endpoint *ep = (viommu_endpoint *)data; + + if (ep->domain) { + virtio_iommu_detach_endpoint_from_domain(ep); + g_tree_unref(ep->domain->mappings); + } + + trace_virtio_iommu_put_endpoint(ep->id); + g_free(ep); +} + +viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id); +viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id) +{ + viommu_domain *domain; + + domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id)); + if (domain) { + return domain; + } + domain = g_malloc0(sizeof(*domain)); + domain->id = domain_id; + domain->mappings = g_tree_new_full((GCompareDataFunc)interval_cmp, + NULL, (GDestroyNotify)g_free, + (GDestroyNotify)g_free); + g_tree_insert(s->domains, GUINT_TO_POINTER(domain_id), domain); + QLIST_INIT(&domain->endpoint_list); + trace_virtio_iommu_get_domain(domain_id); + return domain; +} + +static void virtio_iommu_put_domain(gpointer data) +{ + viommu_domain *domain = (viommu_domain *)data; + viommu_endpoint *iter, *tmp; + + QLIST_FOREACH_SAFE(iter, &domain->endpoint_list, next, tmp) { + virtio_iommu_detach_endpoint_from_domain(iter); + } + g_tree_destroy(domain->mappings); + trace_virtio_iommu_put_domain(domain->id); + g_free(domain); +} + static AddressSpace *virtio_iommu_find_add_as(PCIBus *bus, void *opaque, int devfn) { @@ -308,6 +411,13 @@ static const VMStateDescription vmstate_virtio_iommu_device = { .unmigratable = 1, }; +static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data) +{ + uint ua = GPOINTER_TO_UINT(a); + uint ub = GPOINTER_TO_UINT(b); + return (ua > ub) - (ua < ub); +} + static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); @@ -334,6 +444,8 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MMIO); + qemu_mutex_init(&s->mutex); + memset(s->as_by_bus_num, 0, sizeof(s->as_by_bus_num)); s->as_by_busptr = g_hash_table_new(NULL, NULL); @@ -342,11 +454,20 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) } else { error_setg(errp, "VIRTIO-IOMMU is not attached to any PCI bus!"); } + + s->domains = g_tree_new_full((GCompareDataFunc)int_cmp, + NULL, NULL, virtio_iommu_put_domain); + s->endpoints = g_tree_new_full((GCompareDataFunc)int_cmp, + NULL, NULL, virtio_iommu_put_endpoint); } static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOIOMMU *s = VIRTIO_IOMMU(dev); + + g_tree_destroy(s->domains); + g_tree_destroy(s->endpoints); virtio_cleanup(vdev); } From patchwork Tue Jul 30 17:21:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066307 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 895051395 for ; Tue, 30 Jul 2019 17:24:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6B028285FB for ; Tue, 30 Jul 2019 17:24:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5F89528653; Tue, 30 Jul 2019 17:24:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 08DA5285FB for ; Tue, 30 Jul 2019 17:24:44 +0000 (UTC) Received: from localhost ([::1]:34859 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVrf-0005IG-Ff for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:24:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32772) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVq3-00015P-Hl for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVq2-00013c-GE for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56318) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVpz-00011T-Uq; Tue, 30 Jul 2019 13:23:00 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2A63930860A7; Tue, 30 Jul 2019 17:22:59 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id B19E460BE5; Tue, 30 Jul 2019 17:22:51 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:29 +0200 Message-Id: <20190730172137.23114-8-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Tue, 30 Jul 2019 17:22:59 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 07/15] virtio-iommu: Implement attach/detach command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch implements the endpoint attach/detach to/from a domain. Signed-off-by: Eric Auger --- --- hw/virtio/virtio-iommu.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 77dccecc0a..5ea0930cc2 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -80,8 +80,8 @@ static void virtio_iommu_detach_endpoint_from_domain(viommu_endpoint *ep) ep->domain = NULL; } -viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id); -viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id) +static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, + uint32_t ep_id) { viommu_endpoint *ep; @@ -110,8 +110,8 @@ static void virtio_iommu_put_endpoint(gpointer data) g_free(ep); } -viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id); -viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t domain_id) +static viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, + uint32_t domain_id) { viommu_domain *domain; @@ -187,10 +187,27 @@ static int virtio_iommu_attach(VirtIOIOMMU *s, { uint32_t domain_id = le32_to_cpu(req->domain); uint32_t ep_id = le32_to_cpu(req->endpoint); + viommu_domain *domain; + viommu_endpoint *ep; trace_virtio_iommu_attach(domain_id, ep_id); - return VIRTIO_IOMMU_S_UNSUPP; + ep = virtio_iommu_get_endpoint(s, ep_id); + if (ep->domain) { + /* + * the device is already attached to a domain, + * detach it first + */ + virtio_iommu_detach_endpoint_from_domain(ep); + } + + domain = virtio_iommu_get_domain(s, domain_id); + QLIST_INSERT_HEAD(&domain->endpoint_list, ep, next); + + ep->domain = domain; + g_tree_ref(domain->mappings); + + return VIRTIO_IOMMU_S_OK; } static int virtio_iommu_detach(VirtIOIOMMU *s, @@ -198,10 +215,21 @@ static int virtio_iommu_detach(VirtIOIOMMU *s, { uint32_t domain_id = le32_to_cpu(req->domain); uint32_t ep_id = le32_to_cpu(req->endpoint); + viommu_endpoint *ep; trace_virtio_iommu_detach(domain_id, ep_id); - return VIRTIO_IOMMU_S_UNSUPP; + ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id)); + if (!ep) { + return VIRTIO_IOMMU_S_NOENT; + } + + if (!ep->domain) { + return VIRTIO_IOMMU_S_INVAL; + } + + virtio_iommu_detach_endpoint_from_domain(ep); + return VIRTIO_IOMMU_S_OK; } static int virtio_iommu_map(VirtIOIOMMU *s, From patchwork Tue Jul 30 17:21:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066317 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1B90713B1 for ; Tue, 30 Jul 2019 17:27:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F1F161FFE4 for ; Tue, 30 Jul 2019 17:27:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E619D283AD; Tue, 30 Jul 2019 17:27:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6C5DC1FFE4 for ; Tue, 30 Jul 2019 17:27:24 +0000 (UTC) Received: from localhost ([::1]:34900 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVuF-0001rA-IA for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:27:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32817) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqB-0001PH-J2 for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVqA-00019P-A8 for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56224) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVq7-000174-FX; Tue, 30 Jul 2019 13:23:07 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BED803086268; Tue, 30 Jul 2019 17:23:06 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7CAC260BE5; Tue, 30 Jul 2019 17:22:59 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:30 +0200 Message-Id: <20190730172137.23114-9-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Tue, 30 Jul 2019 17:23:06 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 08/15] virtio-iommu: Implement map/unmap X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch implements virtio_iommu_map/unmap. Signed-off-by: Eric Auger --- v5 -> v6: - use new v0.6 fields - replace error_report by qemu_log_mask v3 -> v4: - implement unmap semantics as specified in v0.4 --- hw/virtio/trace-events | 3 ++ hw/virtio/virtio-iommu.c | 94 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index a373bdebb3..25a71b0505 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -71,3 +71,6 @@ virtio_iommu_get_endpoint(uint32_t ep_id) "Alloc endpoint=%d" virtio_iommu_put_endpoint(uint32_t ep_id) "Free endpoint=%d" virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=%d" virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d" +virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t next_low, uint64_t next_high) "Unmap left [0x%"PRIx64",0x%"PRIx64"], new interval=[0x%"PRIx64",0x%"PRIx64"]" +virtio_iommu_unmap_right_interval(uint64_t low, uint64_t high, uint64_t next_low, uint64_t next_high) "Unmap right [0x%"PRIx64",0x%"PRIx64"], new interval=[0x%"PRIx64",0x%"PRIx64"]" +virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc [0x%"PRIx64",0x%"PRIx64"]" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 5ea0930cc2..4706b9da6e 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "qemu/iov.h" #include "qemu-common.h" #include "hw/virtio/virtio.h" @@ -55,6 +56,13 @@ typedef struct viommu_interval { uint64_t high; } viommu_interval; +typedef struct viommu_mapping { + uint64_t virt_addr; + uint64_t phys_addr; + uint64_t size; + uint32_t flags; +} viommu_mapping; + static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) { return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); @@ -240,10 +248,37 @@ static int virtio_iommu_map(VirtIOIOMMU *s, uint64_t virt_start = le64_to_cpu(req->virt_start); uint64_t virt_end = le64_to_cpu(req->virt_end); uint32_t flags = le32_to_cpu(req->flags); + viommu_domain *domain; + viommu_interval *interval; + viommu_mapping *mapping; + + interval = g_malloc0(sizeof(*interval)); + + interval->low = virt_start; + interval->high = virt_end; + + domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id)); + if (!domain) { + return VIRTIO_IOMMU_S_NOENT; + } + + mapping = g_tree_lookup(domain->mappings, (gpointer)interval); + if (mapping) { + g_free(interval); + return VIRTIO_IOMMU_S_INVAL; + } trace_virtio_iommu_map(domain_id, virt_start, virt_end, phys_start, flags); - return VIRTIO_IOMMU_S_UNSUPP; + mapping = g_malloc0(sizeof(*mapping)); + mapping->virt_addr = virt_start; + mapping->phys_addr = phys_start; + mapping->size = virt_end - virt_start + 1; + mapping->flags = flags; + + g_tree_insert(domain->mappings, interval, mapping); + + return VIRTIO_IOMMU_S_OK; } static int virtio_iommu_unmap(VirtIOIOMMU *s, @@ -252,10 +287,65 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s, uint32_t domain_id = le32_to_cpu(req->domain); uint64_t virt_start = le64_to_cpu(req->virt_start); uint64_t virt_end = le64_to_cpu(req->virt_end); + uint64_t size = virt_end - virt_start + 1; + viommu_mapping *mapping; + viommu_interval interval; + viommu_domain *domain; trace_virtio_iommu_unmap(domain_id, virt_start, virt_end); - return VIRTIO_IOMMU_S_UNSUPP; + domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id)); + if (!domain) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: no domain\n", __func__); + return VIRTIO_IOMMU_S_NOENT; + } + interval.low = virt_start; + interval.high = virt_end; + + mapping = g_tree_lookup(domain->mappings, (gpointer)(&interval)); + + while (mapping) { + viommu_interval current; + uint64_t low = mapping->virt_addr; + uint64_t high = mapping->virt_addr + mapping->size - 1; + + current.low = low; + current.high = high; + + if (low == interval.low && size >= mapping->size) { + g_tree_remove(domain->mappings, (gpointer)(¤t)); + interval.low = high + 1; + trace_virtio_iommu_unmap_left_interval(current.low, current.high, + interval.low, interval.high); + } else if (high == interval.high && size >= mapping->size) { + trace_virtio_iommu_unmap_right_interval(current.low, current.high, + interval.low, interval.high); + g_tree_remove(domain->mappings, (gpointer)(¤t)); + interval.high = low - 1; + } else if (low > interval.low && high < interval.high) { + trace_virtio_iommu_unmap_inc_interval(current.low, current.high); + g_tree_remove(domain->mappings, (gpointer)(¤t)); + } else { + break; + } + if (interval.low >= interval.high) { + return VIRTIO_IOMMU_S_OK; + } else { + mapping = g_tree_lookup(domain->mappings, (gpointer)(&interval)); + } + } + + if (mapping) { + qemu_log_mask(LOG_GUEST_ERROR, + "****** %s: Unmap 0x%"PRIx64" size=0x%"PRIx64 + " from 0x%"PRIx64" size=0x%"PRIx64" is not supported\n", + __func__, interval.low, size, + mapping->virt_addr, mapping->size); + } else { + return VIRTIO_IOMMU_S_OK; + } + + return VIRTIO_IOMMU_S_INVAL; } static int virtio_iommu_iov_to_req(struct iovec *iov, From patchwork Tue Jul 30 17:21:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066329 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CC1481395 for ; Tue, 30 Jul 2019 17:29:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF24B1FFBD for ; Tue, 30 Jul 2019 17:29:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A28D4205A8; Tue, 30 Jul 2019 17:29:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3DABC1FFBD for ; Tue, 30 Jul 2019 17:29:56 +0000 (UTC) Received: from localhost ([::1]:34940 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVwh-0007EZ-H3 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:29:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32846) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqH-0001fo-Cl for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVqG-0001Cn-9Q for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56264) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVqC-0001Aw-SM; Tue, 30 Jul 2019 13:23:13 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1C0B230862BE; Tue, 30 Jul 2019 17:23:12 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2254960BE5; Tue, 30 Jul 2019 17:23:06 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:31 +0200 Message-Id: <20190730172137.23114-10-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Tue, 30 Jul 2019 17:23:12 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 09/15] virtio-iommu: Implement translate X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch implements the translate callback Signed-off-by: Eric Auger --- v6 -> v7: - implemented bypass-mode v5 -> v6: - replace error_report by qemu_log_mask v4 -> v5: - check the device domain is not NULL - s/printf/error_report - set flags to IOMMU_NONE in case of all translation faults --- hw/virtio/trace-events | 1 + hw/virtio/virtio-iommu.c | 58 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 25a71b0505..8257065159 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -74,3 +74,4 @@ virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d" virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t next_low, uint64_t next_high) "Unmap left [0x%"PRIx64",0x%"PRIx64"], new interval=[0x%"PRIx64",0x%"PRIx64"]" virtio_iommu_unmap_right_interval(uint64_t low, uint64_t high, uint64_t next_low, uint64_t next_high) "Unmap right [0x%"PRIx64",0x%"PRIx64"], new interval=[0x%"PRIx64",0x%"PRIx64"]" virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc [0x%"PRIx64",0x%"PRIx64"]" +virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 4706b9da6e..a8de583f9a 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -464,19 +464,75 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, int iommu_idx) { IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr); + VirtIOIOMMU *s = sdev->viommu; uint32_t sid; + viommu_endpoint *ep; + viommu_mapping *mapping; + viommu_interval interval; + bool bypass_allowed; + + interval.low = addr; + interval.high = addr + 1; IOMMUTLBEntry entry = { .target_as = &address_space_memory, .iova = addr, .translated_addr = addr, - .addr_mask = ~(hwaddr)0, + .addr_mask = (1 << ctz32(s->config.page_size_mask)) - 1, .perm = IOMMU_NONE, }; + bypass_allowed = virtio_has_feature(s->acked_features, + VIRTIO_IOMMU_F_BYPASS); + sid = virtio_iommu_get_sid(sdev); trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag); + qemu_mutex_lock(&s->mutex); + + ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(sid)); + if (!ep) { + if (!bypass_allowed) { + error_report("%s sid=%d is not known!!", __func__, sid); + } else { + entry.perm = flag; + } + goto unlock; + } + + if (!ep->domain) { + if (!bypass_allowed) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s %02x:%02x.%01x not attached to any domain\n", + __func__, PCI_BUS_NUM(sid), + PCI_SLOT(sid), PCI_FUNC(sid)); + } else { + entry.perm = flag; + } + goto unlock; + } + + mapping = g_tree_lookup(ep->domain->mappings, (gpointer)(&interval)); + if (!mapping) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s no mapping for 0x%"PRIx64" for sid=%d\n", + __func__, addr, sid); + goto unlock; + } + + if (((flag & IOMMU_RO) && !(mapping->flags & VIRTIO_IOMMU_MAP_F_READ)) || + ((flag & IOMMU_WO) && !(mapping->flags & VIRTIO_IOMMU_MAP_F_WRITE))) { + qemu_log_mask(LOG_GUEST_ERROR, + "Permission error on 0x%"PRIx64"(%d): allowed=%d\n", + addr, flag, mapping->flags); + goto unlock; + } + entry.translated_addr = addr - mapping->virt_addr + mapping->phys_addr; + entry.perm = flag; + trace_virtio_iommu_translate_out(addr, entry.translated_addr, sid); + +unlock: + qemu_mutex_unlock(&s->mutex); return entry; } From patchwork Tue Jul 30 17:21:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066305 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 74EFC13B1 for ; Tue, 30 Jul 2019 17:24:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 57157205A8 for ; Tue, 30 Jul 2019 17:24:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4AF2E2861E; Tue, 30 Jul 2019 17:24:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8E13E205A8 for ; Tue, 30 Jul 2019 17:24:15 +0000 (UTC) Received: from localhost ([::1]:34846 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVrD-0003oc-1H for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:24:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32883) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqP-00022p-HH for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVqO-0001HL-1O for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:32778) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVqK-0001EO-JY; Tue, 30 Jul 2019 13:23:20 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DAD33308FC5F; Tue, 30 Jul 2019 17:23:19 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7470960BE5; Tue, 30 Jul 2019 17:23:12 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:32 +0200 Message-Id: <20190730172137.23114-11-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Tue, 30 Jul 2019 17:23:19 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 10/15] virtio-iommu: Implement probe request X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch implements the PROBE request. At the moment, no reserved regions are returned as none are registered per device. Only a NONE property is returned. Signed-off-by: Eric Auger Reviewed-by: Peter Xu --- v8 -> v9: - fix filling of properties (changes induced by v0.7 -> v0.8 spec evolution) - return VIRTIO_IOMMU_S_INVAL in case of error v7 -> v8: - adapt to removal of value filed in virtio_iommu_probe_property v6 -> v7: - adapt to the change in virtio_iommu_probe_resv_mem fields - use get_endpoint() instead of directly checking the EP was registered. v4 -> v5: - initialize bufstate.error to false - add cpu_to_le64(size) --- hw/virtio/trace-events | 2 + hw/virtio/virtio-iommu.c | 168 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 8257065159..2e557dffb4 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -75,3 +75,5 @@ virtio_iommu_unmap_left_interval(uint64_t low, uint64_t high, uint64_t next_low, virtio_iommu_unmap_right_interval(uint64_t low, uint64_t high, uint64_t next_low, uint64_t next_high) "Unmap right [0x%"PRIx64",0x%"PRIx64"], new interval=[0x%"PRIx64",0x%"PRIx64"]" virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc [0x%"PRIx64",0x%"PRIx64"]" virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d" +virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t start, uint64_t end, uint32_t flags, size_t filled) "dev= %d, subtype=%d start=0x%"PRIx64" end=0x%"PRIx64" flags=%d filled=0x%lx" +virtio_iommu_fill_none_property(uint32_t devid) "devid=%d" diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index a8de583f9a..66be9a4627 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -37,6 +37,10 @@ /* Max size */ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 +#define VIOMMU_PROBE_SIZE 512 + +#define SUPPORTED_PROBE_PROPERTIES (\ + 1 << VIRTIO_IOMMU_PROBE_T_RESV_MEM) typedef struct viommu_domain { uint32_t id; @@ -49,6 +53,7 @@ typedef struct viommu_endpoint { viommu_domain *domain; QLIST_ENTRY(viommu_endpoint) next; VirtIOIOMMU *viommu; + GTree *reserved_regions; } viommu_endpoint; typedef struct viommu_interval { @@ -63,6 +68,13 @@ typedef struct viommu_mapping { uint32_t flags; } viommu_mapping; +typedef struct viommu_property_buffer { + viommu_endpoint *endpoint; + size_t filled; + uint8_t *start; + bool error; +} viommu_property_buffer; + static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) { return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); @@ -102,6 +114,9 @@ static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, ep->viommu = s; trace_virtio_iommu_get_endpoint(ep_id); g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep); + ep->reserved_regions = g_tree_new_full((GCompareDataFunc)interval_cmp, + NULL, (GDestroyNotify)g_free, + (GDestroyNotify)g_free); return ep; } @@ -115,6 +130,7 @@ static void virtio_iommu_put_endpoint(gpointer data) } trace_virtio_iommu_put_endpoint(ep->id); + g_tree_destroy(ep->reserved_regions); g_free(ep); } @@ -348,6 +364,125 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s, return VIRTIO_IOMMU_S_INVAL; } +/** + * virtio_iommu_fill_resv_mem_prop - Add a RESV_MEM probe + * property into the probe request buffer + * + * @key: interval handle + * @value: handle to the reserved memory region + * @data: handle to the probe request buffer state + */ +static gboolean virtio_iommu_fill_resv_mem_prop(gpointer key, + gpointer value, + gpointer data) +{ + struct virtio_iommu_probe_resv_mem *resv = + (struct virtio_iommu_probe_resv_mem *)value; + struct virtio_iommu_probe_resv_mem *buf_prop; + viommu_property_buffer *bufstate = (viommu_property_buffer *)data; + size_t prop_size = sizeof(*resv); + + if (bufstate->filled + prop_size >= VIOMMU_PROBE_SIZE) { + bufstate->error = true; + /* get the traversal stopped by returning true */ + return true; + } + buf_prop = (struct virtio_iommu_probe_resv_mem *) + (bufstate->start + bufstate->filled); + *buf_prop = *resv; + + bufstate->filled += prop_size; + trace_virtio_iommu_fill_resv_property(bufstate->endpoint->id, + resv->subtype, resv->start, + resv->end, resv->subtype, + bufstate->filled); + return false; +} + +static int virtio_iommu_fill_none_prop(viommu_property_buffer *bufstate) +{ + struct virtio_iommu_probe_property *prop; + + prop = (struct virtio_iommu_probe_property *) + (bufstate->start + bufstate->filled); + prop->type = 0; + prop->length = 0; + bufstate->filled += sizeof(*prop); + trace_virtio_iommu_fill_none_property(bufstate->endpoint->id); + return 0; +} + +/* Fill the properties[] buffer with properties of type @type */ +static int virtio_iommu_fill_property(int type, + viommu_property_buffer *bufstate) +{ + int ret = -ENOSPC; + + if (bufstate->filled + sizeof(struct virtio_iommu_probe_property) + >= VIOMMU_PROBE_SIZE) { + /* no space left for the header */ + bufstate->error = true; + goto out; + } + + switch (type) { + case VIRTIO_IOMMU_PROBE_T_NONE: + ret = virtio_iommu_fill_none_prop(bufstate); + break; + case VIRTIO_IOMMU_PROBE_T_RESV_MEM: + { + viommu_endpoint *ep = bufstate->endpoint; + + g_tree_foreach(ep->reserved_regions, + virtio_iommu_fill_resv_mem_prop, + bufstate); + if (!bufstate->error) { + ret = 0; + } + break; + } + default: + ret = -ENOENT; + break; + } +out: + if (ret) { + error_report("%s property of type=%d could not be filled (%d)," + " remaining size = 0x%lx", + __func__, type, ret, bufstate->filled); + } + return ret; +} + +/** + * virtio_iommu_probe - Fill the probe request buffer with all + * the properties the device is able to return and add a NONE + * property at the end. @buf points to properties[]. + */ +static int virtio_iommu_probe(VirtIOIOMMU *s, + struct virtio_iommu_req_probe *req, + uint8_t *buf) +{ + uint32_t ep_id = le32_to_cpu(req->endpoint); + viommu_endpoint *ep = virtio_iommu_get_endpoint(s, ep_id); + int16_t prop_types = SUPPORTED_PROBE_PROPERTIES, type; + viommu_property_buffer bufstate = {.start = buf, .filled = 0, + .error = false, .endpoint = ep}; + + while ((type = ctz32(prop_types)) != 32) { + if (virtio_iommu_fill_property(type, &bufstate)) { + goto failure; + } + prop_types &= ~(1 << type); + } + if (virtio_iommu_fill_property(VIRTIO_IOMMU_PROBE_T_NONE, &bufstate)) { + goto failure; + } + return VIRTIO_IOMMU_S_OK; +failure: + return VIRTIO_IOMMU_S_INVAL; +} + static int virtio_iommu_iov_to_req(struct iovec *iov, unsigned int iov_cnt, void *req, size_t req_sz) @@ -398,6 +533,17 @@ static int virtio_iommu_handle_unmap(VirtIOIOMMU *s, return ret ? ret : virtio_iommu_unmap(s, &req); } +static int virtio_iommu_handle_probe(VirtIOIOMMU *s, + struct iovec *iov, + unsigned int iov_cnt, + uint8_t *buf) +{ + struct virtio_iommu_req_probe req; + int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req)); + + return ret ? ret : virtio_iommu_probe(s, &req, buf); +} + static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) { VirtIOIOMMU *s = VIRTIO_IOMMU(vdev); @@ -443,17 +589,33 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) case VIRTIO_IOMMU_T_UNMAP: tail.status = virtio_iommu_handle_unmap(s, iov, iov_cnt); break; + case VIRTIO_IOMMU_T_PROBE: + { + struct virtio_iommu_req_tail *ptail; + uint8_t *buf = g_malloc0(s->config.probe_size + sizeof(tail)); + + ptail = (struct virtio_iommu_req_tail *) + (buf + s->config.probe_size); + ptail->status = virtio_iommu_handle_probe(s, iov, iov_cnt, buf); + + sz = iov_from_buf(elem->in_sg, elem->in_num, 0, + buf, s->config.probe_size + sizeof(tail)); + g_free(buf); + assert(sz == s->config.probe_size + sizeof(tail)); + goto push; + } default: tail.status = VIRTIO_IOMMU_S_UNSUPP; } - qemu_mutex_unlock(&s->mutex); out: sz = iov_from_buf(elem->in_sg, elem->in_num, 0, &tail, sizeof(tail)); assert(sz == sizeof(tail)); - virtqueue_push(vq, elem, sizeof(tail)); +push: + qemu_mutex_unlock(&s->mutex); + virtqueue_push(vq, elem, sz); virtio_notify(vdev, vq); g_free(elem); } @@ -608,6 +770,7 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) s->config.input_range.end = -1UL; s->config.domain_range.start = 0; s->config.domain_range.end = 32; + s->config.probe_size = VIOMMU_PROBE_SIZE; virtio_add_feature(&s->features, VIRTIO_RING_F_EVENT_IDX); virtio_add_feature(&s->features, VIRTIO_RING_F_INDIRECT_DESC); @@ -617,6 +780,7 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS); virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MMIO); + virtio_add_feature(&s->features, VIRTIO_IOMMU_F_PROBE); qemu_mutex_init(&s->mutex); From patchwork Tue Jul 30 17:21:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066315 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1D1BD1395 for ; Tue, 30 Jul 2019 17:26:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3AAB205AD for ; Tue, 30 Jul 2019 17:26:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E8172285CE; Tue, 30 Jul 2019 17:26:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 87855205AD for ; Tue, 30 Jul 2019 17:26:52 +0000 (UTC) Received: from localhost ([::1]:34890 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVtj-0000ua-Ph for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:26:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32908) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqT-0002DT-Jo for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVqS-0001JR-Ie for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40192) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVqQ-0001I1-3J; Tue, 30 Jul 2019 13:23:26 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4EB4D3082141; Tue, 30 Jul 2019 17:23:25 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3D57D60BE5; Tue, 30 Jul 2019 17:23:20 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:33 +0200 Message-Id: <20190730172137.23114-12-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Tue, 30 Jul 2019 17:23:25 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 11/15] virtio-iommu: Expose the IOAPIC MSI reserved region when relevant X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP We introduce a new msi_bypass field which indicates whether the IOAPIC MSI window [0xFEE00000 - 0xFEEFFFFF] must be exposed as a reserved region. By default the field is set to true at instantiation time. Later on we will introduce a property at virtio pci proxy level to turn it off. Signed-off-by: Eric Auger --- v8 -> v9: - pass IOAPIC_RANGE_END to virtio_iommu_register_resv_region - take into account the change in the struct virtio_iommu_probe_resv_mem definition - We just introduce the field here. A property will be introduced later on at pci proxy level. --- hw/virtio/virtio-iommu.c | 36 ++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-iommu.h | 1 + 2 files changed, 37 insertions(+) diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 66be9a4627..74038288b0 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -39,6 +39,9 @@ #define VIOMMU_DEFAULT_QUEUE_SIZE 256 #define VIOMMU_PROBE_SIZE 512 +#define IOAPIC_RANGE_START (0xfee00000) +#define IOAPIC_RANGE_END (0xfeefffff) + #define SUPPORTED_PROBE_PROPERTIES (\ 1 << VIRTIO_IOMMU_PROBE_T_RESV_MEM) @@ -100,6 +103,30 @@ static void virtio_iommu_detach_endpoint_from_domain(viommu_endpoint *ep) ep->domain = NULL; } +static void virtio_iommu_register_resv_region(viommu_endpoint *ep, + uint8_t subtype, + uint64_t start, uint64_t end) +{ + viommu_interval *interval; + struct virtio_iommu_probe_resv_mem *resv_reg_prop; + size_t prop_size = sizeof(struct virtio_iommu_probe_resv_mem); + size_t value_size = prop_size - + sizeof(struct virtio_iommu_probe_property); + + interval = g_malloc0(sizeof(*interval)); + interval->low = start; + interval->high = end; + + resv_reg_prop = g_malloc0(prop_size); + resv_reg_prop->head.type = VIRTIO_IOMMU_PROBE_T_RESV_MEM; + resv_reg_prop->head.length = cpu_to_le64(value_size); + resv_reg_prop->subtype = cpu_to_le64(subtype); + resv_reg_prop->start = cpu_to_le64(start); + resv_reg_prop->end = cpu_to_le64(end); + + g_tree_insert(ep->reserved_regions, interval, resv_reg_prop); +} + static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, uint32_t ep_id) { @@ -117,6 +144,12 @@ static viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s, ep->reserved_regions = g_tree_new_full((GCompareDataFunc)interval_cmp, NULL, (GDestroyNotify)g_free, (GDestroyNotify)g_free); + if (s->msi_bypass) { + virtio_iommu_register_resv_region(ep, VIRTIO_IOMMU_RESV_MEM_T_MSI, + IOAPIC_RANGE_START, + IOAPIC_RANGE_END); + } + return ep; } @@ -822,6 +855,9 @@ static void virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status) static void virtio_iommu_instance_init(Object *obj) { + VirtIOIOMMU *s = VIRTIO_IOMMU(obj); + + s->msi_bypass = true; } static const VMStateDescription vmstate_virtio_iommu = { diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h index f55f48d304..56c8b4e57f 100644 --- a/include/hw/virtio/virtio-iommu.h +++ b/include/hw/virtio/virtio-iommu.h @@ -59,6 +59,7 @@ typedef struct VirtIOIOMMU { GTree *domains; QemuMutex mutex; GTree *endpoints; + bool msi_bypass; } VirtIOIOMMU; #endif From patchwork Tue Jul 30 17:21:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6CCA1395 for ; Tue, 30 Jul 2019 17:28:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A868D1FFBD for ; Tue, 30 Jul 2019 17:28:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9CE55283AD; Tue, 30 Jul 2019 17:28:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 268FC285D4 for ; Tue, 30 Jul 2019 17:28:19 +0000 (UTC) Received: from localhost ([::1]:34918 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVv8-0004FG-Is for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:28:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32940) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqZ-0002YK-KY for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVqY-0001M9-BT for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:35 -0400 Received: from mx1.redhat.com ([209.132.183.28]:26338) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVqV-0001Kb-GB; Tue, 30 Jul 2019 13:23:31 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BA747308218D; Tue, 30 Jul 2019 17:23:30 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id A655160BE5; Tue, 30 Jul 2019 17:23:25 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:34 +0200 Message-Id: <20190730172137.23114-13-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Tue, 30 Jul 2019 17:23:30 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 12/15] virtio-iommu: Implement fault reporting X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The event queue allows to report asynchronous errors. The translate function now injects faults when relevant. Signed-off-by: Eric Auger --- hw/virtio/trace-events | 1 + hw/virtio/virtio-iommu.c | 67 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 2e557dffb4..046290a971 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -77,3 +77,4 @@ virtio_iommu_unmap_inc_interval(uint64_t low, uint64_t high) "Unmap inc [0x%"PRI virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d" virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t start, uint64_t end, uint32_t flags, size_t filled) "dev= %d, subtype=%d start=0x%"PRIx64" end=0x%"PRIx64" flags=%d filled=0x%lx" virtio_iommu_fill_none_property(uint32_t devid) "devid=%d" +virtio_iommu_report_fault(uint8_t reason, uint32_t flags, uint32_t endpoint, uint64_t addr) "FAULT reason=%d flags=%d endpoint=%d address =0x%"PRIx64 diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 74038288b0..8e54a17227 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -654,17 +654,63 @@ push: } } +static void virtio_iommu_report_fault(VirtIOIOMMU *viommu, uint8_t reason, + uint32_t flags, uint32_t endpoint, + uint64_t address) +{ + VirtIODevice *vdev = &viommu->parent_obj; + VirtQueue *vq = viommu->event_vq; + struct virtio_iommu_fault fault; + VirtQueueElement *elem; + size_t sz; + + memset(&fault, 0, sizeof(fault)); + fault.reason = reason; + fault.flags = flags; + fault.endpoint = endpoint; + fault.address = address; + + for (;;) { + elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); + + if (!elem) { + virtio_error(vdev, + "no buffer available in event queue to report event"); + return; + } + + if (iov_size(elem->in_sg, elem->in_num) < sizeof(fault)) { + virtio_error(vdev, "error buffer of wrong size"); + virtqueue_detach_element(vq, elem, 0); + g_free(elem); + continue; + } + break; + } + /* we have a buffer to fill in */ + sz = iov_from_buf(elem->in_sg, elem->in_num, 0, + &fault, sizeof(fault)); + assert(sz == sizeof(fault)); + + trace_virtio_iommu_report_fault(reason, flags, endpoint, address); + virtqueue_push(vq, elem, sz); + virtio_notify(vdev, vq); + g_free(elem); + +} + static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, IOMMUAccessFlags flag, int iommu_idx) { IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr); VirtIOIOMMU *s = sdev->viommu; - uint32_t sid; + uint32_t sid, flags; viommu_endpoint *ep; viommu_mapping *mapping; viommu_interval interval; bool bypass_allowed; + bool read_fault, write_fault; interval.low = addr; interval.high = addr + 1; @@ -689,6 +735,8 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, if (!ep) { if (!bypass_allowed) { error_report("%s sid=%d is not known!!", __func__, sid); + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_UNKNOWN, + 0, sid, 0); } else { entry.perm = flag; } @@ -701,6 +749,8 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, "%s %02x:%02x.%01x not attached to any domain\n", __func__, PCI_BUS_NUM(sid), PCI_SLOT(sid), PCI_FUNC(sid)); + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_DOMAIN, + 0, sid, 0); } else { entry.perm = flag; } @@ -712,14 +762,25 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, qemu_log_mask(LOG_GUEST_ERROR, "%s no mapping for 0x%"PRIx64" for sid=%d\n", __func__, addr, sid); + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING, + 0, sid, addr); goto unlock; } - if (((flag & IOMMU_RO) && !(mapping->flags & VIRTIO_IOMMU_MAP_F_READ)) || - ((flag & IOMMU_WO) && !(mapping->flags & VIRTIO_IOMMU_MAP_F_WRITE))) { + read_fault = (flag & IOMMU_RO) && + !(mapping->flags & VIRTIO_IOMMU_MAP_F_READ); + write_fault = (flag & IOMMU_WO) && + !(mapping->flags & VIRTIO_IOMMU_MAP_F_WRITE); + + flags = read_fault ? VIRTIO_IOMMU_FAULT_F_READ : 0; + flags |= write_fault ? VIRTIO_IOMMU_FAULT_F_WRITE : 0; + if (flags) { qemu_log_mask(LOG_GUEST_ERROR, "Permission error on 0x%"PRIx64"(%d): allowed=%d\n", addr, flag, mapping->flags); + flags |= VIRTIO_IOMMU_FAULT_F_ADDRESS; + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING, + flags, sid, addr); goto unlock; } entry.translated_addr = addr - mapping->virt_addr + mapping->phys_addr; From patchwork Tue Jul 30 17:21:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066313 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0378D1395 for ; Tue, 30 Jul 2019 17:26:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D893D285E2 for ; Tue, 30 Jul 2019 17:26:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CC8EB28516; Tue, 30 Jul 2019 17:26:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7A52028516 for ; Tue, 30 Jul 2019 17:26:03 +0000 (UTC) Received: from localhost ([::1]:34876 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVsw-0007r6-UR for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:26:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32965) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqg-0002qA-56 for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVqf-0001QV-43 for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40838) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVqc-0001O5-VP; Tue, 30 Jul 2019 13:23:39 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 427D03091761; Tue, 30 Jul 2019 17:23:38 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1E0C060BE5; Tue, 30 Jul 2019 17:23:30 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:35 +0200 Message-Id: <20190730172137.23114-14-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Tue, 30 Jul 2019 17:23:38 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 13/15] virtio_iommu: Handle reserved regions in translation process X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP When translating an address we need to check if it belongs to a reserved virtual address range. If it does, there are 2 cases: - it belongs to a RESERVED region: the guest should neither use this address in a MAP not instruct the end-point to DMA on them. We report an error - It belongs to an MSI region: we bypass the translation. Signed-off-by: Eric Auger Reviewed-by: Peter Xu --- v9 -> v10: - in case of MSI region, we immediatly return --- hw/virtio/virtio-iommu.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 8e54a17227..20d92b7ab0 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -711,6 +711,7 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, viommu_interval interval; bool bypass_allowed; bool read_fault, write_fault; + struct virtio_iommu_probe_resv_mem *reg; interval.low = addr; interval.high = addr + 1; @@ -743,6 +744,21 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr, goto unlock; } + reg = g_tree_lookup(ep->reserved_regions, (gpointer)(&interval)); + if (reg) { + switch (reg->subtype) { + case VIRTIO_IOMMU_RESV_MEM_T_MSI: + entry.perm = flag; + return entry; + case VIRTIO_IOMMU_RESV_MEM_T_RESERVED: + default: + virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING, + 0, sid, addr); + break; + } + goto unlock; + } + if (!ep->domain) { if (!bypass_allowed) { qemu_log_mask(LOG_GUEST_ERROR, From patchwork Tue Jul 30 17:21:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066339 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 50EC31395 for ; Tue, 30 Jul 2019 17:32:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3633E286BE for ; Tue, 30 Jul 2019 17:32:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2A88128710; Tue, 30 Jul 2019 17:32:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A1D0C286BE for ; Tue, 30 Jul 2019 17:32:15 +0000 (UTC) Received: from localhost ([::1]:35004 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVyx-0003tb-16 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:32:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33030) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqs-0002y8-Rf for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVqr-0001Xv-HY for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45132) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVqi-0001Sr-Tw; Tue, 30 Jul 2019 13:23:45 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9C67C3C93; Tue, 30 Jul 2019 17:23:43 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 99F7A60BE5; Tue, 30 Jul 2019 17:23:38 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:36 +0200 Message-Id: <20190730172137.23114-15-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 30 Jul 2019 17:23:43 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 14/15] virtio-iommu-pci: Add virtio iommu pci support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds virtio-iommu-pci, which is the pci proxy for the virtio-iommu device. Signed-off-by: Eric Auger --- v8 -> v9: - add the msi-bypass property - create virtio-iommu-pci.c --- hw/virtio/Makefile.objs | 1 + hw/virtio/virtio-iommu-pci.c | 88 ++++++++++++++++++++++++++++++++ include/hw/pci/pci.h | 1 + include/hw/virtio/virtio-iommu.h | 1 + qdev-monitor.c | 1 + 5 files changed, 92 insertions(+) create mode 100644 hw/virtio/virtio-iommu-pci.c diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index f42e4dd94f..80ca719f1c 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -27,6 +27,7 @@ obj-$(CONFIG_VIRTIO_INPUT_HOST) += virtio-input-host-pci.o obj-$(CONFIG_VIRTIO_INPUT) += virtio-input-pci.o obj-$(CONFIG_VIRTIO_RNG) += virtio-rng-pci.o obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon-pci.o +obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu-pci.o obj-$(CONFIG_VIRTIO_9P) += virtio-9p-pci.o obj-$(CONFIG_VIRTIO_SCSI) += virtio-scsi-pci.o obj-$(CONFIG_VIRTIO_BLK) += virtio-blk-pci.o diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c new file mode 100644 index 0000000000..f9977096bd --- /dev/null +++ b/hw/virtio/virtio-iommu-pci.c @@ -0,0 +1,88 @@ +/* + * Virtio IOMMU PCI Bindings + * + * Copyright (c) 2019 Red Hat, Inc. + * Written by Eric Auger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +#include "qemu/osdep.h" + +#include "virtio-pci.h" +#include "hw/virtio/virtio-iommu.h" + +typedef struct VirtIOIOMMUPCI VirtIOIOMMUPCI; + +/* + * virtio-iommu-pci: This extends VirtioPCIProxy. + * + */ +#define VIRTIO_IOMMU_PCI(obj) \ + OBJECT_CHECK(VirtIOIOMMUPCI, (obj), TYPE_VIRTIO_IOMMU_PCI) + +struct VirtIOIOMMUPCI { + VirtIOPCIProxy parent_obj; + VirtIOIOMMU vdev; +}; + +static Property virtio_iommu_pci_properties[] = { + DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0), + DEFINE_PROP_BOOL("msi-bypass", VirtIOIOMMUPCI, vdev.msi_bypass, true), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) +{ + VirtIOIOMMUPCI *dev = VIRTIO_IOMMU_PCI(vpci_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus)); + object_property_set_link(OBJECT(dev), + OBJECT(pci_get_bus(&vpci_dev->pci_dev)), + "primary-bus", errp); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_iommu_pci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); + k->realize = virtio_iommu_pci_realize; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + dc->props = virtio_iommu_pci_properties; + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; + pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_IOMMU; + pcidev_k->revision = VIRTIO_PCI_ABI_VERSION; + pcidev_k->class_id = PCI_CLASS_OTHERS; +} + +static void virtio_iommu_pci_instance_init(Object *obj) +{ + VirtIOIOMMUPCI *dev = VIRTIO_IOMMU_PCI(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_IOMMU); +} + +static const VirtioPCIDeviceTypeInfo virtio_iommu_pci_info = { + .base_name = TYPE_VIRTIO_IOMMU_PCI, + .generic_name = "virtio-iommu-pci", + .transitional_name = "virtio-iommu-pci-transitional", + .non_transitional_name = "virtio-iommu-pci-non-transitional", + .instance_size = sizeof(VirtIOIOMMUPCI), + .instance_init = virtio_iommu_pci_instance_init, + .class_init = virtio_iommu_pci_class_init, +}; + +static void virtio_iommu_pci_register(void) +{ + virtio_pci_types_register(&virtio_iommu_pci_info); +} + +type_init(virtio_iommu_pci_register) + + diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index aaf1b9f70d..492ea7e68d 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -86,6 +86,7 @@ extern bool pci_available; #define PCI_DEVICE_ID_VIRTIO_9P 0x1009 #define PCI_DEVICE_ID_VIRTIO_VSOCK 0x1012 #define PCI_DEVICE_ID_VIRTIO_PMEM 0x1013 +#define PCI_DEVICE_ID_VIRTIO_IOMMU 0x1014 #define PCI_VENDOR_ID_REDHAT 0x1b36 #define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001 diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h index 56c8b4e57f..893ac65c0b 100644 --- a/include/hw/virtio/virtio-iommu.h +++ b/include/hw/virtio/virtio-iommu.h @@ -25,6 +25,7 @@ #include "hw/pci/pci.h" #define TYPE_VIRTIO_IOMMU "virtio-iommu-device" +#define TYPE_VIRTIO_IOMMU_PCI "virtio-iommu-device-base" #define VIRTIO_IOMMU(obj) \ OBJECT_CHECK(VirtIOIOMMU, (obj), TYPE_VIRTIO_IOMMU) diff --git a/qdev-monitor.c b/qdev-monitor.c index 58222c2211..74cf090c61 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -63,6 +63,7 @@ static const QDevAlias qdev_alias_table[] = { { "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_S390X }, { "virtio-input-host-pci", "virtio-input-host", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X }, + { "virtio-iommu-pci", "virtio-iommu", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X }, { "virtio-keyboard-ccw", "virtio-keyboard", QEMU_ARCH_S390X }, { "virtio-keyboard-pci", "virtio-keyboard", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X }, From patchwork Tue Jul 30 17:21:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 11066325 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C53231395 for ; Tue, 30 Jul 2019 17:28:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A5CA726E54 for ; Tue, 30 Jul 2019 17:28:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 97F542841F; Tue, 30 Jul 2019 17:28:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 213851FFBD for ; Tue, 30 Jul 2019 17:28:41 +0000 (UTC) Received: from localhost ([::1]:34926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVvU-0005Kn-Gw for patchwork-qemu-devel@patchwork.kernel.org; Tue, 30 Jul 2019 13:28:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33047) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hsVqu-000316-Bo for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hsVqt-0001ZE-3g for qemu-devel@nongnu.org; Tue, 30 Jul 2019 13:23:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35822) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hsVqn-0001VT-Ls; Tue, 30 Jul 2019 13:23:50 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E3E154E924; Tue, 30 Jul 2019 17:23:48 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-49.ams2.redhat.com [10.36.116.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id F288160BE5; Tue, 30 Jul 2019 17:23:43 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, mst@redhat.com, peter.maydell@linaro.org, alex.williamson@redhat.com, jean-philippe@linaro.org, kevin.tian@intel.com Date: Tue, 30 Jul 2019 19:21:37 +0200 Message-Id: <20190730172137.23114-16-eric.auger@redhat.com> In-Reply-To: <20190730172137.23114-1-eric.auger@redhat.com> References: <20190730172137.23114-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 30 Jul 2019 17:23:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.2 v10 15/15] hw/arm/virt: Add the virtio-iommu device tree mappings X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tn@semihalf.com, bharat.bhushan@nxp.com, peterx@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Adds the "virtio,pci-iommu" node in the host bridge node and the RID mapping, excluding the IOMMU RID. Signed-off-by: Eric Auger --- v8 -> v9: - disable msi-bypass property - addition of the subnode is handled is the hotplug handler and IOMMU RID is notimposed anymore v6 -> v7: - align to the smmu instantiation code v4 -> v5: - VirtMachineClass no_iommu added in this patch - Use object_resolve_path_type --- hw/arm/virt.c | 54 +++++++++++++++++++++++++++++++++++++------ include/hw/arm/virt.h | 2 ++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index d9496c9363..8f6bcba99e 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -32,6 +32,7 @@ #include "qemu-common.h" #include "qemu/units.h" #include "qemu/option.h" +#include "monitor/qdev.h" #include "qapi/error.h" #include "hw/sysbus.h" #include "hw/arm/boot.h" @@ -52,6 +53,7 @@ #include "qemu/error-report.h" #include "qemu/module.h" #include "hw/pci-host/gpex.h" +#include "hw/virtio/virtio-pci.h" #include "hw/arm/sysbus-fdt.h" #include "hw/platform-bus.h" #include "hw/arm/fdt.h" @@ -64,6 +66,7 @@ #include "hw/arm/smmuv3.h" #include "hw/acpi/acpi.h" #include "target/arm/internals.h" +#include "hw/virtio/virtio-iommu.h" #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ @@ -1147,6 +1150,30 @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic, g_free(node); } +static void create_virtio_iommu(VirtMachineState *vms, Error **errp) +{ + const char compat[] = "virtio,pci-iommu"; + uint16_t bdf = vms->virtio_iommu_bdf; + char *node; + + vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt); + + node = g_strdup_printf("%s/virtio_iommu@%d", vms->pciehb_nodename, bdf); + qemu_fdt_add_subnode(vms->fdt, node); + qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", + 1, bdf << 8, 1, 0, 1, 0, + 1, 0, 1, 0); + + qemu_fdt_setprop_cell(vms->fdt, node, "#iommu-cells", 1); + qemu_fdt_setprop_cell(vms->fdt, node, "phandle", vms->iommu_phandle); + g_free(node); + + qemu_fdt_setprop_cells(vms->fdt, vms->pciehb_nodename, "iommu-map", + 0x0, vms->iommu_phandle, 0x0, bdf, + bdf + 1, vms->iommu_phandle, bdf + 1, 0xffff - bdf); +} + static void create_pcie(VirtMachineState *vms, qemu_irq *pic) { hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base; @@ -1224,7 +1251,7 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic) } } - nodename = g_strdup_printf("/pcie@%" PRIx64, base); + nodename = vms->pciehb_nodename = g_strdup_printf("/pcie@%" PRIx64, base); qemu_fdt_add_subnode(vms->fdt, nodename); qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "pci-host-ecam-generic"); @@ -1267,13 +1294,17 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic) if (vms->iommu) { vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt); - create_smmu(vms, pic, pci->bus); + switch (vms->iommu) { + case VIRT_IOMMU_SMMUV3: + create_smmu(vms, pic, pci->bus); + qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map", + 0x0, vms->iommu_phandle, 0x0, 0x10000); + break; + default: + g_assert_not_reached(); + } - qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map", - 0x0, vms->iommu_phandle, 0x0, 0x10000); } - - g_free(nodename); } static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic) @@ -1882,12 +1913,21 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, SYS_BUS_DEVICE(dev)); } } + if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { + PCIDevice *pdev = PCI_DEVICE(dev); + + vms->iommu = VIRT_IOMMU_VIRTIO; + vms->virtio_iommu_bdf = pci_get_bdf(pdev); + object_property_set_bool(OBJECT(dev), false, "msi-bypass", errp); + create_virtio_iommu(vms, errp); + } } static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, DeviceState *dev) { - if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) { + if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE) || + object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { return HOTPLUG_HANDLER(machine); } diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index a72094204e..abdee94f3a 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -121,8 +121,10 @@ typedef struct { bool virt; int32_t gic_version; VirtIOMMUType iommu; + uint16_t virtio_iommu_bdf; struct arm_boot_info bootinfo; MemMapEntry *memmap; + char *pciehb_nodename; const int *irqmap; int smp_cpus; void *fdt;