Commit 6c321179 authored by Tom Lendacky's avatar Tom Lendacky Committed by Borislav Petkov (AMD)
Browse files

x86/sev: Add SNP-specific unaccepted memory support



Add SNP-specific hooks to the unaccepted memory support in the boot
path (__accept_memory()) and the core kernel (accept_memory()) in order
to support booting SNP guests when unaccepted memory is present. Without
this support, SNP guests will fail to boot and/or panic() when unaccepted
memory is present in the EFI memory map.

The process of accepting memory under SNP involves invoking the hypervisor
to perform a page state change for the page to private memory and then
issuing a PVALIDATE instruction to accept the page.

Since the boot path and the core kernel paths perform similar operations,
move the pvalidate_pages() and vmgexit_psc() functions into sev-shared.c
to avoid code duplication.

Create the new header file arch/x86/boot/compressed/sev.h because adding
the function declaration to any of the existing SEV related header files
pulls in too many other header files, causing the build to fail.

Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/a52fa69f460fd1876d70074b20ad68210dfc31dd.1686063086.git.thomas.lendacky@amd.com
parent 15d90887
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1543,11 +1543,13 @@ config X86_MEM_ENCRYPT
config AMD_MEM_ENCRYPT
	bool "AMD Secure Memory Encryption (SME) support"
	depends on X86_64 && CPU_SUP_AMD
	depends on EFI_STUB
	select DMA_COHERENT_POOL
	select ARCH_USE_MEMREMAP_PROT
	select INSTRUCTION_DECODER
	select ARCH_HAS_CC_PLATFORM
	select X86_MEM_ENCRYPT
	select UNACCEPTED_MEMORY
	help
	  Say yes to enable support for the encryption of system memory.
	  This requires an AMD processor that supports Secure Memory
+3 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#include "error.h"
#include "misc.h"
#include "tdx.h"
#include "sev.h"
#include <asm/shared/tdx.h>

/*
@@ -37,6 +38,8 @@ void arch_accept_memory(phys_addr_t start, phys_addr_t end)
	if (early_is_tdx_guest()) {
		if (!tdx_accept_memory(start, end))
			panic("TDX: Failed to accept memory\n");
	} else if (sev_snp_enabled()) {
		snp_accept_memory(start, end);
	} else {
		error("Cannot accept memory: unknown platform\n");
	}
+53 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
/* Include code for early handlers */
#include "../../kernel/sev-shared.c"

static inline bool sev_snp_enabled(void)
bool sev_snp_enabled(void)
{
	return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
}
@@ -181,6 +181,58 @@ static bool early_setup_ghcb(void)
	return true;
}

static phys_addr_t __snp_accept_memory(struct snp_psc_desc *desc,
				       phys_addr_t pa, phys_addr_t pa_end)
{
	struct psc_hdr *hdr;
	struct psc_entry *e;
	unsigned int i;

	hdr = &desc->hdr;
	memset(hdr, 0, sizeof(*hdr));

	e = desc->entries;

	i = 0;
	while (pa < pa_end && i < VMGEXIT_PSC_MAX_ENTRY) {
		hdr->end_entry = i;

		e->gfn = pa >> PAGE_SHIFT;
		e->operation = SNP_PAGE_STATE_PRIVATE;
		if (IS_ALIGNED(pa, PMD_SIZE) && (pa_end - pa) >= PMD_SIZE) {
			e->pagesize = RMP_PG_SIZE_2M;
			pa += PMD_SIZE;
		} else {
			e->pagesize = RMP_PG_SIZE_4K;
			pa += PAGE_SIZE;
		}

		e++;
		i++;
	}

	if (vmgexit_psc(boot_ghcb, desc))
		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);

	pvalidate_pages(desc);

	return pa;
}

void snp_accept_memory(phys_addr_t start, phys_addr_t end)
{
	struct snp_psc_desc desc = {};
	unsigned int i;
	phys_addr_t pa;

	if (!boot_ghcb && !early_setup_ghcb())
		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);

	pa = start;
	while (pa < end)
		pa = __snp_accept_memory(&desc, pa, end);
}

void sev_es_shutdown_ghcb(void)
{
	if (!boot_ghcb)
+23 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * AMD SEV header for early boot related functions.
 *
 * Author: Tom Lendacky <thomas.lendacky@amd.com>
 */

#ifndef BOOT_COMPRESSED_SEV_H
#define BOOT_COMPRESSED_SEV_H

#ifdef CONFIG_AMD_MEM_ENCRYPT

bool sev_snp_enabled(void);
void snp_accept_memory(phys_addr_t start, phys_addr_t end);

#else

static inline bool sev_snp_enabled(void) { return false; }
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }

#endif

#endif
+3 −0
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ 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);
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
#else
static inline void sev_es_ist_enter(struct pt_regs *regs) { }
static inline void sev_es_ist_exit(void) { }
@@ -229,6 +230,8 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in
{
	return -ENOTTY;
}

static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
#endif

#endif
Loading