Commit 01d5e787 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86_sev_for_v5.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 SEV updates from Borislav Petkov:
 "The accumulated pile of x86/sev generalizations and cleanups:

   - Share the SEV string unrolling logic with TDX as TDX guests need it
     too

   - Cleanups and generalzation of code shared by SEV and TDX"

* tag 'x86_sev_for_v5.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/sev: Move common memory encryption code to mem_encrypt.c
  x86/sev: Rename mem_encrypt.c to mem_encrypt_amd.c
  x86/sev: Use CC_ATTR attribute to generalize string I/O unroll
  x86/sev: Remove do_early_exception() forward declarations
  x86/head64: Carve out the guest encryption postprocessing into a helper
  x86/sev: Get rid of excessive use of defines
  x86/sev: Shorten GHCB terminate macro names
parents cd36722d 20f07a04
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -1523,16 +1523,20 @@ config X86_CPA_STATISTICS
	  helps to determine the effectiveness of preserving large and huge
	  page mappings when mapping protections are changed.

config X86_MEM_ENCRYPT
	select ARCH_HAS_FORCE_DMA_UNENCRYPTED
	select DYNAMIC_PHYSICAL_MASK
	select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
	def_bool n

config AMD_MEM_ENCRYPT
	bool "AMD Secure Memory Encryption (SME) support"
	depends on X86_64 && CPU_SUP_AMD
	select DMA_COHERENT_POOL
	select DYNAMIC_PHYSICAL_MASK
	select ARCH_USE_MEMREMAP_PROT
	select ARCH_HAS_FORCE_DMA_UNENCRYPTED
	select INSTRUCTION_DECODER
	select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
	select ARCH_HAS_CC_PLATFORM
	select X86_MEM_ENCRYPT
	help
	  Say yes to enable support for the encryption of system memory.
	  This requires an AMD processor that supports Secure Memory
+3 −3
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
static bool early_setup_sev_es(void)
{
	if (!sev_es_negotiate_protocol())
		sev_es_terminate(GHCB_SEV_ES_REASON_PROTOCOL_UNSUPPORTED);
		sev_es_terminate(GHCB_SEV_ES_PROT_UNSUPPORTED);

	if (set_page_decrypted((unsigned long)&boot_ghcb_page))
		return false;
@@ -175,7 +175,7 @@ void do_boot_stage2_vc(struct pt_regs *regs, unsigned long exit_code)
	enum es_result result;

	if (!boot_ghcb && !early_setup_sev_es())
		sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST);
		sev_es_terminate(GHCB_SEV_ES_GEN_REQ);

	vc_ghcb_invalidate(boot_ghcb);
	result = vc_init_em_ctxt(&ctxt, regs, exit_code);
@@ -202,5 +202,5 @@ void do_boot_stage2_vc(struct pt_regs *regs, unsigned long exit_code)
	if (result == ES_OK)
		vc_finish_insn(&ctxt);
	else if (result != ES_RETRY)
		sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST);
		sev_es_terminate(GHCB_SEV_ES_GEN_REQ);
}
+3 −17
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@

#include <linux/string.h>
#include <linux/compiler.h>
#include <linux/cc_platform.h>
#include <asm/page.h>
#include <asm/early_ioremap.h>
#include <asm/pgtable_types.h>
@@ -256,21 +257,6 @@ static inline void slow_down_io(void)

#endif

#ifdef CONFIG_AMD_MEM_ENCRYPT
#include <linux/jump_label.h>

extern struct static_key_false sev_enable_key;
static inline bool sev_key_active(void)
{
	return static_branch_unlikely(&sev_enable_key);
}

#else /* !CONFIG_AMD_MEM_ENCRYPT */

static inline bool sev_key_active(void) { return false; }

#endif /* CONFIG_AMD_MEM_ENCRYPT */

#define BUILDIO(bwl, bw, type)						\
static inline void out##bwl(unsigned type value, int port)		\
{									\
@@ -301,7 +287,7 @@ static inline unsigned type in##bwl##_p(int port) \
									\
static inline void outs##bwl(int port, const void *addr, unsigned long count) \
{									\
	if (sev_key_active()) {						\
	if (cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) {		\
		unsigned type *value = (unsigned type *)addr;		\
		while (count) {						\
			out##bwl(*value, port);				\
@@ -317,7 +303,7 @@ static inline void outs##bwl(int port, const void *addr, unsigned long count) \
									\
static inline void ins##bwl(int port, void *addr, unsigned long count)	\
{									\
	if (sev_key_active()) {						\
	if (cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) {		\
		unsigned type *value = (unsigned type *)addr;		\
		while (count) {						\
			*value = in##bwl(port);				\
+30 −25
Original line number Diff line number Diff line
@@ -18,20 +18,19 @@
/* SEV Information Request/Response */
#define GHCB_MSR_SEV_INFO_RESP		0x001
#define GHCB_MSR_SEV_INFO_REQ		0x002
#define GHCB_MSR_VER_MAX_POS		48
#define GHCB_MSR_VER_MAX_MASK		0xffff
#define GHCB_MSR_VER_MIN_POS		32
#define GHCB_MSR_VER_MIN_MASK		0xffff
#define GHCB_MSR_CBIT_POS		24
#define GHCB_MSR_CBIT_MASK		0xff

#define GHCB_MSR_SEV_INFO(_max, _min, _cbit)	\
	((((_max) & GHCB_MSR_VER_MAX_MASK) << GHCB_MSR_VER_MAX_POS) |	\
	 (((_min) & GHCB_MSR_VER_MIN_MASK) << GHCB_MSR_VER_MIN_POS) |	\
	 (((_cbit) & GHCB_MSR_CBIT_MASK) << GHCB_MSR_CBIT_POS) |	\
	/* GHCBData[63:48] */			\
	((((_max) & 0xffff) << 48) |		\
	 /* GHCBData[47:32] */			\
	 (((_min) & 0xffff) << 32) |		\
	 /* GHCBData[31:24] */			\
	 (((_cbit) & 0xff)  << 24) |		\
	 GHCB_MSR_SEV_INFO_RESP)

#define GHCB_MSR_INFO(v)		((v) & 0xfffUL)
#define GHCB_MSR_PROTO_MAX(v)		(((v) >> GHCB_MSR_VER_MAX_POS) & GHCB_MSR_VER_MAX_MASK)
#define GHCB_MSR_PROTO_MIN(v)		(((v) >> GHCB_MSR_VER_MIN_POS) & GHCB_MSR_VER_MIN_MASK)
#define GHCB_MSR_PROTO_MAX(v)		(((v) >> 48) & 0xffff)
#define GHCB_MSR_PROTO_MIN(v)		(((v) >> 32) & 0xffff)

/* CPUID Request/Response */
#define GHCB_MSR_CPUID_REQ		0x004
@@ -47,9 +46,12 @@
#define GHCB_CPUID_REQ_ECX		2
#define GHCB_CPUID_REQ_EDX		3
#define GHCB_CPUID_REQ(fn, reg)				\
	/* GHCBData[11:0] */				\
	(GHCB_MSR_CPUID_REQ |				\
		(((unsigned long)reg & GHCB_MSR_CPUID_REG_MASK) << GHCB_MSR_CPUID_REG_POS) | \
		(((unsigned long)fn) << GHCB_MSR_CPUID_FUNC_POS))
	/* GHCBData[31:12] */				\
	(((unsigned long)(reg) & 0x3) << 30) |		\
	/* GHCBData[63:32] */				\
	(((unsigned long)fn) << 32))

/* AP Reset Hold */
#define GHCB_MSR_AP_RESET_HOLD_REQ	0x006
@@ -64,12 +66,15 @@
#define GHCB_MSR_TERM_REASON_SET_MASK	0xf
#define GHCB_MSR_TERM_REASON_POS	16
#define GHCB_MSR_TERM_REASON_MASK	0xff

#define GHCB_SEV_TERM_REASON(reason_set, reason_val)	\
	(((((u64)reason_set) &  GHCB_MSR_TERM_REASON_SET_MASK) << GHCB_MSR_TERM_REASON_SET_POS) | \
	((((u64)reason_val) & GHCB_MSR_TERM_REASON_MASK) << GHCB_MSR_TERM_REASON_POS))
	/* GHCBData[15:12] */				\
	(((((u64)reason_set) &  0xf) << 12) |		\
	 /* GHCBData[23:16] */				\
	((((u64)reason_val) & 0xff) << 16))

#define GHCB_SEV_ES_REASON_GENERAL_REQUEST	0
#define GHCB_SEV_ES_REASON_PROTOCOL_UNSUPPORTED	1
#define GHCB_SEV_ES_GEN_REQ		0
#define GHCB_SEV_ES_PROT_UNSUPPORTED	1

#define GHCB_RESP_CODE(v)		((v) & GHCB_MSR_INFO_MASK)

+8 −0
Original line number Diff line number Diff line
@@ -50,6 +50,14 @@ static bool amd_cc_platform_has(enum cc_attr attr)
	case CC_ATTR_GUEST_STATE_ENCRYPT:
		return sev_status & MSR_AMD64_SEV_ES_ENABLED;

	/*
	 * With SEV, the rep string I/O instructions need to be unrolled
	 * but SEV-ES supports them through the #VC handler.
	 */
	case CC_ATTR_GUEST_UNROLL_STRING_IO:
		return (sev_status & MSR_AMD64_SEV_ENABLED) &&
			!(sev_status & MSR_AMD64_SEV_ES_ENABLED);

	default:
		return false;
	}
Loading