linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper
@ 2018-02-09 14:07 Kirill A. Shutemov
  2018-02-09 14:07 ` [PATCHv3 1/5] x86/cpufeatures: Add Intel Total Memory Encryption cpufeature Kirill A. Shutemov
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Kirill A. Shutemov @ 2018-02-09 14:07 UTC (permalink / raw)
  To: Ingo Molnar, x86, Thomas Gleixner, H. Peter Anvin
  Cc: Tom Lendacky, Dave Hansen, Kai Huang, linux-kernel, Kirill A. Shutemov

Multikey Total Memory Encryption (MKTME)[1] is a technology that allows
transparent memory encryption in upcoming Intel platforms.

MKTME is built on top of TME. TME allows encryption of the entirety of
system memory using a single key. MKTME allows to have multiple encryption
domains, each having own key -- different memory pages can be encrypted
with different keys.

The patchset does some ground work for MKTME enabling:
  - Adds two new cpufeatures: TME and PCONFIG;
  - Detects if BIOS enabled TME and MKTME;
  - Enumerates what PCONFIG targets are supported;
  - Provides helper to program encryption keys into CPU;

As part of TME enumeration we check out how many bits from physical address
are claimed for encryption key ID. This may be critical as we or guest VM
must not use these bits for physical address.

Please review and consider applying.

v3:
  - Address Dave's feedback;
v2:
  - Fixes for TME enumeration;
  - Add PCONFIG CPUID leaf support;
  - Add MKTME_KEY_PROG helper;

[1] https://software.intel.com/sites/default/files/managed/a5/16/Multi-Key-Total-Memory-Encryption-Spec.pdf

Kirill A. Shutemov (5):
  x86/cpufeatures: Add Intel Total Memory Encryption cpufeature
  x86/tme: Detect if TME and MKTME is activated by BIOS
  x86/cpufeatures: Add Intel PCONFIG cpufeature
  x86/pconfig: Detect PCONFIG targets
  x86/pconfig: Provide defines and helper to run MKTME_KEY_PROG leaf

 arch/x86/include/asm/cpufeatures.h   |  2 +
 arch/x86/include/asm/intel_pconfig.h | 65 ++++++++++++++++++++++++++
 arch/x86/kernel/cpu/Makefile         |  2 +-
 arch/x86/kernel/cpu/intel.c          | 90 ++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/intel_pconfig.c  | 82 ++++++++++++++++++++++++++++++++
 5 files changed, 240 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/include/asm/intel_pconfig.h
 create mode 100644 arch/x86/kernel/cpu/intel_pconfig.c

-- 
2.15.1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCHv3 1/5] x86/cpufeatures: Add Intel Total Memory Encryption cpufeature
  2018-02-09 14:07 [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Kirill A. Shutemov
@ 2018-02-09 14:07 ` Kirill A. Shutemov
  2018-02-09 14:07 ` [PATCHv3 2/5] x86/tme: Detect if TME and MKTME is activated by BIOS Kirill A. Shutemov
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Kirill A. Shutemov @ 2018-02-09 14:07 UTC (permalink / raw)
  To: Ingo Molnar, x86, Thomas Gleixner, H. Peter Anvin
  Cc: Tom Lendacky, Dave Hansen, Kai Huang, linux-kernel, Kirill A. Shutemov

CPUID.0x7.0x0:ECX[13] indicates whether CPU supports Intel Total Memory
Encryption.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/include/asm/cpufeatures.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 14c3aa2b5f90..d3702d9ac012 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -315,6 +315,7 @@
 #define X86_FEATURE_VPCLMULQDQ		(16*32+10) /* Carry-Less Multiplication Double Quadword */
 #define X86_FEATURE_AVX512_VNNI		(16*32+11) /* Vector Neural Network Instructions */
 #define X86_FEATURE_AVX512_BITALG	(16*32+12) /* Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */
+#define X86_FEATURE_TME			(16*32+13) /* Intel Total Memory Encryption */
 #define X86_FEATURE_AVX512_VPOPCNTDQ	(16*32+14) /* POPCNT for vectors of DW/QW */
 #define X86_FEATURE_LA57		(16*32+16) /* 5-level page tables */
 #define X86_FEATURE_RDPID		(16*32+22) /* RDPID instruction */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv3 2/5] x86/tme: Detect if TME and MKTME is activated by BIOS
  2018-02-09 14:07 [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Kirill A. Shutemov
  2018-02-09 14:07 ` [PATCHv3 1/5] x86/cpufeatures: Add Intel Total Memory Encryption cpufeature Kirill A. Shutemov
@ 2018-02-09 14:07 ` Kirill A. Shutemov
  2018-02-09 14:07 ` [PATCHv3 3/5] x86/cpufeatures: Add Intel PCONFIG cpufeature Kirill A. Shutemov
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Kirill A. Shutemov @ 2018-02-09 14:07 UTC (permalink / raw)
  To: Ingo Molnar, x86, Thomas Gleixner, H. Peter Anvin
  Cc: Tom Lendacky, Dave Hansen, Kai Huang, linux-kernel, Kirill A. Shutemov

IA32_TME_ACTIVATE MSR (0x982) can be used to check if BIOS has enabled
TME and MKTME. It includes which encryption policy/algorithm is selected
for TME or available for MKTME. For MKTME, the MSR also enumerates how
many KeyIDs are available.

We would need to exclude KeyID bits from physical address bits.
detect_tme() would adjust cpuinfo_x86::x86_phys_bits accordingly.

We have to do this even if we are not going to use KeyID bits
ourself. VM guests still have to know that these bits are not usable
for physical address.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/kernel/cpu/intel.c | 90 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 319bf989fad1..5aa51efc2ff2 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -506,6 +506,93 @@ static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
 	}
 }
 
+#define MSR_IA32_TME_ACTIVATE		0x982
+
+/* Helpers to access TME_ACTIVATE MSR */
+#define TME_ACTIVATE_LOCKED(x)		(x & 0x1)
+#define TME_ACTIVATE_ENABLED(x)		(x & 0x2)
+
+#define TME_ACTIVATE_POLICY(x)		((x >> 4) & 0xf)	/* Bits 7:4 */
+#define TME_ACTIVATE_POLICY_AES_XTS_128	0
+
+#define TME_ACTIVATE_KEYID_BITS(x)	((x >> 32) & 0xf)	/* Bits 35:32 */
+
+#define TME_ACTIVATE_CRYPTO_ALGS(x)	((x >> 48) & 0xffff)	/* Bits 63:48 */
+#define TME_ACTIVATE_CRYPTO_AES_XTS_128	1
+
+/* Values for mktme_status (SW only construct) */
+#define MKTME_ENABLED			0
+#define MKTME_DISABLED			1
+#define MKTME_UNINITIALIZED		2
+static int mktme_status = MKTME_UNINITIALIZED;
+
+static void detect_tme(struct cpuinfo_x86 *c)
+{
+	u64 tme_activate, tme_policy, tme_crypto_algs;
+	int keyid_bits = 0, nr_keyids = 0;
+	static u64 tme_activate_cpu0 = 0;
+
+	rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate);
+
+	if (mktme_status != MKTME_UNINITIALIZED) {
+		if (tme_activate != tme_activate_cpu0) {
+			/* Broken BIOS? */
+			pr_err_once("x86/tme: configuation is inconsistent between CPUs\n");
+			pr_err_once("x86/tme: MKTME is not usable\n");
+			mktme_status = MKTME_DISABLED;
+
+			/* Proceed. We may need to exclude bits from x86_phys_bits. */
+		}
+	} else {
+		tme_activate_cpu0 = tme_activate;
+	}
+
+	if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) {
+		pr_info_once("x86/tme: not enabled by BIOS\n");
+		mktme_status = MKTME_DISABLED;
+		return;
+	}
+
+	if (mktme_status != MKTME_UNINITIALIZED)
+		goto detect_keyid_bits;
+
+	pr_info("x86/tme: enabled by BIOS\n");
+
+	tme_policy = TME_ACTIVATE_POLICY(tme_activate);
+	if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128)
+		pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy);
+
+	tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate);
+	if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) {
+		pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n",
+				tme_crypto_algs);
+		mktme_status = MKTME_DISABLED;
+	}
+detect_keyid_bits:
+	keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate);
+	nr_keyids = (1UL << keyid_bits) - 1;
+	if (nr_keyids) {
+		pr_info_once("x86/mktme: enabled by BIOS\n");
+		pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids);
+	} else {
+		pr_info_once("x86/mktme: disabled by BIOS\n");
+	}
+
+	if (mktme_status == MKTME_UNINITIALIZED) {
+		/* MKTME is usable */
+		mktme_status = MKTME_ENABLED;
+	}
+
+	/*
+	 * Exclude KeyID bits from physical address bits.
+	 *
+	 * We have to do this even if we are not going to use KeyID bits
+	 * ourself. VM guests still have to know that these bits are not usable
+	 * for physical address.
+	 */
+	c->x86_phys_bits -= keyid_bits;
+}
+
 static void init_intel_energy_perf(struct cpuinfo_x86 *c)
 {
 	u64 epb;
@@ -676,6 +763,9 @@ static void init_intel(struct cpuinfo_x86 *c)
 	if (cpu_has(c, X86_FEATURE_VMX))
 		detect_vmx_virtcap(c);
 
+	if (cpu_has(c, X86_FEATURE_TME))
+		detect_tme(c);
+
 	init_intel_energy_perf(c);
 
 	init_intel_misc_features(c);
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv3 3/5] x86/cpufeatures: Add Intel PCONFIG cpufeature
  2018-02-09 14:07 [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Kirill A. Shutemov
  2018-02-09 14:07 ` [PATCHv3 1/5] x86/cpufeatures: Add Intel Total Memory Encryption cpufeature Kirill A. Shutemov
  2018-02-09 14:07 ` [PATCHv3 2/5] x86/tme: Detect if TME and MKTME is activated by BIOS Kirill A. Shutemov
@ 2018-02-09 14:07 ` Kirill A. Shutemov
  2018-02-09 14:07 ` [PATCHv3 4/5] x86/pconfig: Detect PCONFIG targets Kirill A. Shutemov
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Kirill A. Shutemov @ 2018-02-09 14:07 UTC (permalink / raw)
  To: Ingo Molnar, x86, Thomas Gleixner, H. Peter Anvin
  Cc: Tom Lendacky, Dave Hansen, Kai Huang, linux-kernel, Kirill A. Shutemov

CPUID.0x7.0x0:EDX[18] indicates whether Intel CPU support PCONFIG instruction.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/include/asm/cpufeatures.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index d3702d9ac012..b9b46b593938 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -328,6 +328,7 @@
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
 #define X86_FEATURE_AVX512_4VNNIW	(18*32+ 2) /* AVX-512 Neural Network Instructions */
 #define X86_FEATURE_AVX512_4FMAPS	(18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
+#define X86_FEATURE_PCONFIG		(18*32+18) /* Intel PCONFIG */
 #define X86_FEATURE_SPEC_CTRL		(18*32+26) /* "" Speculation Control (IBRS + IBPB) */
 #define X86_FEATURE_INTEL_STIBP		(18*32+27) /* "" Single Thread Indirect Branch Predictors */
 #define X86_FEATURE_ARCH_CAPABILITIES	(18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv3 4/5] x86/pconfig: Detect PCONFIG targets
  2018-02-09 14:07 [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Kirill A. Shutemov
                   ` (2 preceding siblings ...)
  2018-02-09 14:07 ` [PATCHv3 3/5] x86/cpufeatures: Add Intel PCONFIG cpufeature Kirill A. Shutemov
@ 2018-02-09 14:07 ` Kirill A. Shutemov
  2018-02-09 14:07 ` [PATCHv3 5/5] x86/pconfig: Provide defines and helper to run MKTME_KEY_PROG leaf Kirill A. Shutemov
  2018-02-11 19:02 ` [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Ingo Molnar
  5 siblings, 0 replies; 9+ messages in thread
From: Kirill A. Shutemov @ 2018-02-09 14:07 UTC (permalink / raw)
  To: Ingo Molnar, x86, Thomas Gleixner, H. Peter Anvin
  Cc: Tom Lendacky, Dave Hansen, Kai Huang, linux-kernel, Kirill A. Shutemov

Intel PCONFIG targets are enumerated via new CPUID leaf 0x1b. This patch
detects all supported targets of PCONFIG and implements helper to check
if the target is supported.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/include/asm/intel_pconfig.h | 15 +++++++
 arch/x86/kernel/cpu/Makefile         |  2 +-
 arch/x86/kernel/cpu/intel_pconfig.c  | 82 ++++++++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/include/asm/intel_pconfig.h
 create mode 100644 arch/x86/kernel/cpu/intel_pconfig.c

diff --git a/arch/x86/include/asm/intel_pconfig.h b/arch/x86/include/asm/intel_pconfig.h
new file mode 100644
index 000000000000..fb7a37c3798b
--- /dev/null
+++ b/arch/x86/include/asm/intel_pconfig.h
@@ -0,0 +1,15 @@
+#ifndef	_ASM_X86_INTEL_PCONFIG_H
+#define	_ASM_X86_INTEL_PCONFIG_H
+
+#include <asm/asm.h>
+#include <asm/processor.h>
+
+enum pconfig_target {
+	INVALID_TARGET	= 0,
+	MKTME_TARGET	= 1,
+	PCONFIG_TARGET_NR
+};
+
+int pconfig_target_supported(enum pconfig_target target);
+
+#endif	/* _ASM_X86_INTEL_PCONFIG_H */
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 570e8bb1f386..a66229f51b12 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -28,7 +28,7 @@ obj-y			+= cpuid-deps.o
 obj-$(CONFIG_PROC_FS)	+= proc.o
 obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
 
-obj-$(CONFIG_CPU_SUP_INTEL)		+= intel.o
+obj-$(CONFIG_CPU_SUP_INTEL)		+= intel.o intel_pconfig.o
 obj-$(CONFIG_CPU_SUP_AMD)		+= amd.o
 obj-$(CONFIG_CPU_SUP_CYRIX_32)		+= cyrix.o
 obj-$(CONFIG_CPU_SUP_CENTAUR)		+= centaur.o
diff --git a/arch/x86/kernel/cpu/intel_pconfig.c b/arch/x86/kernel/cpu/intel_pconfig.c
new file mode 100644
index 000000000000..0771a905b286
--- /dev/null
+++ b/arch/x86/kernel/cpu/intel_pconfig.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel PCONFIG instruction support.
+ *
+ * Copyright (C) 2017 Intel Corporation
+ *
+ * Author:
+ *	Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+ */
+
+#include <asm/cpufeature.h>
+#include <asm/intel_pconfig.h>
+
+#define	PCONFIG_CPUID			0x1b
+
+#define PCONFIG_CPUID_SUBLEAF_MASK	((1 << 12) - 1)
+
+/* Subleaf type (EAX) for PCONFIG CPUID leaf (0x1B) */
+enum {
+	PCONFIG_CPUID_SUBLEAF_INVALID	= 0,
+	PCONFIG_CPUID_SUBLEAF_TARGETID	= 1,
+};
+
+/* Bitmask of supported targets */
+static u64 targets_supported __read_mostly;
+
+int pconfig_target_supported(enum pconfig_target target)
+{
+	/*
+	 * We would need to re-think the implementation once we get > 64
+	 * PCONFIG targets. Spec allows up to 2^32 targets.
+	 */
+	BUILD_BUG_ON(PCONFIG_TARGET_NR >= 64);
+
+	if (WARN_ON_ONCE(target >= 64))
+		return 0;
+	return targets_supported & (1ULL << target);
+}
+
+static int __init intel_pconfig_init(void)
+{
+	int subleaf;
+
+	if (!boot_cpu_has(X86_FEATURE_PCONFIG))
+		return 0;
+
+	/*
+	 * Scan subleafs of PCONFIG CPUID leaf.
+	 *
+	 * Subleafs of the same type need not to be consecutive.
+	 *
+	 * Stop on the first invalid subleaf type. All subleafs after the first
+	 * invalid are invalid too.
+	 */
+	for (subleaf = 0; subleaf < INT_MAX; subleaf++) {
+		struct cpuid_regs regs;
+
+		cpuid_count(PCONFIG_CPUID, subleaf,
+				&regs.eax, &regs.ebx, &regs.ecx, &regs.edx);
+
+		switch (regs.eax & PCONFIG_CPUID_SUBLEAF_MASK) {
+		case PCONFIG_CPUID_SUBLEAF_INVALID:
+			/* Stop on the first invalid subleaf */
+			goto out;
+		case PCONFIG_CPUID_SUBLEAF_TARGETID:
+			/* Mark supported PCONFIG targets */
+			if (regs.ebx < 64)
+				targets_supported |= (1ULL << regs.ebx);
+			if (regs.ecx < 64)
+				targets_supported |= (1ULL << regs.ecx);
+			if (regs.edx < 64)
+				targets_supported |= (1ULL << regs.edx);
+			break;
+		default:
+			/* Unknown CPUID.PCONFIG subleaf: ignore */
+			break;
+		}
+	}
+out:
+	return 0;
+}
+arch_initcall(intel_pconfig_init);
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv3 5/5] x86/pconfig: Provide defines and helper to run MKTME_KEY_PROG leaf
  2018-02-09 14:07 [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Kirill A. Shutemov
                   ` (3 preceding siblings ...)
  2018-02-09 14:07 ` [PATCHv3 4/5] x86/pconfig: Detect PCONFIG targets Kirill A. Shutemov
@ 2018-02-09 14:07 ` Kirill A. Shutemov
  2018-02-11 19:02 ` [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Ingo Molnar
  5 siblings, 0 replies; 9+ messages in thread
From: Kirill A. Shutemov @ 2018-02-09 14:07 UTC (permalink / raw)
  To: Ingo Molnar, x86, Thomas Gleixner, H. Peter Anvin
  Cc: Tom Lendacky, Dave Hansen, Kai Huang, linux-kernel, Kirill A. Shutemov

MKTME_KEY_PROG allows to manipulate MKTME keys in the CPU.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/include/asm/intel_pconfig.h | 50 ++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/x86/include/asm/intel_pconfig.h b/arch/x86/include/asm/intel_pconfig.h
index fb7a37c3798b..3cb002b1d0f9 100644
--- a/arch/x86/include/asm/intel_pconfig.h
+++ b/arch/x86/include/asm/intel_pconfig.h
@@ -12,4 +12,54 @@ enum pconfig_target {
 
 int pconfig_target_supported(enum pconfig_target target);
 
+enum pconfig_leaf {
+	MKTME_KEY_PROGRAM	= 0,
+	PCONFIG_LEAF_INVALID,
+};
+
+#define PCONFIG ".byte 0x0f, 0x01, 0xc5"
+
+/* Defines and structure for MKTME_KEY_PROGRAM of PCONFIG instruction */
+
+/* mktme_key_program::keyid_ctrl COMMAND, bits [7:0] */
+#define MKTME_KEYID_SET_KEY_DIRECT	0
+#define MKTME_KEYID_SET_KEY_RANDOM	1
+#define MKTME_KEYID_CLEAR_KEY		2
+#define MKTME_KEYID_NO_ENCRYPT		3
+
+/* mktme_key_program::keyid_ctrl ENC_ALG, bits [23:8] */
+#define MKTME_AES_XTS_128	(1 << 8)
+
+/* Return codes from the PCONFIG MKTME_KEY_PROGRAM */
+#define MKTME_PROG_SUCCESS	0
+#define MKTME_INVALID_PROG_CMD	1
+#define MKTME_ENTROPY_ERROR	2
+#define MKTME_INVALID_KEYID	3
+#define MKTME_INVALID_ENC_ALG	4
+#define MKTME_DEVICE_BUSY	5
+
+/* Hardware requires the structure to be 256 byte alinged. Otherwise #GP(0). */
+struct mktme_key_program {
+	u16 keyid;
+	u32 keyid_ctrl;
+	u8 __rsvd[58];
+	u8 key_field_1[64];
+	u8 key_field_2[64];
+} __packed __aligned(256);
+
+static inline int mktme_key_program(struct mktme_key_program *key_program)
+{
+	unsigned long rax = MKTME_KEY_PROGRAM;
+
+	if (!pconfig_target_supported(MKTME_TARGET))
+		return -ENXIO;
+
+	asm volatile(PCONFIG
+		: "=a" (rax), "=b" (key_program)
+		: "0" (rax), "1" (key_program)
+		: "memory", "cc");
+
+	return rax;
+}
+
 #endif	/* _ASM_X86_INTEL_PCONFIG_H */
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper
  2018-02-09 14:07 [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Kirill A. Shutemov
                   ` (4 preceding siblings ...)
  2018-02-09 14:07 ` [PATCHv3 5/5] x86/pconfig: Provide defines and helper to run MKTME_KEY_PROG leaf Kirill A. Shutemov
@ 2018-02-11 19:02 ` Ingo Molnar
  2018-02-12  7:48   ` Kirill A. Shutemov
  5 siblings, 1 reply; 9+ messages in thread
From: Ingo Molnar @ 2018-02-11 19:02 UTC (permalink / raw)
  To: Kirill A. Shutemov, Tom Lendacky
  Cc: Ingo Molnar, x86, Thomas Gleixner, H. Peter Anvin, Tom Lendacky,
	Dave Hansen, Kai Huang, linux-kernel


* Kirill A. Shutemov <kirill.shutemov@linux.intel.com> wrote:

> Multikey Total Memory Encryption (MKTME)[1] is a technology that allows
> transparent memory encryption in upcoming Intel platforms.
>
> MKTME is built on top of TME. TME allows encryption of the entirety of
> system memory using a single key. MKTME allows to have multiple encryption
> domains, each having own key -- different memory pages can be encrypted
> with different keys.
> 
> The patchset does some ground work for MKTME enabling:
>   - Adds two new cpufeatures: TME and PCONFIG;
>   - Detects if BIOS enabled TME and MKTME;
>   - Enumerates what PCONFIG targets are supported;
>   - Provides helper to program encryption keys into CPU;
> 
> As part of TME enumeration we check out how many bits from physical address
> are claimed for encryption key ID. This may be critical as we or guest VM
> must not use these bits for physical address.

So how will the 'full' patchset look like, roughly - is there a tree or diffstat 
we could take a look at perhaps?

I'm also wondering how 'TME' compares to AMD's SME (Secure Memory Encryption) and 
SEV features. SME required a number of low level boot code changes - I'm wondering 
how much commonality there can be achieved with Intel's TME so that we don't end 
up with two sets of interfaces.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper
  2018-02-11 19:02 ` [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Ingo Molnar
@ 2018-02-12  7:48   ` Kirill A. Shutemov
  2018-02-13  8:53     ` Ingo Molnar
  0 siblings, 1 reply; 9+ messages in thread
From: Kirill A. Shutemov @ 2018-02-12  7:48 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Kirill A. Shutemov, Tom Lendacky, Ingo Molnar, x86,
	Thomas Gleixner, H. Peter Anvin, Dave Hansen, Kai Huang,
	linux-kernel

On Sun, Feb 11, 2018 at 08:02:41PM +0100, Ingo Molnar wrote:
> 
> * Kirill A. Shutemov <kirill.shutemov@linux.intel.com> wrote:
> 
> > Multikey Total Memory Encryption (MKTME)[1] is a technology that allows
> > transparent memory encryption in upcoming Intel platforms.
> >
> > MKTME is built on top of TME. TME allows encryption of the entirety of
> > system memory using a single key. MKTME allows to have multiple encryption
> > domains, each having own key -- different memory pages can be encrypted
> > with different keys.
> > 
> > The patchset does some ground work for MKTME enabling:
> >   - Adds two new cpufeatures: TME and PCONFIG;
> >   - Detects if BIOS enabled TME and MKTME;
> >   - Enumerates what PCONFIG targets are supported;
> >   - Provides helper to program encryption keys into CPU;
> > 
> > As part of TME enumeration we check out how many bits from physical address
> > are claimed for encryption key ID. This may be critical as we or guest VM
> > must not use these bits for physical address.
> 
> So how will the 'full' patchset look like, roughly - is there a tree or diffstat 
> we could take a look at perhaps?

I don't have anything to show beyond this yet. I'll post as soon I have it
ready.

This patchset includes only things that are close to hardware and unlikely
to change substantially by the next steps.

> I'm also wondering how 'TME' compares to AMD's SME (Secure Memory Encryption) and 
> SEV features. SME required a number of low level boot code changes - I'm wondering 
> how much commonality there can be achieved with Intel's TME so that we don't end 
> up with two sets of interfaces.

Unlike AMD SME, Intel TME doesn't really requires enabling on kernel side.

It's job of BIOS to get it enabled and by time kernel has control all
memory it has access too is encrypted with the single TME key. BIOS
exclude some of its memory for encryption to work properly.

What requires enabling is MKTME. As with TME, it gets enabled by BIOS: it
reserves a number of upper bits from physical address to indicate KeyID.

This means we don't need to change anything during early boot. MKTME is
targeted to userspace memory: typically to protect one VM from another.

Of course we can choose to use MKTME for kernel hardening and it may
require changes during early boot, that's not part of my initial enabling
plan.

Key design points of Intel MKTME:

 - Initial HW implementation would support upto 63 keys (plus one default
   TME key). But the number of keys may be as low as 3, depending to SKU
   and BIOS settings

 - To access encrypted memory you need to use mapping with proper KeyID
   int the page table entry. KeyID is encoded in upper bits of PFN in page
   table entry.

   This means we cannot use direct map to access encrypted memory from
   kernel side. My idea is to re-use kmap() interface to get proper
   temporary mapping on kernel side.

 - CPU does not enforce coherency between mappings of the same physical
   page with different KeyIDs or encryption keys. We wound need to take
   care about flushing cache on allocation of encrypted page and on
   returning it back to free pool.

 - For managing keys, there's MKTME_KEY_PROGRAM leaf of the new PCONFIG
   (platform configuration) instruction. It allows load and clear keys
   associated with a KeyID. You can also ask CPU to generate a key for
   you or disable memory encryption when a KeyID is used.

If you have any questions I would be glad to answer.

-- 
 Kirill A. Shutemov

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper
  2018-02-12  7:48   ` Kirill A. Shutemov
@ 2018-02-13  8:53     ` Ingo Molnar
  0 siblings, 0 replies; 9+ messages in thread
From: Ingo Molnar @ 2018-02-13  8:53 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: Kirill A. Shutemov, Tom Lendacky, Ingo Molnar, x86,
	Thomas Gleixner, H. Peter Anvin, Dave Hansen, Kai Huang,
	linux-kernel


* Kirill A. Shutemov <kirill@shutemov.name> wrote:

> On Sun, Feb 11, 2018 at 08:02:41PM +0100, Ingo Molnar wrote:
> > 
> > * Kirill A. Shutemov <kirill.shutemov@linux.intel.com> wrote:
> > 
> > > Multikey Total Memory Encryption (MKTME)[1] is a technology that allows
> > > transparent memory encryption in upcoming Intel platforms.
> > >
> > > MKTME is built on top of TME. TME allows encryption of the entirety of
> > > system memory using a single key. MKTME allows to have multiple encryption
> > > domains, each having own key -- different memory pages can be encrypted
> > > with different keys.
> > > 
> > > The patchset does some ground work for MKTME enabling:
> > >   - Adds two new cpufeatures: TME and PCONFIG;
> > >   - Detects if BIOS enabled TME and MKTME;
> > >   - Enumerates what PCONFIG targets are supported;
> > >   - Provides helper to program encryption keys into CPU;
> > > 
> > > As part of TME enumeration we check out how many bits from physical address
> > > are claimed for encryption key ID. This may be critical as we or guest VM
> > > must not use these bits for physical address.
> > 
> > So how will the 'full' patchset look like, roughly - is there a tree or diffstat 
> > we could take a look at perhaps?
> 
> I don't have anything to show beyond this yet. I'll post as soon I have it
> ready.
> 
> This patchset includes only things that are close to hardware and unlikely
> to change substantially by the next steps.

Ok.

> > I'm also wondering how 'TME' compares to AMD's SME (Secure Memory Encryption) and 
> > SEV features. SME required a number of low level boot code changes - I'm wondering 
> > how much commonality there can be achieved with Intel's TME so that we don't end 
> > up with two sets of interfaces.
> 
> Unlike AMD SME, Intel TME doesn't really requires enabling on kernel side.
> 
> It's job of BIOS to get it enabled and by time kernel has control all
> memory it has access too is encrypted with the single TME key. BIOS
> exclude some of its memory for encryption to work properly.
> 
> What requires enabling is MKTME. As with TME, it gets enabled by BIOS: it
> reserves a number of upper bits from physical address to indicate KeyID.
> 
> This means we don't need to change anything during early boot. MKTME is
> targeted to userspace memory: typically to protect one VM from another.
> 
> Of course we can choose to use MKTME for kernel hardening and it may
> require changes during early boot, that's not part of my initial enabling
> plan.
> 
> Key design points of Intel MKTME:
> 
>  - Initial HW implementation would support upto 63 keys (plus one default
>    TME key). But the number of keys may be as low as 3, depending to SKU
>    and BIOS settings
> 
>  - To access encrypted memory you need to use mapping with proper KeyID
>    int the page table entry. KeyID is encoded in upper bits of PFN in page
>    table entry.
> 
>    This means we cannot use direct map to access encrypted memory from
>    kernel side. My idea is to re-use kmap() interface to get proper
>    temporary mapping on kernel side.
> 
>  - CPU does not enforce coherency between mappings of the same physical
>    page with different KeyIDs or encryption keys. We wound need to take
>    care about flushing cache on allocation of encrypted page and on
>    returning it back to free pool.
>
>  - For managing keys, there's MKTME_KEY_PROGRAM leaf of the new PCONFIG
>    (platform configuration) instruction. It allows load and clear keys
>    associated with a KeyID. You can also ask CPU to generate a key for
>    you or disable memory encryption when a KeyID is used.
> 
> If you have any questions I would be glad to answer.

Ok, this sounds pretty flexible at first glance - thanks for the summary!

	Ingo

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-02-13  8:53 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-09 14:07 [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Kirill A. Shutemov
2018-02-09 14:07 ` [PATCHv3 1/5] x86/cpufeatures: Add Intel Total Memory Encryption cpufeature Kirill A. Shutemov
2018-02-09 14:07 ` [PATCHv3 2/5] x86/tme: Detect if TME and MKTME is activated by BIOS Kirill A. Shutemov
2018-02-09 14:07 ` [PATCHv3 3/5] x86/cpufeatures: Add Intel PCONFIG cpufeature Kirill A. Shutemov
2018-02-09 14:07 ` [PATCHv3 4/5] x86/pconfig: Detect PCONFIG targets Kirill A. Shutemov
2018-02-09 14:07 ` [PATCHv3 5/5] x86/pconfig: Provide defines and helper to run MKTME_KEY_PROG leaf Kirill A. Shutemov
2018-02-11 19:02 ` [PATCHv3 0/5] x86: Enumerate TME and PCONFIG, add MKTME_KEY_PROG helper Ingo Molnar
2018-02-12  7:48   ` Kirill A. Shutemov
2018-02-13  8:53     ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).