From patchwork Wed Apr 14 14:49:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203069 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 8EB37C4360C for ; Wed, 14 Apr 2021 14:50:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 61479611B0 for ; Wed, 14 Apr 2021 14:50:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351962AbhDNOuw (ORCPT ); Wed, 14 Apr 2021 10:50:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232107AbhDNOus (ORCPT ); Wed, 14 Apr 2021 10:50:48 -0400 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C81F7C06175F; Wed, 14 Apr 2021 07:50:25 -0700 (PDT) Received: by mail-pl1-x62a.google.com with SMTP id p16so6280186plf.12; Wed, 14 Apr 2021 07:50:25 -0700 (PDT) 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=OsFA5UjGBBz+WpI+wHtQ7Mb2J7cYrRLymhsyTS1f9mI=; b=dvEn7FiJ1SLom9xWKqMrGFlIo/UlMk3c6iQjeTXBfWODS9IhMJsyMTZ4T1MWyHKk/4 Ix8pR/zj8RdUuVlBI3ZAcfvK7Y1vkv8B0grJfNVMiycDAw1nN84wKIiCCHarKZnTpAAd yRsIqVkNTbfLqBTAPuU56Fk8Fjkp13hnLsMXR0yNyxBPTC3F5CL4ste7XhqNfOHBeRiH lRHYGYH7S/xtunirGgYHazOMlHl8Xt//vGYTB2KCLdGA8YGV4X4SWLPOTMNUNjHdh2L6 FHWlGTxK7iHLx+Wwh2HdefoSlQe/4ZwhjFfZyz6JAP50pp7EB0eC+OEONvK82+QyrEBc F3Yw== 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=OsFA5UjGBBz+WpI+wHtQ7Mb2J7cYrRLymhsyTS1f9mI=; b=REEBFLfp8c5/yU7luB6xFF0wfRdNc1cOs3gtSpZyPhvvFazLPukCz1UFoBaJxPQKut CwumnnGbVvXiyVcJ+GQjTZEHyprenTnz2v2k/BSM2Pj9HsthRq2azDUfxP7Jr9s8EHH4 QTBOIaiIm4GeHYKxlVKTibeV4q2qp8f3hDMi9Wbkhk65QVfEbXSwzueYsE9g6op3dOx6 LtzntidU8g9DCvqSgEHfUcLYhNfMrUtdW73LKWgq3seD4QPThrctwQ4ih7sTQ9nxJgj+ INfIKVuK8zn7vjaZCVIaPck57fa6ebamqmxjf1snTyKMeIKvPZ+RvxjdtMouXs1h09LO MMiA== X-Gm-Message-State: AOAM5327cDwfNYp1OVm1J5uq5DxanN/2zJzyoPQwH3HedFweRxj/GMNA yUqWgT1mYr1bDsf5clIkACc= X-Google-Smtp-Source: ABdhPJxOQSk6nZAoLefZfe857h19ZUVboJUlPFq4tkSU5Klpf/RhVEGVnYRpm3ZLMAu1mlXfBJ+M3Q== X-Received: by 2002:a17:902:e784:b029:e9:997a:6a27 with SMTP id cp4-20020a170902e784b02900e9997a6a27mr33074259plb.9.1618411825427; Wed, 14 Apr 2021 07:50:25 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:25 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 01/12] x86/HV: Initialize GHCB page in Isolation VM Date: Wed, 14 Apr 2021 10:49:34 -0400 Message-Id: <20210414144945.3460554-2-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan Hyper-V exposes GHCB page via SEV ES GHCB MSR for SNP guest to communicate with hypervisor. Map GHCB page for all cpus to read/write MSR register and submit hvcall request via GHCB. Signed-off-by: Tianyu Lan --- arch/x86/hyperv/hv_init.c | 52 +++++++++++++++++++++++++++++++--- include/asm-generic/mshyperv.h | 1 + 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 0db5137d5b81..90e65fbf4c58 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -82,6 +82,9 @@ static int hv_cpu_init(unsigned int cpu) struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()]; void **input_arg; struct page *pg; + u64 ghcb_gpa; + void *ghcb_va; + void **ghcb_base; /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */ pg = alloc_pages(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL, hv_root_partition ? 1 : 0); @@ -128,6 +131,17 @@ static int hv_cpu_init(unsigned int cpu) wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, val); } + if (ms_hyperv.ghcb_base) { + rdmsrl(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa); + + ghcb_va = ioremap_cache(ghcb_gpa, HV_HYP_PAGE_SIZE); + if (!ghcb_va) + return -ENOMEM; + + ghcb_base = (void **)this_cpu_ptr(ms_hyperv.ghcb_base); + *ghcb_base = ghcb_va; + } + return 0; } @@ -223,6 +237,7 @@ static int hv_cpu_die(unsigned int cpu) unsigned long flags; void **input_arg; void *pg; + void **ghcb_va = NULL; local_irq_save(flags); input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); @@ -236,6 +251,13 @@ static int hv_cpu_die(unsigned int cpu) *output_arg = NULL; } + if (ms_hyperv.ghcb_base) { + ghcb_va = (void **)this_cpu_ptr(ms_hyperv.ghcb_base); + if (*ghcb_va) + iounmap(*ghcb_va); + *ghcb_va = NULL; + } + local_irq_restore(flags); free_pages((unsigned long)pg, hv_root_partition ? 1 : 0); @@ -372,6 +394,9 @@ void __init hyperv_init(void) u64 guest_id, required_msrs; union hv_x64_msr_hypercall_contents hypercall_msr; int cpuhp, i; + u64 ghcb_gpa; + void *ghcb_va; + void **ghcb_base; if (x86_hyper_type != X86_HYPER_MS_HYPERV) return; @@ -432,9 +457,24 @@ void __init hyperv_init(void) VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS, NUMA_NO_NODE, __builtin_return_address(0)); - if (hv_hypercall_pg == NULL) { - wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); - goto remove_cpuhp_state; + if (hv_hypercall_pg == NULL) + goto clean_guest_os_id; + + if (hv_isolation_type_snp()) { + ms_hyperv.ghcb_base = alloc_percpu(void *); + if (!ms_hyperv.ghcb_base) + goto clean_guest_os_id; + + rdmsrl(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa); + ghcb_va = ioremap_cache(ghcb_gpa, HV_HYP_PAGE_SIZE); + if (!ghcb_va) { + free_percpu(ms_hyperv.ghcb_base); + ms_hyperv.ghcb_base = NULL; + goto clean_guest_os_id; + } + + ghcb_base = (void **)this_cpu_ptr(ms_hyperv.ghcb_base); + *ghcb_base = ghcb_va; } rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); @@ -499,7 +539,8 @@ void __init hyperv_init(void) return; -remove_cpuhp_state: +clean_guest_os_id: + wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); cpuhp_remove_state(cpuhp); free_vp_assist_page: kfree(hv_vp_assist_page); @@ -528,6 +569,9 @@ void hyperv_cleanup(void) */ hv_hypercall_pg = NULL; + if (ms_hyperv.ghcb_base) + free_percpu(ms_hyperv.ghcb_base); + /* Reset the hypercall page */ hypercall_msr.as_uint64 = 0; wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h index dff58a3db5d5..c6f4c5c20fb8 100644 --- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -35,6 +35,7 @@ struct ms_hyperv_info { u32 max_lp_index; u32 isolation_config_a; u32 isolation_config_b; + void __percpu **ghcb_base; }; extern struct ms_hyperv_info ms_hyperv; From patchwork Wed Apr 14 14:49:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203071 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 9CF59C43619 for ; Wed, 14 Apr 2021 14:50:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7126A6117A for ; Wed, 14 Apr 2021 14:50:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351971AbhDNOuy (ORCPT ); Wed, 14 Apr 2021 10:50:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350003AbhDNOut (ORCPT ); Wed, 14 Apr 2021 10:50:49 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB474C061574; Wed, 14 Apr 2021 07:50:26 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id f2-20020a17090a4a82b02900c67bf8dc69so12659772pjh.1; Wed, 14 Apr 2021 07:50:26 -0700 (PDT) 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=Iz6kQKmaAStJz2j939/tUEj2NIuTRDYIEtDill+C7IA=; b=D2taYVTe0z905CX87qYISBKtJJpcQncx/+jlzFtm+dqJ1FQrZXjYZ180oWEO28Y5y7 hlj6+yRPwjy4zDBc0qTSTOI4n3R9lkebe1U3i+D2ckp00qt3mqEM+7XERpL1KMDNXJn4 7wjSfLucr+uk3vZczBhcDhkKTijEPUzFZEFYwB9fuw000bOFSdkhpR5X452OAoNmDZSB 6R6DV6d3gKGUbhWxGXR8WhVAEQ7hP4x7wYAWlA87Le8gNxzh+cepaPjZjUSKkvMtMjhr s43ZTcJK8Kv06ThNFTuC2wlW97YulfZnT+41LKU+KQPRORDoo8Bg8JSixilt/nL1ihKW mQ+Q== 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=Iz6kQKmaAStJz2j939/tUEj2NIuTRDYIEtDill+C7IA=; b=AATid6iZ/MaYVrgV5BoG0WktjMso1ISqO5MoNS+tQbKPR+vO7ctXEfwOs62LltuWec EhkeF8jvT1QO+Giuxp5RBX5GEG0AEjH+1MpxQno6D2Vf+HGhRoKGr4lpfZ1PSif2PxFg BQaofx9SUuHql05ukc9qeLsJxJJLvhQfeJd5hb9ep0grRimZ94hjFRZbiKymm2xxLl+N HyMhB7yHjsNl07PTAAA+AqZ3ykYXnYMSNRcauxgYa/751zGRYa/7R/R/kyP7vF7EpWtM qsXt+ngr0+PJmO7DPsfBgHdsPF+vJk0gjV1DRJJqG7VSy/GwESvtuJbU4IXLokdHVRvh PTMQ== X-Gm-Message-State: AOAM530VU/uagLS7AtplvH2xozMVyB67rp3ZxaaYCq48Pors8+v57ojh 0gL6w4WNg5UiH6hRni06zDo= X-Google-Smtp-Source: ABdhPJwoWQUtM+Kmo2QdePpZgHK8I2K8arUG2KPZ/TVvHugCh22W4iDEwoDeLZUiglDRWNvFY5wZBA== X-Received: by 2002:a17:90a:bf17:: with SMTP id c23mr4103212pjs.12.1618411826429; Wed, 14 Apr 2021 07:50:26 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:26 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 02/12] x86/HV: Initialize shared memory boundary in Isolation VM Date: Wed, 14 Apr 2021 10:49:35 -0400 Message-Id: <20210414144945.3460554-3-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan Hyper-V exposes shared memory boundary via cpuid HYPERV_ CPUID_ISOLATION_CONFIG and store it in the shared_gpa_ boundary of ms_hyperv struct. This prepares to share memory with host for AMD SEV SNP guest. Signed-off-by: Tianyu Lan --- arch/x86/kernel/cpu/mshyperv.c | 2 ++ include/asm-generic/mshyperv.h | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index e88bc296afca..aeafd4017c89 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -328,6 +328,8 @@ static void __init ms_hyperv_init_platform(void) if (ms_hyperv.features_b & HV_ISOLATION) { ms_hyperv.isolation_config_a = cpuid_eax(HYPERV_CPUID_ISOLATION_CONFIG); ms_hyperv.isolation_config_b = cpuid_ebx(HYPERV_CPUID_ISOLATION_CONFIG); + ms_hyperv.shared_gpa_boundary = + (u64)1 << ms_hyperv.shared_gpa_boundary_bits; pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n", ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b); diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h index c6f4c5c20fb8..b73e201abc70 100644 --- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -34,8 +34,19 @@ struct ms_hyperv_info { u32 max_vp_index; u32 max_lp_index; u32 isolation_config_a; - u32 isolation_config_b; + union + { + u32 isolation_config_b; + struct { + u32 cvm_type : 4; + u32 Reserved11 : 1; + u32 shared_gpa_boundary_active : 1; + u32 shared_gpa_boundary_bits : 6; + u32 Reserved12 : 20; + }; + }; void __percpu **ghcb_base; + u64 shared_gpa_boundary; }; extern struct ms_hyperv_info ms_hyperv; From patchwork Wed Apr 14 14:49:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203073 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 38182C41602 for ; Wed, 14 Apr 2021 14:50:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2CB17611F2 for ; Wed, 14 Apr 2021 14:50:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351983AbhDNOuz (ORCPT ); Wed, 14 Apr 2021 10:50:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351943AbhDNOuv (ORCPT ); Wed, 14 Apr 2021 10:50:51 -0400 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D76E6C061756; Wed, 14 Apr 2021 07:50:27 -0700 (PDT) Received: by mail-pf1-x435.google.com with SMTP id a12so13892857pfc.7; Wed, 14 Apr 2021 07:50:27 -0700 (PDT) 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=VCvpfni3tSAbSi77TUkA2y1YbUZDkx34x/OnlYhxw8U=; b=Y4yuMsQrTwKF51+tI3EAmrTclCZmcXNduShvUGKd7yNr9z3memicyKPwZNm4qSBsGo O2Pzkt4P71rbVeXwiOWPZYmSmax+RCqnLlLqzCL91IgoIwWb/SjjfDDmQsOLFNnJQQ81 N9ZRYO+gyHFjsVXbLuxDTr364faVhXkMywA0lqXYLNc//7SU2ViCE4PB1KXcEDaA/SQE NmKjdpVM2jyAYHRgKzOlm0B+nG+0zXuxu6W+0zxNQwkkxEThjUY1w0/sYO9IqKprGVUW 0cBAYKgRFAU71ztTilCKrzUqQ8QwE/hDOdn5hlcpec4LvT4Z5M8V+d+W8blgs4jE97Qm bYwA== 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=VCvpfni3tSAbSi77TUkA2y1YbUZDkx34x/OnlYhxw8U=; b=X8QsPx0LmYqoID49fwvNmfublOgjTgaQh2d4F10jRzK1L9Pt8MOsnybgU57hLtY3s8 SKyk/AtVeHYrudVXnY0cd3nzCwyrx+jOUPaLgYBpX3CmTqfhfdRRE87BxBUGcHIxLySj q8bvgOvqQC+lNWu7X+/nPl2tDuUhdRgq/ildJTprbMvchBjBEn2Ze94YAU5OOZbEUpPa N/Aa36qxQmltOz8CqvKWlOpUpK/YnKKJ90BEFed/6birKs0/Rhv8iOV8bKHXlOJc8lQ1 x/4gkoxhFjtL+YnU1tqNvfawA6oQXZzq51k5+BbgZSoy4XbvADgTmV6dKRLsNbO5VLGr fEKA== X-Gm-Message-State: AOAM5315M+32F3bQ4KA+mOGLJ7d+p8EK+qSSN3gP9iDoJOcm8kx8gDy6 pQK9EcPBX1SiYJ0lNIMP94U= X-Google-Smtp-Source: ABdhPJwK9XTSF4hhe6a5pw4+t4k7NVTtvsq1u7vrg8AXSM02uZPeZfyWPVg9Y2BFjGfctgOe6bSeGA== X-Received: by 2002:aa7:850e:0:b029:248:2cfa:2ae2 with SMTP id v14-20020aa7850e0000b02902482cfa2ae2mr23726323pfn.38.1618411827420; Wed, 14 Apr 2021 07:50:27 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:27 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 03/12] x86/Hyper-V: Add new hvcall guest address host visibility support Date: Wed, 14 Apr 2021 10:49:36 -0400 Message-Id: <20210414144945.3460554-4-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan Add new hvcall guest address host visibility support. Mark vmbus ring buffer visible to host when create gpadl buffer and mark back to not visible when tear down gpadl buffer. Co-Developed-by: Sunil Muthuswamy Signed-off-by: Tianyu Lan --- arch/x86/hyperv/Makefile | 2 +- arch/x86/hyperv/ivm.c | 90 ++++++++++++++++++++++++++++++ arch/x86/include/asm/hyperv-tlfs.h | 22 ++++++++ arch/x86/include/asm/mshyperv.h | 2 + drivers/hv/channel.c | 34 ++++++++++- include/asm-generic/hyperv-tlfs.h | 1 + include/linux/hyperv.h | 12 +++- 7 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 arch/x86/hyperv/ivm.c diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile index 48e2c51464e8..5d2de10809ae 100644 --- a/arch/x86/hyperv/Makefile +++ b/arch/x86/hyperv/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-y := hv_init.o mmu.o nested.o irqdomain.o +obj-y := hv_init.o mmu.o nested.o irqdomain.o ivm.o obj-$(CONFIG_X86_64) += hv_apic.o hv_proc.o ifdef CONFIG_X86_64 diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c new file mode 100644 index 000000000000..a5950b7a9214 --- /dev/null +++ b/arch/x86/hyperv/ivm.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hyper-V Isolation VM interface with paravisor and hypervisor + * + * Author: + * Tianyu Lan + */ + +#include +#include +#include +#include +#include + +/* + * hv_set_mem_host_visibility - Set host visibility for specified memory. + */ +int hv_set_mem_host_visibility(void *kbuffer, u32 size, u32 visibility) +{ + int i, pfn; + int pagecount = size >> HV_HYP_PAGE_SHIFT; + u64 *pfn_array; + int ret = 0; + + pfn_array = vzalloc(HV_HYP_PAGE_SIZE); + if (!pfn_array) + return -ENOMEM; + + for (i = 0, pfn = 0; i < pagecount; i++) { + pfn_array[pfn] = virt_to_hvpfn(kbuffer + i * HV_HYP_PAGE_SIZE); + pfn++; + + if (pfn == HV_MAX_MODIFY_GPA_REP_COUNT || i == pagecount - 1) { + ret = hv_mark_gpa_visibility(pfn, pfn_array, visibility); + pfn = 0; + + if (ret) + goto err_free_pfn_array; + } + } + + err_free_pfn_array: + vfree(pfn_array); + return ret; +} +EXPORT_SYMBOL_GPL(hv_set_mem_host_visibility); + +int hv_mark_gpa_visibility(u16 count, const u64 pfn[], u32 visibility) +{ + struct hv_input_modify_sparse_gpa_page_host_visibility **input_pcpu; + struct hv_input_modify_sparse_gpa_page_host_visibility *input; + u16 pages_processed; + u64 hv_status; + unsigned long flags; + + /* no-op if partition isolation is not enabled */ + if (!hv_is_isolation_supported()) + return 0; + + if (count > HV_MAX_MODIFY_GPA_REP_COUNT) { + pr_err("Hyper-V: GPA count:%d exceeds supported:%lu\n", count, + HV_MAX_MODIFY_GPA_REP_COUNT); + return -EINVAL; + } + + local_irq_save(flags); + input_pcpu = (struct hv_input_modify_sparse_gpa_page_host_visibility **) + this_cpu_ptr(hyperv_pcpu_input_arg); + input = *input_pcpu; + if (unlikely(!input)) { + local_irq_restore(flags); + return -1; + } + + input->partition_id = HV_PARTITION_ID_SELF; + input->host_visibility = visibility; + input->reserved0 = 0; + input->reserved1 = 0; + memcpy((void *)input->gpa_page_list, pfn, count * sizeof(*pfn)); + hv_status = hv_do_rep_hypercall( + HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY, count, + 0, input, &pages_processed); + local_irq_restore(flags); + + if (!(hv_status & HV_HYPERCALL_RESULT_MASK)) + return 0; + + return hv_status & HV_HYPERCALL_RESULT_MASK; +} +EXPORT_SYMBOL(hv_mark_gpa_visibility); diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index e6cd3fee562b..1f1ce9afb6f1 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h @@ -236,6 +236,15 @@ enum hv_isolation_type { /* TSC invariant control */ #define HV_X64_MSR_TSC_INVARIANT_CONTROL 0x40000118 +/* Hyper-V GPA map flags */ +#define HV_MAP_GPA_PERMISSIONS_NONE 0x0 +#define HV_MAP_GPA_READABLE 0x1 +#define HV_MAP_GPA_WRITABLE 0x2 + +#define VMBUS_PAGE_VISIBLE_READ_ONLY HV_MAP_GPA_READABLE +#define VMBUS_PAGE_VISIBLE_READ_WRITE (HV_MAP_GPA_READABLE|HV_MAP_GPA_WRITABLE) +#define VMBUS_PAGE_NOT_VISIBLE HV_MAP_GPA_PERMISSIONS_NONE + /* * Declare the MSR used to setup pages used to communicate with the hypervisor. */ @@ -564,4 +573,17 @@ enum hv_interrupt_type { #include +/* All input parameters should be in single page. */ +#define HV_MAX_MODIFY_GPA_REP_COUNT \ + ((PAGE_SIZE / sizeof(u64)) - 2) + +/* HvCallModifySparseGpaPageHostVisibility hypercall */ +struct hv_input_modify_sparse_gpa_page_host_visibility { + u64 partition_id; + u32 host_visibility:2; + u32 reserved0:30; + u32 reserved1; + u64 gpa_page_list[HV_MAX_MODIFY_GPA_REP_COUNT]; +} __packed; + #endif diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index ccf60a809a17..d9437f096ce5 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -269,6 +269,8 @@ int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector, struct hv_interrupt_entry *entry); int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry); +int hv_set_mem_host_visibility(void *kbuffer, u32 size, u32 visibility); +int hv_mark_gpa_visibility(u16 count, const u64 pfn[], u32 visibility); #else /* CONFIG_HYPERV */ static inline void hyperv_init(void) {} static inline void hyperv_setup_mmu_ops(void) {} diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 0bd202de7960..407b74d72f3f 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -400,7 +400,7 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel, struct list_head *curr; u32 next_gpadl_handle; unsigned long flags; - int ret = 0; + int ret = 0, index; next_gpadl_handle = (atomic_inc_return(&vmbus_connection.next_gpadl_handle) - 1); @@ -409,6 +409,13 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel, if (ret) return ret; + ret = hv_set_mem_host_visibility(kbuffer, size, + VMBUS_PAGE_VISIBLE_READ_WRITE); + if (ret) { + pr_warn("Failed to set host visibility.\n"); + return ret; + } + init_completion(&msginfo->waitevent); msginfo->waiting_channel = channel; @@ -484,6 +491,16 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel, } kfree(msginfo); + + if (type == HV_GPADL_BUFFER) + index = 0; + else + index = channel->gpadl_range[1].gpadlhandle ? 2 : 1; + + channel->gpadl_range[index].size = size; + channel->gpadl_range[index].buffer = kbuffer; + channel->gpadl_range[index].gpadlhandle = *gpadl_handle; + return ret; } @@ -743,7 +760,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) struct vmbus_channel_gpadl_teardown *msg; struct vmbus_channel_msginfo *info; unsigned long flags; - int ret; + int ret, i; info = kzalloc(sizeof(*info) + sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); @@ -791,6 +808,19 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); kfree(info); + + /* Find gpadl buffer virtual address and size. */ + for (i = 0; i < VMBUS_GPADL_RANGE_COUNT; i++) + if (channel->gpadl_range[i].gpadlhandle == gpadl_handle) + break; + + if (hv_set_mem_host_visibility(channel->gpadl_range[i].buffer, + channel->gpadl_range[i].size, + VMBUS_PAGE_NOT_VISIBLE)) + pr_warn("Fail to set mem host visibility.\n"); + + channel->gpadl_range[i].gpadlhandle = 0; + return ret; } EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl); diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h index 83448e837ded..ad19f4199f90 100644 --- a/include/asm-generic/hyperv-tlfs.h +++ b/include/asm-generic/hyperv-tlfs.h @@ -158,6 +158,7 @@ struct ms_hyperv_tsc_page { #define HVCALL_RETARGET_INTERRUPT 0x007e #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0 +#define HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY 0x00db #define HV_FLUSH_ALL_PROCESSORS BIT(0) #define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index f1d74dcf0353..b877a68f326c 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -788,6 +788,14 @@ struct vmbus_device { bool allowed_in_isolated; }; +struct vmbus_gpadl_range { + u32 gpadlhandle; + u32 size; + void *buffer; +}; + +#define VMBUS_GPADL_RANGE_COUNT 3 + struct vmbus_channel { struct list_head listentry; @@ -808,6 +816,8 @@ struct vmbus_channel { struct completion rescind_event; u32 ringbuffer_gpadlhandle; + /* GPADL_RING and Send/Receive GPADL_BUFFER. */ + struct vmbus_gpadl_range gpadl_range[VMBUS_GPADL_RANGE_COUNT]; /* Allocated memory for ring buffer */ struct page *ringbuffer_page; @@ -1182,7 +1192,7 @@ extern int vmbus_establish_gpadl(struct vmbus_channel *channel, u32 *gpadl_handle); extern int vmbus_teardown_gpadl(struct vmbus_channel *channel, - u32 gpadl_handle); + u32 gpadl_handle); void vmbus_reset_channel_cb(struct vmbus_channel *channel); From patchwork Wed Apr 14 14:49:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203075 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.7 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,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 CE8EAC001E6 for ; Wed, 14 Apr 2021 14:50:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A9474611EE for ; Wed, 14 Apr 2021 14:50:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351995AbhDNOu4 (ORCPT ); Wed, 14 Apr 2021 10:50:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351955AbhDNOuv (ORCPT ); Wed, 14 Apr 2021 10:50:51 -0400 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E48EBC06138C; Wed, 14 Apr 2021 07:50:28 -0700 (PDT) Received: by mail-pl1-x62e.google.com with SMTP id w8so7905465plg.9; Wed, 14 Apr 2021 07:50:28 -0700 (PDT) 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=4uHLDXPTV0NPaJIPR0JcU4jnzokfZP+lvBQuVxSWxeo=; b=nz98yTtMltCvc8Lxfq4xMqWxGfuacMv6r1QxoLnhLqwEJVXhV14zOJuZJk+Qpe6Eh2 LQBFybrZrRrAPeV5c9jwoCQhjUxuCzEm2HyA8UpdL1ZyGqunpDdxSoB0bpWpXHgydWm0 NP4ZYbte8Cj2Mm9o9A9JalIHNGFbQjKvuhzRjxaq+5eoYjMr5ZkXSrl8kP7EPsWrZXv4 fbIcXezTUHFNuiEl/leuLsb4nTDN3g/iZi6bXSfF/uijSv9wY/FGr+K5QwCHGra8knj3 5NUoOm6VqALCqxQJMX9YpAL3igLtgbiNMoNPGHEOz4kiZ0AW4E3sQ4LJgr4FIkNSG9Xh EBpA== 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=4uHLDXPTV0NPaJIPR0JcU4jnzokfZP+lvBQuVxSWxeo=; b=gz9uFWl6bW1rH4r/mwXE6hp9M477Lj7Odakmu6CcvmUezM4tqs+pICNfZ/gXxQo0yq Ltzm6O2Fs0ltsKpI4Es/l3BnDFCrjhVuBUazcDocKOHi/wA1+G9NEFRwdPQ8XRReF/Hh N8lhejf8iWQuh7vMFEO4VOFAirPCsp0/TpkCfHiYGq5bjPh557NCaJtk5nPpNxbL5l+Y kAB+GzxK4+4Cgayx7rqM8l9TH/iyUQibS9o84Ag1CGI9MAlN4wmkD0+KZ+DzlRxt62yx zmqFlByXEyFGiVWR6QvHgBeey6YuZef1lOy07HNc4AaGE7ZIygl69OGcsEbnOCFFVQN1 WqmA== X-Gm-Message-State: AOAM533FI855UKGZEmAmkunjDXn9Q1P0Q/ktak7q+9UzCU/JcE4KDfYr bYMcYXEmED+1Wo2pQjH2+sI= X-Google-Smtp-Source: ABdhPJxNEHJsldB9/l9DrcCPvmaCi5un8TIOv2g6d7WPnLPy6fp1j7ZtGlaVow6yyJCqbdyXmxus9A== X-Received: by 2002:a17:90a:5907:: with SMTP id k7mr4219377pji.197.1618411828425; Wed, 14 Apr 2021 07:50:28 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:28 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 04/12] HV: Add Write/Read MSR registers via ghcb Date: Wed, 14 Apr 2021 10:49:37 -0400 Message-Id: <20210414144945.3460554-5-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan Hyper-V provides GHCB protocol to write Synthetic Interrupt Controller MSR registers and these registers are emulated by Hypervisor rather than paravisor. Hyper-V requests to write SINTx MSR registers twice(once via GHCB and once via wrmsr instruction including the proxy bit 21) Guest OS ID MSR also needs to be set via GHCB. Signed-off-by: Tianyu Lan --- arch/x86/hyperv/hv_init.c | 18 +---- arch/x86/hyperv/ivm.c | 130 ++++++++++++++++++++++++++++++++ arch/x86/include/asm/mshyperv.h | 87 +++++++++++++++++---- arch/x86/kernel/cpu/mshyperv.c | 3 + drivers/hv/hv.c | 65 +++++++++++----- include/asm-generic/mshyperv.h | 4 +- 6 files changed, 261 insertions(+), 46 deletions(-) diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 90e65fbf4c58..87b1dd9c84d6 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -475,6 +475,9 @@ void __init hyperv_init(void) ghcb_base = (void **)this_cpu_ptr(ms_hyperv.ghcb_base); *ghcb_base = ghcb_va; + + /* Hyper-V requires to write guest os id via ghcb in SNP IVM. */ + hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, guest_id); } rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); @@ -561,6 +564,7 @@ void hyperv_cleanup(void) /* Reset our OS id */ wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); + hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, 0); /* * Reset hypercall page reference before reset the page, @@ -668,17 +672,3 @@ bool hv_is_hibernation_supported(void) return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4); } EXPORT_SYMBOL_GPL(hv_is_hibernation_supported); - -enum hv_isolation_type hv_get_isolation_type(void) -{ - if (!(ms_hyperv.features_b & HV_ISOLATION)) - return HV_ISOLATION_TYPE_NONE; - return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b); -} -EXPORT_SYMBOL_GPL(hv_get_isolation_type); - -bool hv_is_isolation_supported(void) -{ - return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE; -} -EXPORT_SYMBOL_GPL(hv_is_isolation_supported); diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c index a5950b7a9214..2ec64b367aaf 100644 --- a/arch/x86/hyperv/ivm.c +++ b/arch/x86/hyperv/ivm.c @@ -6,12 +6,139 @@ * Tianyu Lan */ +#include +#include #include #include #include #include +#include +#include #include +union hv_ghcb { + struct ghcb ghcb; +} __packed __aligned(PAGE_SIZE); + +void hv_ghcb_msr_write(u64 msr, u64 value) +{ + union hv_ghcb *hv_ghcb; + void **ghcb_base; + unsigned long flags; + + if (!ms_hyperv.ghcb_base) + return; + + local_irq_save(flags); + ghcb_base = (void **)this_cpu_ptr(ms_hyperv.ghcb_base); + hv_ghcb = (union hv_ghcb *)*ghcb_base; + if (!hv_ghcb) { + local_irq_restore(flags); + return; + } + + memset(hv_ghcb, 0x00, HV_HYP_PAGE_SIZE); + + hv_ghcb->ghcb.protocol_version = 1; + hv_ghcb->ghcb.ghcb_usage = 0; + + ghcb_set_sw_exit_code(&hv_ghcb->ghcb, SVM_EXIT_MSR); + ghcb_set_rcx(&hv_ghcb->ghcb, msr); + ghcb_set_rax(&hv_ghcb->ghcb, lower_32_bits(value)); + ghcb_set_rdx(&hv_ghcb->ghcb, value >> 32); + ghcb_set_sw_exit_info_1(&hv_ghcb->ghcb, 1); + ghcb_set_sw_exit_info_2(&hv_ghcb->ghcb, 0); + + VMGEXIT(); + + if ((hv_ghcb->ghcb.save.sw_exit_info_1 & 0xffffffff) == 1) + pr_warn("Fail to write msr via ghcb.\n."); + + local_irq_restore(flags); +} +EXPORT_SYMBOL_GPL(hv_ghcb_msr_write); + +void hv_ghcb_msr_read(u64 msr, u64 *value) +{ + union hv_ghcb *hv_ghcb; + void **ghcb_base; + unsigned long flags; + + if (!ms_hyperv.ghcb_base) + return; + + local_irq_save(flags); + ghcb_base = (void **)this_cpu_ptr(ms_hyperv.ghcb_base); + hv_ghcb = (union hv_ghcb *)*ghcb_base; + if (!hv_ghcb) { + local_irq_restore(flags); + return; + } + + memset(hv_ghcb, 0x00, PAGE_SIZE); + hv_ghcb->ghcb.protocol_version = 1; + hv_ghcb->ghcb.ghcb_usage = 0; + + ghcb_set_sw_exit_code(&hv_ghcb->ghcb, SVM_EXIT_MSR); + ghcb_set_rcx(&hv_ghcb->ghcb, msr); + ghcb_set_sw_exit_info_1(&hv_ghcb->ghcb, 0); + ghcb_set_sw_exit_info_2(&hv_ghcb->ghcb, 0); + + VMGEXIT(); + + if ((hv_ghcb->ghcb.save.sw_exit_info_1 & 0xffffffff) == 1) + pr_warn("Fail to write msr via ghcb.\n."); + else + *value = (u64)lower_32_bits(hv_ghcb->ghcb.save.rax) + | ((u64)lower_32_bits(hv_ghcb->ghcb.save.rdx) << 32); + local_irq_restore(flags); +} +EXPORT_SYMBOL_GPL(hv_ghcb_msr_read); + +void hv_sint_rdmsrl_ghcb(u64 msr, u64 *value) +{ + hv_ghcb_msr_read(msr, value); +} +EXPORT_SYMBOL_GPL(hv_sint_rdmsrl_ghcb); + +void hv_sint_wrmsrl_ghcb(u64 msr, u64 value) +{ + hv_ghcb_msr_write(msr, value); + + /* Write proxy bit vua wrmsrl instruction. */ + if (msr >= HV_X64_MSR_SINT0 && msr <= HV_X64_MSR_SINT15) + wrmsrl(msr, value | 1 << 20); +} +EXPORT_SYMBOL_GPL(hv_sint_wrmsrl_ghcb); + +inline void hv_signal_eom_ghcb(void) +{ + hv_sint_wrmsrl_ghcb(HV_X64_MSR_EOM, 0); +} +EXPORT_SYMBOL_GPL(hv_signal_eom_ghcb); + +enum hv_isolation_type hv_get_isolation_type(void) +{ + if (!(ms_hyperv.features_b & HV_ISOLATION)) + return HV_ISOLATION_TYPE_NONE; + return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b); +} +EXPORT_SYMBOL_GPL(hv_get_isolation_type); + +bool hv_is_isolation_supported(void) +{ + return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE; +} +EXPORT_SYMBOL_GPL(hv_is_isolation_supported); + +DEFINE_STATIC_KEY_FALSE(isolation_type_snp); + +bool hv_isolation_type_snp(void) +{ + return static_branch_unlikely(&isolation_type_snp); +} +EXPORT_SYMBOL_GPL(hv_isolation_type_snp); + /* * hv_set_mem_host_visibility - Set host visibility for specified memory. */ @@ -22,6 +149,9 @@ int hv_set_mem_host_visibility(void *kbuffer, u32 size, u32 visibility) u64 *pfn_array; int ret = 0; + if (!hv_is_isolation_supported()) + return 0; + pfn_array = vzalloc(HV_HYP_PAGE_SIZE); if (!pfn_array) return -ENOMEM; diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index d9437f096ce5..73501dbbc240 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -10,6 +10,8 @@ #include #include +DECLARE_STATIC_KEY_FALSE(isolation_type_snp); + typedef int (*hyperv_fill_flush_list_func)( struct hv_guest_mapping_flush_list *flush, void *data); @@ -19,24 +21,64 @@ typedef int (*hyperv_fill_flush_list_func)( #define hv_init_timer_config(timer, val) \ wrmsrl(HV_X64_MSR_STIMER0_CONFIG + (2*timer), val) -#define hv_get_simp(val) rdmsrl(HV_X64_MSR_SIMP, val) -#define hv_set_simp(val) wrmsrl(HV_X64_MSR_SIMP, val) +#define hv_get_sint_reg(val, reg) { \ + if (hv_isolation_type_snp()) \ + hv_get_##reg##_ghcb(&val); \ + else \ + rdmsrl(HV_X64_MSR_##reg, val); \ + } + +#define hv_set_sint_reg(val, reg) { \ + if (hv_isolation_type_snp()) \ + hv_set_##reg##_ghcb(val); \ + else \ + wrmsrl(HV_X64_MSR_##reg, val); \ + } + -#define hv_get_siefp(val) rdmsrl(HV_X64_MSR_SIEFP, val) -#define hv_set_siefp(val) wrmsrl(HV_X64_MSR_SIEFP, val) +#define hv_get_simp(val) hv_get_sint_reg(val, SIMP) +#define hv_get_siefp(val) hv_get_sint_reg(val, SIEFP) -#define hv_get_synic_state(val) rdmsrl(HV_X64_MSR_SCONTROL, val) -#define hv_set_synic_state(val) wrmsrl(HV_X64_MSR_SCONTROL, val) +#define hv_set_simp(val) hv_set_sint_reg(val, SIMP) +#define hv_set_siefp(val) hv_set_sint_reg(val, SIEFP) + +#define hv_get_synic_state(val) { \ + if (hv_isolation_type_snp()) \ + hv_get_synic_state_ghcb(&val); \ + else \ + rdmsrl(HV_X64_MSR_SCONTROL, val); \ + } +#define hv_set_synic_state(val) { \ + if (hv_isolation_type_snp()) \ + hv_set_synic_state_ghcb(val); \ + else \ + wrmsrl(HV_X64_MSR_SCONTROL, val); \ + } #define hv_get_vp_index(index) rdmsrl(HV_X64_MSR_VP_INDEX, index) -#define hv_signal_eom() wrmsrl(HV_X64_MSR_EOM, 0) +#define hv_signal_eom() { \ + if (hv_isolation_type_snp() && \ + old_msg_type != HVMSG_TIMER_EXPIRED) \ + hv_signal_eom_ghcb(); \ + else \ + wrmsrl(HV_X64_MSR_EOM, 0); \ + } -#define hv_get_synint_state(int_num, val) \ - rdmsrl(HV_X64_MSR_SINT0 + int_num, val) -#define hv_set_synint_state(int_num, val) \ - wrmsrl(HV_X64_MSR_SINT0 + int_num, val) -#define hv_recommend_using_aeoi() \ +#define hv_get_synint_state(int_num, val) { \ + if (hv_isolation_type_snp()) \ + hv_get_synint_state_ghcb(int_num, &val);\ + else \ + rdmsrl(HV_X64_MSR_SINT0 + int_num, val);\ + } +#define hv_set_synint_state(int_num, val) { \ + if (hv_isolation_type_snp()) \ + hv_set_synint_state_ghcb(int_num, val); \ + else \ + wrmsrl(HV_X64_MSR_SINT0 + int_num, val);\ + } + +#define hv_recommend_using_aeoi() \ (!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)) #define hv_get_crash_ctl(val) \ @@ -271,6 +313,25 @@ int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry); int hv_set_mem_host_visibility(void *kbuffer, u32 size, u32 visibility); int hv_mark_gpa_visibility(u16 count, const u64 pfn[], u32 visibility); +void hv_sint_wrmsrl_ghcb(u64 msr, u64 value); +void hv_sint_rdmsrl_ghcb(u64 msr, u64 *value); +void hv_signal_eom_ghcb(void); +void hv_ghcb_msr_write(u64 msr, u64 value); +void hv_ghcb_msr_read(u64 msr, u64 *value); + +#define hv_get_synint_state_ghcb(int_num, val) \ + hv_sint_rdmsrl_ghcb(HV_X64_MSR_SINT0 + int_num, val) +#define hv_set_synint_state_ghcb(int_num, val) \ + hv_sint_wrmsrl_ghcb(HV_X64_MSR_SINT0 + int_num, val) + +#define hv_get_SIMP_ghcb(val) hv_sint_rdmsrl_ghcb(HV_X64_MSR_SIMP, val) +#define hv_set_SIMP_ghcb(val) hv_sint_wrmsrl_ghcb(HV_X64_MSR_SIMP, val) + +#define hv_get_SIEFP_ghcb(val) hv_sint_rdmsrl_ghcb(HV_X64_MSR_SIEFP, val) +#define hv_set_SIEFP_ghcb(val) hv_sint_wrmsrl_ghcb(HV_X64_MSR_SIEFP, val) + +#define hv_get_synic_state_ghcb(val) hv_sint_rdmsrl_ghcb(HV_X64_MSR_SCONTROL, val) +#define hv_set_synic_state_ghcb(val) hv_sint_wrmsrl_ghcb(HV_X64_MSR_SCONTROL, val) #else /* CONFIG_HYPERV */ static inline void hyperv_init(void) {} static inline void hyperv_setup_mmu_ops(void) {} @@ -289,9 +350,9 @@ static inline int hyperv_flush_guest_mapping_range(u64 as, { return -1; } +static inline void hv_signal_eom_ghcb(void) { }; #endif /* CONFIG_HYPERV */ - #include #endif diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index aeafd4017c89..6eaa0891c0f7 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -333,6 +333,9 @@ static void __init ms_hyperv_init_platform(void) pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n", ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b); + + if (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP) + static_branch_enable(&isolation_type_snp); } if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) { diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index f202ac7f4b3d..069530eeb7c6 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -99,17 +99,24 @@ int hv_synic_alloc(void) tasklet_init(&hv_cpu->msg_dpc, vmbus_on_msg_dpc, (unsigned long) hv_cpu); - hv_cpu->synic_message_page = - (void *)get_zeroed_page(GFP_ATOMIC); - if (hv_cpu->synic_message_page == NULL) { - pr_err("Unable to allocate SYNIC message page\n"); - goto err; - } + /* + * Synic message and event pages are allocated by paravisor. + * Skip these pages allocation here. + */ + if (!hv_isolation_type_snp()) { + hv_cpu->synic_message_page = + (void *)get_zeroed_page(GFP_ATOMIC); + if (hv_cpu->synic_message_page == NULL) { + pr_err("Unable to allocate SYNIC message page\n"); + goto err; + } - hv_cpu->synic_event_page = (void *)get_zeroed_page(GFP_ATOMIC); - if (hv_cpu->synic_event_page == NULL) { - pr_err("Unable to allocate SYNIC event page\n"); - goto err; + hv_cpu->synic_event_page = + (void *)get_zeroed_page(GFP_ATOMIC); + if (hv_cpu->synic_event_page == NULL) { + pr_err("Unable to allocate SYNIC event page\n"); + goto err; + } } hv_cpu->post_msg_page = (void *)get_zeroed_page(GFP_ATOMIC); @@ -136,10 +143,17 @@ void hv_synic_free(void) for_each_present_cpu(cpu) { struct hv_per_cpu_context *hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); + free_page((unsigned long)hv_cpu->post_msg_page); + + /* + * Synic message and event pages are allocated by paravisor. + * Skip free these pages here. + */ + if (hv_isolation_type_snp()) + continue; free_page((unsigned long)hv_cpu->synic_event_page); free_page((unsigned long)hv_cpu->synic_message_page); - free_page((unsigned long)hv_cpu->post_msg_page); } kfree(hv_context.hv_numa_map); @@ -161,20 +175,36 @@ void hv_synic_enable_regs(unsigned int cpu) union hv_synic_sint shared_sint; union hv_synic_scontrol sctrl; - /* Setup the Synic's message page */ + + /* Setup the Synic's message. */ hv_get_simp(simp.as_uint64); simp.simp_enabled = 1; - simp.base_simp_gpa = virt_to_phys(hv_cpu->synic_message_page) - >> HV_HYP_PAGE_SHIFT; + + if (hv_isolation_type_snp()) { + hv_cpu->synic_message_page + = ioremap_cache(simp.base_simp_gpa << HV_HYP_PAGE_SHIFT, + HV_HYP_PAGE_SIZE); + if (!hv_cpu->synic_message_page) + pr_err("Fail to map syinc message page.\n"); + } else { + simp.base_simp_gpa = virt_to_phys(hv_cpu->synic_message_page) + >> HV_HYP_PAGE_SHIFT; + } hv_set_simp(simp.as_uint64); /* Setup the Synic's event page */ hv_get_siefp(siefp.as_uint64); siefp.siefp_enabled = 1; - siefp.base_siefp_gpa = virt_to_phys(hv_cpu->synic_event_page) - >> HV_HYP_PAGE_SHIFT; - + if (hv_isolation_type_snp()) { + hv_cpu->synic_event_page = ioremap_cache( + siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT, HV_HYP_PAGE_SIZE); + if (!hv_cpu->synic_event_page) + pr_err("Fail to map syinc event page.\n"); + } else { + siefp.base_siefp_gpa = virt_to_phys(hv_cpu->synic_event_page) + >> HV_HYP_PAGE_SHIFT; + } hv_set_siefp(siefp.as_uint64); /* Setup the shared SINT. */ @@ -188,7 +218,6 @@ void hv_synic_enable_regs(unsigned int cpu) /* Enable the global synic bit */ hv_get_synic_state(sctrl.as_uint64); sctrl.enable = 1; - hv_set_synic_state(sctrl.as_uint64); } diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h index b73e201abc70..59777377e641 100644 --- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -23,6 +23,7 @@ #include #include #include +#include #include struct ms_hyperv_info { @@ -52,7 +53,7 @@ extern struct ms_hyperv_info ms_hyperv; extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr); extern u64 hv_do_fast_hypercall8(u16 control, u64 input8); - +extern bool hv_isolation_type_snp(void); /* Generate the guest OS identifier as described in the Hyper-V TLFS */ static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version, @@ -186,6 +187,7 @@ bool hv_is_hyperv_initialized(void); bool hv_is_hibernation_supported(void); enum hv_isolation_type hv_get_isolation_type(void); bool hv_is_isolation_supported(void); +bool hv_isolation_type_snp(void); void hyperv_cleanup(void); #else /* CONFIG_HYPERV */ static inline bool hv_is_hyperv_initialized(void) { return false; } From patchwork Wed Apr 14 14:49:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203077 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.7 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,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 65B02C43461 for ; Wed, 14 Apr 2021 14:50:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 430B661220 for ; Wed, 14 Apr 2021 14:50:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352010AbhDNOu5 (ORCPT ); Wed, 14 Apr 2021 10:50:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38920 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351957AbhDNOuv (ORCPT ); Wed, 14 Apr 2021 10:50:51 -0400 Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BFE30C06175F; Wed, 14 Apr 2021 07:50:29 -0700 (PDT) Received: by mail-pg1-x532.google.com with SMTP id t22so14611111pgu.0; Wed, 14 Apr 2021 07:50:29 -0700 (PDT) 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=a/EDNIO90x+e8AFI7mOKhNKA82m+L7igtpPovmD+rhw=; b=fm6CEGbsAMSfOKQ0+U7jTSCU69Q/Jdxm8mK6rFCM9gsDglj1XVWQGjeCyw+ATWyFhB XOwSGA9F7r5iEo5NUIpOie2H5axtYlGJFeRScNRcNgL1Vj3HIzTwwVIRUXXFmV14bsU/ luUs4mo/+E6UFDaDTOXfHEmzzgJKMHv6pCTCFRT1gfrhDw4F/GLGzv3F6iZRbmTan39l jyR+18wObZr28Z7CxyvIIVbJF+Xl6p9yOOqtAmjzORgvBEY2rUtNdk/FQ9mEmbKX+BpZ JhIxFQPmU6hRwNTP02ghT7RFg0IInpZ+2LkxKJL/vlnwNxgbuFtNCQFFW2X83yX2pcK0 AhGA== 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=a/EDNIO90x+e8AFI7mOKhNKA82m+L7igtpPovmD+rhw=; b=hEE/wfPrQ+21UEsr4MfMx272lb8FGnWtB5FFW4jf8f3O92E53BDHszUj49fNAwc1nq epjFkH1PAT61N3axnTkULjP9P3c93d3IGivfZVC8IhMTeTp0pHjtTpbeYrLtTGp+/RKd 328W43541MHbBcybIjkIMVaakUnZ7ZbmZDVeJJQ3ecE/g2D2rqjGOs1mAP7OluZoFCw4 XJwCIU5zqYiT74/Roo40GBe+vrKhM+vy42/CuuLSq1kdC9ZchJ+iPDpcH6w34hNY11bM 5h8Qoh70cQgiC2T3wzLCgTxjkoFxotDc8wsBLxNat9vbSfPPYEDkKi8yHkQjiFInirZ1 TTzA== X-Gm-Message-State: AOAM533+4E/PJqNfbKRWM+lm3BaDh8uCjixB8wCWqAIcuEDICmMUCRLf YBA4Z0dIts3lFnbJ1jc696E= X-Google-Smtp-Source: ABdhPJz4Mcv4+AWZTLNcrQH1pgpMGbOS+rHmkbuYkxqX8ZUry/+RhEuiyE8vNgkOAmPPyHY1FCOteg== X-Received: by 2002:a62:5c6:0:b029:24d:e97f:1b1d with SMTP id 189-20020a6205c60000b029024de97f1b1dmr13734445pff.40.1618411829236; Wed, 14 Apr 2021 07:50:29 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:28 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 05/12] HV: Add ghcb hvcall support for SNP VM Date: Wed, 14 Apr 2021 10:49:38 -0400 Message-Id: <20210414144945.3460554-6-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan Hyper-V provides ghcb hvcall to handle VMBus HVCALL_SIGNAL_EVENT and HVCALL_POST_MESSAGE msg in SNP Isolation VM. Add such support. Signed-off-by: Tianyu Lan --- arch/x86/hyperv/ivm.c | 69 +++++++++++++++++++++++++++++++++ arch/x86/include/asm/mshyperv.h | 1 + drivers/hv/connection.c | 6 ++- drivers/hv/hv.c | 8 +++- 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c index 2ec64b367aaf..0ad73ea60c8f 100644 --- a/arch/x86/hyperv/ivm.c +++ b/arch/x86/hyperv/ivm.c @@ -18,8 +18,77 @@ union hv_ghcb { struct ghcb ghcb; + struct { + u64 hypercalldata[509]; + u64 outputgpa; + union { + union { + struct { + u32 callcode : 16; + u32 isfast : 1; + u32 reserved1 : 14; + u32 isnested : 1; + u32 countofelements : 12; + u32 reserved2 : 4; + u32 repstartindex : 12; + u32 reserved3 : 4; + }; + u64 asuint64; + } hypercallinput; + union { + struct { + u16 callstatus; + u16 reserved1; + u32 elementsprocessed : 12; + u32 reserved2 : 20; + }; + u64 asunit64; + } hypercalloutput; + }; + u64 reserved2; + } hypercall; } __packed __aligned(PAGE_SIZE); +u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size) +{ + union hv_ghcb *hv_ghcb; + void **ghcb_base; + unsigned long flags; + + if (!ms_hyperv.ghcb_base) + return -EFAULT; + + local_irq_save(flags); + ghcb_base = (void **)this_cpu_ptr(ms_hyperv.ghcb_base); + hv_ghcb = (union hv_ghcb *)*ghcb_base; + if (!hv_ghcb) { + local_irq_restore(flags); + return -EFAULT; + } + + memset(hv_ghcb, 0x00, HV_HYP_PAGE_SIZE); + hv_ghcb->ghcb.protocol_version = 1; + hv_ghcb->ghcb.ghcb_usage = 1; + + hv_ghcb->hypercall.outputgpa = (u64)output; + hv_ghcb->hypercall.hypercallinput.asuint64 = 0; + hv_ghcb->hypercall.hypercallinput.callcode = control; + + if (input_size) + memcpy(hv_ghcb->hypercall.hypercalldata, input, input_size); + + VMGEXIT(); + + hv_ghcb->ghcb.ghcb_usage = 0xffffffff; + memset(hv_ghcb->ghcb.save.valid_bitmap, 0, + sizeof(hv_ghcb->ghcb.save.valid_bitmap)); + + local_irq_restore(flags); + + return hv_ghcb->hypercall.hypercalloutput.callstatus; +} +EXPORT_SYMBOL_GPL(hv_ghcb_hypercall); + void hv_ghcb_msr_write(u64 msr, u64 value) { union hv_ghcb *hv_ghcb; diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 73501dbbc240..929504fe8654 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -318,6 +318,7 @@ void hv_sint_rdmsrl_ghcb(u64 msr, u64 *value); void hv_signal_eom_ghcb(void); void hv_ghcb_msr_write(u64 msr, u64 value); void hv_ghcb_msr_read(u64 msr, u64 *value); +u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size); #define hv_get_synint_state_ghcb(int_num, val) \ hv_sint_rdmsrl_ghcb(HV_X64_MSR_SINT0 + int_num, val) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index c83612cddb99..79bca653dce9 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -442,6 +442,10 @@ void vmbus_set_event(struct vmbus_channel *channel) ++channel->sig_events; - hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event); + if (hv_isolation_type_snp()) + hv_ghcb_hypercall(HVCALL_SIGNAL_EVENT, &channel->sig_event, + NULL, sizeof(u64)); + else + hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event); } EXPORT_SYMBOL_GPL(vmbus_set_event); diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 069530eeb7c6..bff7c9049ffb 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -60,7 +60,13 @@ int hv_post_message(union hv_connection_id connection_id, aligned_msg->payload_size = payload_size; memcpy((void *)aligned_msg->payload, payload, payload_size); - status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL); + if (hv_isolation_type_snp()) + status = hv_ghcb_hypercall(HVCALL_POST_MESSAGE, + (void *)aligned_msg, NULL, + sizeof(struct hv_input_post_message)); + else + status = hv_do_hypercall(HVCALL_POST_MESSAGE, + aligned_msg, NULL); /* Preemption must remain disabled until after the hypercall * so some other thread can't get scheduled onto this cpu and From patchwork Wed Apr 14 14:49:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203079 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.7 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,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 EBF3DC001EC for ; Wed, 14 Apr 2021 14:50:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D39786121E for ; Wed, 14 Apr 2021 14:50:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352028AbhDNOu6 (ORCPT ); Wed, 14 Apr 2021 10:50:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351963AbhDNOuw (ORCPT ); Wed, 14 Apr 2021 10:50:52 -0400 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB1F2C06138D; Wed, 14 Apr 2021 07:50:30 -0700 (PDT) Received: by mail-pl1-x636.google.com with SMTP id u15so1688487plf.10; Wed, 14 Apr 2021 07:50:30 -0700 (PDT) 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=CewzcGN2queQHJd+J82WZLFtEsY18cNfiGHIrQj3GfM=; b=nOk4uGV2612icoE6KiiMnihVY5JHClv+KaiNAxHeX6msxOQj9xeFgeyXgzuV9Sd7Ij 3EGstiuG7E5ZaMqZazQ8zFoKTzoT62iMzgmBH+tZh+iYpEEsK600XCCcKCclZh0Y0x/u lPI4sDQZdZAMWqD+sOUOmLSztUBF0emqbSbT/bkw4pOBBCkruQo/ok2VzdifznwsKJMs ocsgxtRZuZhwa/4H3uMNQQH/MJK+ZGYBL5Une8lbE2Hi2dVG9kDPFVwgbdYojKKilNwO hZojnsV4Uidmr/W8cT1MCoZwuTcUd6+620Huo4X0ZKIUTvMpEIF6giQ2Vs7uJP0RlbHX V1IA== 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=CewzcGN2queQHJd+J82WZLFtEsY18cNfiGHIrQj3GfM=; b=A2zSNmAY/eNh5iTFCqMjc0M/4kLDDRmqA3/NStBj5XrJAmzjjRSqHDnLv4z1u5OikC ZziqdwZTqEM1Nhfq5+ogcI+tnzhPFInfkSrKi4LiTgPE8LT7rxqKylt8GS5zZNDWA7Ac bG4s8GjJiXwuYREhwknBxWvks0LxqvnAPIqLtEbrlF0XCsm/85uhVW7588aWZ9PJbFih r+5CFLd05zckaqfqYhFPrOx8pP7I3fSVFH1bR4N/R+4/jX3T972kHGWFzHBWgeuy3Top iDhq1zrPx8snO8fl7hJxuiX6cbd0F2uCuCQinE12Zjfd35F0mVtnYtnuRNdjjXQ0guPI +RyQ== X-Gm-Message-State: AOAM5320WSVKha8CREFKYGwvPHXJSx8RlmNzdB4gp5i3eNeOneaLgjsg fFWY45IQBzE0lOM+VcgNrnk= X-Google-Smtp-Source: ABdhPJwbB1PldwXbeyiSuCQkyOEtifm++hxPqnW8Qh9Ekcj5s31E29ArK58tbba9T8p/t1IP5sOX7w== X-Received: by 2002:a17:90a:5306:: with SMTP id x6mr4089960pjh.39.1618411830278; Wed, 14 Apr 2021 07:50:30 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:29 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 06/12] HV/Vmbus: Add SNP support for VMbus channel initiate message Date: Wed, 14 Apr 2021 10:49:39 -0400 Message-Id: <20210414144945.3460554-7-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan The physical address of monitor pages in the CHANNELMSG_INITIATE_CONTACT msg should be in the extra address space for SNP support and these pages also should be accessed via the extra address space inside Linux guest and remap the extra address by ioremap function. Signed-off-by: Tianyu Lan --- drivers/hv/connection.c | 62 +++++++++++++++++++++++++++++++++++++++ drivers/hv/hyperv_vmbus.h | 1 + 2 files changed, 63 insertions(+) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 79bca653dce9..a0be9c11d737 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -101,6 +101,12 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version) msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); + + if (hv_isolation_type_snp()) { + msg->monitor_page1 += ms_hyperv.shared_gpa_boundary; + msg->monitor_page2 += ms_hyperv.shared_gpa_boundary; + } + msg->target_vcpu = hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU); /* @@ -145,6 +151,29 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version) return -ECONNREFUSED; } + if (hv_isolation_type_snp()) { + vmbus_connection.monitor_pages_va[0] + = vmbus_connection.monitor_pages[0]; + vmbus_connection.monitor_pages[0] + = ioremap_cache(msg->monitor_page1, HV_HYP_PAGE_SIZE); + if (!vmbus_connection.monitor_pages[0]) + return -ENOMEM; + + vmbus_connection.monitor_pages_va[1] + = vmbus_connection.monitor_pages[1]; + vmbus_connection.monitor_pages[1] + = ioremap_cache(msg->monitor_page2, HV_HYP_PAGE_SIZE); + if (!vmbus_connection.monitor_pages[1]) { + vunmap(vmbus_connection.monitor_pages[0]); + return -ENOMEM; + } + + memset(vmbus_connection.monitor_pages[0], 0x00, + HV_HYP_PAGE_SIZE); + memset(vmbus_connection.monitor_pages[1], 0x00, + HV_HYP_PAGE_SIZE); + } + return ret; } @@ -156,6 +185,7 @@ int vmbus_connect(void) struct vmbus_channel_msginfo *msginfo = NULL; int i, ret = 0; __u32 version; + u64 pfn[2]; /* Initialize the vmbus connection */ vmbus_connection.conn_state = CONNECTING; @@ -213,6 +243,16 @@ int vmbus_connect(void) goto cleanup; } + if (hv_isolation_type_snp()) { + pfn[0] = virt_to_hvpfn(vmbus_connection.monitor_pages[0]); + pfn[1] = virt_to_hvpfn(vmbus_connection.monitor_pages[1]); + if (hv_mark_gpa_visibility(2, pfn, + VMBUS_PAGE_VISIBLE_READ_WRITE)) { + ret = -EFAULT; + goto cleanup; + } + } + msginfo = kzalloc(sizeof(*msginfo) + sizeof(struct vmbus_channel_initiate_contact), GFP_KERNEL); @@ -279,6 +319,8 @@ int vmbus_connect(void) void vmbus_disconnect(void) { + u64 pfn[2]; + /* * First send the unload request to the host. */ @@ -298,6 +340,26 @@ void vmbus_disconnect(void) vmbus_connection.int_page = NULL; } + if (hv_isolation_type_snp()) { + if (vmbus_connection.monitor_pages_va[0]) { + vunmap(vmbus_connection.monitor_pages[0]); + vmbus_connection.monitor_pages[0] + = vmbus_connection.monitor_pages_va[0]; + vmbus_connection.monitor_pages_va[0] = NULL; + } + + if (vmbus_connection.monitor_pages_va[1]) { + vunmap(vmbus_connection.monitor_pages[1]); + vmbus_connection.monitor_pages[1] + = vmbus_connection.monitor_pages_va[1]; + vmbus_connection.monitor_pages_va[1] = NULL; + } + + pfn[0] = virt_to_hvpfn(vmbus_connection.monitor_pages[0]); + pfn[1] = virt_to_hvpfn(vmbus_connection.monitor_pages[1]); + hv_mark_gpa_visibility(2, pfn, VMBUS_PAGE_NOT_VISIBLE); + } + hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[0]); hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[1]); vmbus_connection.monitor_pages[0] = NULL; diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 9416e09ebd58..0778add21a9c 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -240,6 +240,7 @@ struct vmbus_connection { * is child->parent notification */ struct hv_monitor_page *monitor_pages[2]; + void *monitor_pages_va[2]; struct list_head chn_msg_list; spinlock_t channelmsg_lock; From patchwork Wed Apr 14 14:49:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203081 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.7 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,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 14AC2C4360C for ; Wed, 14 Apr 2021 14:50:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E31216117A for ; Wed, 14 Apr 2021 14:50:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352037AbhDNOvA (ORCPT ); Wed, 14 Apr 2021 10:51:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351964AbhDNOux (ORCPT ); Wed, 14 Apr 2021 10:50:53 -0400 Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 829D0C061574; Wed, 14 Apr 2021 07:50:31 -0700 (PDT) Received: by mail-pg1-x529.google.com with SMTP id k8so14572733pgf.4; Wed, 14 Apr 2021 07:50:31 -0700 (PDT) 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=J7OMHxrj++vzM3fqEEVHDpiVziTWhlJNkVZ7Vyu86JI=; b=KRambbjbzL1OFoz5ZZGIZ2+8tC+DkTGQ0cIvxWKddRoW/LQ4AweHdLyBespo5JogFv O4pIw1bGbvLu1UG7zR4YauUQQAPp1u8f1CLUDbYUfKB6nrLR8pt+BzQltCQ1tbcrwweM GKYcOMHH0tvd6U7nMjmTB9PrvdMhjcsuFhdHHeKD6qSUvv3LY08ZqMwkv4ll5YZIAnjT mduBEmfZVmF78LtAMLRglbtJegVoB6p8PHD5SjJu2c61S+r+iEsqMaew6tOHa1QrcEFA cfZPS62Fei9C+bRvXncXXuv+X6C50HBnBI6dgQkpHrlOKhhirE45T0PiBRd352eDRAkf 5eWA== 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=J7OMHxrj++vzM3fqEEVHDpiVziTWhlJNkVZ7Vyu86JI=; b=B9XDtyU0Od5Y562z6wUnp7ESrA3zUM76ak4a83b2lzJ7LlHojGnN6iuCyxJNd9U/8t MnSeV+ftKI0MAqRY8VsLxP/Q5NbupD2M4UGVyhH7pCvjh53Z3N3/mPRX8Eq6XWcarm39 NXQD/OtuyCI1pTqfh0nl4LqDetP8rikjijs2BSr4SaOnqx5L770Mzk+oC5pWoU0cESq8 FOvOnrX4UnAAAAoZ4gcXszzssx3oRzhib1ybMg89X6vRQIryhpTZw/5Pk04U1WwCsGiJ Zi8ICEl61tpNE8YlPaszqWCZdO0EnYlj3rgVB7jBOMobzMX7hNatCjmcCze8ayqqUqhF ul2A== X-Gm-Message-State: AOAM532IvKBmTg0mOi8nWEC02bYuMQ4XROx68xE3hW3PMzdI+uEGkv6H XCl+i0+DPPDua+yeGmX0Wfs= X-Google-Smtp-Source: ABdhPJy1DmuXFvWHwxBGqhJreI4EMi/PXznrYBK3I2OIXVRIaxFUGQKwxsoi/VPGWNFQeVVlZ/LSTQ== X-Received: by 2002:a65:6643:: with SMTP id z3mr36898952pgv.387.1618411831039; Wed, 14 Apr 2021 07:50:31 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:30 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 07/12] HV/Vmbus: Initialize VMbus ring buffer for Isolation VM Date: Wed, 14 Apr 2021 10:49:40 -0400 Message-Id: <20210414144945.3460554-8-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan VMbus ring buffer are shared with host and it's need to be accessed via extra address space of Isolation VM with SNP support. This patch is to map the ring buffer address in extra address space via ioremap(). HV host visibility hvcall smears data in the ring buffer and so reset the ring buffer memory to zero after calling visibility hvcall. Signed-off-by: Tianyu Lan --- drivers/hv/channel.c | 10 +++++ drivers/hv/hyperv_vmbus.h | 2 + drivers/hv/ring_buffer.c | 83 +++++++++++++++++++++++++++++---------- mm/ioremap.c | 1 + mm/vmalloc.c | 1 + 5 files changed, 76 insertions(+), 21 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 407b74d72f3f..4a9fb7ad4c72 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -634,6 +634,16 @@ static int __vmbus_open(struct vmbus_channel *newchannel, if (err) goto error_clean_ring; + err = hv_ringbuffer_post_init(&newchannel->outbound, + page, send_pages); + if (err) + goto error_free_gpadl; + + err = hv_ringbuffer_post_init(&newchannel->inbound, + &page[send_pages], recv_pages); + if (err) + goto error_free_gpadl; + /* Create and init the channel open message */ open_info = kzalloc(sizeof(*open_info) + sizeof(struct vmbus_channel_open_channel), diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 0778add21a9c..d78a04ad5490 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -172,6 +172,8 @@ extern int hv_synic_cleanup(unsigned int cpu); /* Interface */ void hv_ringbuffer_pre_init(struct vmbus_channel *channel); +int hv_ringbuffer_post_init(struct hv_ring_buffer_info *ring_info, + struct page *pages, u32 page_cnt); int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, struct page *pages, u32 pagecnt); diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 35833d4d1a1d..c8b0f7b45158 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "hyperv_vmbus.h" @@ -188,6 +190,44 @@ void hv_ringbuffer_pre_init(struct vmbus_channel *channel) mutex_init(&channel->outbound.ring_buffer_mutex); } +int hv_ringbuffer_post_init(struct hv_ring_buffer_info *ring_info, + struct page *pages, u32 page_cnt) +{ + struct vm_struct *area; + u64 physic_addr = page_to_pfn(pages) << PAGE_SHIFT; + unsigned long vaddr; + int err = 0; + + if (!hv_isolation_type_snp()) + return 0; + + physic_addr += ms_hyperv.shared_gpa_boundary; + area = get_vm_area((2 * page_cnt - 1) * PAGE_SIZE, VM_IOREMAP); + if (!area || !area->addr) + return -EFAULT; + + vaddr = (unsigned long)area->addr; + err = ioremap_page_range(vaddr, vaddr + page_cnt * PAGE_SIZE, + physic_addr, PAGE_KERNEL_IO); + err |= ioremap_page_range(vaddr + page_cnt * PAGE_SIZE, + vaddr + (2 * page_cnt - 1) * PAGE_SIZE, + physic_addr + PAGE_SIZE, PAGE_KERNEL_IO); + if (err) { + vunmap((void *)vaddr); + return -EFAULT; + } + + /* Clean memory after setting host visibility. */ + memset((void *)vaddr, 0x00, page_cnt * PAGE_SIZE); + + ring_info->ring_buffer = (struct hv_ring_buffer *)vaddr; + ring_info->ring_buffer->read_index = 0; + ring_info->ring_buffer->write_index = 0; + ring_info->ring_buffer->feature_bits.value = 1; + + return 0; +} + /* Initialize the ring buffer. */ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, struct page *pages, u32 page_cnt) @@ -197,33 +237,34 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, BUILD_BUG_ON((sizeof(struct hv_ring_buffer) != PAGE_SIZE)); - /* - * First page holds struct hv_ring_buffer, do wraparound mapping for - * the rest. - */ - pages_wraparound = kcalloc(page_cnt * 2 - 1, sizeof(struct page *), - GFP_KERNEL); - if (!pages_wraparound) - return -ENOMEM; - - pages_wraparound[0] = pages; - for (i = 0; i < 2 * (page_cnt - 1); i++) - pages_wraparound[i + 1] = &pages[i % (page_cnt - 1) + 1]; + if (!hv_isolation_type_snp()) { + /* + * First page holds struct hv_ring_buffer, do wraparound mapping for + * the rest. + */ + pages_wraparound = kcalloc(page_cnt * 2 - 1, sizeof(struct page *), + GFP_KERNEL); + if (!pages_wraparound) + return -ENOMEM; - ring_info->ring_buffer = (struct hv_ring_buffer *) - vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP, PAGE_KERNEL); + pages_wraparound[0] = pages; + for (i = 0; i < 2 * (page_cnt - 1); i++) + pages_wraparound[i + 1] = &pages[i % (page_cnt - 1) + 1]; - kfree(pages_wraparound); + ring_info->ring_buffer = (struct hv_ring_buffer *) + vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP, PAGE_KERNEL); + kfree(pages_wraparound); - if (!ring_info->ring_buffer) - return -ENOMEM; + if (!ring_info->ring_buffer) + return -ENOMEM; - ring_info->ring_buffer->read_index = - ring_info->ring_buffer->write_index = 0; + ring_info->ring_buffer->read_index = + ring_info->ring_buffer->write_index = 0; - /* Set the feature bit for enabling flow control. */ - ring_info->ring_buffer->feature_bits.value = 1; + /* Set the feature bit for enabling flow control. */ + ring_info->ring_buffer->feature_bits.value = 1; + } ring_info->ring_size = page_cnt << PAGE_SHIFT; ring_info->ring_size_div10_reciprocal = diff --git a/mm/ioremap.c b/mm/ioremap.c index 5fa1ab41d152..d63c4ba067f9 100644 --- a/mm/ioremap.c +++ b/mm/ioremap.c @@ -248,6 +248,7 @@ int ioremap_page_range(unsigned long addr, return err; } +EXPORT_SYMBOL_GPL(ioremap_page_range); #ifdef CONFIG_GENERIC_IOREMAP void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index e6f352bf0498..19724a8ebcb7 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -2131,6 +2131,7 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) NUMA_NO_NODE, GFP_KERNEL, __builtin_return_address(0)); } +EXPORT_SYMBOL_GPL(get_vm_area); struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, const void *caller) From patchwork Wed Apr 14 14:49:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203083 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.7 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,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 CA33EC43470 for ; Wed, 14 Apr 2021 14:50:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 942C761244 for ; Wed, 14 Apr 2021 14:50:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352042AbhDNOvB (ORCPT ); Wed, 14 Apr 2021 10:51:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351969AbhDNOux (ORCPT ); Wed, 14 Apr 2021 10:50:53 -0400 Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5D4D1C061756; Wed, 14 Apr 2021 07:50:32 -0700 (PDT) Received: by mail-pg1-x532.google.com with SMTP id f29so14577103pgm.8; Wed, 14 Apr 2021 07:50:32 -0700 (PDT) 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=bVkRTqUPBzQHoWP1iz19JnEvLpWiwpbLKKeUDMKlliw=; b=E+2cIG4luSiauZCXt8F0KkKTk61dfk7whIIE/VHBZpNK6ARjyQdSQbpdQClQ4sSrp/ dGr6hJu/fS4Ac4GvGFZRUctlN3UoGYzjwv/J4NIfKYbBrLXDX0DII3Kqd0z13GyzT7N9 3K8eWfVsyRnUmawlgrvkAxuuTExFaWpsJRH42W4ZrmtKgAL9Ko81HY7WIxnfJaEZ8aiH Re9gsUe5b3chBVWCDNntU9qAIDzO3tUL22enF3c2ium4ZddwWgTLyh5yVJnZkUplcHhN 5Di+lzE1Zg2G82MYEnz9s+UIXemJpVVS+BIdIcbJOLkBiyzwWmhzx/daa53C594lB6Z4 MjZA== 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=bVkRTqUPBzQHoWP1iz19JnEvLpWiwpbLKKeUDMKlliw=; b=aDPftXD0vZ+cp0ekM59SlWDwFIKr348YQdK0x7vNhL7sfG9ZdWzWqLRz0Brktf47mJ Bly5vE8eVVMhJO8uBxSvHMDHMfF5gdA4sP5OXh80fLDPcLVMK37Tgi4FOwlE1JUCgW7W 7/BCzuexFCZH25V6k+9B9l94LThQ4se/SX7PjRo0k4CVcGmxyniDCQqny87Gig3T2uVd IxBPGtIB9+Gut0Y9phvxFBpQ3VIOx/quuvyxUOiP+GnmWbXe2SbFphnq+PG/ASsUlMqw WagdgNM1JW6n/ch7Pw2lubs388W3wHUetPYY7gZiUO0IG1N3wT7tlVgx8+mPRCCGQ4AZ 1u1w== X-Gm-Message-State: AOAM533s0XiZ93jVavkCA5rkn8tONKfik7MoLMZaT77DVytldPZ/vh85 r/e7Tzun/rBPp0qn7eg7SHk= X-Google-Smtp-Source: ABdhPJyJQo3QYxkwZd2R/2jbCS/20DZeDnEWp76po+53FmLx6JhMmfhewCcVF2Q2CCy9ma7VhRrp6w== X-Received: by 2002:a63:4e47:: with SMTP id o7mr37301695pgl.286.1618411832013; Wed, 14 Apr 2021 07:50:32 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:31 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 08/12] UIO/Hyper-V: Not load UIO HV driver in the isolation VM. Date: Wed, 14 Apr 2021 10:49:41 -0400 Message-Id: <20210414144945.3460554-9-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan UIO HV driver should not load in the isolation VM for security reason. Return ENOTSUPP in the hv_uio_probe() in the isolation VM. Signed-off-by: Tianyu Lan --- drivers/uio/uio_hv_generic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 0330ba99730e..678b021d66f8 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "../hv/hyperv_vmbus.h" @@ -241,6 +242,10 @@ hv_uio_probe(struct hv_device *dev, void *ring_buffer; int ret; + /* UIO driver should not be loaded in the isolation VM.*/ + if (hv_is_isolation_supported()) + return -ENOTSUPP; + /* Communicating with host has to be via shared memory not hypercall */ if (!channel->offermsg.monitor_allocated) { dev_err(&dev->device, "vmbus channel requires hypercall\n"); From patchwork Wed Apr 14 14:49:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203085 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.7 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,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 5DF0EC4646B for ; Wed, 14 Apr 2021 14:50:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3AB13611F2 for ; Wed, 14 Apr 2021 14:50:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232107AbhDNOvC (ORCPT ); Wed, 14 Apr 2021 10:51:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351974AbhDNOuy (ORCPT ); Wed, 14 Apr 2021 10:50:54 -0400 Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F89DC06138C; Wed, 14 Apr 2021 07:50:33 -0700 (PDT) Received: by mail-pg1-x52e.google.com with SMTP id l76so14569079pga.6; Wed, 14 Apr 2021 07:50:33 -0700 (PDT) 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=SNYshAOIhIfYWplCoKI3GKQhqu3xrQdJgtDgLoPsrVY=; b=gibuXI9Xv7PARINSU43+2rKSBQQrekXZwe4JwQ/fSldoGkdBytnFZKjdh1uWMusUxb BgQY9KiYPHHhszJbeOVJvpB162ge6nEZtamVklk/8VdVGikS2QFEHa3d9VbIgsDYtERj U1OSC2tKMrST6MfaGv0Wb6lLasokI084S8I+7JWirTDKYvAwF3mlQNItQCfKFGXibXmC 7VRGkERZJV1hiFl4tiD76EFkxRAk795i6uHAAHh8lY4jJ7szOhMfztnOyTsBNuY9Oyph VepV73vkdDvoHqf5lLhBskr9fBJmbsLOV+hZuDDGaRYdMEzhtsR6nl0UPEAno8awUema iuOg== 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=SNYshAOIhIfYWplCoKI3GKQhqu3xrQdJgtDgLoPsrVY=; b=WyFm8hdhyNdU97kPaXyUYnTAyEeTNBbPcnO+TJ8Fg8FokWcMho+yuus+ZxLFrKzOOf mXm2ziEPweDCnvXSTpKGc+mdGCu4Ytde9/pcm1LQ1A+SzuIpFwgQ55yAmvp4IVXT1tEV 02sjV4+dEbIVhfGMujaDxwox+prMTvBwGaefNL5KiXOoYNtRkWGylRZMNIWg1qQzBb33 G130oX2DHCbfSCZy+GNIsiolIT3wPMtUoTpfhVAVNaeUZX+YU+7bp1GF9hxSp6r/bhES gZXKsH1OsCB3b5cHuBxdwWR0+vSdUPk+n1hB9jNUxegmlN+rC8D/xSi0SPVnfgKGIt8G imJw== X-Gm-Message-State: AOAM532ap4JHEYp+4mHyATGPmV0XBUm0s2ZgwOHEU00PTQux3r/P/1bQ c2lQV4VuY6eT37CF79xnZsA= X-Google-Smtp-Source: ABdhPJwnbnl089PfsrvpvokDoexGwlHUvaiFWcLBnccsg7u15LM3+for4Cf+c0I1NoLoEZ/CfdV9tg== X-Received: by 2002:a63:c741:: with SMTP id v1mr37348049pgg.207.1618411832810; Wed, 14 Apr 2021 07:50:32 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:32 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 09/12] swiotlb: Add bounce buffer remap address setting function Date: Wed, 14 Apr 2021 10:49:42 -0400 Message-Id: <20210414144945.3460554-10-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan For Hyper-V isolation VM with AMD SEV SNP, the bounce buffer(shared memory) needs to be accessed via extra address space(e.g address above bit39). Hyper-V code may remap extra address space outside of swiotlb. swiotlb_bounce() needs to use remap virtual address to copy data from/to bounce buffer. Add new interface swiotlb_set_bounce_remap() to do that. Signed-off-by: Tianyu Lan --- include/linux/swiotlb.h | 5 +++++ kernel/dma/swiotlb.c | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index d9c9fc9ca5d2..3ccd08116683 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -82,8 +82,13 @@ unsigned int swiotlb_max_segment(void); size_t swiotlb_max_mapping_size(struct device *dev); bool is_swiotlb_active(void); void __init swiotlb_adjust_size(unsigned long new_size); +void swiotlb_set_bounce_remap(unsigned char *vaddr); #else #define swiotlb_force SWIOTLB_NO_FORCE +static inline void swiotlb_set_bounce_remap(unsigned char *vaddr) +{ +} + static inline bool is_swiotlb_buffer(phys_addr_t paddr) { return false; diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 7c42df6e6100..5fd2db6aa149 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -94,6 +94,7 @@ static unsigned int io_tlb_index; * not be bounced (unless SWIOTLB_FORCE is set). */ static unsigned int max_segment; +static unsigned char *swiotlb_bounce_remap_addr; /* * We need to save away the original address corresponding to a mapped entry @@ -421,6 +422,11 @@ void __init swiotlb_exit(void) swiotlb_cleanup(); } +void swiotlb_set_bounce_remap(unsigned char *vaddr) +{ + swiotlb_bounce_remap_addr = vaddr; +} + /* * Bounce: copy the swiotlb buffer from or back to the original dma location */ @@ -428,7 +434,12 @@ static void swiotlb_bounce(phys_addr_t orig_addr, phys_addr_t tlb_addr, size_t size, enum dma_data_direction dir) { unsigned long pfn = PFN_DOWN(orig_addr); - unsigned char *vaddr = phys_to_virt(tlb_addr); + unsigned char *vaddr; + + if (swiotlb_bounce_remap_addr) + vaddr = swiotlb_bounce_remap_addr + tlb_addr - io_tlb_start; + else + vaddr = phys_to_virt(tlb_addr); if (PageHighMem(pfn_to_page(pfn))) { /* The buffer does not have a mapping. Map it in and copy */ From patchwork Wed Apr 14 14:49:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203087 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.7 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,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 3BD03C43460 for ; Wed, 14 Apr 2021 14:50:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EE2B46117A for ; Wed, 14 Apr 2021 14:50:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352062AbhDNOvE (ORCPT ); Wed, 14 Apr 2021 10:51:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38920 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351984AbhDNOuz (ORCPT ); Wed, 14 Apr 2021 10:50:55 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A575C06175F; Wed, 14 Apr 2021 07:50:34 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id o123so13909133pfb.4; Wed, 14 Apr 2021 07:50:34 -0700 (PDT) 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=BJQLwkA9W/535NLWBZWmq8i7UzFGYSRLRmzJAHK8gIA=; b=JeMh273MlJLiBAiimx+AK/wv4TS0pmL3eBkyQYbrrXJc1p9t/yVCYThm+LfoCsHw8b qc357p2ojcjzv+t66VCGbcpGh6sP5aej3NeI2NGQBx8TWlHjcVniMXHPRLSAy02Xtfj9 QmnwrGOGhe4Phsl7n/ZircRPOOVmQ1TXqt4Avf0iGoJRapPIK9HXosZecvlfzBd5EhXH FDzxhyyvEEVP1UJI3OfWsiOepqSyZscMd5MY4KXWWWVrmZVVEgwSl/2MiBesqnrJ8uYs RB2C4rHWHp/EqEuAXdrglsAw6k/T1G14KlpgPV4Ly+ua1TDR6WZgt4jXYpCgu5UDIdgy /svw== 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=BJQLwkA9W/535NLWBZWmq8i7UzFGYSRLRmzJAHK8gIA=; b=FEYN/SOC2giOO4xm1xvfNix8fGsW95KuFRZHpqN9ja/hYMGy/w5XX4enzMx1Ntu7Gc HFa1AeLbJGjlT2X+Jntcbwm4TvHoGeJphARMgtQngPt+5CA+RVrFf2hOarWVlHfKRWdT YSdKs2aP6BClVPTNVT2Qf0CRNPagPp8sLaaCIB+U2n+YVYtNYkvt/xU4+aoDBEXgLhQ8 yvrzQwiUwHBaeqrp036kEGa44qXj35VpPCXBlsUYuqzwdQ/OQmW66wKFpk5hLkT6VTig ghF1gBoKa7u/55ckQuBCICM0iOHn1pFV2TtvNyltseZaoyiB8ryxWcKXhTLGZ+XHv64L 24VQ== X-Gm-Message-State: AOAM531sOes8r5o4f8Ewc2Nq64jvtmy94kZOGkLuiBkL9cvYBm20g3BK agEpuyXzeKvEMVITmV4txrc= X-Google-Smtp-Source: ABdhPJwOhx54FmzERuqfo9qVMIzIREINFZJXuw5QLznc5Vw3o4KmCJSYx6u1IpzPG7gCSgG4YUCpkA== X-Received: by 2002:a63:77cf:: with SMTP id s198mr38257555pgc.252.1618411833797; Wed, 14 Apr 2021 07:50:33 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:33 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 10/12] HV/IOMMU: Add Hyper-V dma ops support Date: Wed, 14 Apr 2021 10:49:43 -0400 Message-Id: <20210414144945.3460554-11-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan Hyper-V Isolation VM requires bounce buffer support. To use swiotlb bounce buffer, add Hyper-V dma ops and use swiotlb functions in the map and unmap callback. Allocate bounce buffer in the Hyper-V code because bounce buffer needs to be accessed via extra address space(e.g, address above 39bit) in the AMD SEV SNP based Isolation VM. ioremap_cache() can't use in the hyperv_iommu_swiotlb_init() which is too early place and remap bounce buffer in the hyperv_iommu_swiotlb_ later_init(). Signed-off-by: Tianyu Lan --- arch/x86/kernel/pci-swiotlb.c | 3 +- drivers/hv/vmbus_drv.c | 3 + drivers/iommu/hyperv-iommu.c | 127 ++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index c2cfa5e7c152..caaf68c06f24 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c @@ -15,6 +15,7 @@ #include int swiotlb __read_mostly; +extern int hyperv_swiotlb; /* * pci_swiotlb_detect_override - set swiotlb to 1 if necessary @@ -68,7 +69,7 @@ void __init pci_swiotlb_init(void) void __init pci_swiotlb_late_init(void) { /* An IOMMU turned us off. */ - if (!swiotlb) + if (!swiotlb && !hyperv_swiotlb) swiotlb_exit(); else { printk(KERN_INFO "PCI-DMA: " diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 10dce9f91216..0ee6ec3a5de6 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -2030,6 +2031,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 */ @@ -2070,6 +2072,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..588ba847f0cc 100644 --- a/drivers/iommu/hyperv-iommu.c +++ b/drivers/iommu/hyperv-iommu.c @@ -13,19 +13,28 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include #include #include #include +#include +#include +#include #include "irq_remapping.h" #ifdef CONFIG_IRQ_REMAP +int hyperv_swiotlb __read_mostly; + /* * According 82093AA IO-APIC spec , IO APIC has a 24-entry Interrupt * Redirection Table. Hyper-V exposes one single IO-APIC and so define @@ -36,6 +45,10 @@ static cpumask_t ioapic_max_cpumask = { CPU_BITS_NONE }; static struct irq_domain *ioapic_ir_domain; +static unsigned long hyperv_io_tlb_start, *hyperv_io_tlb_end; +static unsigned long hyperv_io_tlb_nslabs, hyperv_io_tlb_size; +static void *hyperv_io_tlb_remap; + static int hyperv_ir_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { @@ -337,4 +350,118 @@ static const struct irq_domain_ops hyperv_root_ir_domain_ops = { .free = hyperv_root_irq_remapping_free, }; +static dma_addr_t hyperv_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + unsigned long attrs) +{ + phys_addr_t map, phys = (page_to_pfn(page) << PAGE_SHIFT) + offset; + + if (!hv_is_isolation_supported()) + return phys; + + map = swiotlb_tbl_map_single(dev, phys, size, HV_HYP_PAGE_SIZE, dir, + attrs); + if (map == (phys_addr_t)DMA_MAPPING_ERROR) + return DMA_MAPPING_ERROR; + + return map; +} + +static void hyperv_unmap_page(struct device *dev, dma_addr_t dev_addr, + size_t size, enum dma_data_direction dir, unsigned long attrs) +{ + if (!hv_is_isolation_supported()) + return; + + swiotlb_tbl_unmap_single(dev, dev_addr, size, HV_HYP_PAGE_SIZE, dir, + attrs); +} + +int __init hyperv_swiotlb_init(void) +{ + unsigned long bytes; + void *vstart = 0; + + bytes = 200 * 1024 * 1024; + vstart = memblock_alloc_low(PAGE_ALIGN(bytes), PAGE_SIZE); + hyperv_io_tlb_nslabs = bytes >> IO_TLB_SHIFT; + hyperv_io_tlb_size = bytes; + + if (!vstart) { + pr_warn("Fail to allocate swiotlb.\n"); + return -ENOMEM; + } + + hyperv_io_tlb_start = virt_to_phys(vstart); + if (!hyperv_io_tlb_start) + panic("%s: Failed to allocate %lu bytes align=0x%lx.\n", + __func__, PAGE_ALIGN(bytes), PAGE_SIZE); + + if (swiotlb_init_with_tbl(vstart, hyperv_io_tlb_nslabs, 1)) + panic("%s: Cannot allocate SWIOTLB buffer.\n", __func__); + + swiotlb_set_max_segment(PAGE_SIZE); + hyperv_io_tlb_end = hyperv_io_tlb_start + bytes; + return 0; +} + +const struct dma_map_ops hyperv_dma_ops = { + .map_page = hyperv_map_page, + .unmap_page = hyperv_unmap_page, +}; + +int __init hyperv_swiotlb_detect(void) +{ + dma_ops = &hyperv_dma_ops; + + if (hypervisor_is_type(X86_HYPER_MS_HYPERV) + && hv_is_isolation_supported()) { + /* + * Disable generic swiotlb and allocate Hyper-v swiotlb + * in the hyperv_iommu_swiotlb_init(). + */ + swiotlb = 0; + hyperv_swiotlb = 1; + + return 1; + } + + return 0; +} + +void __init hyperv_iommu_swiotlb_init(void) +{ + hyperv_swiotlb_init(); +} + +void __init hyperv_iommu_swiotlb_later_init(void) +{ + int ret; + + /* Mask bounce buffer visible to host and remap extra address. */ + if (hv_isolation_type_snp()) { + ret = hv_set_mem_host_visibility( + phys_to_virt(hyperv_io_tlb_start), + hyperv_io_tlb_size, + VMBUS_PAGE_VISIBLE_READ_WRITE); + if (ret) + panic("%s: Fail to mark Hyper-v swiotlb buffer visible to host. err=%d\n", + __func__, ret); + + hyperv_io_tlb_remap = ioremap_cache(hyperv_io_tlb_start + + ms_hyperv.shared_gpa_boundary, + hyperv_io_tlb_size); + if (!hyperv_io_tlb_remap) + panic("%s: Fail to remap io tlb.\n", __func__); + + memset(hyperv_io_tlb_remap, 0x00, hyperv_io_tlb_size); + swiotlb_set_bounce_remap(hyperv_io_tlb_remap); + } +} + +IOMMU_INIT_FINISH(hyperv_swiotlb_detect, + NULL, hyperv_iommu_swiotlb_init, + hyperv_iommu_swiotlb_later_init); + #endif From patchwork Wed Apr 14 14:49:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203089 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.7 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,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 F32C2C433ED for ; Wed, 14 Apr 2021 14:50:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C4B0F6117A for ; Wed, 14 Apr 2021 14:50:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352073AbhDNOvG (ORCPT ); Wed, 14 Apr 2021 10:51:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351998AbhDNOu4 (ORCPT ); Wed, 14 Apr 2021 10:50:56 -0400 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A088C061574; Wed, 14 Apr 2021 07:50:35 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id s14so5550006pjl.5; Wed, 14 Apr 2021 07:50:35 -0700 (PDT) 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=rEnojfxzKMIKinSbA6nTujnDRb/izr87Op+NW+5m2CE=; b=o/koGepbeM26DluIG2Fi9arPS0eBN/lI4S0aDxn3Xk9LzgaVt6M7oJgL5HXo7UWY41 pbvQM7udAhKMXg/b1zc4VAc50+yOXH3kPlRulsY7eIuVt3ETUFqssKsQPT64CndQo7uX K5kByBP3DsifozzJLYCf3UXuTBfEx+iYDrIIK070FEErgIte1KuXT3IlsUs9ovAEV2Mb ro8JRMoBHlZnOio/fG9AIqPzZkHsEx9ZOMT8aYJ6FeP1dFo124kw6eCzR9iBLLydqRmw SYu7YIoO8ykwu9slOG50CLRu8T5SbbBLLwkws+qpqpC5VBap8oYs4XoOX4/RBZFAhi8w sQRg== 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=rEnojfxzKMIKinSbA6nTujnDRb/izr87Op+NW+5m2CE=; b=sBGhBn57DdW3EjU5TUCxJ0B9wPKVXSUghbtbV8fE6wR61A27LKQcuC1XRA0cI8rq5e +dD5Zlpg/V7tnN02NWaWIk78xXgzav9QZ3LyBIwW2RUE0j41wUgZse+yd1luJTbO7BjE NabvB7Tr2hx4WK45FYvvBC6ZxbzhzLMM7JdU+BZeGTMS32Fdy3npFb7wsbkdfhGSEQGC oHG4j08iLR/1e/MQxcdFzaBKEfANlTdv/TZf9JYEpIeqSgcJLZa0g1SfCyxp2r6hbhCt kvhP+e80i+dDxHA3SdkhmFd4dD16ieVm63lTw9EoKfsVO6BL6t7IinKruMHRIdvHwJ+x NaUg== X-Gm-Message-State: AOAM532KGPWKIq+C/BTAxsNkRoEQYY8hEWXUD8u1k9D8P059JsAxPYLv 2j5RzMeUkEJ+yv9zYCg4SAY= X-Google-Smtp-Source: ABdhPJymBmW993DhTofbaszulRmUAiPb/+8poEshIM9VBunj5uilMiDDp5eNxLDJEiVrIn8kvigDbg== X-Received: by 2002:a17:90a:528b:: with SMTP id w11mr4092618pjh.162.1618411834737; Wed, 14 Apr 2021 07:50:34 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:34 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 11/12] HV/Netvsc: Add Isolation VM support for netvsc driver Date: Wed, 14 Apr 2021 10:49:44 -0400 Message-Id: <20210414144945.3460554-12-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan In Isolation VM, all shared memory with host needs to mark visible to host via hvcall. vmbus_establish_gpadl() has already done it for netvsc rx/tx ring buffer. The page buffer used by vmbus_sendpacket_ pagebuffer() still need to handle. Use DMA API to map/umap these memory during sending/receiving packet and Hyper-V DMA ops callback will use swiotlb fucntion to allocate bounce buffer and copy data from/to bounce buffer. Signed-off-by: Tianyu Lan --- drivers/net/hyperv/hyperv_net.h | 11 +++ drivers/net/hyperv/netvsc.c | 137 ++++++++++++++++++++++++++++-- drivers/net/hyperv/rndis_filter.c | 3 + 3 files changed, 144 insertions(+), 7 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 2a87cfa27ac0..d85f811238c7 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -130,6 +130,7 @@ struct hv_netvsc_packet { u32 total_bytes; u32 send_buf_index; u32 total_data_buflen; + struct dma_range *dma_range; }; #define NETVSC_HASH_KEYLEN 40 @@ -1026,6 +1027,7 @@ struct netvsc_device { /* Receive buffer allocated by us but manages by NetVSP */ void *recv_buf; + void *recv_original_buf; u32 recv_buf_size; /* allocated bytes */ u32 recv_buf_gpadl_handle; u32 recv_section_cnt; @@ -1034,6 +1036,8 @@ struct netvsc_device { /* Send buffer allocated by us */ void *send_buf; + void *send_original_buf; + u32 send_buf_size; u32 send_buf_gpadl_handle; u32 send_section_cnt; u32 send_section_size; @@ -1715,4 +1719,11 @@ struct rndis_message { #define TRANSPORT_INFO_IPV6_TCP 0x10 #define TRANSPORT_INFO_IPV6_UDP 0x20 +struct dma_range { + dma_addr_t dma; + u32 mapping_size; +}; + +void netvsc_dma_unmap(struct hv_device *hv_dev, + struct hv_netvsc_packet *packet); #endif /* _HYPERV_NET_H */ diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 2353623259f3..1a5f5be4eeea 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -26,6 +26,7 @@ #include "hyperv_net.h" #include "netvsc_trace.h" +#include "../../hv/hyperv_vmbus.h" /* * Switch the data path from the synthetic interface to the VF @@ -119,8 +120,21 @@ static void free_netvsc_device(struct rcu_head *head) int i; kfree(nvdev->extension); - vfree(nvdev->recv_buf); - vfree(nvdev->send_buf); + + if (nvdev->recv_original_buf) { + iounmap(nvdev->recv_buf); + vfree(nvdev->recv_original_buf); + } else { + vfree(nvdev->recv_buf); + } + + if (nvdev->send_original_buf) { + iounmap(nvdev->send_buf); + vfree(nvdev->send_original_buf); + } else { + vfree(nvdev->send_buf); + } + kfree(nvdev->send_section_map); for (i = 0; i < VRSS_CHANNEL_MAX; i++) { @@ -302,9 +316,12 @@ static int netvsc_init_buf(struct hv_device *device, struct nvsp_1_message_send_receive_buffer_complete *resp; struct net_device *ndev = hv_get_drvdata(device); struct nvsp_message *init_packet; + struct vm_struct *area; + u64 extra_phys; unsigned int buf_size; + unsigned long vaddr; size_t map_words; - int ret = 0; + int ret = 0, i; /* Get receive buffer area. */ buf_size = device_info->recv_sections * device_info->recv_section_size; @@ -340,6 +357,27 @@ static int netvsc_init_buf(struct hv_device *device, goto cleanup; } + if (hv_isolation_type_snp()) { + area = get_vm_area(buf_size, VM_IOREMAP); + if (!area) + goto cleanup; + + vaddr = (unsigned long)area->addr; + for (i = 0; i < buf_size / HV_HYP_PAGE_SIZE; i++) { + extra_phys = (virt_to_hvpfn(net_device->recv_buf + i * HV_HYP_PAGE_SIZE) + << HV_HYP_PAGE_SHIFT) + ms_hyperv.shared_gpa_boundary; + ret |= ioremap_page_range(vaddr + i * HV_HYP_PAGE_SIZE, + vaddr + (i + 1) * HV_HYP_PAGE_SIZE, + extra_phys, PAGE_KERNEL_IO); + } + + if (ret) + goto cleanup; + + net_device->recv_original_buf = net_device->recv_buf; + net_device->recv_buf = (void *)vaddr; + } + /* Notify the NetVsp of the gpadl handle */ init_packet = &net_device->channel_init_pkt; memset(init_packet, 0, sizeof(struct nvsp_message)); @@ -432,6 +470,28 @@ static int netvsc_init_buf(struct hv_device *device, goto cleanup; } + if (hv_isolation_type_snp()) { + area = get_vm_area(buf_size, VM_IOREMAP); + if (!area) + goto cleanup; + + vaddr = (unsigned long)area->addr; + + for (i = 0; i < buf_size / HV_HYP_PAGE_SIZE; i++) { + extra_phys = (virt_to_hvpfn(net_device->send_buf + i * HV_HYP_PAGE_SIZE) + << HV_HYP_PAGE_SHIFT) + ms_hyperv.shared_gpa_boundary; + ret |= ioremap_page_range(vaddr + i * HV_HYP_PAGE_SIZE, + vaddr + (i + 1) * HV_HYP_PAGE_SIZE, + extra_phys, PAGE_KERNEL_IO); + } + + if (ret) + goto cleanup; + + net_device->send_original_buf = net_device->send_buf; + net_device->send_buf = (void *)vaddr; + } + /* Notify the NetVsp of the gpadl handle */ init_packet = &net_device->channel_init_pkt; memset(init_packet, 0, sizeof(struct nvsp_message)); @@ -722,7 +782,7 @@ static void netvsc_send_tx_complete(struct net_device *ndev, /* Notify the layer above us */ if (likely(skb)) { - const struct hv_netvsc_packet *packet + struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)skb->cb; u32 send_index = packet->send_buf_index; struct netvsc_stats *tx_stats; @@ -738,6 +798,7 @@ static void netvsc_send_tx_complete(struct net_device *ndev, tx_stats->bytes += packet->total_bytes; u64_stats_update_end(&tx_stats->syncp); + netvsc_dma_unmap(ndev_ctx->device_ctx, packet); napi_consume_skb(skb, budget); } @@ -878,6 +939,60 @@ static void netvsc_copy_to_send_buf(struct netvsc_device *net_device, memset(dest, 0, padding); } +void netvsc_dma_unmap(struct hv_device *hv_dev, + struct hv_netvsc_packet *packet) +{ + u32 page_count = packet->cp_partial ? + packet->page_buf_cnt - packet->rmsg_pgcnt : + packet->page_buf_cnt; + int i; + + if (!packet->dma_range) + return; + + for (i = 0; i < page_count; i++) + dma_unmap_single(&hv_dev->device, packet->dma_range[i].dma, + packet->dma_range[i].mapping_size, + DMA_TO_DEVICE); + + kfree(packet->dma_range); +} + +int netvsc_dma_map(struct hv_device *hv_dev, + struct hv_netvsc_packet *packet, + struct hv_page_buffer *pb) +{ + u32 page_count = packet->cp_partial ? + packet->page_buf_cnt - packet->rmsg_pgcnt : + packet->page_buf_cnt; + dma_addr_t dma; + int i; + + packet->dma_range = kzalloc(sizeof(struct dma_range) * page_count, + GFP_KERNEL); + if (!packet->dma_range) + return -ENOMEM; + + for (i = 0; i < page_count; i++) { + char *src = phys_to_virt((pb[i].pfn << HV_HYP_PAGE_SHIFT) + + pb[i].offset); + u32 len = pb[i].len; + + dma = dma_map_single(&hv_dev->device, src, len, + DMA_TO_DEVICE); + if (dma_mapping_error(&hv_dev->device, dma)) + return -ENOMEM; + + packet->dma_range[i].dma = dma; + packet->dma_range[i].mapping_size = len; + pb[i].pfn = dma >> HV_HYP_PAGE_SHIFT; + pb[i].offset = offset_in_hvpage(dma); + pb[i].len = len; + } + + return 0; +} + static inline int netvsc_send_pkt( struct hv_device *device, struct hv_netvsc_packet *packet, @@ -917,14 +1032,22 @@ static inline int netvsc_send_pkt( trace_nvsp_send_pkt(ndev, out_channel, rpkt); + packet->dma_range = NULL; if (packet->page_buf_cnt) { if (packet->cp_partial) pb += packet->rmsg_pgcnt; + ret = netvsc_dma_map(ndev_ctx->device_ctx, packet, pb); + if (ret) + return ret; + ret = vmbus_sendpacket_pagebuffer(out_channel, - pb, packet->page_buf_cnt, - &nvmsg, sizeof(nvmsg), - req_id); + pb, packet->page_buf_cnt, + &nvmsg, sizeof(nvmsg), + req_id); + + if (ret) + netvsc_dma_unmap(ndev_ctx->device_ctx, packet); } else { ret = vmbus_sendpacket(out_channel, &nvmsg, sizeof(nvmsg), diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 598713c0d5a8..b19243f5874c 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -263,6 +263,8 @@ static void rndis_filter_receive_response(struct net_device *ndev, { struct rndis_device *dev = nvdev->extension; struct rndis_request *request = NULL; + struct hv_device *hv_dev = ((struct net_device_context *) + netdev_priv(ndev))->device_ctx; bool found = false; unsigned long flags; @@ -327,6 +329,7 @@ static void rndis_filter_receive_response(struct net_device *ndev, } } + netvsc_dma_unmap(hv_dev, &request->pkt); complete(&request->wait_event); } else { netdev_err(ndev, From patchwork Wed Apr 14 14:49:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianyu Lan X-Patchwork-Id: 12203091 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.7 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,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 75DBEC001E7 for ; Wed, 14 Apr 2021 14:50:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D6C86117A for ; Wed, 14 Apr 2021 14:50:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352080AbhDNOvI (ORCPT ); Wed, 14 Apr 2021 10:51:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352003AbhDNOu5 (ORCPT ); Wed, 14 Apr 2021 10:50:57 -0400 Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7A99C061756; Wed, 14 Apr 2021 07:50:35 -0700 (PDT) Received: by mail-pg1-x532.google.com with SMTP id d10so14564546pgf.12; Wed, 14 Apr 2021 07:50:35 -0700 (PDT) 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=FJbcZ8KnexDAAQ5C4Sah9FWkqLY6Pv3HeJbolDJY4aA=; b=pJqRunkA+uvhxmvikCt8JBi6ru5mMAHBSouNbpNF9rJ0/UZBeBZbNJBCihskZckNdz VF19al63x7JcKIwSaI+KgRMKfSCSAY1Rw9bm3SeZTFumtAQ1F6F2t95WHbTa7fd9i7Tn oYWyOXXwTN9+AehaDQOGu3IYPhNL0uJPAF/Y5xrfhILPXupgDCaiPCDkfxwVRVWqt8q+ v1FJRcKkKffDj4UMUcXDwJEin7yz4TBxBoW5ErGESAAdJKNwJ1ukgEYbn+s0z/MPExFU EV7Gn16e8uqLMsjL1/Ua5qlsNxwABA+5vNnnX0j44xHWZEyyVt04dkbZk7p6QtVwr46f qTdQ== 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=FJbcZ8KnexDAAQ5C4Sah9FWkqLY6Pv3HeJbolDJY4aA=; b=GvNpKmeYZCewxMj0gRCDXVdOYeh3MQ+MeNV8pKu3jhgw/kVZ8J2zvbxrBbvyksOm0S 3vOKTdwaaNX6Ik2Sg4yR2auW25wWkQplZqArGOtHuaCTL5+D/tZV9K9ZGBpLNZcWL90P ymxJ6i7rczWFuvBk9gGbKNTBx5OuHEpSlFHU+C/hLqP122iLaMDoIyLxI6z+YlU2Zk7C u19mOOuaSQqqzp0brUhBt2bviw7ZoMg2X4gaotqHDKrtrKA1fcCGeE8FjW9D4YPgTi7O nym2F5zriPEz0mJC8ODj7X1sd4dl2yyc8/eivA+HembqYyUBNs7nzGTGMEakh0C0wLIY 3YkA== X-Gm-Message-State: AOAM533X0H9AFVC1D6IT0Dl2YDG0eK7eSMQCSeObnhKoiAIrecBnPlgF VXjh1zdDMqm1xfd8bghS/j0= X-Google-Smtp-Source: ABdhPJxHAv83JdLDizjV20z7u62dRC/ZGAyfJ/XHZQUwINjnLav8NcwqNU6XQrZbUuAS+bM3Dz+Utw== X-Received: by 2002:a63:1646:: with SMTP id 6mr39049996pgw.321.1618411835543; Wed, 14 Apr 2021 07:50:35 -0700 (PDT) Received: from ubuntu-Virtual-Machine.corp.microsoft.com ([2001:4898:80e8:35:ebad:12c1:f579:e332]) by smtp.gmail.com with ESMTPSA id w67sm17732522pgb.87.2021.04.14.07.50.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Apr 2021 07:50:35 -0700 (PDT) From: Tianyu Lan To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, akpm@linux-foundation.org, gregkh@linuxfoundation.org, konrad.wilk@oracle.com, hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, joro@8bytes.org, will@kernel.org, davem@davemloft.net, kuba@kernel.org, jejb@linux.ibm.com, martin.petersen@oracle.com Cc: Tianyu Lan , iommu@lists.linux-foundation.org, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-scsi@vger.kernel.org, netdev@vger.kernel.org, vkuznets@redhat.com, thomas.lendacky@amd.com, brijesh.singh@amd.com, sunilmut@microsoft.com Subject: [Resend RFC PATCH V2 12/12] HV/Storvsc: Add Isolation VM support for storvsc driver Date: Wed, 14 Apr 2021 10:49:45 -0400 Message-Id: <20210414144945.3460554-13-ltykernel@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210414144945.3460554-1-ltykernel@gmail.com> References: <20210414144945.3460554-1-ltykernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Tianyu Lan In Isolation VM, all shared memory with host needs to mark visible to host via hvcall. vmbus_establish_gpadl() has already done it for netvsc rx/tx ring buffer. The page buffer used by vmbus_sendpacket_ mpb_desc() still need to handle. Use DMA API to map/umap these memory during sending/receiving packet and Hyper-V DMA ops callback will use swiotlb fucntion to allocate bounce buffer and copy data from/to bounce buffer. Signed-off-by: Tianyu Lan --- drivers/scsi/storvsc_drv.c | 67 +++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 2e4fa77445fd..d271578b1811 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -414,6 +416,11 @@ static void storvsc_on_channel_callback(void *context); #define STORVSC_IDE_MAX_TARGETS 1 #define STORVSC_IDE_MAX_CHANNELS 1 +struct dma_range { + dma_addr_t dma; + u32 mapping_size; +}; + struct storvsc_cmd_request { struct scsi_cmnd *cmd; @@ -427,6 +434,8 @@ struct storvsc_cmd_request { u32 payload_sz; struct vstor_packet vstor_packet; + u32 hvpg_count; + struct dma_range *dma_range; }; @@ -1236,6 +1245,7 @@ static void storvsc_on_channel_callback(void *context) const struct vmpacket_descriptor *desc; struct hv_device *device; struct storvsc_device *stor_device; + int i; if (channel->primary_channel != NULL) device = channel->primary_channel->device_obj; @@ -1249,6 +1259,8 @@ static void storvsc_on_channel_callback(void *context) foreach_vmbus_pkt(desc, channel) { void *packet = hv_pkt_data(desc); struct storvsc_cmd_request *request; + enum dma_data_direction dir; + u32 attrs; u64 cmd_rqst; cmd_rqst = vmbus_request_addr(&channel->requestor, @@ -1261,6 +1273,22 @@ static void storvsc_on_channel_callback(void *context) request = (struct storvsc_cmd_request *)(unsigned long)cmd_rqst; + if (request->vstor_packet.vm_srb.data_in == READ_TYPE) + dir = DMA_FROM_DEVICE; + else + dir = DMA_TO_DEVICE; + + if (request->dma_range) { + for (i = 0; i < request->hvpg_count; i++) + dma_unmap_page_attrs(&device->device, + request->dma_range[i].dma, + request->dma_range[i].mapping_size, + request->vstor_packet.vm_srb.data_in + == READ_TYPE ? + DMA_FROM_DEVICE : DMA_TO_DEVICE, attrs); + kfree(request->dma_range); + } + if (request == &stor_device->init_request || request == &stor_device->reset_request) { memcpy(&request->vstor_packet, packet, @@ -1682,8 +1710,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) struct vmscsi_request *vm_srb; struct scatterlist *cur_sgl; struct vmbus_packet_mpb_array *payload; + enum dma_data_direction dir; u32 payload_sz; u32 length; + u32 attrs; if (vmstor_proto_version <= VMSTOR_PROTO_VERSION_WIN8) { /* @@ -1722,14 +1752,17 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) case DMA_TO_DEVICE: vm_srb->data_in = WRITE_TYPE; vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_OUT; + dir = DMA_TO_DEVICE; break; case DMA_FROM_DEVICE: vm_srb->data_in = READ_TYPE; vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_IN; + dir = DMA_FROM_DEVICE; break; case DMA_NONE: vm_srb->data_in = UNKNOWN_TYPE; vm_srb->win8_extension.srb_flags |= SRB_FLAGS_NO_DATA_TRANSFER; + dir = DMA_NONE; break; default: /* @@ -1786,6 +1819,12 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) hvpgoff = sgl->offset >> HV_HYP_PAGE_SHIFT; cur_sgl = sgl; + + cmd_request->dma_range = kzalloc(sizeof(struct dma_range) * hvpg_count, + GFP_ATOMIC); + if (!cmd_request->dma_range) + return -ENOMEM; + for (i = 0; i < hvpg_count; i++) { /* * 'i' is the index of hv pages in the payload and @@ -1805,6 +1844,8 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) */ unsigned int hvpgoff_in_page = (i + hvpgoff) % NR_HV_HYP_PAGES_IN_PAGE; + dma_addr_t dma; + u32 size; /* * Two cases that we need to fetch a page: @@ -1817,8 +1858,28 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) cur_sgl = sg_next(cur_sgl); } - payload->range.pfn_array[i] = hvpfn + hvpgoff_in_page; + size = min(HV_HYP_PAGE_SIZE - offset_in_hvpg, (unsigned long)length); + dma = dma_map_page_attrs(&dev->device, + pfn_to_page(hvpfn), + offset_in_hvpg, size, + scmnd->sc_data_direction, attrs); + if (dma_mapping_error(&dev->device, dma)) { + pr_warn("dma map error.\n"); + ret = -ENOMEM; + goto free_dma_range; + } + + if (offset_in_hvpg) { + payload->range.offset = dma & ~HV_HYP_PAGE_MASK; + offset_in_hvpg = 0; + } + + cmd_request->dma_range[i].dma = dma; + cmd_request->dma_range[i].mapping_size = size; + payload->range.pfn_array[i] = dma >> HV_HYP_PAGE_SHIFT; + length -= size; } + cmd_request->hvpg_count = hvpg_count; } cmd_request->payload = payload; @@ -1836,6 +1897,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) } return 0; + +free_dma_range: + kfree(cmd_request->dma_range); + return ret; } static struct scsi_host_template scsi_driver = {