Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp3356707pxk; Mon, 7 Sep 2020 10:30:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx2UFl15dnJbYZYt/5gBs8XIrQt873S86AL2GW/4naajQn3M4U16VJbB12+VZaf0FI2Z1M8 X-Received: by 2002:aa7:d991:: with SMTP id u17mr6527365eds.11.1599499811991; Mon, 07 Sep 2020 10:30:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599499811; cv=none; d=google.com; s=arc-20160816; b=Vw8D3kxSKRQKnxIf9r5SuVhRppm+IzjckGuJsTRLS2LwoZL6wh/UaXz8mVrp6IPhwy Vulkydva5IapybveS9rlhcNh6I7qFSlcibHvBtD7C444jgO0TEfXLD0AJQN2pN009za5 cKebja6fcYJJRnfEIVDddlaAhEn8eKb60hsAF+hA70i2gPKe4cDj6IqaYgnVzTpoBBR7 fai6tb22AQxeu94EOfYSNM7LvUVZlQbcabPXOAogqpzE+rol6tp57MoBJTDlT4mBx70P ycEKkiRt1pCgq2yYOaIFoxaWPfHKOcIeOuUwcNr5bYyksEm743Y6a1ff73UdXzfkgxlQ DSng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=dG/en/bXN/1pZCbIAq8aN0lZOoV6stLqSDSFzAUC+vQ=; b=CWm+J9R3klDYCaYdhzAxoYLUgefSWXUzbITG1aun7s9wGvTrZuH1RDhJCzLUso/hdM 7IDlBZzU9A9A7KiQte0sRaTc1e7cEI0faHIesj6J+ems1id1gl9McxM+uJEZ0GyDpan+ soyNyzY3zCJjb9uXSPfXoKSNV5PRsmY/kJXhTQuTvTrftlow36Yt3sXPoeRCloNkMoQb fX3DGtK7THR2czYjxb0uN0h4Zjd37CGLueDPqeK0hZysE/fx3YAMGuDlNH5R/Oau677c U5G6IkdSeg7UzWvQYCCmB4F7i/eqABvibmiHlw7ZZAfthRVSnj2McNW30sK/uFe6qhKh mMVg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=8bytes.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z22si10196351ejc.596.2020.09.07.10.29.50; Mon, 07 Sep 2020 10:30:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=8bytes.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731318AbgIGR3Q (ORCPT + 99 others); Mon, 7 Sep 2020 13:29:16 -0400 Received: from 8bytes.org ([81.169.241.247]:43572 "EHLO theia.8bytes.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729520AbgIGNTh (ORCPT ); Mon, 7 Sep 2020 09:19:37 -0400 Received: from cap.home.8bytes.org (p549add56.dip0.t-ipconnect.de [84.154.221.86]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by theia.8bytes.org (Postfix) with ESMTPSA id F1CD33AB0; Mon, 7 Sep 2020 15:17:19 +0200 (CEST) From: Joerg Roedel To: x86@kernel.org Cc: Joerg Roedel , Joerg Roedel , Tom Lendacky , hpa@zytor.com, Andy Lutomirski , Dave Hansen , Peter Zijlstra , Jiri Slaby , Dan Williams , Juergen Gross , Kees Cook , David Rientjes , Cfir Cohen , Erdem Aktas , Masami Hiramatsu , Mike Stunes , Sean Christopherson , Martin Radev , linux-kernel@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org Subject: [PATCH v7 71/72] x86/efi: Add GHCB mappings when SEV-ES is active Date: Mon, 7 Sep 2020 15:16:12 +0200 Message-Id: <20200907131613.12703-72-joro@8bytes.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907131613.12703-1-joro@8bytes.org> References: <20200907131613.12703-1-joro@8bytes.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tom Lendacky Calling down to EFI runtime services can result in the firmware performing VMGEXIT calls. The firmware is likely to use the GHCB of the OS (e.g., for setting EFI variables), so each GHCB in the system needs to be identity mapped in the EFI page tables, as unencrypted, to avoid page faults. Signed-off-by: Tom Lendacky [ jroedel@suse.de: Moved GHCB mapping loop to sev-es.c ] Signed-off-by: Joerg Roedel --- arch/x86/boot/compressed/sev-es.c | 1 + arch/x86/include/asm/sev-es.h | 2 ++ arch/x86/kernel/sev-es.c | 30 ++++++++++++++++++++++++++++++ arch/x86/platform/efi/efi_64.c | 10 ++++++++++ 4 files changed, 43 insertions(+) diff --git a/arch/x86/boot/compressed/sev-es.c b/arch/x86/boot/compressed/sev-es.c index 45702b866c33..0a9a248ca33d 100644 --- a/arch/x86/boot/compressed/sev-es.c +++ b/arch/x86/boot/compressed/sev-es.c @@ -12,6 +12,7 @@ */ #include "misc.h" +#include #include #include #include diff --git a/arch/x86/include/asm/sev-es.h b/arch/x86/include/asm/sev-es.h index e919f09ae33c..cf1d957c7091 100644 --- a/arch/x86/include/asm/sev-es.h +++ b/arch/x86/include/asm/sev-es.h @@ -102,11 +102,13 @@ static __always_inline void sev_es_nmi_complete(void) if (static_branch_unlikely(&sev_es_enable_key)) __sev_es_nmi_complete(); } +extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd); #else static inline void sev_es_ist_enter(struct pt_regs *regs) { } static inline void sev_es_ist_exit(void) { } static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; } static inline void sev_es_nmi_complete(void) { } +static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; } #endif #endif diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index 9ab3a4dfecd8..4e2b7e4d9b87 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -491,6 +491,36 @@ int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) return 0; } +/* + * This is needed by the OVMF UEFI firmware which will use whatever it finds in + * the GHCB MSR as its GHCB to talk to the hypervisor. So make sure the per-cpu + * runtime GHCBs used by the kernel are also mapped in the EFI page-table. + */ +int __init sev_es_efi_map_ghcbs(pgd_t *pgd) +{ + struct sev_es_runtime_data *data; + unsigned long address, pflags; + int cpu; + u64 pfn; + + if (!sev_es_active()) + return 0; + + pflags = _PAGE_NX | _PAGE_RW; + + for_each_possible_cpu(cpu) { + data = per_cpu(runtime_data, cpu); + + address = __pa(&data->ghcb_page); + pfn = address >> PAGE_SHIFT; + + if (kernel_map_pages_in_pgd(pgd, pfn, address, 1, pflags)) + return 1; + } + + return 0; +} + static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt) { struct pt_regs *regs = ctxt->regs; diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 6af4da1149ba..8f5759df7776 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -47,6 +47,7 @@ #include #include #include +#include /* * We allocate runtime services regions top-down, starting from -4G, i.e. @@ -229,6 +230,15 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) return 1; } + /* + * When SEV-ES is active, the GHCB as set by the kernel will be used + * by firmware. Create a 1:1 unencrypted mapping for each GHCB. + */ + if (sev_es_efi_map_ghcbs(pgd)) { + pr_err("Failed to create 1:1 mapping for the GHCBs!\n"); + return 1; + } + /* * When making calls to the firmware everything needs to be 1:1 * mapped and addressable with 32-bit pointers. Map the kernel -- 2.28.0