public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb@kernel.org>
To: linux-efi@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel <ardb@kernel.org>,
	Evgeniy Baskov <baskov@ispras.ru>, Borislav Petkov <bp@alien8.de>,
	Andy Lutomirski <luto@kernel.org>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Alexey Khoroshilov <khoroshilov@ispras.ru>,
	Peter Jones <pjones@redhat.com>,
	Gerd Hoffmann <kraxel@redhat.com>, Dave Young <dyoung@redhat.com>,
	Mario Limonciello <mario.limonciello@amd.com>,
	Kees Cook <keescook@chromium.org>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH v3 20/21] x86/efistub: Check SEV/SNP support while running in the firmware
Date: Mon, 22 May 2023 09:14:14 +0200	[thread overview]
Message-ID: <20230522071415.501717-21-ardb@kernel.org> (raw)
In-Reply-To: <20230522071415.501717-1-ardb@kernel.org>

Before refactoring the EFI stub boot flow to avoid the legacy bare metal
decompressor, duplicate the SEV initialization and SNP feature check in
the EFI stub before handing over to the kernel proper.

This must be done after calling ExitBootServices(), to ensure that the
SEV initialization does not corrupt any state that the firmware itself
still relies on. This means that, unfortunately, the only recourse
available when the SNP feature mask contains unsupported features is to
terminate the virtual machine, which is what the bare metal decompressor
does as well.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/x86/boot/compressed/sev.c          | 19 ++++++++++++++-----
 arch/x86/include/asm/sev.h              |  6 ++++++
 drivers/firmware/efi/libstub/x86-stub.c | 17 +++++++++++++++++
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index 014b89c890887b9a..d33d48359d09bfb5 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -315,23 +315,32 @@ static void enforce_vmpl0(void)
  */
 #define SNP_FEATURES_PRESENT (0)
 
+u64 snp_get_unsupported_features(void)
+{
+	if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+		return 0;
+	return sev_status & SNP_FEATURES_IMPL_REQ & ~SNP_FEATURES_PRESENT;
+}
+
+void sev_es_terminate_snp_unsupported(void)
+{
+	sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+}
+
 void snp_check_features(void)
 {
 	u64 unsupported;
 
-	if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
-		return;
-
 	/*
 	 * Terminate the boot if hypervisor has enabled any feature lacking
 	 * guest side implementation. Pass on the unsupported features mask through
 	 * EXIT_INFO_2 of the GHCB protocol so that those features can be reported
 	 * as part of the guest boot failure.
 	 */
-	unsupported = sev_status & SNP_FEATURES_IMPL_REQ & ~SNP_FEATURES_PRESENT;
+	unsupported = snp_get_unsupported_features();
 	if (unsupported) {
 		if (ghcb_version < 2 || (!boot_ghcb && !early_setup_ghcb()))
-			sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+			sev_es_terminate_snp_unsupported();
 
 		sev_es_ghcb_terminate(boot_ghcb, SEV_TERM_SET_GEN,
 				      GHCB_SNP_UNSUPPORTED, unsupported);
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 13dc2a9d23c1eb25..084a91aa5a6c708f 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -157,6 +157,7 @@ static __always_inline void sev_es_nmi_complete(void)
 		__sev_es_nmi_complete();
 }
 extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd);
+extern void sev_enable(struct boot_params *bp);
 
 static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs)
 {
@@ -202,12 +203,15 @@ void snp_set_wakeup_secondary_cpu(void);
 bool snp_init(struct boot_params *bp);
 void __init __noreturn snp_abort(void);
 int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio);
+u64 snp_get_unsupported_features(void);
+void sev_es_terminate_snp_unsupported(void);
 #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; }
+static inline void sev_enable(struct boot_params *bp) { }
 static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) { return 0; }
 static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; }
 static inline void setup_ghcb(void) { }
@@ -225,6 +229,8 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in
 {
 	return -ENOTTY;
 }
+static inline u64 snp_get_unsupported_features(void) { return 0; }
+static inline void sev_es_terminate_snp_unsupported(void) {}
 #endif
 
 #endif
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index fcdae5db0c63c7e5..02633199a8502b71 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -15,6 +15,7 @@
 #include <asm/setup.h>
 #include <asm/desc.h>
 #include <asm/boot.h>
+#include <asm/sev.h>
 
 #include "efistub.h"
 #include "x86-stub.h"
@@ -923,6 +924,22 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
 		goto fail;
 	}
 
+	/*
+	 * Call the SEV init code while still running with the firmware's
+	 * GDT/IDT, so #VC exceptions will be handled by EFI.
+	 */
+	if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
+		u64 unsupported;
+
+		sev_enable(boot_params);
+		unsupported = snp_get_unsupported_features();
+		if (unsupported) {
+			efi_err("Unsupported SEV-SNP features detected: 0x%llx\n",
+				unsupported);
+			sev_es_terminate_snp_unsupported();
+		}
+	}
+
 	if (IS_ENABLED(CONFIG_X86_64)) {
 		efi_5level_switch();
 
-- 
2.39.2


  parent reply	other threads:[~2023-05-22  7:17 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-22  7:13 [PATCH v3 00/21] efi/x86: Avoid bare metal decompressor during EFI boot Ard Biesheuvel
2023-05-22  7:13 ` [PATCH v3 01/21] x86/efistub: Branch straight to kernel entry point from C code Ard Biesheuvel
2023-05-22  7:13 ` [PATCH v3 02/21] x86/efistub: Simplify and clean up handover entry code Ard Biesheuvel
2023-05-22  7:13 ` [PATCH v3 03/21] x86/decompressor: Avoid magic offsets for EFI handover entrypoint Ard Biesheuvel
2023-05-22  7:13 ` [PATCH v3 04/21] x86/efistub: Clear BSS in EFI handover protocol entrypoint Ard Biesheuvel
2023-05-22  7:13 ` [PATCH v3 05/21] x86/decompressor: Use proper sequence to take the address of the GOT Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 06/21] x86/decompressor: Store boot_params pointer in callee save register Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 07/21] x86/decompressor: Call trampoline as a normal function Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 08/21] x86/decompressor: Use standard calling convention for trampoline Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 09/21] x86/decompressor: Avoid the need for a stack in the 32-bit trampoline Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 10/21] x86/decompressor: Call trampoline directly from C code Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 11/21] x86/decompressor: Only call the trampoline when changing paging levels Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 12/21] x86/decompressor: Merge trampoline cleanup with switching code Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 13/21] x86/efistub: Perform 4/5 level paging switch from the stub Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 14/21] x86/efistub: Prefer EFI memory attributes protocol over DXE services Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 15/21] decompress: Use 8 byte alignment Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 16/21] x86/decompressor: Move global symbol references to C code Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 17/21] x86/decompressor: Factor out kernel decompression and relocation Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 18/21] x86/head_64: Store boot_params pointer in callee-preserved register Ard Biesheuvel
2023-05-22  7:14 ` [PATCH v3 19/21] efi/libstub: Add limit argument to efi_random_alloc() Ard Biesheuvel
2023-05-22  7:14 ` Ard Biesheuvel [this message]
2023-05-22  7:14 ` [PATCH v3 21/21] x86/efistub: Avoid legacy decompressor when doing EFI boot Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230522071415.501717-21-ardb@kernel.org \
    --to=ardb@kernel.org \
    --cc=baskov@ispras.ru \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=dyoung@redhat.com \
    --cc=keescook@chromium.org \
    --cc=khoroshilov@ispras.ru \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=kraxel@redhat.com \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mario.limonciello@amd.com \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=pjones@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox