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 Original line Diff line number Diff line
@@ -1523,16 +1523,20 @@ config X86_CPA_STATISTICS
	  helps to determine the effectiveness of preserving large and huge
	  helps to determine the effectiveness of preserving large and huge
	  page mappings when mapping protections are changed.
	  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
config AMD_MEM_ENCRYPT
	bool "AMD Secure Memory Encryption (SME) support"
	bool "AMD Secure Memory Encryption (SME) support"
	depends on X86_64 && CPU_SUP_AMD
	depends on X86_64 && CPU_SUP_AMD
	select DMA_COHERENT_POOL
	select DMA_COHERENT_POOL
	select DYNAMIC_PHYSICAL_MASK
	select ARCH_USE_MEMREMAP_PROT
	select ARCH_USE_MEMREMAP_PROT
	select ARCH_HAS_FORCE_DMA_UNENCRYPTED
	select INSTRUCTION_DECODER
	select INSTRUCTION_DECODER
	select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
	select ARCH_HAS_CC_PLATFORM
	select ARCH_HAS_CC_PLATFORM
	select X86_MEM_ENCRYPT
	help
	help
	  Say yes to enable support for the encryption of system memory.
	  Say yes to enable support for the encryption of system memory.
	  This requires an AMD processor that supports Secure Memory
	  This requires an AMD processor that supports Secure Memory
+3 −3
Original line number Original line 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)
static bool early_setup_sev_es(void)
{
{
	if (!sev_es_negotiate_protocol())
	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))
	if (set_page_decrypted((unsigned long)&boot_ghcb_page))
		return false;
		return false;
@@ -175,7 +175,7 @@ void do_boot_stage2_vc(struct pt_regs *regs, unsigned long exit_code)
	enum es_result result;
	enum es_result result;


	if (!boot_ghcb && !early_setup_sev_es())
	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);
	vc_ghcb_invalidate(boot_ghcb);
	result = vc_init_em_ctxt(&ctxt, regs, exit_code);
	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)
	if (result == ES_OK)
		vc_finish_insn(&ctxt);
		vc_finish_insn(&ctxt);
	else if (result != ES_RETRY)
	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 Original line Diff line number Diff line
@@ -40,6 +40,7 @@


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


#endif
#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)						\
#define BUILDIO(bwl, bw, type)						\
static inline void out##bwl(unsigned type value, int port)		\
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) \
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;		\
		unsigned type *value = (unsigned type *)addr;		\
		while (count) {						\
		while (count) {						\
			out##bwl(*value, port);				\
			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)	\
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;		\
		unsigned type *value = (unsigned type *)addr;		\
		while (count) {						\
		while (count) {						\
			*value = in##bwl(port);				\
			*value = in##bwl(port);				\
+30 −25
Original line number Original line Diff line number Diff line
@@ -18,20 +18,19 @@
/* SEV Information Request/Response */
/* SEV Information Request/Response */
#define GHCB_MSR_SEV_INFO_RESP		0x001
#define GHCB_MSR_SEV_INFO_RESP		0x001
#define GHCB_MSR_SEV_INFO_REQ		0x002
#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)	\
#define GHCB_MSR_SEV_INFO(_max, _min, _cbit)	\
	((((_max) & GHCB_MSR_VER_MAX_MASK) << GHCB_MSR_VER_MAX_POS) |	\
	/* GHCBData[63:48] */			\
	 (((_min) & GHCB_MSR_VER_MIN_MASK) << GHCB_MSR_VER_MIN_POS) |	\
	((((_max) & 0xffff) << 48) |		\
	 (((_cbit) & GHCB_MSR_CBIT_MASK) << GHCB_MSR_CBIT_POS) |	\
	 /* GHCBData[47:32] */			\
	 (((_min) & 0xffff) << 32) |		\
	 /* GHCBData[31:24] */			\
	 (((_cbit) & 0xff)  << 24) |		\
	 GHCB_MSR_SEV_INFO_RESP)
	 GHCB_MSR_SEV_INFO_RESP)

#define GHCB_MSR_INFO(v)		((v) & 0xfffUL)
#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_MAX(v)		(((v) >> 48) & 0xffff)
#define GHCB_MSR_PROTO_MIN(v)		(((v) >> GHCB_MSR_VER_MIN_POS) & GHCB_MSR_VER_MIN_MASK)
#define GHCB_MSR_PROTO_MIN(v)		(((v) >> 32) & 0xffff)


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


/* AP Reset Hold */
/* AP Reset Hold */
#define GHCB_MSR_AP_RESET_HOLD_REQ	0x006
#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_SET_MASK	0xf
#define GHCB_MSR_TERM_REASON_POS	16
#define GHCB_MSR_TERM_REASON_POS	16
#define GHCB_MSR_TERM_REASON_MASK	0xff
#define GHCB_MSR_TERM_REASON_MASK	0xff

#define GHCB_SEV_TERM_REASON(reason_set, reason_val)	\
#define GHCB_SEV_TERM_REASON(reason_set, reason_val)	\
	(((((u64)reason_set) &  GHCB_MSR_TERM_REASON_SET_MASK) << GHCB_MSR_TERM_REASON_SET_POS) | \
	/* GHCBData[15:12] */				\
	((((u64)reason_val) & GHCB_MSR_TERM_REASON_MASK) << GHCB_MSR_TERM_REASON_POS))
	(((((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_GEN_REQ		0
#define GHCB_SEV_ES_REASON_PROTOCOL_UNSUPPORTED	1
#define GHCB_SEV_ES_PROT_UNSUPPORTED	1


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


+8 −0
Original line number Original line 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:
	case CC_ATTR_GUEST_STATE_ENCRYPT:
		return sev_status & MSR_AMD64_SEV_ES_ENABLED;
		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:
	default:
		return false;
		return false;
	}
	}
Loading