Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp1701512ybh; Tue, 14 Jul 2020 05:13:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzlLnta7T5OJ0mUiS8Hz3czcdlhjA8ztq92dvNRF1iEURYrxGGJY9qUTfjaRw1XUWPjNQLk X-Received: by 2002:a50:ee01:: with SMTP id g1mr4090215eds.264.1594728793807; Tue, 14 Jul 2020 05:13:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594728793; cv=none; d=google.com; s=arc-20160816; b=k99wneMj7VTSVfO1n2qEAmGic5L5PpvsNCIJLm56HYBhJh74pG7Pq7NypR66hluquo k4AA1Vnsv7mfmI3pVzyemlEYrOb+I5LLEjPpY0nyKvYhNjEW1bDwbQ/GAuVP6c26aRM6 g6nYTwL1cMOPDiVPi7qSvwnaeJ5F5BzmQcYUi3bfFjhu+oBMbky9ngS2MHahxB7ESGNu 3hrRsE4pTKnOdfLgT3yysWZ/p1Pbt01M2gajbkwX1hPn6LVMBOGw6AAvnO5TWglvgLRp HDIId7oCThgSFww07pF4uHoepJeSkTVNJiZ6f35pIvS0oZ77+qRAETra4cQoBtG52jy1 q7oQ== 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=Olsq0NX7VCiyBj7MbQTNf7fMDvad9q3l5MNHuOlip/w=; b=oKEzbkEihwcEZ0CQl8WT5GoLMBsR+rDOgXA+eiDybafeetnCiX7cEmNvH6UmHZQGQU I03swC5ZyOI5DXfBdu54QwESPBlB7rFzVMMdw737sasjZ2X8oAaSpxKPWvS5Kv7ba0HL 0aVxkUs5X1RB0rLBLMsuXHArEYxXGGvDxQUs45AZh4fKXOOxyPDMsZrx1Ukaoi16N4VF gjz5Oiuhh5gOBuOv4k9rWEVSxu5HlA2EnuWlKIdCVLVmFuEPZAz03d6yLViqsJ7XMTSS l2A70pUNol4S6QOdVZ5b1IYXl8x9Q86zAAS3v2SVLvvYgJEn0Cu2mGdzJ0412f7Tii4v DSoQ== 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 dr16si14572847ejc.320.2020.07.14.05.12.48; Tue, 14 Jul 2020 05:13:13 -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 S1728663AbgGNMLm (ORCPT + 99 others); Tue, 14 Jul 2020 08:11:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728612AbgGNMLX (ORCPT ); Tue, 14 Jul 2020 08:11:23 -0400 Received: from theia.8bytes.org (8bytes.org [IPv6:2a01:238:4383:600:38bc:a715:4b6d:a889]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B88C3C08C5DD; Tue, 14 Jul 2020 05:11:22 -0700 (PDT) Received: from cap.home.8bytes.org (p5b006776.dip0.t-ipconnect.de [91.0.103.118]) (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 26D7FFF3; Tue, 14 Jul 2020 14:11:14 +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 v4 74/75] x86/efi: Add GHCB mappings when SEV-ES is active Date: Tue, 14 Jul 2020 14:09:16 +0200 Message-Id: <20200714120917.11253-75-joro@8bytes.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714120917.11253-1-joro@8bytes.org> References: <20200714120917.11253-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 1ce144e0ddc3..b522c18c0588 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 de4d3f63fdf8..03e114c727c8 100644 --- a/arch/x86/include/asm/sev-es.h +++ b/arch/x86/include/asm/sev-es.h @@ -85,11 +85,13 @@ extern void sev_es_ist_enter(struct pt_regs *regs); extern void sev_es_ist_exit(void); extern int sev_es_setup_ap_jump_table(struct real_mode_header *rmh); extern void sev_es_nmi_complete(void); +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 ff440b6e5e78..61308f9c8138 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -507,6 +507,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 8e364c4c6768..42e0628c45ca 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. @@ -238,6 +239,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.27.0