From patchwork Fri Aug 27 17:21:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12462579 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77288C432BE for ; Fri, 27 Aug 2021 17:31:23 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1DB5760E78 for ; Fri, 27 Aug 2021 17:31:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 1DB5760E78 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.173852.317213 (Exim 4.92) (envelope-from ) id 1mJfh9-0000Pk-V7; Fri, 27 Aug 2021 17:31:11 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 173852.317213; Fri, 27 Aug 2021 17:31:11 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mJfh9-0000Pd-S0; Fri, 27 Aug 2021 17:31:11 +0000 Received: by outflank-mailman (input) for mailman id 173852; Fri, 27 Aug 2021 17:31:10 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mJfYX-00016Q-OM for xen-devel@lists.xenproject.org; Fri, 27 Aug 2021 17:22:17 +0000 Received: from mail-pf1-x42f.google.com (unknown [2607:f8b0:4864:20::42f]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id c2bb90f7-b2bf-47ce-82a5-3477241e9920; Fri, 27 Aug 2021 17:21:50 +0000 (UTC) Received: by mail-pf1-x42f.google.com with SMTP id y11so6214929pfl.13 for ; Fri, 27 Aug 2021 10:21:50 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:36:ef50:8fcd:44d1:eb17]) by smtp.gmail.com with ESMTPSA id f5sm7155015pjo.23.2021.08.27.10.21.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Aug 2021 10:21:48 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: c2bb90f7-b2bf-47ce-82a5-3477241e9920 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=f/xiBxoq9p910rq4iCCIXN3piXXicO8x7yFYnpejeEk=; b=Ju+1YsPkg+UbMh1or5AIAI/ZvTETioYtgUuZZBnkEMEAY4wG/GpaOnM5lRpCuVEexe tumb++OLULd903N2hp7Qy2sLv493o0sqM1ciJZGGmOTkFHwpc0J/Yi0A4EFKybLEXp6A jHk4b+zO0G8lnOcidl94Qugbz4vzXgvdD20Gf0+Za3mE4U4VRUylL95yNp387frjeho3 Tydc+sAk2HjHyRM2/aBSNofuAZ7hYsTRhM8t4bBXBsNP8Ghfc2Eobpq+STxZiiZ5Bjmz KaaohXKSjVg3XUlnBIKCvvdh/pNN14L9P6XuRbik+Tc9GG6lDQBqK96lrzNtAflEBlew xsmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=f/xiBxoq9p910rq4iCCIXN3piXXicO8x7yFYnpejeEk=; b=PEU8loJZo9gmj2l0C3demIuTaPatfCreiYoyyk/Rpn5SN/9bgeVD1OA4gbK649C8VH bjgkVm7ybM8t684zPecAEo0T6AHTygaGTpK3o2FhCQQBQXlNEtf0JxPWMvso7OIhGh5j 1h4V/dvrcRP+YUq5XolOds6AZwqUpSQXDCzkWaWpP3Rmhmx/L227BwiEj0gZkQ41snPn NEJpYprJV5lAWZgZJGMCS4xw0NEv+LpVlZ4KyoMRWBDBrqn96wZOiusMSb8NZtu7ZdEA Zp1uSmYWOm56Z7Q53QZonhPOMUFU66WcEwZkuKZ1l7zO4fqbHwFtTMoiOhZDqXXS6ccH iNHw== X-Gm-Message-State: AOAM532H178asoJW+Mf5ICYGJg/+70Q0lrdlZjCBeorMo94pEwlYr9xQ +6Z/wvetQ/5KwSmyCVjtwig= X-Google-Smtp-Source: ABdhPJzpavlzdHZS1F6vdwwwOqwaFBPaG/YJGq0r0zJwRIjYidAu7mB3ClbmW59sMbVlOn28t15kbQ== X-Received: by 2002:a63:4f51:: with SMTP id p17mr8806904pgl.29.1630084909372; Fri, 27 Aug 2021 10:21:49 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, dave.hansen@linux.intel.com, luto@kernel.org, peterz@infradead.org, konrad.wilk@oracle.com, boris.ostrovsky@oracle.com, jgross@suse.com, sstabellini@kernel.org, joro@8bytes.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com, gregkh@linuxfoundation.org, arnd@arndb.de, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, brijesh.singh@amd.com, thomas.lendacky@amd.com, Tianyu.Lan@microsoft.com, pgonda@google.com, martin.b.radev@gmail.com, akpm@linux-foundation.org, kirill.shutemov@linux.intel.com, rppt@kernel.org, hannes@cmpxchg.org, aneesh.kumar@linux.ibm.com, krish.sadhukhan@oracle.com, saravanand@fb.com, linux-arm-kernel@lists.infradead.org, xen-devel@lists.xenproject.org, rientjes@google.com, ardb@kernel.org, michael.h.kelley@microsoft.com Cc: iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, parri.andrea@gmail.com, dave.hansen@intel.com Subject: [PATCH V4 11/13] hyperv/IOMMU: Enable swiotlb bounce buffer for Isolation VM Date: Fri, 27 Aug 2021 13:21:09 -0400 Message-Id: <20210827172114.414281-12-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210827172114.414281-1-ltykernel@gmail.com> References: <20210827172114.414281-1-ltykernel@gmail.com> MIME-Version: 1.0 From: Tianyu Lan hyperv Isolation VM requires bounce buffer support to copy data from/to encrypted memory and so enable swiotlb force mode to use swiotlb bounce buffer for DMA transaction. In Isolation VM with AMD SEV, the bounce buffer needs to be accessed via extra address space which is above shared_gpa_boundary (E.G 39 bit address line) reported by Hyper-V CPUID ISOLATION_CONFIG. The access physical address will be original physical address + shared_gpa_boundary. The shared_gpa_boundary in the AMD SEV SNP spec is called virtual top of memory(vTOM). Memory addresses below vTOM are automatically treated as private while memory above vTOM is treated as shared. Swiotlb bounce buffer code calls dma_map_decrypted() to mark bounce buffer visible to host and map it in extra address space. Populate dma memory decrypted ops with hv map/unmap function. Hyper-V initalizes swiotlb bounce buffer and default swiotlb needs to be disabled. pci_swiotlb_detect_override() and pci_swiotlb_detect_4gb() enable the default one. To override the setting, hyperv_swiotlb_detect() needs to run before these detect functions which depends on the pci_xen_swiotlb_ init(). Make pci_xen_swiotlb_init() depends on the hyperv_swiotlb _detect() to keep the order. The map function vmap_pfn() can't work in the early place hyperv_iommu_swiotlb_init() and so initialize swiotlb bounce buffer in the hyperv_iommu_swiotlb_later_init(). Signed-off-by: Tianyu Lan --- Change since v3: * Get hyperv bounce bufffer size via default swiotlb bounce buffer size function and keep default size as same as the one in the AMD SEV VM. --- arch/x86/hyperv/ivm.c | 28 +++++++++++++++ arch/x86/include/asm/mshyperv.h | 2 ++ arch/x86/mm/mem_encrypt.c | 3 +- arch/x86/xen/pci-swiotlb-xen.c | 3 +- drivers/hv/vmbus_drv.c | 3 ++ drivers/iommu/hyperv-iommu.c | 61 +++++++++++++++++++++++++++++++++ include/linux/hyperv.h | 1 + 7 files changed, 99 insertions(+), 2 deletions(-) diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c index e761c67e2218..84563b3c9f3a 100644 --- a/arch/x86/hyperv/ivm.c +++ b/arch/x86/hyperv/ivm.c @@ -294,3 +294,31 @@ int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible) return __hv_set_mem_host_visibility((void *)addr, numpages, visibility); } + +/* + * hv_map_memory - map memory to extra space in the AMD SEV-SNP Isolation VM. + */ +void *hv_map_memory(void *addr, unsigned long size) +{ + unsigned long *pfns = kcalloc(size / HV_HYP_PAGE_SIZE, + sizeof(unsigned long), GFP_KERNEL); + void *vaddr; + int i; + + if (!pfns) + return NULL; + + for (i = 0; i < size / PAGE_SIZE; i++) + pfns[i] = virt_to_hvpfn(addr + i * PAGE_SIZE) + + (ms_hyperv.shared_gpa_boundary >> PAGE_SHIFT); + + vaddr = vmap_pfn(pfns, size / PAGE_SIZE, PAGE_KERNEL_IO); + kfree(pfns); + + return vaddr; +} + +void hv_unmap_memory(void *addr) +{ + vunmap(addr); +} diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index b77f4caee3ee..627fcf8d443c 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -252,6 +252,8 @@ int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry); int hv_mark_gpa_visibility(u16 count, const u64 pfn[], enum hv_mem_host_visibility visibility); int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible); +void *hv_map_memory(void *addr, unsigned long size); +void hv_unmap_memory(void *addr); void hv_sint_wrmsrl_ghcb(u64 msr, u64 value); void hv_sint_rdmsrl_ghcb(u64 msr, u64 *value); void hv_signal_eom_ghcb(void); diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index ff08dc463634..e2db0b8ed938 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "mm_internal.h" @@ -202,7 +203,7 @@ void __init sev_setup_arch(void) phys_addr_t total_mem = memblock_phys_mem_size(); unsigned long size; - if (!sev_active()) + if (!sev_active() && !hv_is_isolation_supported()) return; /* diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index 54f9aa7e8457..43bd031aa332 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -91,6 +92,6 @@ int pci_xen_swiotlb_init_late(void) EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late); IOMMU_INIT_FINISH(pci_xen_swiotlb_detect, - NULL, + hyperv_swiotlb_detect, pci_xen_swiotlb_init, NULL); diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 57bbbaa4e8f7..f068e22a5636 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -2081,6 +2082,7 @@ struct hv_device *vmbus_device_create(const guid_t *type, return child_device_obj; } +static u64 vmbus_dma_mask = DMA_BIT_MASK(64); /* * vmbus_device_register - Register the child device */ @@ -2121,6 +2123,7 @@ int vmbus_device_register(struct hv_device *child_device_obj) } hv_debug_add_dev_dir(child_device_obj); + child_device_obj->device.dma_mask = &vmbus_dma_mask; return 0; err_kset_unregister: diff --git a/drivers/iommu/hyperv-iommu.c b/drivers/iommu/hyperv-iommu.c index e285a220c913..899563551574 100644 --- a/drivers/iommu/hyperv-iommu.c +++ b/drivers/iommu/hyperv-iommu.c @@ -13,14 +13,22 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include #include #include #include +#include +#include +#include +#include #include "irq_remapping.h" @@ -36,6 +44,9 @@ static cpumask_t ioapic_max_cpumask = { CPU_BITS_NONE }; static struct irq_domain *ioapic_ir_domain; +static unsigned long hyperv_io_tlb_size; +static void *hyperv_io_tlb_start; + static int hyperv_ir_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { @@ -337,4 +348,54 @@ static const struct irq_domain_ops hyperv_root_ir_domain_ops = { .free = hyperv_root_irq_remapping_free, }; +void __init hyperv_iommu_swiotlb_init(void) +{ + /* + * Allocate Hyper-V swiotlb bounce buffer at early place + * to reserve large contiguous memory. + */ + hyperv_io_tlb_size = swiotlb_size_or_default(); + hyperv_io_tlb_start = memblock_alloc( + hyperv_io_tlb_size, HV_HYP_PAGE_SIZE); + + if (!hyperv_io_tlb_start) { + pr_warn("Fail to allocate Hyper-V swiotlb buffer.\n"); + return; + } +} + +int __init hyperv_swiotlb_detect(void) +{ + if (hypervisor_is_type(X86_HYPER_MS_HYPERV) + && hv_is_isolation_supported()) { + /* + * Enable swiotlb force mode in Isolation VM to + * use swiotlb bounce buffer for dma transaction. + */ + swiotlb_force = SWIOTLB_FORCE; + + dma_memory_generic_decrypted_ops.map = hv_map_memory; + dma_memory_generic_decrypted_ops.unmap = hv_unmap_memory; + return 1; + } + + return 0; +} + +void __init hyperv_iommu_swiotlb_later_init(void) +{ + /* + * Swiotlb bounce buffer needs to be mapped in extra address + * space. Map function doesn't work in the early place and so + * call swiotlb_late_init_with_tbl() here. + */ + if (swiotlb_late_init_with_tbl(hyperv_io_tlb_start, + hyperv_io_tlb_size >> IO_TLB_SHIFT)) + panic("Fail to initialize hyperv swiotlb.\n"); +} + +IOMMU_INIT_FINISH(hyperv_swiotlb_detect, + NULL, hyperv_iommu_swiotlb_init, + hyperv_iommu_swiotlb_later_init); + #endif diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 757e09606fd3..724a735d722a 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1739,6 +1739,7 @@ int hyperv_write_cfg_blk(struct pci_dev *dev, void *buf, unsigned int len, int hyperv_reg_block_invalidate(struct pci_dev *dev, void *context, void (*block_invalidate)(void *context, u64 block_mask)); +int __init hyperv_swiotlb_detect(void); struct hyperv_pci_block_ops { int (*read_block)(struct pci_dev *dev, void *buf, unsigned int buf_len,