All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] x86: Cleanup and extend computing computing API
@ 2022-02-22 18:57 Kirill A. Shutemov
  2022-02-22 18:57 ` [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency Kirill A. Shutemov
                   ` (6 more replies)
  0 siblings, 7 replies; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-22 18:57 UTC (permalink / raw)
  To: tglx, mingo, bp, dave.hansen, luto, peterz
  Cc: sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, Kirill A. Shutemov

Updates for CC API:
 - Fix for HyperV when AMD SME/SEV disabled;
 - New home for CC code: arch/x86/coco;
 - Explicitly declare vendor of CC platform;
 - New cc_mkenc() and cc_mkdec();

Kirill A. Shutemov (4):
  x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  x86: Rename cc_platform.c to arch/x86/coco/core.c
  x86/coco: Explicitly declare type of confidential computing platform
  x86/coco: Add API to handle encryption mask

 arch/x86/Kbuild                               |  2 +
 arch/x86/coco/Makefile                        |  6 ++
 .../x86/{kernel/cc_platform.c => coco/core.c} | 56 +++++++++++++++----
 arch/x86/include/asm/coco.h                   | 32 +++++++++++
 arch/x86/include/asm/pgtable.h                | 13 +++--
 arch/x86/kernel/Makefile                      |  5 --
 arch/x86/kernel/cpu/mshyperv.c                |  3 +
 arch/x86/mm/mem_encrypt_identity.c            | 12 ++--
 arch/x86/mm/pat/set_memory.c                  |  5 +-
 drivers/hv/Kconfig                            |  1 +
 10 files changed, 106 insertions(+), 29 deletions(-)
 create mode 100644 arch/x86/coco/Makefile
 rename arch/x86/{kernel/cc_platform.c => coco/core.c} (73%)
 create mode 100644 arch/x86/include/asm/coco.h

-- 
2.34.1


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

* [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-22 18:57 [PATCH 0/4] x86: Cleanup and extend computing computing API Kirill A. Shutemov
@ 2022-02-22 18:57 ` Kirill A. Shutemov
  2022-02-22 20:08   ` Borislav Petkov
  2022-02-22 18:57 ` [PATCH 2/4] x86: Rename cc_platform.c to arch/x86/coco/core.c Kirill A. Shutemov
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-22 18:57 UTC (permalink / raw)
  To: tglx, mingo, bp, dave.hansen, luto, peterz
  Cc: sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, Kirill A. Shutemov, K. Y. Srinivasan,
	Haiyang Zhang, Stephen Hemminger, Wei Liu, Dexuan Cui,
	Tianyu Lan

On x86, cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) supposes to return
true for HyperV if isolation is supported. But it only does it if the
kernel is compiled with AMD_MEM_ENCRYPT enabled.

It happens due to missed ARCH_HAS_CC_PLATFORM dependency. Without
ARCH_HAS_CC_PLATFORM enabled, cc_platform_has() always returns false.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Cc: Wei Liu <wei.liu@kernel.org>
Cc: Dexuan Cui <decui@microsoft.com>
Cc: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 drivers/hv/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 0747a8f1fcee..424d3f0751dc 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -8,6 +8,7 @@ config HYPERV
 		|| (ARM64 && !CPU_BIG_ENDIAN))
 	select PARAVIRT
 	select X86_HV_CALLBACK_VECTOR if X86
+	select ARCH_HAS_CC_PLATFORM if x86
 	select VMAP_PFN
 	help
 	  Select this option to run Linux as a Hyper-V client operating
-- 
2.34.1


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

* [PATCH 2/4] x86: Rename cc_platform.c to arch/x86/coco/core.c
  2022-02-22 18:57 [PATCH 0/4] x86: Cleanup and extend computing computing API Kirill A. Shutemov
  2022-02-22 18:57 ` [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency Kirill A. Shutemov
@ 2022-02-22 18:57 ` Kirill A. Shutemov
  2022-02-22 20:52   ` Borislav Petkov
  2022-02-24 11:59   ` [tip: x86/cc] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c} tip-bot2 for Kirill A. Shutemov
  2022-02-22 18:57 ` [PATCH 3/4] x86/coco: Explicitly declare type of confidential computing platform Kirill A. Shutemov
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-22 18:57 UTC (permalink / raw)
  To: tglx, mingo, bp, dave.hansen, luto, peterz
  Cc: sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, Kirill A. Shutemov

Move cc_platform.c to the newly created arch/x86/coco. The directly is
going to be a home space for code related to confidential computing.

Intel TDX code will land here. AMD SEV code will also eventually be
moved there.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/Kbuild                                | 2 ++
 arch/x86/coco/Makefile                         | 6 ++++++
 arch/x86/{kernel/cc_platform.c => coco/core.c} | 0
 arch/x86/kernel/Makefile                       | 5 -----
 4 files changed, 8 insertions(+), 5 deletions(-)
 create mode 100644 arch/x86/coco/Makefile
 rename arch/x86/{kernel/cc_platform.c => coco/core.c} (100%)

diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index f384cb1a4f7a..5a83da703e87 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_ARCH_HAS_CC_PLATFORM) += coco/
+
 obj-y += entry/
 
 obj-$(CONFIG_PERF_EVENTS) += events/
diff --git a/arch/x86/coco/Makefile b/arch/x86/coco/Makefile
new file mode 100644
index 000000000000..c1ead00017a7
--- /dev/null
+++ b/arch/x86/coco/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+CFLAGS_REMOVE_core.o	= -pg
+KASAN_SANITIZE_core.o	:= n
+CFLAGS_core.o		+= -fno-stack-protector
+
+obj-y += core.o
diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/coco/core.c
similarity index 100%
rename from arch/x86/kernel/cc_platform.c
rename to arch/x86/coco/core.c
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 6aef9ee28a39..6462e3dd98f4 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -21,7 +21,6 @@ CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
 CFLAGS_REMOVE_head64.o = -pg
 CFLAGS_REMOVE_sev.o = -pg
-CFLAGS_REMOVE_cc_platform.o = -pg
 endif
 
 KASAN_SANITIZE_head$(BITS).o				:= n
@@ -30,7 +29,6 @@ KASAN_SANITIZE_dumpstack_$(BITS).o			:= n
 KASAN_SANITIZE_stacktrace.o				:= n
 KASAN_SANITIZE_paravirt.o				:= n
 KASAN_SANITIZE_sev.o					:= n
-KASAN_SANITIZE_cc_platform.o				:= n
 
 # With some compiler versions the generated code results in boot hangs, caused
 # by several compilation units. To be safe, disable all instrumentation.
@@ -49,7 +47,6 @@ endif
 KCOV_INSTRUMENT		:= n
 
 CFLAGS_head$(BITS).o	+= -fno-stack-protector
-CFLAGS_cc_platform.o	+= -fno-stack-protector
 
 CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace
 
@@ -151,8 +148,6 @@ obj-$(CONFIG_UNWINDER_GUESS)		+= unwind_guess.o
 
 obj-$(CONFIG_AMD_MEM_ENCRYPT)		+= sev.o
 
-obj-$(CONFIG_ARCH_HAS_CC_PLATFORM)	+= cc_platform.o
-
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
-- 
2.34.1


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

* [PATCH 3/4] x86/coco: Explicitly declare type of confidential computing platform
  2022-02-22 18:57 [PATCH 0/4] x86: Cleanup and extend computing computing API Kirill A. Shutemov
  2022-02-22 18:57 ` [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency Kirill A. Shutemov
  2022-02-22 18:57 ` [PATCH 2/4] x86: Rename cc_platform.c to arch/x86/coco/core.c Kirill A. Shutemov
@ 2022-02-22 18:57 ` Kirill A. Shutemov
  2022-02-24 11:59   ` [tip: x86/cc] " tip-bot2 for Kirill A. Shutemov
  2022-02-22 18:57 ` [PATCH 4/4] x86/coco: Add API to handle encryption mask Kirill A. Shutemov
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-22 18:57 UTC (permalink / raw)
  To: tglx, mingo, bp, dave.hansen, luto, peterz
  Cc: sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, Kirill A. Shutemov

Kernel derives type of confidential computing platform from sme_me_mask
value and hv_is_isolation_supported(). This detection process will be
more complicated as more platforms get added.

Declare confidential computing vendor explicitly via cc_set_vendor().

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/coco/core.c               | 29 +++++++++++++++++------------
 arch/x86/include/asm/coco.h        | 14 ++++++++++++++
 arch/x86/kernel/cpu/mshyperv.c     |  3 +++
 arch/x86/mm/mem_encrypt_identity.c | 11 +++++++----
 4 files changed, 41 insertions(+), 16 deletions(-)
 create mode 100644 arch/x86/include/asm/coco.h

diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index 6a6ffcd978f6..476dcd198af5 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -9,18 +9,15 @@
 
 #include <linux/export.h>
 #include <linux/cc_platform.h>
-#include <linux/mem_encrypt.h>
 
-#include <asm/mshyperv.h>
+#include <asm/coco.h>
 #include <asm/processor.h>
 
-static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
+static enum cc_vendor vendor __ro_after_init;
+
+static bool intel_cc_platform_has(enum cc_attr attr)
 {
-#ifdef CONFIG_INTEL_TDX_GUEST
-	return false;
-#else
 	return false;
-#endif
 }
 
 /*
@@ -74,12 +71,20 @@ static bool hyperv_cc_platform_has(enum cc_attr attr)
 
 bool cc_platform_has(enum cc_attr attr)
 {
-	if (sme_me_mask)
+	switch (vendor) {
+	case CC_VENDOR_AMD:
 		return amd_cc_platform_has(attr);
-
-	if (hv_is_isolation_supported())
+	case CC_VENDOR_INTEL:
+		return intel_cc_platform_has(attr);
+	case CC_VENDOR_HYPERV:
 		return hyperv_cc_platform_has(attr);
-
-	return false;
+	default:
+		return false;
+	}
 }
 EXPORT_SYMBOL_GPL(cc_platform_has);
+
+__init void cc_set_vendor(enum cc_vendor v)
+{
+	vendor = v;
+}
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
new file mode 100644
index 000000000000..e49f9ddb6ae6
--- /dev/null
+++ b/arch/x86/include/asm/coco.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_COCO_H
+#define _ASM_X86_COCO_H
+
+enum cc_vendor {
+	CC_VENDOR_NONE,
+	CC_VENDOR_AMD,
+	CC_VENDOR_HYPERV,
+	CC_VENDOR_INTEL,
+};
+
+void cc_set_vendor(enum cc_vendor v);
+
+#endif /* _ASM_X86_COCO_H */
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 5a99f993e639..c1c0123859b9 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -33,6 +33,7 @@
 #include <asm/nmi.h>
 #include <clocksource/hyperv_timer.h>
 #include <asm/numa.h>
+#include <asm/coco.h>
 
 /* Is Linux running as the root partition? */
 bool hv_root_partition;
@@ -344,6 +345,8 @@ static void __init ms_hyperv_init_platform(void)
 		 */
 		swiotlb_force = SWIOTLB_FORCE;
 #endif
+		if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE)
+			cc_set_vendor(CC_VENDOR_HYPERV);
 	}
 
 	if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index 3f0abb403340..06314ae3998e 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -44,6 +44,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/cmdline.h>
+#include <asm/coco.h>
 
 #include "mm_internal.h"
 
@@ -565,8 +566,7 @@ void __init sme_enable(struct boot_params *bp)
 	} else {
 		/* SEV state cannot be controlled by a command line option */
 		sme_me_mask = me_mask;
-		physical_mask &= ~sme_me_mask;
-		return;
+		goto out;
 	}
 
 	/*
@@ -600,6 +600,9 @@ void __init sme_enable(struct boot_params *bp)
 		sme_me_mask = 0;
 	else
 		sme_me_mask = active_by_default ? me_mask : 0;
-
-	physical_mask &= ~sme_me_mask;
+out:
+	if (sme_me_mask) {
+		physical_mask &= ~sme_me_mask;
+		cc_set_vendor(CC_VENDOR_AMD);
+	}
 }
-- 
2.34.1


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

* [PATCH 4/4] x86/coco: Add API to handle encryption mask
  2022-02-22 18:57 [PATCH 0/4] x86: Cleanup and extend computing computing API Kirill A. Shutemov
                   ` (2 preceding siblings ...)
  2022-02-22 18:57 ` [PATCH 3/4] x86/coco: Explicitly declare type of confidential computing platform Kirill A. Shutemov
@ 2022-02-22 18:57 ` Kirill A. Shutemov
  2022-02-24 11:59   ` [tip: x86/cc] " tip-bot2 for Kirill A. Shutemov
  2022-02-22 21:56 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Tom Lendacky
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-22 18:57 UTC (permalink / raw)
  To: tglx, mingo, bp, dave.hansen, luto, peterz
  Cc: sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, Kirill A. Shutemov

AMD SME/SEV uses a bit in the page table entries to indicate that the
page is encrypted and not accessible to the VMM.

TDX uses a similar approach, but the polarity of the mask is opposite to
AMD: if the bit is set the page is accessible to VMM.

Provide vendor-neutral API to deal with the mask: cc_mkenc() and
cc_mkdec() modify given address to make it encrypted/decrypted. It can
be applied to phys_addr_t, pgprotval_t or page table entry value.

pgprot_encrypted() and pgprot_decrypted() reimplemented using new
helpers.

The implementation will be extended to cover TDX.

pgprot_decrypted() is used by drivers (i915, virtio_gpu, vfio).
cc_mkdec() called by pgprot_decrypted(). Export cc_mkdec().

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/coco/core.c               | 27 +++++++++++++++++++++++++++
 arch/x86/include/asm/coco.h        | 18 ++++++++++++++++++
 arch/x86/include/asm/pgtable.h     | 13 +++++++------
 arch/x86/mm/mem_encrypt_identity.c |  1 +
 arch/x86/mm/pat/set_memory.c       |  5 +++--
 5 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index 476dcd198af5..fc1365dd927e 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 
 static enum cc_vendor vendor __ro_after_init;
+static u64 cc_mask __ro_after_init;
 
 static bool intel_cc_platform_has(enum cc_attr attr)
 {
@@ -84,7 +85,33 @@ bool cc_platform_has(enum cc_attr attr)
 }
 EXPORT_SYMBOL_GPL(cc_platform_has);
 
+u64 cc_mkenc(u64 val)
+{
+	switch (vendor) {
+	case CC_VENDOR_AMD:
+		return val | cc_mask;
+	default:
+		return val;
+	}
+}
+
+u64 cc_mkdec(u64 val)
+{
+	switch (vendor) {
+	case CC_VENDOR_AMD:
+		return val & ~cc_mask;
+	default:
+		return val;
+	}
+}
+EXPORT_SYMBOL_GPL(cc_mkdec);
+
 __init void cc_set_vendor(enum cc_vendor v)
 {
 	vendor = v;
 }
+
+__init void cc_set_mask(u64 mask)
+{
+	cc_mask = mask;
+}
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
index e49f9ddb6ae6..3d98c3a60d34 100644
--- a/arch/x86/include/asm/coco.h
+++ b/arch/x86/include/asm/coco.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_COCO_H
 #define _ASM_X86_COCO_H
 
+#include <asm/types.h>
+
 enum cc_vendor {
 	CC_VENDOR_NONE,
 	CC_VENDOR_AMD,
@@ -10,5 +12,21 @@ enum cc_vendor {
 };
 
 void cc_set_vendor(enum cc_vendor v);
+void cc_set_mask(u64 mask);
+
+#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
+u64 cc_mkenc(u64 val);
+u64 cc_mkdec(u64 val);
+#else
+static inline u64 cc_mkenc(u64 val)
+{
+	return val;
+}
+
+static inline u64 cc_mkdec(u64 val)
+{
+	return val;
+}
+#endif
 
 #endif /* _ASM_X86_COCO_H */
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 8a9432fb3802..62ab07e24aef 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -15,17 +15,12 @@
 		     cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS)))	\
 	 : (prot))
 
-/*
- * Macros to add or remove encryption attribute
- */
-#define pgprot_encrypted(prot)	__pgprot(__sme_set(pgprot_val(prot)))
-#define pgprot_decrypted(prot)	__pgprot(__sme_clr(pgprot_val(prot)))
-
 #ifndef __ASSEMBLY__
 #include <linux/spinlock.h>
 #include <asm/x86_init.h>
 #include <asm/pkru.h>
 #include <asm/fpu/api.h>
+#include <asm/coco.h>
 #include <asm-generic/pgtable_uffd.h>
 #include <linux/page_table_check.h>
 
@@ -38,6 +33,12 @@ void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
 void ptdump_walk_pgd_level_checkwx(void);
 void ptdump_walk_user_pgd_level_checkwx(void);
 
+/*
+ * Macros to add or remove encryption attribute
+ */
+#define pgprot_encrypted(prot)	__pgprot(cc_mkenc(pgprot_val(prot)))
+#define pgprot_decrypted(prot)	__pgprot(cc_mkdec(pgprot_val(prot)))
+
 #ifdef CONFIG_DEBUG_WX
 #define debug_checkwx()		ptdump_walk_pgd_level_checkwx()
 #define debug_checkwx_user()	ptdump_walk_user_pgd_level_checkwx()
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index 06314ae3998e..b43bc24d2bb6 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -604,5 +604,6 @@ void __init sme_enable(struct boot_params *bp)
 	if (sme_me_mask) {
 		physical_mask &= ~sme_me_mask;
 		cc_set_vendor(CC_VENDOR_AMD);
+		cc_set_mask(sme_me_mask);
 	}
 }
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index b4072115c8ef..af77dbfd143c 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1990,6 +1990,7 @@ int set_memory_global(unsigned long addr, int numpages)
 static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 {
 	struct cpa_data cpa;
+	pgprot_t empty = __pgprot(0);
 	int ret;
 
 	/* Should not be working on unaligned addresses */
@@ -1999,8 +2000,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	memset(&cpa, 0, sizeof(cpa));
 	cpa.vaddr = &addr;
 	cpa.numpages = numpages;
-	cpa.mask_set = enc ? __pgprot(_PAGE_ENC) : __pgprot(0);
-	cpa.mask_clr = enc ? __pgprot(0) : __pgprot(_PAGE_ENC);
+	cpa.mask_set = enc ? pgprot_encrypted(empty) : pgprot_decrypted(empty);
+	cpa.mask_clr = enc ? pgprot_decrypted(empty) : pgprot_encrypted(empty);
 	cpa.pgd = init_mm.pgd;
 
 	/* Must avoid aliasing mappings in the highmem code */
-- 
2.34.1


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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-22 18:57 ` [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency Kirill A. Shutemov
@ 2022-02-22 20:08   ` Borislav Petkov
  2022-02-23  7:04     ` Tianyu Lan
  0 siblings, 1 reply; 33+ messages in thread
From: Borislav Petkov @ 2022-02-22 20:08 UTC (permalink / raw)
  To: Kirill A. Shutemov, Wei Liu
  Cc: tglx, mingo, dave.hansen, luto, peterz,
	sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Dexuan Cui, Tianyu Lan

On Tue, Feb 22, 2022 at 09:57:37PM +0300, Kirill A. Shutemov wrote:
> On x86, cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) supposes to return
> true for HyperV if isolation is supported. But it only does it if the
> kernel is compiled with AMD_MEM_ENCRYPT enabled.
> 
> It happens due to missed ARCH_HAS_CC_PLATFORM dependency. Without
> ARCH_HAS_CC_PLATFORM enabled, cc_platform_has() always returns false.
> 
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Cc: "K. Y. Srinivasan" <kys@microsoft.com>
> Cc: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: Stephen Hemminger <sthemmin@microsoft.com>
> Cc: Wei Liu <wei.liu@kernel.org>
> Cc: Dexuan Cui <decui@microsoft.com>
> Cc: Tianyu Lan <Tianyu.Lan@microsoft.com>
> ---
>  drivers/hv/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> index 0747a8f1fcee..424d3f0751dc 100644
> --- a/drivers/hv/Kconfig
> +++ b/drivers/hv/Kconfig
> @@ -8,6 +8,7 @@ config HYPERV
>  		|| (ARM64 && !CPU_BIG_ENDIAN))
>  	select PARAVIRT
>  	select X86_HV_CALLBACK_VECTOR if X86
> +	select ARCH_HAS_CC_PLATFORM if x86
>  	select VMAP_PFN
>  	help
>  	  Select this option to run Linux as a Hyper-V client operating
> -- 

Good catch.

I'm guessing this needs

Fixes: c789b90a6904 ("x86/hyper-v: Add hyperv Isolation VM check in the cc_platform_has()")

which added hyperv_cc_platform_has() and which needs to go to Linus now,
as an urgent fix for 5.17 as that patch came into 5.17-rc1.

Wei?

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

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

* Re: [PATCH 2/4] x86: Rename cc_platform.c to arch/x86/coco/core.c
  2022-02-22 18:57 ` [PATCH 2/4] x86: Rename cc_platform.c to arch/x86/coco/core.c Kirill A. Shutemov
@ 2022-02-22 20:52   ` Borislav Petkov
  2022-02-24 11:59   ` [tip: x86/cc] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c} tip-bot2 for Kirill A. Shutemov
  1 sibling, 0 replies; 33+ messages in thread
From: Borislav Petkov @ 2022-02-22 20:52 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: tglx, mingo, dave.hansen, luto, peterz,
	sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel

On Tue, Feb 22, 2022 at 09:57:38PM +0300, Kirill A. Shutemov wrote:
> Subject: Re: [PATCH 2/4] x86: Rename cc_platform.c to arch/x86/coco/core.c

Just like git formats it:

Subject: x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c}

> Move cc_platform.c to the newly created arch/x86/coco. The directly is

s/directly/directory/

> going to be a home space for code related to confidential computing.
> 
> Intel TDX code will land here. AMD SEV code will also eventually be
> moved there.

Yap, that's the plan.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

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

* Re: [PATCH 0/4] x86: Cleanup and extend computing computing API
  2022-02-22 18:57 [PATCH 0/4] x86: Cleanup and extend computing computing API Kirill A. Shutemov
                   ` (3 preceding siblings ...)
  2022-02-22 18:57 ` [PATCH 4/4] x86/coco: Add API to handle encryption mask Kirill A. Shutemov
@ 2022-02-22 21:56 ` Tom Lendacky
  2022-02-23  4:35 ` [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable() Brijesh Singh
  2022-02-23 19:10 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Borislav Petkov
  6 siblings, 0 replies; 33+ messages in thread
From: Tom Lendacky @ 2022-02-22 21:56 UTC (permalink / raw)
  To: Kirill A. Shutemov, tglx, mingo, bp, dave.hansen, luto, peterz
  Cc: sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, brijesh.singh, x86, linux-kernel

On 2/22/22 12:57, Kirill A. Shutemov wrote:
> Updates for CC API:
>   - Fix for HyperV when AMD SME/SEV disabled;
>   - New home for CC code: arch/x86/coco;
>   - Explicitly declare vendor of CC platform;
>   - New cc_mkenc() and cc_mkdec();
> 
> Kirill A. Shutemov (4):
>    x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
>    x86: Rename cc_platform.c to arch/x86/coco/core.c
>    x86/coco: Explicitly declare type of confidential computing platform
>    x86/coco: Add API to handle encryption mask

For the series:

Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>

> 
>   arch/x86/Kbuild                               |  2 +
>   arch/x86/coco/Makefile                        |  6 ++
>   .../x86/{kernel/cc_platform.c => coco/core.c} | 56 +++++++++++++++----
>   arch/x86/include/asm/coco.h                   | 32 +++++++++++
>   arch/x86/include/asm/pgtable.h                | 13 +++--
>   arch/x86/kernel/Makefile                      |  5 --
>   arch/x86/kernel/cpu/mshyperv.c                |  3 +
>   arch/x86/mm/mem_encrypt_identity.c            | 12 ++--
>   arch/x86/mm/pat/set_memory.c                  |  5 +-
>   drivers/hv/Kconfig                            |  1 +
>   10 files changed, 106 insertions(+), 29 deletions(-)
>   create mode 100644 arch/x86/coco/Makefile
>   rename arch/x86/{kernel/cc_platform.c => coco/core.c} (73%)
>   create mode 100644 arch/x86/include/asm/coco.h
> 

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

* [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-22 18:57 [PATCH 0/4] x86: Cleanup and extend computing computing API Kirill A. Shutemov
                   ` (4 preceding siblings ...)
  2022-02-22 21:56 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Tom Lendacky
@ 2022-02-23  4:35 ` Brijesh Singh
  2022-02-23 11:31   ` Borislav Petkov
  2022-02-24 11:59   ` [tip: x86/cc] " tip-bot2 for Brijesh Singh
  2022-02-23 19:10 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Borislav Petkov
  6 siblings, 2 replies; 33+ messages in thread
From: Brijesh Singh @ 2022-02-23  4:35 UTC (permalink / raw)
  To: x86, linux-kernel, kvm, linux-coco
  Cc: Thomas Gleixner, Ingo Molnar, Joerg Roedel, Tom Lendacky,
	H. Peter Anvin, Paolo Bonzini, Sean Christopherson,
	Andy Lutomirski, Dave Hansen, Peter Gonda, Peter Zijlstra,
	David Rientjes, Borislav Petkov, Michael Roth,
	Kirill A . Shutemov, Andi Kleen, Brijesh Singh

The kernel provides infrastructure to set or clear the encryption mask
from the pages for AMD SEV, but TDX requires few tweaks.

- TDX and SEV have different requirements to the cache and tlb
  flushing.

- TDX has own routine to notify VMM about page encryption status change.

Modify __set_memory_enc_pgtable() and make it flexible enough to cover
both AMD SEV and Intel TDX. The AMD-specific behavior is isolated in
callback under x86_platform.cc. TDX will provide own version of the
callbacks.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---

Depends on Krill's CC cleanup
https://lore.kernel.org/all/20220222185740.26228-1-kirill.shutemov@linux.intel.com/

 arch/x86/include/asm/set_memory.h |  1 -
 arch/x86/include/asm/x86_init.h   | 21 +++++++++
 arch/x86/mm/mem_encrypt_amd.c     | 75 ++++++++++++++++++++++---------
 arch/x86/mm/pat/set_memory.c      | 20 +++++----
 4 files changed, 85 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index ff0f2d90338a..ce8dd215f5b3 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -84,7 +84,6 @@ int set_pages_rw(struct page *page, int numpages);
 int set_direct_map_invalid_noflush(struct page *page);
 int set_direct_map_default_noflush(struct page *page);
 bool kernel_page_present(struct page *page);
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);
 
 extern int kernel_set_to_readonly;
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 22b7412c08f6..dce92e2cb9e1 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -141,6 +141,26 @@ struct x86_init_acpi {
 	void (*reduced_hw_early_init)(void);
 };
 
+/**
+ * struct x86_cc_runtime - Functions used by misc guest incarnations like SEV, TDX, etc.
+ *
+ * @enc_status_change_prepare	Notify HV before the encryption status of a range
+ *				is changed.
+ *
+ * @enc_status_change_finish	Notify HV after the encryption status of a range
+ *				is changed.
+ *
+ * @enc_tlb_flush_required	Flush the TLB before changing the encryption status.
+ *
+ * @enc_cache_flush_required	Flush the caches before changing the encryption status.
+ */
+struct x86_cc_runtime {
+	void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+	void (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+	bool (*enc_tlb_flush_required)(bool enc);
+	bool (*enc_cache_flush_required)(void);
+};
+
 /**
  * struct x86_init_ops - functions for platform specific setup
  *
@@ -287,6 +307,7 @@ struct x86_platform_ops {
 	struct x86_legacy_features legacy;
 	void (*set_legacy_features)(void);
 	struct x86_hyper_runtime hyper;
+	const struct x86_cc_runtime *cc;
 };
 
 struct x86_apic_ops {
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 2b2d018ea345..22b86af5edf1 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -177,25 +177,6 @@ void __init sme_map_bootdata(char *real_mode_data)
 	__sme_early_map_unmap_mem(__va(cmdline_paddr), COMMAND_LINE_SIZE, true);
 }
 
-void __init sme_early_init(void)
-{
-	unsigned int i;
-
-	if (!sme_me_mask)
-		return;
-
-	early_pmd_flags = __sme_set(early_pmd_flags);
-
-	__supported_pte_mask = __sme_set(__supported_pte_mask);
-
-	/* Update the protection map with memory encryption mask */
-	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
-		protection_map[i] = pgprot_encrypted(protection_map[i]);
-
-	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
-		swiotlb_force = SWIOTLB_FORCE;
-}
-
 void __init sev_setup_arch(void)
 {
 	phys_addr_t total_mem = memblock_phys_mem_size();
@@ -256,7 +237,17 @@ static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
 	return pfn;
 }
 
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
+static bool amd_enc_tlb_flush_required(bool enc)
+{
+	return true;
+}
+
+static bool amd_enc_cache_flush_required(void)
+{
+	return !this_cpu_has(X86_FEATURE_SME_COHERENT);
+}
+
+static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
 #ifdef CONFIG_PARAVIRT
 	unsigned long sz = npages << PAGE_SHIFT;
@@ -287,6 +278,18 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
 #endif
 }
 
+static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+{
+}
+
+static void amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+{
+	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+		return;
+
+	enc_dec_hypercall(vaddr, npages, enc);
+}
+
 static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
 {
 	pgprot_t old_prot, new_prot;
@@ -392,7 +395,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
 
 	ret = 0;
 
-	notify_range_enc_status_changed(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
+	early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
 out:
 	__flush_tlb_all();
 	return ret;
@@ -410,7 +413,35 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
 
 void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
-	notify_range_enc_status_changed(vaddr, npages, enc);
+	enc_dec_hypercall(vaddr, npages, enc);
+}
+
+static const struct x86_cc_runtime amd_cc_runtime = {
+	.enc_status_change_prepare = amd_enc_status_change_prepare,
+	.enc_status_change_finish = amd_enc_status_change_finish,
+	.enc_tlb_flush_required = amd_enc_tlb_flush_required,
+	.enc_cache_flush_required = amd_enc_cache_flush_required,
+};
+
+void __init sme_early_init(void)
+{
+	unsigned int i;
+
+	if (!sme_me_mask)
+		return;
+
+	early_pmd_flags = __sme_set(early_pmd_flags);
+
+	__supported_pte_mask = __sme_set(__supported_pte_mask);
+
+	/* Update the protection map with memory encryption mask */
+	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
+		protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+		swiotlb_force = SWIOTLB_FORCE;
+
+	x86_platform.cc = &amd_cc_runtime;
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index af77dbfd143c..4de2a7509039 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1997,6 +1997,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	if (WARN_ONCE(addr & ~PAGE_MASK, "misaligned address: %#lx\n", addr))
 		addr &= PAGE_MASK;
 
+	BUG_ON(!x86_platform.cc);
+
 	memset(&cpa, 0, sizeof(cpa));
 	cpa.vaddr = &addr;
 	cpa.numpages = numpages;
@@ -2008,10 +2010,12 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	kmap_flush_unused();
 	vm_unmap_aliases();
 
-	/*
-	 * Before changing the encryption attribute, we need to flush caches.
-	 */
-	cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
+	/* Flush the caches as needed before changing the encryption attribute. */
+	if (x86_platform.cc->enc_tlb_flush_required(enc))
+		cpa_flush(&cpa, x86_platform.cc->enc_cache_flush_required());
+
+	/* Notify hypervisor that we are about to set/clr encryption attribute. */
+	x86_platform.cc->enc_status_change_prepare(addr, numpages, enc);
 
 	ret = __change_page_attr_set_clr(&cpa, 1);
 
@@ -2024,11 +2028,9 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	 */
 	cpa_flush(&cpa, 0);
 
-	/*
-	 * Notify hypervisor that a given memory range is mapped encrypted
-	 * or decrypted.
-	 */
-	notify_range_enc_status_changed(addr, numpages, enc);
+	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
+	if (!ret)
+		x86_platform.cc->enc_status_change_finish(addr, numpages, enc);
 
 	return ret;
 }
-- 
2.25.1


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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-22 20:08   ` Borislav Petkov
@ 2022-02-23  7:04     ` Tianyu Lan
  2022-02-23 10:41       ` Borislav Petkov
  0 siblings, 1 reply; 33+ messages in thread
From: Tianyu Lan @ 2022-02-23  7:04 UTC (permalink / raw)
  To: Borislav Petkov, Kirill A. Shutemov, Wei Liu
  Cc: tglx, mingo, dave.hansen, luto, peterz,
	sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Dexuan Cui, Tianyu Lan

On 2/23/2022 4:08 AM, Borislav Petkov wrote:
> On Tue, Feb 22, 2022 at 09:57:37PM +0300, Kirill A. Shutemov wrote:
>> On x86, cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) supposes to return
>> true for HyperV if isolation is supported. But it only does it if the
>> kernel is compiled with AMD_MEM_ENCRYPT enabled.
>>
>> It happens due to missed ARCH_HAS_CC_PLATFORM dependency. Without
>> ARCH_HAS_CC_PLATFORM enabled, cc_platform_has() always returns false.
>>
>> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
>> Cc: "K. Y. Srinivasan" <kys@microsoft.com>
>> Cc: Haiyang Zhang <haiyangz@microsoft.com>
>> Cc: Stephen Hemminger <sthemmin@microsoft.com>
>> Cc: Wei Liu <wei.liu@kernel.org>
>> Cc: Dexuan Cui <decui@microsoft.com>
>> Cc: Tianyu Lan <Tianyu.Lan@microsoft.com>
>> ---
>>   drivers/hv/Kconfig | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
>> index 0747a8f1fcee..424d3f0751dc 100644
>> --- a/drivers/hv/Kconfig
>> +++ b/drivers/hv/Kconfig
>> @@ -8,6 +8,7 @@ config HYPERV
>>   		|| (ARM64 && !CPU_BIG_ENDIAN))
>>   	select PARAVIRT
>>   	select X86_HV_CALLBACK_VECTOR if X86
>> +	select ARCH_HAS_CC_PLATFORM if x86
>>   	select VMAP_PFN
>>   	help
>>   	  Select this option to run Linux as a Hyper-V client operating
>> -- 
> 
> Good catch.
> 
> I'm guessing this needs
> 
> Fixes: c789b90a6904 ("x86/hyper-v: Add hyperv Isolation VM check in the cc_platform_has()")
> 
> which added hyperv_cc_platform_has() and which needs to go to Linus now,
> as an urgent fix for 5.17 as that patch came into 5.17-rc1.
> 
> Wei?
> 

Hi Borias, wei and Kill:
       Current Hyper-V Isolation VM requires AMD_MEM_ENCRYPT option 
which selects ARCH_HAS_CC_PLATFORM. Linux guest can't boot up without 
AMD_MEM_ENCRYPT option. So this is why not select ARCH_HAS_CC_PLATFORM
here.

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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-23  7:04     ` Tianyu Lan
@ 2022-02-23 10:41       ` Borislav Petkov
  2022-02-23 10:43         ` Tianyu Lan
  0 siblings, 1 reply; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 10:41 UTC (permalink / raw)
  To: Tianyu Lan
  Cc: Kirill A. Shutemov, Wei Liu, tglx, mingo, dave.hansen, luto,
	peterz, sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams,
	david, hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh,
	x86, linux-kernel, K. Y. Srinivasan, Haiyang Zhang,
	Stephen Hemminger, Dexuan Cui, Tianyu Lan

On Wed, Feb 23, 2022 at 03:04:41PM +0800, Tianyu Lan wrote:
>       Current Hyper-V Isolation VM requires AMD_MEM_ENCRYPT option which

Where is that isolation VM option? Out of tree?

Because

$ git grep AMD_MEM_ENCRYPT | grep Kconfig
arch/x86/Kconfig:1540:config AMD_MEM_ENCRYPT
arch/x86/Kconfig:1553:config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
arch/x86/Kconfig:1555:  depends on AMD_MEM_ENCRYPT

and those ain't it.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-23 10:41       ` Borislav Petkov
@ 2022-02-23 10:43         ` Tianyu Lan
  2022-02-23 10:56           ` Borislav Petkov
  0 siblings, 1 reply; 33+ messages in thread
From: Tianyu Lan @ 2022-02-23 10:43 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Kirill A. Shutemov, Wei Liu, tglx, mingo, dave.hansen, luto,
	peterz, sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams,
	david, hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh,
	x86, linux-kernel, K. Y. Srinivasan, Haiyang Zhang,
	Stephen Hemminger, Dexuan Cui, Tianyu Lan



On 2/23/2022 6:41 PM, Borislav Petkov wrote:
> On Wed, Feb 23, 2022 at 03:04:41PM +0800, Tianyu Lan wrote:
>>        Current Hyper-V Isolation VM requires AMD_MEM_ENCRYPT option which
> 
> Where is that isolation VM option? Out of tree?
> 
> Because
> 
> $ git grep AMD_MEM_ENCRYPT | grep Kconfig
> arch/x86/Kconfig:1540:config AMD_MEM_ENCRYPT
> arch/x86/Kconfig:1553:config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
> arch/x86/Kconfig:1555:  depends on AMD_MEM_ENCRYPT
> 
> and those ain't it.

Hyper-V code check cpuid during runtime and there is no Hyper-V
isolation VM option.



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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-23 10:43         ` Tianyu Lan
@ 2022-02-23 10:56           ` Borislav Petkov
  2022-02-23 11:02             ` Tianyu Lan
  0 siblings, 1 reply; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 10:56 UTC (permalink / raw)
  To: Tianyu Lan
  Cc: Kirill A. Shutemov, Wei Liu, tglx, mingo, dave.hansen, luto,
	peterz, sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams,
	david, hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh,
	x86, linux-kernel, K. Y. Srinivasan, Haiyang Zhang,
	Stephen Hemminger, Dexuan Cui, Tianyu Lan

On Wed, Feb 23, 2022 at 06:43:40PM +0800, Tianyu Lan wrote:
> Hyper-V code check cpuid during runtime and there is no Hyper-V
> isolation VM option.

So how does "Current Hyper-V Isolation VM requires AMD_MEM_ENCRYPT" work
exactly?

Please explain in detail and not in piecemeal sentences.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-23 10:56           ` Borislav Petkov
@ 2022-02-23 11:02             ` Tianyu Lan
  2022-02-23 11:47               ` Kirill A. Shutemov
  0 siblings, 1 reply; 33+ messages in thread
From: Tianyu Lan @ 2022-02-23 11:02 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Kirill A. Shutemov, Wei Liu, tglx, mingo, dave.hansen, luto,
	peterz, sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams,
	david, hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh,
	x86, linux-kernel, K. Y. Srinivasan, Haiyang Zhang,
	Stephen Hemminger, Dexuan Cui, Tianyu Lan

On 2/23/2022 6:56 PM, Borislav Petkov wrote:
> On Wed, Feb 23, 2022 at 06:43:40PM +0800, Tianyu Lan wrote:
>> Hyper-V code check cpuid during runtime and there is no Hyper-V
>> isolation VM option.
> 
> So how does "Current Hyper-V Isolation VM requires AMD_MEM_ENCRYPT" work
> exactly?
> 
> Please explain in detail and not in piecemeal sentences.
>
The kernel in the image needs to select AMD_MEM_ENCRYPT option
otherwise the kernel can't boot up due to missing SEV support and
sev_es_ghcb_hv_call() always return error.



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

* Re: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23  4:35 ` [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable() Brijesh Singh
@ 2022-02-23 11:31   ` Borislav Petkov
  2022-02-23 11:55     ` Kirill A. Shutemov
  2022-02-24 11:59   ` [tip: x86/cc] " tip-bot2 for Brijesh Singh
  1 sibling, 1 reply; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 11:31 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: x86, linux-kernel, kvm, linux-coco, Thomas Gleixner, Ingo Molnar,
	Joerg Roedel, Tom Lendacky, H. Peter Anvin, Paolo Bonzini,
	Sean Christopherson, Andy Lutomirski, Dave Hansen, Peter Gonda,
	Peter Zijlstra, David Rientjes, Michael Roth,
	Kirill A . Shutemov, Andi Kleen

On Tue, Feb 22, 2022 at 10:35:28PM -0600, Brijesh Singh wrote:
> Depends on Krill's CC cleanup
> https://lore.kernel.org/all/20220222185740.26228-1-kirill.shutemov@linux.intel.com/

I've massaged it into what it should be, see below.

The BUG_ON() is gone because we don't do BUG_ONs - if you had used
checkpatch, it would've told you. So I've added noops like that x86_init
stuff is usually done.

Anyway, Kirill, your turn. Is the below enough for TDX?

---
From daa6fb150e495511c699820bce925d89e55e96d4 Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Tue, 22 Feb 2022 22:35:28 -0600
Subject: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()

The kernel provides infrastructure to set or clear the encryption mask
from the pages for AMD SEV, but TDX requires few tweaks.

- TDX and SEV have different requirements to the cache and TLB
  flushing.

- TDX has own routine to notify VMM about page encryption status change.

Modify __set_memory_enc_pgtable() and make it flexible enough to cover
both AMD SEV and Intel TDX. The AMD-specific behavior is isolated in
callback under x86_platform_cc. TDX will provide own version of the
callbacks.

  [ bp: Beat into submission. ]

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20220223043528.2093214-1-brijesh.singh@amd.com
---
 arch/x86/include/asm/set_memory.h |  1 -
 arch/x86/include/asm/x86_init.h   | 16 +++++++
 arch/x86/kernel/x86_init.c        | 16 ++++++-
 arch/x86/mm/mem_encrypt_amd.c     | 71 +++++++++++++++++++++----------
 arch/x86/mm/pat/set_memory.c      | 18 ++++----
 5 files changed, 88 insertions(+), 34 deletions(-)

diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index ff0f2d90338a..ce8dd215f5b3 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -84,7 +84,6 @@ int set_pages_rw(struct page *page, int numpages);
 int set_direct_map_invalid_noflush(struct page *page);
 int set_direct_map_default_noflush(struct page *page);
 bool kernel_page_present(struct page *page);
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);
 
 extern int kernel_set_to_readonly;
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 22b7412c08f6..dfdcd3152f8d 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -141,6 +141,21 @@ struct x86_init_acpi {
 	void (*reduced_hw_early_init)(void);
 };
 
+/**
+ * struct x86_guest - Functions used by misc guest incarnations like SEV, TDX, etc.
+ *
+ * @enc_status_change_prepare	Notify HV before the encryption status of a range is changed
+ * @enc_status_change_finish	Notify HV after the encryption status of a range is changed
+ * @enc_tlb_flush_required	Returns true if a TLB flush is needed before changing page encryption status
+ * @enc_cache_flush_required	Returns true if a cache flush is needed before changing page encryption status
+ */
+struct x86_guest {
+	void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+	void (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+	bool (*enc_tlb_flush_required)(bool enc);
+	bool (*enc_cache_flush_required)(void);
+};
+
 /**
  * struct x86_init_ops - functions for platform specific setup
  *
@@ -287,6 +302,7 @@ struct x86_platform_ops {
 	struct x86_legacy_features legacy;
 	void (*set_legacy_features)(void);
 	struct x86_hyper_runtime hyper;
+	struct x86_guest guest;
 };
 
 struct x86_apic_ops {
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 7d20c1d34a3c..bb57410dde2d 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -129,6 +129,11 @@ struct x86_cpuinit_ops x86_cpuinit = {
 
 static void default_nmi_init(void) { };
 
+static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { }
+static void enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { }
+static bool enc_tlb_flush_required_noop(bool enc) { return false; }
+static bool enc_cache_flush_required_noop(void) { return false; }
+
 struct x86_platform_ops x86_platform __ro_after_init = {
 	.calibrate_cpu			= native_calibrate_cpu_early,
 	.calibrate_tsc			= native_calibrate_tsc,
@@ -138,9 +143,16 @@ struct x86_platform_ops x86_platform __ro_after_init = {
 	.is_untracked_pat_range		= is_ISA_range,
 	.nmi_init			= default_nmi_init,
 	.get_nmi_reason			= default_get_nmi_reason,
-	.save_sched_clock_state 	= tsc_save_sched_clock_state,
-	.restore_sched_clock_state 	= tsc_restore_sched_clock_state,
+	.save_sched_clock_state		= tsc_save_sched_clock_state,
+	.restore_sched_clock_state	= tsc_restore_sched_clock_state,
 	.hyper.pin_vcpu			= x86_op_int_noop,
+
+	.guest = {
+		.enc_status_change_prepare = enc_status_change_prepare_noop,
+		.enc_status_change_finish  = enc_status_change_finish_noop,
+		.enc_tlb_flush_required	   = enc_tlb_flush_required_noop,
+		.enc_cache_flush_required  = enc_cache_flush_required_noop,
+	},
 };
 
 EXPORT_SYMBOL_GPL(x86_platform);
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 2b2d018ea345..4c57c8988f37 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -177,25 +177,6 @@ void __init sme_map_bootdata(char *real_mode_data)
 	__sme_early_map_unmap_mem(__va(cmdline_paddr), COMMAND_LINE_SIZE, true);
 }
 
-void __init sme_early_init(void)
-{
-	unsigned int i;
-
-	if (!sme_me_mask)
-		return;
-
-	early_pmd_flags = __sme_set(early_pmd_flags);
-
-	__supported_pte_mask = __sme_set(__supported_pte_mask);
-
-	/* Update the protection map with memory encryption mask */
-	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
-		protection_map[i] = pgprot_encrypted(protection_map[i]);
-
-	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
-		swiotlb_force = SWIOTLB_FORCE;
-}
-
 void __init sev_setup_arch(void)
 {
 	phys_addr_t total_mem = memblock_phys_mem_size();
@@ -256,7 +237,17 @@ static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
 	return pfn;
 }
 
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
+static bool amd_enc_tlb_flush_required(bool enc)
+{
+	return true;
+}
+
+static bool amd_enc_cache_flush_required(void)
+{
+	return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT);
+}
+
+static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
 #ifdef CONFIG_PARAVIRT
 	unsigned long sz = npages << PAGE_SHIFT;
@@ -287,6 +278,18 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
 #endif
 }
 
+static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+{
+}
+
+static void amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+{
+	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+		return;
+
+	enc_dec_hypercall(vaddr, npages, enc);
+}
+
 static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
 {
 	pgprot_t old_prot, new_prot;
@@ -392,7 +395,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
 
 	ret = 0;
 
-	notify_range_enc_status_changed(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
+	early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
 out:
 	__flush_tlb_all();
 	return ret;
@@ -410,7 +413,31 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
 
 void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
-	notify_range_enc_status_changed(vaddr, npages, enc);
+	enc_dec_hypercall(vaddr, npages, enc);
+}
+
+void __init sme_early_init(void)
+{
+	unsigned int i;
+
+	if (!sme_me_mask)
+		return;
+
+	early_pmd_flags = __sme_set(early_pmd_flags);
+
+	__supported_pte_mask = __sme_set(__supported_pte_mask);
+
+	/* Update the protection map with memory encryption mask */
+	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
+		protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+		swiotlb_force = SWIOTLB_FORCE;
+
+	x86_platform.guest.enc_status_change_prepare = amd_enc_status_change_prepare;
+	x86_platform.guest.enc_status_change_finish  = amd_enc_status_change_finish;
+	x86_platform.guest.enc_tlb_flush_required    = amd_enc_tlb_flush_required;
+	x86_platform.guest.enc_cache_flush_required  = amd_enc_cache_flush_required;
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index af77dbfd143c..92c26828265c 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2008,10 +2008,12 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	kmap_flush_unused();
 	vm_unmap_aliases();
 
-	/*
-	 * Before changing the encryption attribute, we need to flush caches.
-	 */
-	cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
+	/* Flush the caches as needed before changing the encryption attribute. */
+	if (x86_platform.guest.enc_tlb_flush_required(enc))
+		cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
+
+	/* Notify hypervisor that we are about to set/clr encryption attribute. */
+	x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
 
 	ret = __change_page_attr_set_clr(&cpa, 1);
 
@@ -2024,11 +2026,9 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	 */
 	cpa_flush(&cpa, 0);
 
-	/*
-	 * Notify hypervisor that a given memory range is mapped encrypted
-	 * or decrypted.
-	 */
-	notify_range_enc_status_changed(addr, numpages, enc);
+	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
+	if (!ret)
+		x86_platform.guest.enc_status_change_finish(addr, numpages, enc);
 
 	return ret;
 }
-- 
2.29.2


-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-23 11:02             ` Tianyu Lan
@ 2022-02-23 11:47               ` Kirill A. Shutemov
  2022-02-23 14:09                 ` Tianyu Lan
  0 siblings, 1 reply; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-23 11:47 UTC (permalink / raw)
  To: Tianyu Lan
  Cc: Borislav Petkov, Wei Liu, tglx, mingo, dave.hansen, luto, peterz,
	sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Dexuan Cui, Tianyu Lan

On Wed, Feb 23, 2022 at 07:02:49PM +0800, Tianyu Lan wrote:
> On 2/23/2022 6:56 PM, Borislav Petkov wrote:
> > On Wed, Feb 23, 2022 at 06:43:40PM +0800, Tianyu Lan wrote:
> > > Hyper-V code check cpuid during runtime and there is no Hyper-V
> > > isolation VM option.
> > 
> > So how does "Current Hyper-V Isolation VM requires AMD_MEM_ENCRYPT" work
> > exactly?
> > 
> > Please explain in detail and not in piecemeal sentences.
> > 
> The kernel in the image needs to select AMD_MEM_ENCRYPT option
> otherwise the kernel can't boot up due to missing SEV support and
> sev_es_ghcb_hv_call() always return error.

If kernel boots under SEV, doesn't it mean we have 'sme_me_mask'
initialized? If it is non zero hv_is_isolation_supported() check in
cc_platform_has() has zero effect as it checked after 'sme_me_mask'.

I still have no idea what is going on.

How SEV related to HyperV isolation? How detection happens? Could you
give full picture?

-- 
 Kirill A. Shutemov

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

* Re: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23 11:31   ` Borislav Petkov
@ 2022-02-23 11:55     ` Kirill A. Shutemov
  2022-02-23 12:13       ` Borislav Petkov
  0 siblings, 1 reply; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-23 11:55 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Brijesh Singh, x86, linux-kernel, kvm, linux-coco,
	Thomas Gleixner, Ingo Molnar, Joerg Roedel, Tom Lendacky,
	H. Peter Anvin, Paolo Bonzini, Sean Christopherson,
	Andy Lutomirski, Dave Hansen, Peter Gonda, Peter Zijlstra,
	David Rientjes, Michael Roth, Andi Kleen

On Wed, Feb 23, 2022 at 12:31:56PM +0100, Borislav Petkov wrote:
> @@ -2024,11 +2026,9 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
>  	 */
>  	cpa_flush(&cpa, 0);
>  
> -	/*
> -	 * Notify hypervisor that a given memory range is mapped encrypted
> -	 * or decrypted.
> -	 */
> -	notify_range_enc_status_changed(addr, numpages, enc);
> +	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
> +	if (!ret)
> +		x86_platform.guest.enc_status_change_finish(addr, numpages, enc);
>  
>  	return ret;
>  }

This operation can fail for TDX. We need to be able to return error code
here:
	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
	if (!ret)
		ret = x86_platform.guest.enc_status_change_finish(addr, numpages, enc);

-- 
 Kirill A. Shutemov

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

* Re: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23 11:55     ` Kirill A. Shutemov
@ 2022-02-23 12:13       ` Borislav Petkov
  2022-02-23 12:25         ` Kirill A. Shutemov
  0 siblings, 1 reply; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 12:13 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: Brijesh Singh, x86, linux-kernel, kvm, linux-coco,
	Thomas Gleixner, Ingo Molnar, Joerg Roedel, Tom Lendacky,
	H. Peter Anvin, Paolo Bonzini, Sean Christopherson,
	Andy Lutomirski, Dave Hansen, Peter Gonda, Peter Zijlstra,
	David Rientjes, Michael Roth, Andi Kleen

On Wed, Feb 23, 2022 at 02:55:39PM +0300, Kirill A. Shutemov wrote:
> This operation can fail for TDX. We need to be able to return error code
> here:
> 	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
> 	if (!ret)
> 		ret = x86_platform.guest.enc_status_change_finish(addr, numpages, enc);

bool to state failure/success or you need to return a specific value?

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

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

* Re: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23 12:13       ` Borislav Petkov
@ 2022-02-23 12:25         ` Kirill A. Shutemov
  2022-02-23 12:38           ` Borislav Petkov
  0 siblings, 1 reply; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-23 12:25 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Brijesh Singh, x86, linux-kernel, kvm, linux-coco,
	Thomas Gleixner, Ingo Molnar, Joerg Roedel, Tom Lendacky,
	H. Peter Anvin, Paolo Bonzini, Sean Christopherson,
	Andy Lutomirski, Dave Hansen, Peter Gonda, Peter Zijlstra,
	David Rientjes, Michael Roth, Andi Kleen

On Wed, Feb 23, 2022 at 01:13:03PM +0100, Borislav Petkov wrote:
> On Wed, Feb 23, 2022 at 02:55:39PM +0300, Kirill A. Shutemov wrote:
> > This operation can fail for TDX. We need to be able to return error code
> > here:
> > 	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
> > 	if (!ret)
> > 		ret = x86_platform.guest.enc_status_change_finish(addr, numpages, enc);
> 
> bool to state failure/success or you need to return a specific value?

So far it is only success or failure. I used int and -EIO as failure.
bool is enough, but I don't see a reason not to use int.

-- 
 Kirill A. Shutemov

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

* Re: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23 12:25         ` Kirill A. Shutemov
@ 2022-02-23 12:38           ` Borislav Petkov
  2022-02-23 12:54             ` Kirill A. Shutemov
  2022-02-23 14:33             ` Brijesh Singh
  0 siblings, 2 replies; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 12:38 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: Brijesh Singh, x86, linux-kernel, kvm, linux-coco,
	Thomas Gleixner, Ingo Molnar, Joerg Roedel, Tom Lendacky,
	H. Peter Anvin, Paolo Bonzini, Sean Christopherson,
	Andy Lutomirski, Dave Hansen, Peter Gonda, Peter Zijlstra,
	David Rientjes, Michael Roth, Andi Kleen

On Wed, Feb 23, 2022 at 03:25:08PM +0300, Kirill A. Shutemov wrote:
> So far it is only success or failure. I used int and -EIO as failure.
> bool is enough, but I don't see a reason not to use int.

bool it is.

---
From 8855bca859d8768ac04bfcf5b4aeb9cf3c69295a Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Tue, 22 Feb 2022 22:35:28 -0600
Subject: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()

The kernel provides infrastructure to set or clear the encryption mask
from the pages for AMD SEV, but TDX requires few tweaks.

- TDX and SEV have different requirements to the cache and TLB
  flushing.

- TDX has own routine to notify VMM about page encryption status change.

Modify __set_memory_enc_pgtable() and make it flexible enough to cover
both AMD SEV and Intel TDX. The AMD-specific behavior is isolated in
callback under x86_platform_cc. TDX will provide own version of the
callbacks.

  [ bp: Beat into submission. ]

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20220223043528.2093214-1-brijesh.singh@amd.com
---
 arch/x86/include/asm/set_memory.h |  1 -
 arch/x86/include/asm/x86_init.h   | 16 +++++++
 arch/x86/kernel/x86_init.c        | 16 ++++++-
 arch/x86/mm/mem_encrypt_amd.c     | 72 +++++++++++++++++++++----------
 arch/x86/mm/pat/set_memory.c      | 22 +++++-----
 5 files changed, 92 insertions(+), 35 deletions(-)

diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index ff0f2d90338a..ce8dd215f5b3 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -84,7 +84,6 @@ int set_pages_rw(struct page *page, int numpages);
 int set_direct_map_invalid_noflush(struct page *page);
 int set_direct_map_default_noflush(struct page *page);
 bool kernel_page_present(struct page *page);
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);
 
 extern int kernel_set_to_readonly;
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 22b7412c08f6..e9170457697e 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -141,6 +141,21 @@ struct x86_init_acpi {
 	void (*reduced_hw_early_init)(void);
 };
 
+/**
+ * struct x86_guest - Functions used by misc guest incarnations like SEV, TDX, etc.
+ *
+ * @enc_status_change_prepare	Notify HV before the encryption status of a range is changed
+ * @enc_status_change_finish	Notify HV after the encryption status of a range is changed
+ * @enc_tlb_flush_required	Returns true if a TLB flush is needed before changing page encryption status
+ * @enc_cache_flush_required	Returns true if a cache flush is needed before changing page encryption status
+ */
+struct x86_guest {
+	void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+	bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+	bool (*enc_tlb_flush_required)(bool enc);
+	bool (*enc_cache_flush_required)(void);
+};
+
 /**
  * struct x86_init_ops - functions for platform specific setup
  *
@@ -287,6 +302,7 @@ struct x86_platform_ops {
 	struct x86_legacy_features legacy;
 	void (*set_legacy_features)(void);
 	struct x86_hyper_runtime hyper;
+	struct x86_guest guest;
 };
 
 struct x86_apic_ops {
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 7d20c1d34a3c..e84ee5cdbd8c 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -129,6 +129,11 @@ struct x86_cpuinit_ops x86_cpuinit = {
 
 static void default_nmi_init(void) { };
 
+static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { }
+static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return false; }
+static bool enc_tlb_flush_required_noop(bool enc) { return false; }
+static bool enc_cache_flush_required_noop(void) { return false; }
+
 struct x86_platform_ops x86_platform __ro_after_init = {
 	.calibrate_cpu			= native_calibrate_cpu_early,
 	.calibrate_tsc			= native_calibrate_tsc,
@@ -138,9 +143,16 @@ struct x86_platform_ops x86_platform __ro_after_init = {
 	.is_untracked_pat_range		= is_ISA_range,
 	.nmi_init			= default_nmi_init,
 	.get_nmi_reason			= default_get_nmi_reason,
-	.save_sched_clock_state 	= tsc_save_sched_clock_state,
-	.restore_sched_clock_state 	= tsc_restore_sched_clock_state,
+	.save_sched_clock_state		= tsc_save_sched_clock_state,
+	.restore_sched_clock_state	= tsc_restore_sched_clock_state,
 	.hyper.pin_vcpu			= x86_op_int_noop,
+
+	.guest = {
+		.enc_status_change_prepare = enc_status_change_prepare_noop,
+		.enc_status_change_finish  = enc_status_change_finish_noop,
+		.enc_tlb_flush_required	   = enc_tlb_flush_required_noop,
+		.enc_cache_flush_required  = enc_cache_flush_required_noop,
+	},
 };
 
 EXPORT_SYMBOL_GPL(x86_platform);
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 2b2d018ea345..9619a5833811 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -177,25 +177,6 @@ void __init sme_map_bootdata(char *real_mode_data)
 	__sme_early_map_unmap_mem(__va(cmdline_paddr), COMMAND_LINE_SIZE, true);
 }
 
-void __init sme_early_init(void)
-{
-	unsigned int i;
-
-	if (!sme_me_mask)
-		return;
-
-	early_pmd_flags = __sme_set(early_pmd_flags);
-
-	__supported_pte_mask = __sme_set(__supported_pte_mask);
-
-	/* Update the protection map with memory encryption mask */
-	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
-		protection_map[i] = pgprot_encrypted(protection_map[i]);
-
-	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
-		swiotlb_force = SWIOTLB_FORCE;
-}
-
 void __init sev_setup_arch(void)
 {
 	phys_addr_t total_mem = memblock_phys_mem_size();
@@ -256,7 +237,17 @@ static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
 	return pfn;
 }
 
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
+static bool amd_enc_tlb_flush_required(bool enc)
+{
+	return true;
+}
+
+static bool amd_enc_cache_flush_required(void)
+{
+	return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT);
+}
+
+static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
 #ifdef CONFIG_PARAVIRT
 	unsigned long sz = npages << PAGE_SHIFT;
@@ -287,6 +278,19 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
 #endif
 }
 
+static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+{
+}
+
+static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+{
+	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+		return false;
+
+	enc_dec_hypercall(vaddr, npages, enc);
+	return true;
+}
+
 static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
 {
 	pgprot_t old_prot, new_prot;
@@ -392,7 +396,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
 
 	ret = 0;
 
-	notify_range_enc_status_changed(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
+	early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
 out:
 	__flush_tlb_all();
 	return ret;
@@ -410,7 +414,31 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
 
 void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
-	notify_range_enc_status_changed(vaddr, npages, enc);
+	enc_dec_hypercall(vaddr, npages, enc);
+}
+
+void __init sme_early_init(void)
+{
+	unsigned int i;
+
+	if (!sme_me_mask)
+		return;
+
+	early_pmd_flags = __sme_set(early_pmd_flags);
+
+	__supported_pte_mask = __sme_set(__supported_pte_mask);
+
+	/* Update the protection map with memory encryption mask */
+	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
+		protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+		swiotlb_force = SWIOTLB_FORCE;
+
+	x86_platform.guest.enc_status_change_prepare = amd_enc_status_change_prepare;
+	x86_platform.guest.enc_status_change_finish  = amd_enc_status_change_finish;
+	x86_platform.guest.enc_tlb_flush_required    = amd_enc_tlb_flush_required;
+	x86_platform.guest.enc_cache_flush_required  = amd_enc_cache_flush_required;
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index af77dbfd143c..3b75262cfb27 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1989,8 +1989,8 @@ int set_memory_global(unsigned long addr, int numpages)
  */
 static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 {
-	struct cpa_data cpa;
 	pgprot_t empty = __pgprot(0);
+	struct cpa_data cpa;
 	int ret;
 
 	/* Should not be working on unaligned addresses */
@@ -2008,10 +2008,12 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	kmap_flush_unused();
 	vm_unmap_aliases();
 
-	/*
-	 * Before changing the encryption attribute, we need to flush caches.
-	 */
-	cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
+	/* Flush the caches as needed before changing the encryption attribute. */
+	if (x86_platform.guest.enc_tlb_flush_required(enc))
+		cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
+
+	/* Notify hypervisor that we are about to set/clr encryption attribute. */
+	x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
 
 	ret = __change_page_attr_set_clr(&cpa, 1);
 
@@ -2024,11 +2026,11 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	 */
 	cpa_flush(&cpa, 0);
 
-	/*
-	 * Notify hypervisor that a given memory range is mapped encrypted
-	 * or decrypted.
-	 */
-	notify_range_enc_status_changed(addr, numpages, enc);
+	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
+	if (!ret) {
+		if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
+			ret = -EIO;
+	}
 
 	return ret;
 }
-- 
2.29.2

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

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

* Re: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23 12:38           ` Borislav Petkov
@ 2022-02-23 12:54             ` Kirill A. Shutemov
  2022-02-23 14:33             ` Brijesh Singh
  1 sibling, 0 replies; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-23 12:54 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Brijesh Singh, x86, linux-kernel, kvm, linux-coco,
	Thomas Gleixner, Ingo Molnar, Joerg Roedel, Tom Lendacky,
	H. Peter Anvin, Paolo Bonzini, Sean Christopherson,
	Andy Lutomirski, Dave Hansen, Peter Gonda, Peter Zijlstra,
	David Rientjes, Michael Roth, Andi Kleen

On Wed, Feb 23, 2022 at 01:38:03PM +0100, Borislav Petkov wrote:
> On Wed, Feb 23, 2022 at 03:25:08PM +0300, Kirill A. Shutemov wrote:
> > So far it is only success or failure. I used int and -EIO as failure.
> > bool is enough, but I don't see a reason not to use int.
> 
> bool it is.
> 
> ---
> From 8855bca859d8768ac04bfcf5b4aeb9cf3c69295a Mon Sep 17 00:00:00 2001
> From: Brijesh Singh <brijesh.singh@amd.com>
> Date: Tue, 22 Feb 2022 22:35:28 -0600
> Subject: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
> 
> The kernel provides infrastructure to set or clear the encryption mask
> from the pages for AMD SEV, but TDX requires few tweaks.
> 
> - TDX and SEV have different requirements to the cache and TLB
>   flushing.
> 
> - TDX has own routine to notify VMM about page encryption status change.
> 
> Modify __set_memory_enc_pgtable() and make it flexible enough to cover
> both AMD SEV and Intel TDX. The AMD-specific behavior is isolated in
> callback under x86_platform_cc. TDX will provide own version of the

"under x86_platform.guest"

> callbacks.
> 
>   [ bp: Beat into submission. ]
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> Signed-off-by: Borislav Petkov <bp@suse.de>
> Link: https://lore.kernel.org/r/20220223043528.2093214-1-brijesh.singh@amd.com

Otherwise, LGTM:

Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>


-- 
 Kirill A. Shutemov

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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-23 11:47               ` Kirill A. Shutemov
@ 2022-02-23 14:09                 ` Tianyu Lan
  2022-02-23 15:46                   ` Kirill A. Shutemov
  0 siblings, 1 reply; 33+ messages in thread
From: Tianyu Lan @ 2022-02-23 14:09 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: Borislav Petkov, Wei Liu, tglx, mingo, dave.hansen, luto, peterz,
	sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Dexuan Cui, Tianyu Lan



On 2/23/2022 7:47 PM, Kirill A. Shutemov wrote:
> On Wed, Feb 23, 2022 at 07:02:49PM +0800, Tianyu Lan wrote:
>> On 2/23/2022 6:56 PM, Borislav Petkov wrote:
>>> On Wed, Feb 23, 2022 at 06:43:40PM +0800, Tianyu Lan wrote:
>>>> Hyper-V code check cpuid during runtime and there is no Hyper-V
>>>> isolation VM option.
>>>
>>> So how does "Current Hyper-V Isolation VM requires AMD_MEM_ENCRYPT" work
>>> exactly?
>>>
>>> Please explain in detail and not in piecemeal sentences.
>>>
>> The kernel in the image needs to select AMD_MEM_ENCRYPT option
>> otherwise the kernel can't boot up due to missing SEV support and
>> sev_es_ghcb_hv_call() always return error.
> 
> If kernel boots under SEV, doesn't it mean we have 'sme_me_mask'
> initialized? If it is non zero hv_is_isolation_supported() check in
> cc_platform_has() has zero effect as it checked after 'sme_me_mask'.
> 
> I still have no idea what is going on.
> 
> How SEV related to HyperV isolation? How detection happens? Could you
> give full picture?
> 

Hi Kriil:
      Current Hyper-V Isolation VM is unenlightened VM design. Hyper-V 
hides SEV capability from Linux guest and expose Hyper-V cpuid to show 
Hyper-V isolation VM capability. So sme_me_mask is zero in this case 
because SEV capability cpuid returns not-support.
      Hyper-V Isolation VM code uses some SEV API sev_es_ghcb_hv_call() 
to share code and so it's necessary to select AMD_MEM_ENCRYPT option for
Hyper-V Isolation VM.

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

* Re: [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23 12:38           ` Borislav Petkov
  2022-02-23 12:54             ` Kirill A. Shutemov
@ 2022-02-23 14:33             ` Brijesh Singh
  1 sibling, 0 replies; 33+ messages in thread
From: Brijesh Singh @ 2022-02-23 14:33 UTC (permalink / raw)
  To: Borislav Petkov, Kirill A. Shutemov
  Cc: brijesh.singh, x86, linux-kernel, kvm, linux-coco,
	Thomas Gleixner, Ingo Molnar, Joerg Roedel, Tom Lendacky,
	H. Peter Anvin, Paolo Bonzini, Sean Christopherson,
	Andy Lutomirski, Dave Hansen, Peter Gonda, Peter Zijlstra,
	David Rientjes, Michael Roth, Andi Kleen



On 2/23/22 06:38, Borislav Petkov wrote:
...

> +static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
> +{
> +}
> +
> +static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
> +{
> +	if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
> +		return false;
                        ^^^^^

We should return true otherwise set_memory_{decrypt,encrypt} will fail 
for the SME case.

thanks

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

* Re: [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency
  2022-02-23 14:09                 ` Tianyu Lan
@ 2022-02-23 15:46                   ` Kirill A. Shutemov
  0 siblings, 0 replies; 33+ messages in thread
From: Kirill A. Shutemov @ 2022-02-23 15:46 UTC (permalink / raw)
  To: Tianyu Lan
  Cc: Borislav Petkov, Wei Liu, tglx, mingo, dave.hansen, luto, peterz,
	sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, brijesh.singh, x86,
	linux-kernel, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Dexuan Cui, Tianyu Lan

On Wed, Feb 23, 2022 at 10:09:19PM +0800, Tianyu Lan wrote:
> 
> 
> On 2/23/2022 7:47 PM, Kirill A. Shutemov wrote:
> > On Wed, Feb 23, 2022 at 07:02:49PM +0800, Tianyu Lan wrote:
> > > On 2/23/2022 6:56 PM, Borislav Petkov wrote:
> > > > On Wed, Feb 23, 2022 at 06:43:40PM +0800, Tianyu Lan wrote:
> > > > > Hyper-V code check cpuid during runtime and there is no Hyper-V
> > > > > isolation VM option.
> > > > 
> > > > So how does "Current Hyper-V Isolation VM requires AMD_MEM_ENCRYPT" work
> > > > exactly?
> > > > 
> > > > Please explain in detail and not in piecemeal sentences.
> > > > 
> > > The kernel in the image needs to select AMD_MEM_ENCRYPT option
> > > otherwise the kernel can't boot up due to missing SEV support and
> > > sev_es_ghcb_hv_call() always return error.
> > 
> > If kernel boots under SEV, doesn't it mean we have 'sme_me_mask'
> > initialized? If it is non zero hv_is_isolation_supported() check in
> > cc_platform_has() has zero effect as it checked after 'sme_me_mask'.
> > 
> > I still have no idea what is going on.
> > 
> > How SEV related to HyperV isolation? How detection happens? Could you
> > give full picture?
> > 
> 
> Hi Kriil:
>      Current Hyper-V Isolation VM is unenlightened VM design. Hyper-V hides
> SEV capability from Linux guest and expose Hyper-V cpuid to show Hyper-V
> isolation VM capability. So sme_me_mask is zero in this case because SEV
> capability cpuid returns not-support.
>      Hyper-V Isolation VM code uses some SEV API sev_es_ghcb_hv_call() to
> share code and so it's necessary to select AMD_MEM_ENCRYPT option for
> Hyper-V Isolation VM.

Borislav, let's drop 1/4 and fold following fixup in 3/4.

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index c1c0123859b9..f9df31421d8c 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -345,7 +345,8 @@ static void __init ms_hyperv_init_platform(void)
 		 */
 		swiotlb_force = SWIOTLB_FORCE;
 #endif
-		if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE)
+		if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE &&
+		    IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT))
 			cc_set_vendor(CC_VENDOR_HYPERV);
 	}
 
-- 
 Kirill A. Shutemov

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

* Re: [PATCH 0/4] x86: Cleanup and extend computing computing API
  2022-02-22 18:57 [PATCH 0/4] x86: Cleanup and extend computing computing API Kirill A. Shutemov
                   ` (5 preceding siblings ...)
  2022-02-23  4:35 ` [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable() Brijesh Singh
@ 2022-02-23 19:10 ` Borislav Petkov
  2022-02-23 19:17   ` [PATCH 1/4] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c} Borislav Petkov
                     ` (3 more replies)
  6 siblings, 4 replies; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 19:10 UTC (permalink / raw)
  To: Kirill A. Shutemov, Brijesh Singh
  Cc: tglx, mingo, dave.hansen, luto, peterz,
	sathyanarayanan.kuppuswamy, aarcange, ak, dan.j.williams, david,
	hpa, jmattson, seanjc, thomas.lendacky, x86, linux-kernel

On Tue, Feb 22, 2022 at 09:57:36PM +0300, Kirill A. Shutemov wrote:
> Updates for CC API:

Ok, I think I've incorporated all the feedback and initial build smoke
tests pass. I'll let it run overnight and if there's no hickups, will
queue them tomorrow.

If you still see issues, holler.

Sending them as a reply to this message.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

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

* [PATCH 1/4] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c}
  2022-02-23 19:10 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Borislav Petkov
@ 2022-02-23 19:17   ` Borislav Petkov
  2022-02-23 19:17   ` [PATCH 2/4] x86/coco: Explicitly declare type of confidential computing platform Borislav Petkov
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 19:17 UTC (permalink / raw)
  To: Kirill A. Shutemov, Brijesh Singh
  Cc: X86 ML, LKML, Tom Lendacky, sathyanarayanan.kuppuswamy, aarcange,
	ak, dan.j.williams, david, hpa, jmattson, seanjc

From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>

Move cc_platform.c to arch/x86/coco/. The directory is going to be the
home space for code related to confidential computing.

Intel TDX code will land here. AMD SEV code will also eventually be
moved there.

No functional changes.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Link: https://lore.kernel.org/r/20220222185740.26228-3-kirill.shutemov@linux.intel.com
---
 arch/x86/Kbuild                                | 2 ++
 arch/x86/coco/Makefile                         | 6 ++++++
 arch/x86/{kernel/cc_platform.c => coco/core.c} | 0
 arch/x86/kernel/Makefile                       | 5 -----
 4 files changed, 8 insertions(+), 5 deletions(-)
 create mode 100644 arch/x86/coco/Makefile
 rename arch/x86/{kernel/cc_platform.c => coco/core.c} (100%)

diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index f384cb1a4f7a..5a83da703e87 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_ARCH_HAS_CC_PLATFORM) += coco/
+
 obj-y += entry/
 
 obj-$(CONFIG_PERF_EVENTS) += events/
diff --git a/arch/x86/coco/Makefile b/arch/x86/coco/Makefile
new file mode 100644
index 000000000000..c1ead00017a7
--- /dev/null
+++ b/arch/x86/coco/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+CFLAGS_REMOVE_core.o	= -pg
+KASAN_SANITIZE_core.o	:= n
+CFLAGS_core.o		+= -fno-stack-protector
+
+obj-y += core.o
diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/coco/core.c
similarity index 100%
rename from arch/x86/kernel/cc_platform.c
rename to arch/x86/coco/core.c
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 6aef9ee28a39..6462e3dd98f4 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -21,7 +21,6 @@ CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
 CFLAGS_REMOVE_head64.o = -pg
 CFLAGS_REMOVE_sev.o = -pg
-CFLAGS_REMOVE_cc_platform.o = -pg
 endif
 
 KASAN_SANITIZE_head$(BITS).o				:= n
@@ -30,7 +29,6 @@ KASAN_SANITIZE_dumpstack_$(BITS).o			:= n
 KASAN_SANITIZE_stacktrace.o				:= n
 KASAN_SANITIZE_paravirt.o				:= n
 KASAN_SANITIZE_sev.o					:= n
-KASAN_SANITIZE_cc_platform.o				:= n
 
 # With some compiler versions the generated code results in boot hangs, caused
 # by several compilation units. To be safe, disable all instrumentation.
@@ -49,7 +47,6 @@ endif
 KCOV_INSTRUMENT		:= n
 
 CFLAGS_head$(BITS).o	+= -fno-stack-protector
-CFLAGS_cc_platform.o	+= -fno-stack-protector
 
 CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace
 
@@ -151,8 +148,6 @@ obj-$(CONFIG_UNWINDER_GUESS)		+= unwind_guess.o
 
 obj-$(CONFIG_AMD_MEM_ENCRYPT)		+= sev.o
 
-obj-$(CONFIG_ARCH_HAS_CC_PLATFORM)	+= cc_platform.o
-
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
-- 
2.29.2


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

* [PATCH 2/4] x86/coco: Explicitly declare type of confidential computing platform
  2022-02-23 19:10 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Borislav Petkov
  2022-02-23 19:17   ` [PATCH 1/4] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c} Borislav Petkov
@ 2022-02-23 19:17   ` Borislav Petkov
  2022-02-23 19:17   ` [PATCH 3/4] x86/coco: Add API to handle encryption mask Borislav Petkov
  2022-02-23 19:17   ` [PATCH 4/4] x86/mm/cpa: Generalize __set_memory_enc_pgtable() Borislav Petkov
  3 siblings, 0 replies; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 19:17 UTC (permalink / raw)
  To: Kirill A. Shutemov, Brijesh Singh
  Cc: X86 ML, LKML, Tom Lendacky, sathyanarayanan.kuppuswamy, aarcange,
	ak, dan.j.williams, david, hpa, jmattson, seanjc

From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>

The kernel derives the confidential computing platform
type it is running as from sme_me_mask on AMD or by using
hv_is_isolation_supported() on HyperV isolation VMs. This detection
process will be more complicated as more platforms get added.

Declare a confidential computing vendor variable explicitly and set it
via cc_set_vendor() on the respective platform.

  [ bp: Massage commit message, fixup HyperV check. ]

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Link: https://lore.kernel.org/r/20220222185740.26228-4-kirill.shutemov@linux.intel.com
---
 arch/x86/coco/core.c               | 29 +++++++++++++++++------------
 arch/x86/include/asm/coco.h        | 14 ++++++++++++++
 arch/x86/kernel/cpu/mshyperv.c     |  6 ++++++
 arch/x86/mm/mem_encrypt_identity.c | 11 +++++++----
 4 files changed, 44 insertions(+), 16 deletions(-)
 create mode 100644 arch/x86/include/asm/coco.h

diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index 6a6ffcd978f6..476dcd198af5 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -9,18 +9,15 @@
 
 #include <linux/export.h>
 #include <linux/cc_platform.h>
-#include <linux/mem_encrypt.h>
 
-#include <asm/mshyperv.h>
+#include <asm/coco.h>
 #include <asm/processor.h>
 
-static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
+static enum cc_vendor vendor __ro_after_init;
+
+static bool intel_cc_platform_has(enum cc_attr attr)
 {
-#ifdef CONFIG_INTEL_TDX_GUEST
-	return false;
-#else
 	return false;
-#endif
 }
 
 /*
@@ -74,12 +71,20 @@ static bool hyperv_cc_platform_has(enum cc_attr attr)
 
 bool cc_platform_has(enum cc_attr attr)
 {
-	if (sme_me_mask)
+	switch (vendor) {
+	case CC_VENDOR_AMD:
 		return amd_cc_platform_has(attr);
-
-	if (hv_is_isolation_supported())
+	case CC_VENDOR_INTEL:
+		return intel_cc_platform_has(attr);
+	case CC_VENDOR_HYPERV:
 		return hyperv_cc_platform_has(attr);
-
-	return false;
+	default:
+		return false;
+	}
 }
 EXPORT_SYMBOL_GPL(cc_platform_has);
+
+__init void cc_set_vendor(enum cc_vendor v)
+{
+	vendor = v;
+}
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
new file mode 100644
index 000000000000..e49f9ddb6ae6
--- /dev/null
+++ b/arch/x86/include/asm/coco.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_COCO_H
+#define _ASM_X86_COCO_H
+
+enum cc_vendor {
+	CC_VENDOR_NONE,
+	CC_VENDOR_AMD,
+	CC_VENDOR_HYPERV,
+	CC_VENDOR_INTEL,
+};
+
+void cc_set_vendor(enum cc_vendor v);
+
+#endif /* _ASM_X86_COCO_H */
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 5a99f993e639..e0a572472052 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -33,6 +33,7 @@
 #include <asm/nmi.h>
 #include <clocksource/hyperv_timer.h>
 #include <asm/numa.h>
+#include <asm/coco.h>
 
 /* Is Linux running as the root partition? */
 bool hv_root_partition;
@@ -344,6 +345,11 @@ static void __init ms_hyperv_init_platform(void)
 		 */
 		swiotlb_force = SWIOTLB_FORCE;
 #endif
+		/* Isolation VMs are unenlightened SEV-based VMs, thus this check: */
+		if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
+			if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE)
+				cc_set_vendor(CC_VENDOR_HYPERV);
+		}
 	}
 
 	if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index 3f0abb403340..06314ae3998e 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -44,6 +44,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/cmdline.h>
+#include <asm/coco.h>
 
 #include "mm_internal.h"
 
@@ -565,8 +566,7 @@ void __init sme_enable(struct boot_params *bp)
 	} else {
 		/* SEV state cannot be controlled by a command line option */
 		sme_me_mask = me_mask;
-		physical_mask &= ~sme_me_mask;
-		return;
+		goto out;
 	}
 
 	/*
@@ -600,6 +600,9 @@ void __init sme_enable(struct boot_params *bp)
 		sme_me_mask = 0;
 	else
 		sme_me_mask = active_by_default ? me_mask : 0;
-
-	physical_mask &= ~sme_me_mask;
+out:
+	if (sme_me_mask) {
+		physical_mask &= ~sme_me_mask;
+		cc_set_vendor(CC_VENDOR_AMD);
+	}
 }
-- 
2.29.2


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

* [PATCH 3/4] x86/coco: Add API to handle encryption mask
  2022-02-23 19:10 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Borislav Petkov
  2022-02-23 19:17   ` [PATCH 1/4] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c} Borislav Petkov
  2022-02-23 19:17   ` [PATCH 2/4] x86/coco: Explicitly declare type of confidential computing platform Borislav Petkov
@ 2022-02-23 19:17   ` Borislav Petkov
  2022-02-23 19:17   ` [PATCH 4/4] x86/mm/cpa: Generalize __set_memory_enc_pgtable() Borislav Petkov
  3 siblings, 0 replies; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 19:17 UTC (permalink / raw)
  To: Kirill A. Shutemov, Brijesh Singh
  Cc: X86 ML, LKML, Tom Lendacky, sathyanarayanan.kuppuswamy, aarcange,
	ak, dan.j.williams, david, hpa, jmattson, seanjc

From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>

AMD SME/SEV uses a bit in the page table entries to indicate that the
page is encrypted and not accessible to the VMM.

TDX uses a similar approach, but the polarity of the mask is opposite to
AMD: if the bit is set the page is accessible to VMM.

Provide vendor-neutral API to deal with the mask: cc_mkenc() and
cc_mkdec() modify given address to make it encrypted/decrypted. It can
be applied to phys_addr_t, pgprotval_t or page table entry value.

pgprot_encrypted() and pgprot_decrypted() reimplemented using new
helpers.

The implementation will be extended to cover TDX.

pgprot_decrypted() is used by drivers (i915, virtio_gpu, vfio).
cc_mkdec() called by pgprot_decrypted(). Export cc_mkdec().

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Link: https://lore.kernel.org/r/20220222185740.26228-5-kirill.shutemov@linux.intel.com
---
 arch/x86/coco/core.c               | 27 +++++++++++++++++++++++++++
 arch/x86/include/asm/coco.h        | 18 ++++++++++++++++++
 arch/x86/include/asm/pgtable.h     | 13 +++++++------
 arch/x86/mm/mem_encrypt_identity.c |  1 +
 arch/x86/mm/pat/set_memory.c       |  5 +++--
 5 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index 476dcd198af5..fc1365dd927e 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 
 static enum cc_vendor vendor __ro_after_init;
+static u64 cc_mask __ro_after_init;
 
 static bool intel_cc_platform_has(enum cc_attr attr)
 {
@@ -84,7 +85,33 @@ bool cc_platform_has(enum cc_attr attr)
 }
 EXPORT_SYMBOL_GPL(cc_platform_has);
 
+u64 cc_mkenc(u64 val)
+{
+	switch (vendor) {
+	case CC_VENDOR_AMD:
+		return val | cc_mask;
+	default:
+		return val;
+	}
+}
+
+u64 cc_mkdec(u64 val)
+{
+	switch (vendor) {
+	case CC_VENDOR_AMD:
+		return val & ~cc_mask;
+	default:
+		return val;
+	}
+}
+EXPORT_SYMBOL_GPL(cc_mkdec);
+
 __init void cc_set_vendor(enum cc_vendor v)
 {
 	vendor = v;
 }
+
+__init void cc_set_mask(u64 mask)
+{
+	cc_mask = mask;
+}
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
index e49f9ddb6ae6..3d98c3a60d34 100644
--- a/arch/x86/include/asm/coco.h
+++ b/arch/x86/include/asm/coco.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_COCO_H
 #define _ASM_X86_COCO_H
 
+#include <asm/types.h>
+
 enum cc_vendor {
 	CC_VENDOR_NONE,
 	CC_VENDOR_AMD,
@@ -10,5 +12,21 @@ enum cc_vendor {
 };
 
 void cc_set_vendor(enum cc_vendor v);
+void cc_set_mask(u64 mask);
+
+#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
+u64 cc_mkenc(u64 val);
+u64 cc_mkdec(u64 val);
+#else
+static inline u64 cc_mkenc(u64 val)
+{
+	return val;
+}
+
+static inline u64 cc_mkdec(u64 val)
+{
+	return val;
+}
+#endif
 
 #endif /* _ASM_X86_COCO_H */
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 8a9432fb3802..62ab07e24aef 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -15,17 +15,12 @@
 		     cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS)))	\
 	 : (prot))
 
-/*
- * Macros to add or remove encryption attribute
- */
-#define pgprot_encrypted(prot)	__pgprot(__sme_set(pgprot_val(prot)))
-#define pgprot_decrypted(prot)	__pgprot(__sme_clr(pgprot_val(prot)))
-
 #ifndef __ASSEMBLY__
 #include <linux/spinlock.h>
 #include <asm/x86_init.h>
 #include <asm/pkru.h>
 #include <asm/fpu/api.h>
+#include <asm/coco.h>
 #include <asm-generic/pgtable_uffd.h>
 #include <linux/page_table_check.h>
 
@@ -38,6 +33,12 @@ void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
 void ptdump_walk_pgd_level_checkwx(void);
 void ptdump_walk_user_pgd_level_checkwx(void);
 
+/*
+ * Macros to add or remove encryption attribute
+ */
+#define pgprot_encrypted(prot)	__pgprot(cc_mkenc(pgprot_val(prot)))
+#define pgprot_decrypted(prot)	__pgprot(cc_mkdec(pgprot_val(prot)))
+
 #ifdef CONFIG_DEBUG_WX
 #define debug_checkwx()		ptdump_walk_pgd_level_checkwx()
 #define debug_checkwx_user()	ptdump_walk_user_pgd_level_checkwx()
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index 06314ae3998e..b43bc24d2bb6 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -604,5 +604,6 @@ void __init sme_enable(struct boot_params *bp)
 	if (sme_me_mask) {
 		physical_mask &= ~sme_me_mask;
 		cc_set_vendor(CC_VENDOR_AMD);
+		cc_set_mask(sme_me_mask);
 	}
 }
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index b4072115c8ef..1441db69cea5 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1989,6 +1989,7 @@ int set_memory_global(unsigned long addr, int numpages)
  */
 static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 {
+	pgprot_t empty = __pgprot(0);
 	struct cpa_data cpa;
 	int ret;
 
@@ -1999,8 +2000,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	memset(&cpa, 0, sizeof(cpa));
 	cpa.vaddr = &addr;
 	cpa.numpages = numpages;
-	cpa.mask_set = enc ? __pgprot(_PAGE_ENC) : __pgprot(0);
-	cpa.mask_clr = enc ? __pgprot(0) : __pgprot(_PAGE_ENC);
+	cpa.mask_set = enc ? pgprot_encrypted(empty) : pgprot_decrypted(empty);
+	cpa.mask_clr = enc ? pgprot_decrypted(empty) : pgprot_encrypted(empty);
 	cpa.pgd = init_mm.pgd;
 
 	/* Must avoid aliasing mappings in the highmem code */
-- 
2.29.2


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

* [PATCH 4/4] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23 19:10 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Borislav Petkov
                     ` (2 preceding siblings ...)
  2022-02-23 19:17   ` [PATCH 3/4] x86/coco: Add API to handle encryption mask Borislav Petkov
@ 2022-02-23 19:17   ` Borislav Petkov
  3 siblings, 0 replies; 33+ messages in thread
From: Borislav Petkov @ 2022-02-23 19:17 UTC (permalink / raw)
  To: Kirill A. Shutemov, Brijesh Singh
  Cc: X86 ML, LKML, sathyanarayanan.kuppuswamy, aarcange, ak,
	dan.j.williams, david, hpa, jmattson, seanjc, thomas.lendacky

From: Brijesh Singh <brijesh.singh@amd.com>

The kernel provides infrastructure to set or clear the encryption mask
from the pages for AMD SEV, but TDX requires few tweaks.

- TDX and SEV have different requirements to the cache and TLB
  flushing.

- TDX has own routine to notify VMM about page encryption status change.

Modify __set_memory_enc_pgtable() and make it flexible enough to cover
both AMD SEV and Intel TDX. The AMD-specific behavior is isolated in the
callbacks under x86_platform.guest. TDX will provide own version of said
callbacks.

  [ bp: Beat into submission. ]

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Link: https://lore.kernel.org/r/20220223043528.2093214-1-brijesh.singh@amd.com
---
 arch/x86/include/asm/set_memory.h |  1 -
 arch/x86/include/asm/x86_init.h   | 16 +++++++
 arch/x86/kernel/x86_init.c        | 16 ++++++-
 arch/x86/mm/mem_encrypt_amd.c     | 72 +++++++++++++++++++++----------
 arch/x86/mm/pat/set_memory.c      | 20 +++++----
 5 files changed, 91 insertions(+), 34 deletions(-)

diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index ff0f2d90338a..ce8dd215f5b3 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -84,7 +84,6 @@ int set_pages_rw(struct page *page, int numpages);
 int set_direct_map_invalid_noflush(struct page *page);
 int set_direct_map_default_noflush(struct page *page);
 bool kernel_page_present(struct page *page);
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);
 
 extern int kernel_set_to_readonly;
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 22b7412c08f6..e9170457697e 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -141,6 +141,21 @@ struct x86_init_acpi {
 	void (*reduced_hw_early_init)(void);
 };
 
+/**
+ * struct x86_guest - Functions used by misc guest incarnations like SEV, TDX, etc.
+ *
+ * @enc_status_change_prepare	Notify HV before the encryption status of a range is changed
+ * @enc_status_change_finish	Notify HV after the encryption status of a range is changed
+ * @enc_tlb_flush_required	Returns true if a TLB flush is needed before changing page encryption status
+ * @enc_cache_flush_required	Returns true if a cache flush is needed before changing page encryption status
+ */
+struct x86_guest {
+	void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+	bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+	bool (*enc_tlb_flush_required)(bool enc);
+	bool (*enc_cache_flush_required)(void);
+};
+
 /**
  * struct x86_init_ops - functions for platform specific setup
  *
@@ -287,6 +302,7 @@ struct x86_platform_ops {
 	struct x86_legacy_features legacy;
 	void (*set_legacy_features)(void);
 	struct x86_hyper_runtime hyper;
+	struct x86_guest guest;
 };
 
 struct x86_apic_ops {
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 7d20c1d34a3c..e84ee5cdbd8c 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -129,6 +129,11 @@ struct x86_cpuinit_ops x86_cpuinit = {
 
 static void default_nmi_init(void) { };
 
+static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { }
+static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return false; }
+static bool enc_tlb_flush_required_noop(bool enc) { return false; }
+static bool enc_cache_flush_required_noop(void) { return false; }
+
 struct x86_platform_ops x86_platform __ro_after_init = {
 	.calibrate_cpu			= native_calibrate_cpu_early,
 	.calibrate_tsc			= native_calibrate_tsc,
@@ -138,9 +143,16 @@ struct x86_platform_ops x86_platform __ro_after_init = {
 	.is_untracked_pat_range		= is_ISA_range,
 	.nmi_init			= default_nmi_init,
 	.get_nmi_reason			= default_get_nmi_reason,
-	.save_sched_clock_state 	= tsc_save_sched_clock_state,
-	.restore_sched_clock_state 	= tsc_restore_sched_clock_state,
+	.save_sched_clock_state		= tsc_save_sched_clock_state,
+	.restore_sched_clock_state	= tsc_restore_sched_clock_state,
 	.hyper.pin_vcpu			= x86_op_int_noop,
+
+	.guest = {
+		.enc_status_change_prepare = enc_status_change_prepare_noop,
+		.enc_status_change_finish  = enc_status_change_finish_noop,
+		.enc_tlb_flush_required	   = enc_tlb_flush_required_noop,
+		.enc_cache_flush_required  = enc_cache_flush_required_noop,
+	},
 };
 
 EXPORT_SYMBOL_GPL(x86_platform);
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 2b2d018ea345..6169053c2854 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -177,25 +177,6 @@ void __init sme_map_bootdata(char *real_mode_data)
 	__sme_early_map_unmap_mem(__va(cmdline_paddr), COMMAND_LINE_SIZE, true);
 }
 
-void __init sme_early_init(void)
-{
-	unsigned int i;
-
-	if (!sme_me_mask)
-		return;
-
-	early_pmd_flags = __sme_set(early_pmd_flags);
-
-	__supported_pte_mask = __sme_set(__supported_pte_mask);
-
-	/* Update the protection map with memory encryption mask */
-	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
-		protection_map[i] = pgprot_encrypted(protection_map[i]);
-
-	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
-		swiotlb_force = SWIOTLB_FORCE;
-}
-
 void __init sev_setup_arch(void)
 {
 	phys_addr_t total_mem = memblock_phys_mem_size();
@@ -256,7 +237,17 @@ static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
 	return pfn;
 }
 
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
+static bool amd_enc_tlb_flush_required(bool enc)
+{
+	return true;
+}
+
+static bool amd_enc_cache_flush_required(void)
+{
+	return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT);
+}
+
+static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
 #ifdef CONFIG_PARAVIRT
 	unsigned long sz = npages << PAGE_SHIFT;
@@ -287,6 +278,19 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
 #endif
 }
 
+static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+{
+}
+
+/* Return true unconditionally: return value doesn't matter for the SEV side */
+static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+{
+	if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+		enc_dec_hypercall(vaddr, npages, enc);
+
+	return true;
+}
+
 static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
 {
 	pgprot_t old_prot, new_prot;
@@ -392,7 +396,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
 
 	ret = 0;
 
-	notify_range_enc_status_changed(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
+	early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
 out:
 	__flush_tlb_all();
 	return ret;
@@ -410,7 +414,31 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
 
 void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
-	notify_range_enc_status_changed(vaddr, npages, enc);
+	enc_dec_hypercall(vaddr, npages, enc);
+}
+
+void __init sme_early_init(void)
+{
+	unsigned int i;
+
+	if (!sme_me_mask)
+		return;
+
+	early_pmd_flags = __sme_set(early_pmd_flags);
+
+	__supported_pte_mask = __sme_set(__supported_pte_mask);
+
+	/* Update the protection map with memory encryption mask */
+	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
+		protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+		swiotlb_force = SWIOTLB_FORCE;
+
+	x86_platform.guest.enc_status_change_prepare = amd_enc_status_change_prepare;
+	x86_platform.guest.enc_status_change_finish  = amd_enc_status_change_finish;
+	x86_platform.guest.enc_tlb_flush_required    = amd_enc_tlb_flush_required;
+	x86_platform.guest.enc_cache_flush_required  = amd_enc_cache_flush_required;
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 1441db69cea5..3b75262cfb27 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2008,10 +2008,12 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	kmap_flush_unused();
 	vm_unmap_aliases();
 
-	/*
-	 * Before changing the encryption attribute, we need to flush caches.
-	 */
-	cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
+	/* Flush the caches as needed before changing the encryption attribute. */
+	if (x86_platform.guest.enc_tlb_flush_required(enc))
+		cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
+
+	/* Notify hypervisor that we are about to set/clr encryption attribute. */
+	x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
 
 	ret = __change_page_attr_set_clr(&cpa, 1);
 
@@ -2024,11 +2026,11 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	 */
 	cpa_flush(&cpa, 0);
 
-	/*
-	 * Notify hypervisor that a given memory range is mapped encrypted
-	 * or decrypted.
-	 */
-	notify_range_enc_status_changed(addr, numpages, enc);
+	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
+	if (!ret) {
+		if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
+			ret = -EIO;
+	}
 
 	return ret;
 }
-- 
2.29.2


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

* [tip: x86/cc] x86/mm/cpa: Generalize __set_memory_enc_pgtable()
  2022-02-23  4:35 ` [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable() Brijesh Singh
  2022-02-23 11:31   ` Borislav Petkov
@ 2022-02-24 11:59   ` tip-bot2 for Brijesh Singh
  1 sibling, 0 replies; 33+ messages in thread
From: tip-bot2 for Brijesh Singh @ 2022-02-24 11:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Brijesh Singh, Borislav Petkov, Kirill A. Shutemov, x86, linux-kernel

The following commit has been merged into the x86/cc branch of tip:

Commit-ID:     1e8c5971c249893ac33ca983c32bafcf5d50c727
Gitweb:        https://git.kernel.org/tip/1e8c5971c249893ac33ca983c32bafcf5d50c727
Author:        Brijesh Singh <brijesh.singh@amd.com>
AuthorDate:    Tue, 22 Feb 2022 22:35:28 -06:00
Committer:     Borislav Petkov <bp@suse.de>
CommitterDate: Wed, 23 Feb 2022 19:14:29 +01:00

x86/mm/cpa: Generalize __set_memory_enc_pgtable()

The kernel provides infrastructure to set or clear the encryption mask
from the pages for AMD SEV, but TDX requires few tweaks.

- TDX and SEV have different requirements to the cache and TLB
  flushing.

- TDX has own routine to notify VMM about page encryption status change.

Modify __set_memory_enc_pgtable() and make it flexible enough to cover
both AMD SEV and Intel TDX. The AMD-specific behavior is isolated in the
callbacks under x86_platform.guest. TDX will provide own version of said
callbacks.

  [ bp: Beat into submission. ]

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Link: https://lore.kernel.org/r/20220223043528.2093214-1-brijesh.singh@amd.com
---
 arch/x86/include/asm/set_memory.h |  1 +-
 arch/x86/include/asm/x86_init.h   | 16 +++++++-
 arch/x86/kernel/x86_init.c        | 16 ++++++-
 arch/x86/mm/mem_encrypt_amd.c     | 72 ++++++++++++++++++++----------
 arch/x86/mm/pat/set_memory.c      | 20 ++++----
 5 files changed, 91 insertions(+), 34 deletions(-)

diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index ff0f2d9..ce8dd21 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -84,7 +84,6 @@ int set_pages_rw(struct page *page, int numpages);
 int set_direct_map_invalid_noflush(struct page *page);
 int set_direct_map_default_noflush(struct page *page);
 bool kernel_page_present(struct page *page);
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);
 
 extern int kernel_set_to_readonly;
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 22b7412..e917045 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -142,6 +142,21 @@ struct x86_init_acpi {
 };
 
 /**
+ * struct x86_guest - Functions used by misc guest incarnations like SEV, TDX, etc.
+ *
+ * @enc_status_change_prepare	Notify HV before the encryption status of a range is changed
+ * @enc_status_change_finish	Notify HV after the encryption status of a range is changed
+ * @enc_tlb_flush_required	Returns true if a TLB flush is needed before changing page encryption status
+ * @enc_cache_flush_required	Returns true if a cache flush is needed before changing page encryption status
+ */
+struct x86_guest {
+	void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+	bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+	bool (*enc_tlb_flush_required)(bool enc);
+	bool (*enc_cache_flush_required)(void);
+};
+
+/**
  * struct x86_init_ops - functions for platform specific setup
  *
  */
@@ -287,6 +302,7 @@ struct x86_platform_ops {
 	struct x86_legacy_features legacy;
 	void (*set_legacy_features)(void);
 	struct x86_hyper_runtime hyper;
+	struct x86_guest guest;
 };
 
 struct x86_apic_ops {
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 7d20c1d..e84ee5c 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -129,6 +129,11 @@ struct x86_cpuinit_ops x86_cpuinit = {
 
 static void default_nmi_init(void) { };
 
+static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { }
+static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return false; }
+static bool enc_tlb_flush_required_noop(bool enc) { return false; }
+static bool enc_cache_flush_required_noop(void) { return false; }
+
 struct x86_platform_ops x86_platform __ro_after_init = {
 	.calibrate_cpu			= native_calibrate_cpu_early,
 	.calibrate_tsc			= native_calibrate_tsc,
@@ -138,9 +143,16 @@ struct x86_platform_ops x86_platform __ro_after_init = {
 	.is_untracked_pat_range		= is_ISA_range,
 	.nmi_init			= default_nmi_init,
 	.get_nmi_reason			= default_get_nmi_reason,
-	.save_sched_clock_state 	= tsc_save_sched_clock_state,
-	.restore_sched_clock_state 	= tsc_restore_sched_clock_state,
+	.save_sched_clock_state		= tsc_save_sched_clock_state,
+	.restore_sched_clock_state	= tsc_restore_sched_clock_state,
 	.hyper.pin_vcpu			= x86_op_int_noop,
+
+	.guest = {
+		.enc_status_change_prepare = enc_status_change_prepare_noop,
+		.enc_status_change_finish  = enc_status_change_finish_noop,
+		.enc_tlb_flush_required	   = enc_tlb_flush_required_noop,
+		.enc_cache_flush_required  = enc_cache_flush_required_noop,
+	},
 };
 
 EXPORT_SYMBOL_GPL(x86_platform);
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 2b2d018..6169053 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -177,25 +177,6 @@ void __init sme_map_bootdata(char *real_mode_data)
 	__sme_early_map_unmap_mem(__va(cmdline_paddr), COMMAND_LINE_SIZE, true);
 }
 
-void __init sme_early_init(void)
-{
-	unsigned int i;
-
-	if (!sme_me_mask)
-		return;
-
-	early_pmd_flags = __sme_set(early_pmd_flags);
-
-	__supported_pte_mask = __sme_set(__supported_pte_mask);
-
-	/* Update the protection map with memory encryption mask */
-	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
-		protection_map[i] = pgprot_encrypted(protection_map[i]);
-
-	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
-		swiotlb_force = SWIOTLB_FORCE;
-}
-
 void __init sev_setup_arch(void)
 {
 	phys_addr_t total_mem = memblock_phys_mem_size();
@@ -256,7 +237,17 @@ static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
 	return pfn;
 }
 
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
+static bool amd_enc_tlb_flush_required(bool enc)
+{
+	return true;
+}
+
+static bool amd_enc_cache_flush_required(void)
+{
+	return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT);
+}
+
+static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
 #ifdef CONFIG_PARAVIRT
 	unsigned long sz = npages << PAGE_SHIFT;
@@ -287,6 +278,19 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
 #endif
 }
 
+static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+{
+}
+
+/* Return true unconditionally: return value doesn't matter for the SEV side */
+static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+{
+	if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+		enc_dec_hypercall(vaddr, npages, enc);
+
+	return true;
+}
+
 static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
 {
 	pgprot_t old_prot, new_prot;
@@ -392,7 +396,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
 
 	ret = 0;
 
-	notify_range_enc_status_changed(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
+	early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
 out:
 	__flush_tlb_all();
 	return ret;
@@ -410,7 +414,31 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
 
 void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
-	notify_range_enc_status_changed(vaddr, npages, enc);
+	enc_dec_hypercall(vaddr, npages, enc);
+}
+
+void __init sme_early_init(void)
+{
+	unsigned int i;
+
+	if (!sme_me_mask)
+		return;
+
+	early_pmd_flags = __sme_set(early_pmd_flags);
+
+	__supported_pte_mask = __sme_set(__supported_pte_mask);
+
+	/* Update the protection map with memory encryption mask */
+	for (i = 0; i < ARRAY_SIZE(protection_map); i++)
+		protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+		swiotlb_force = SWIOTLB_FORCE;
+
+	x86_platform.guest.enc_status_change_prepare = amd_enc_status_change_prepare;
+	x86_platform.guest.enc_status_change_finish  = amd_enc_status_change_finish;
+	x86_platform.guest.enc_tlb_flush_required    = amd_enc_tlb_flush_required;
+	x86_platform.guest.enc_cache_flush_required  = amd_enc_cache_flush_required;
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 1441db6..3b75262 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2008,10 +2008,12 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	kmap_flush_unused();
 	vm_unmap_aliases();
 
-	/*
-	 * Before changing the encryption attribute, we need to flush caches.
-	 */
-	cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
+	/* Flush the caches as needed before changing the encryption attribute. */
+	if (x86_platform.guest.enc_tlb_flush_required(enc))
+		cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
+
+	/* Notify hypervisor that we are about to set/clr encryption attribute. */
+	x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
 
 	ret = __change_page_attr_set_clr(&cpa, 1);
 
@@ -2024,11 +2026,11 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	 */
 	cpa_flush(&cpa, 0);
 
-	/*
-	 * Notify hypervisor that a given memory range is mapped encrypted
-	 * or decrypted.
-	 */
-	notify_range_enc_status_changed(addr, numpages, enc);
+	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
+	if (!ret) {
+		if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
+			ret = -EIO;
+	}
 
 	return ret;
 }

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

* [tip: x86/cc] x86/coco: Add API to handle encryption mask
  2022-02-22 18:57 ` [PATCH 4/4] x86/coco: Add API to handle encryption mask Kirill A. Shutemov
@ 2022-02-24 11:59   ` tip-bot2 for Kirill A. Shutemov
  0 siblings, 0 replies; 33+ messages in thread
From: tip-bot2 for Kirill A. Shutemov @ 2022-02-24 11:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Kirill A. Shutemov, Borislav Petkov, Tom Lendacky, x86, linux-kernel

The following commit has been merged into the x86/cc branch of tip:

Commit-ID:     b577f542f93cbba57f8d6185ef1fb13a41ddf162
Gitweb:        https://git.kernel.org/tip/b577f542f93cbba57f8d6185ef1fb13a41ddf162
Author:        Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
AuthorDate:    Tue, 22 Feb 2022 21:57:40 +03:00
Committer:     Borislav Petkov <bp@suse.de>
CommitterDate: Wed, 23 Feb 2022 19:14:29 +01:00

x86/coco: Add API to handle encryption mask

AMD SME/SEV uses a bit in the page table entries to indicate that the
page is encrypted and not accessible to the VMM.

TDX uses a similar approach, but the polarity of the mask is opposite to
AMD: if the bit is set the page is accessible to VMM.

Provide vendor-neutral API to deal with the mask: cc_mkenc() and
cc_mkdec() modify given address to make it encrypted/decrypted. It can
be applied to phys_addr_t, pgprotval_t or page table entry value.

pgprot_encrypted() and pgprot_decrypted() reimplemented using new
helpers.

The implementation will be extended to cover TDX.

pgprot_decrypted() is used by drivers (i915, virtio_gpu, vfio).
cc_mkdec() called by pgprot_decrypted(). Export cc_mkdec().

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Link: https://lore.kernel.org/r/20220222185740.26228-5-kirill.shutemov@linux.intel.com
---
 arch/x86/coco/core.c               | 27 +++++++++++++++++++++++++++
 arch/x86/include/asm/coco.h        | 18 ++++++++++++++++++
 arch/x86/include/asm/pgtable.h     | 13 +++++++------
 arch/x86/mm/mem_encrypt_identity.c |  1 +
 arch/x86/mm/pat/set_memory.c       |  5 +++--
 5 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index 476dcd1..fc1365d 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 
 static enum cc_vendor vendor __ro_after_init;
+static u64 cc_mask __ro_after_init;
 
 static bool intel_cc_platform_has(enum cc_attr attr)
 {
@@ -84,7 +85,33 @@ bool cc_platform_has(enum cc_attr attr)
 }
 EXPORT_SYMBOL_GPL(cc_platform_has);
 
+u64 cc_mkenc(u64 val)
+{
+	switch (vendor) {
+	case CC_VENDOR_AMD:
+		return val | cc_mask;
+	default:
+		return val;
+	}
+}
+
+u64 cc_mkdec(u64 val)
+{
+	switch (vendor) {
+	case CC_VENDOR_AMD:
+		return val & ~cc_mask;
+	default:
+		return val;
+	}
+}
+EXPORT_SYMBOL_GPL(cc_mkdec);
+
 __init void cc_set_vendor(enum cc_vendor v)
 {
 	vendor = v;
 }
+
+__init void cc_set_mask(u64 mask)
+{
+	cc_mask = mask;
+}
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
index e49f9dd..3d98c3a 100644
--- a/arch/x86/include/asm/coco.h
+++ b/arch/x86/include/asm/coco.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_COCO_H
 #define _ASM_X86_COCO_H
 
+#include <asm/types.h>
+
 enum cc_vendor {
 	CC_VENDOR_NONE,
 	CC_VENDOR_AMD,
@@ -10,5 +12,21 @@ enum cc_vendor {
 };
 
 void cc_set_vendor(enum cc_vendor v);
+void cc_set_mask(u64 mask);
+
+#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
+u64 cc_mkenc(u64 val);
+u64 cc_mkdec(u64 val);
+#else
+static inline u64 cc_mkenc(u64 val)
+{
+	return val;
+}
+
+static inline u64 cc_mkdec(u64 val)
+{
+	return val;
+}
+#endif
 
 #endif /* _ASM_X86_COCO_H */
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 8a9432f..62ab07e 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -15,17 +15,12 @@
 		     cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS)))	\
 	 : (prot))
 
-/*
- * Macros to add or remove encryption attribute
- */
-#define pgprot_encrypted(prot)	__pgprot(__sme_set(pgprot_val(prot)))
-#define pgprot_decrypted(prot)	__pgprot(__sme_clr(pgprot_val(prot)))
-
 #ifndef __ASSEMBLY__
 #include <linux/spinlock.h>
 #include <asm/x86_init.h>
 #include <asm/pkru.h>
 #include <asm/fpu/api.h>
+#include <asm/coco.h>
 #include <asm-generic/pgtable_uffd.h>
 #include <linux/page_table_check.h>
 
@@ -38,6 +33,12 @@ void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
 void ptdump_walk_pgd_level_checkwx(void);
 void ptdump_walk_user_pgd_level_checkwx(void);
 
+/*
+ * Macros to add or remove encryption attribute
+ */
+#define pgprot_encrypted(prot)	__pgprot(cc_mkenc(pgprot_val(prot)))
+#define pgprot_decrypted(prot)	__pgprot(cc_mkdec(pgprot_val(prot)))
+
 #ifdef CONFIG_DEBUG_WX
 #define debug_checkwx()		ptdump_walk_pgd_level_checkwx()
 #define debug_checkwx_user()	ptdump_walk_user_pgd_level_checkwx()
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index 06314ae..b43bc24 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -604,5 +604,6 @@ out:
 	if (sme_me_mask) {
 		physical_mask &= ~sme_me_mask;
 		cc_set_vendor(CC_VENDOR_AMD);
+		cc_set_mask(sme_me_mask);
 	}
 }
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index b407211..1441db6 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1989,6 +1989,7 @@ int set_memory_global(unsigned long addr, int numpages)
  */
 static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 {
+	pgprot_t empty = __pgprot(0);
 	struct cpa_data cpa;
 	int ret;
 
@@ -1999,8 +2000,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 	memset(&cpa, 0, sizeof(cpa));
 	cpa.vaddr = &addr;
 	cpa.numpages = numpages;
-	cpa.mask_set = enc ? __pgprot(_PAGE_ENC) : __pgprot(0);
-	cpa.mask_clr = enc ? __pgprot(0) : __pgprot(_PAGE_ENC);
+	cpa.mask_set = enc ? pgprot_encrypted(empty) : pgprot_decrypted(empty);
+	cpa.mask_clr = enc ? pgprot_decrypted(empty) : pgprot_encrypted(empty);
 	cpa.pgd = init_mm.pgd;
 
 	/* Must avoid aliasing mappings in the highmem code */

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

* [tip: x86/cc] x86/coco: Explicitly declare type of confidential computing platform
  2022-02-22 18:57 ` [PATCH 3/4] x86/coco: Explicitly declare type of confidential computing platform Kirill A. Shutemov
@ 2022-02-24 11:59   ` tip-bot2 for Kirill A. Shutemov
  0 siblings, 0 replies; 33+ messages in thread
From: tip-bot2 for Kirill A. Shutemov @ 2022-02-24 11:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Kirill A. Shutemov, Borislav Petkov, Tom Lendacky, x86, linux-kernel

The following commit has been merged into the x86/cc branch of tip:

Commit-ID:     655a0fa34b4f7ac6e2b1406fab15e52a7b6accb1
Gitweb:        https://git.kernel.org/tip/655a0fa34b4f7ac6e2b1406fab15e52a7b6accb1
Author:        Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
AuthorDate:    Tue, 22 Feb 2022 21:57:39 +03:00
Committer:     Borislav Petkov <bp@suse.de>
CommitterDate: Wed, 23 Feb 2022 19:14:16 +01:00

x86/coco: Explicitly declare type of confidential computing platform

The kernel derives the confidential computing platform
type it is running as from sme_me_mask on AMD or by using
hv_is_isolation_supported() on HyperV isolation VMs. This detection
process will be more complicated as more platforms get added.

Declare a confidential computing vendor variable explicitly and set it
via cc_set_vendor() on the respective platform.

  [ bp: Massage commit message, fixup HyperV check. ]

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Link: https://lore.kernel.org/r/20220222185740.26228-4-kirill.shutemov@linux.intel.com
---
 arch/x86/coco/core.c               | 29 +++++++++++++++++------------
 arch/x86/include/asm/coco.h        | 14 ++++++++++++++-
 arch/x86/kernel/cpu/mshyperv.c     |  6 ++++++-
 arch/x86/mm/mem_encrypt_identity.c | 11 +++++++----
 4 files changed, 44 insertions(+), 16 deletions(-)
 create mode 100644 arch/x86/include/asm/coco.h

diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index 6a6ffcd..476dcd1 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -9,18 +9,15 @@
 
 #include <linux/export.h>
 #include <linux/cc_platform.h>
-#include <linux/mem_encrypt.h>
 
-#include <asm/mshyperv.h>
+#include <asm/coco.h>
 #include <asm/processor.h>
 
-static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
+static enum cc_vendor vendor __ro_after_init;
+
+static bool intel_cc_platform_has(enum cc_attr attr)
 {
-#ifdef CONFIG_INTEL_TDX_GUEST
-	return false;
-#else
 	return false;
-#endif
 }
 
 /*
@@ -74,12 +71,20 @@ static bool hyperv_cc_platform_has(enum cc_attr attr)
 
 bool cc_platform_has(enum cc_attr attr)
 {
-	if (sme_me_mask)
+	switch (vendor) {
+	case CC_VENDOR_AMD:
 		return amd_cc_platform_has(attr);
-
-	if (hv_is_isolation_supported())
+	case CC_VENDOR_INTEL:
+		return intel_cc_platform_has(attr);
+	case CC_VENDOR_HYPERV:
 		return hyperv_cc_platform_has(attr);
-
-	return false;
+	default:
+		return false;
+	}
 }
 EXPORT_SYMBOL_GPL(cc_platform_has);
+
+__init void cc_set_vendor(enum cc_vendor v)
+{
+	vendor = v;
+}
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
new file mode 100644
index 0000000..e49f9dd
--- /dev/null
+++ b/arch/x86/include/asm/coco.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_COCO_H
+#define _ASM_X86_COCO_H
+
+enum cc_vendor {
+	CC_VENDOR_NONE,
+	CC_VENDOR_AMD,
+	CC_VENDOR_HYPERV,
+	CC_VENDOR_INTEL,
+};
+
+void cc_set_vendor(enum cc_vendor v);
+
+#endif /* _ASM_X86_COCO_H */
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 5a99f99..e0a5724 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -33,6 +33,7 @@
 #include <asm/nmi.h>
 #include <clocksource/hyperv_timer.h>
 #include <asm/numa.h>
+#include <asm/coco.h>
 
 /* Is Linux running as the root partition? */
 bool hv_root_partition;
@@ -344,6 +345,11 @@ static void __init ms_hyperv_init_platform(void)
 		 */
 		swiotlb_force = SWIOTLB_FORCE;
 #endif
+		/* Isolation VMs are unenlightened SEV-based VMs, thus this check: */
+		if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
+			if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE)
+				cc_set_vendor(CC_VENDOR_HYPERV);
+		}
 	}
 
 	if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index 3f0abb4..06314ae 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -44,6 +44,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/cmdline.h>
+#include <asm/coco.h>
 
 #include "mm_internal.h"
 
@@ -565,8 +566,7 @@ void __init sme_enable(struct boot_params *bp)
 	} else {
 		/* SEV state cannot be controlled by a command line option */
 		sme_me_mask = me_mask;
-		physical_mask &= ~sme_me_mask;
-		return;
+		goto out;
 	}
 
 	/*
@@ -600,6 +600,9 @@ void __init sme_enable(struct boot_params *bp)
 		sme_me_mask = 0;
 	else
 		sme_me_mask = active_by_default ? me_mask : 0;
-
-	physical_mask &= ~sme_me_mask;
+out:
+	if (sme_me_mask) {
+		physical_mask &= ~sme_me_mask;
+		cc_set_vendor(CC_VENDOR_AMD);
+	}
 }

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

* [tip: x86/cc] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c}
  2022-02-22 18:57 ` [PATCH 2/4] x86: Rename cc_platform.c to arch/x86/coco/core.c Kirill A. Shutemov
  2022-02-22 20:52   ` Borislav Petkov
@ 2022-02-24 11:59   ` tip-bot2 for Kirill A. Shutemov
  1 sibling, 0 replies; 33+ messages in thread
From: tip-bot2 for Kirill A. Shutemov @ 2022-02-24 11:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Kirill A. Shutemov, Borislav Petkov, Tom Lendacky, x86, linux-kernel

The following commit has been merged into the x86/cc branch of tip:

Commit-ID:     6198311093dabcafbe345d580c56b5d5a9ab5f3c
Gitweb:        https://git.kernel.org/tip/6198311093dabcafbe345d580c56b5d5a9ab5f3c
Author:        Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
AuthorDate:    Tue, 22 Feb 2022 21:57:38 +03:00
Committer:     Borislav Petkov <bp@suse.de>
CommitterDate: Wed, 23 Feb 2022 18:25:58 +01:00

x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c}

Move cc_platform.c to arch/x86/coco/. The directory is going to be the
home space for code related to confidential computing.

Intel TDX code will land here. AMD SEV code will also eventually be
moved there.

No functional changes.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Link: https://lore.kernel.org/r/20220222185740.26228-3-kirill.shutemov@linux.intel.com
---
 arch/x86/Kbuild               |  2 +-
 arch/x86/coco/Makefile        |  6 ++-
 arch/x86/coco/core.c          | 85 ++++++++++++++++++++++++++++++++++-
 arch/x86/kernel/Makefile      |  5 +--
 arch/x86/kernel/cc_platform.c | 85 +----------------------------------
 5 files changed, 93 insertions(+), 90 deletions(-)
 create mode 100644 arch/x86/coco/Makefile
 create mode 100644 arch/x86/coco/core.c
 delete mode 100644 arch/x86/kernel/cc_platform.c

diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index f384cb1..5a83da7 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_ARCH_HAS_CC_PLATFORM) += coco/
+
 obj-y += entry/
 
 obj-$(CONFIG_PERF_EVENTS) += events/
diff --git a/arch/x86/coco/Makefile b/arch/x86/coco/Makefile
new file mode 100644
index 0000000..c1ead00
--- /dev/null
+++ b/arch/x86/coco/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+CFLAGS_REMOVE_core.o	= -pg
+KASAN_SANITIZE_core.o	:= n
+CFLAGS_core.o		+= -fno-stack-protector
+
+obj-y += core.o
diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
new file mode 100644
index 0000000..6a6ffcd
--- /dev/null
+++ b/arch/x86/coco/core.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Confidential Computing Platform Capability checks
+ *
+ * Copyright (C) 2021 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky <thomas.lendacky@amd.com>
+ */
+
+#include <linux/export.h>
+#include <linux/cc_platform.h>
+#include <linux/mem_encrypt.h>
+
+#include <asm/mshyperv.h>
+#include <asm/processor.h>
+
+static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
+{
+#ifdef CONFIG_INTEL_TDX_GUEST
+	return false;
+#else
+	return false;
+#endif
+}
+
+/*
+ * SME and SEV are very similar but they are not the same, so there are
+ * times that the kernel will need to distinguish between SME and SEV. The
+ * cc_platform_has() function is used for this.  When a distinction isn't
+ * needed, the CC_ATTR_MEM_ENCRYPT attribute can be used.
+ *
+ * The trampoline code is a good example for this requirement.  Before
+ * paging is activated, SME will access all memory as decrypted, but SEV
+ * will access all memory as encrypted.  So, when APs are being brought
+ * up under SME the trampoline area cannot be encrypted, whereas under SEV
+ * the trampoline area must be encrypted.
+ */
+static bool amd_cc_platform_has(enum cc_attr attr)
+{
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+	switch (attr) {
+	case CC_ATTR_MEM_ENCRYPT:
+		return sme_me_mask;
+
+	case CC_ATTR_HOST_MEM_ENCRYPT:
+		return sme_me_mask && !(sev_status & MSR_AMD64_SEV_ENABLED);
+
+	case CC_ATTR_GUEST_MEM_ENCRYPT:
+		return sev_status & MSR_AMD64_SEV_ENABLED;
+
+	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;
+	}
+#else
+	return false;
+#endif
+}
+
+static bool hyperv_cc_platform_has(enum cc_attr attr)
+{
+	return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
+}
+
+bool cc_platform_has(enum cc_attr attr)
+{
+	if (sme_me_mask)
+		return amd_cc_platform_has(attr);
+
+	if (hv_is_isolation_supported())
+		return hyperv_cc_platform_has(attr);
+
+	return false;
+}
+EXPORT_SYMBOL_GPL(cc_platform_has);
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 6aef9ee..6462e3d 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -21,7 +21,6 @@ CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
 CFLAGS_REMOVE_head64.o = -pg
 CFLAGS_REMOVE_sev.o = -pg
-CFLAGS_REMOVE_cc_platform.o = -pg
 endif
 
 KASAN_SANITIZE_head$(BITS).o				:= n
@@ -30,7 +29,6 @@ KASAN_SANITIZE_dumpstack_$(BITS).o			:= n
 KASAN_SANITIZE_stacktrace.o				:= n
 KASAN_SANITIZE_paravirt.o				:= n
 KASAN_SANITIZE_sev.o					:= n
-KASAN_SANITIZE_cc_platform.o				:= n
 
 # With some compiler versions the generated code results in boot hangs, caused
 # by several compilation units. To be safe, disable all instrumentation.
@@ -49,7 +47,6 @@ endif
 KCOV_INSTRUMENT		:= n
 
 CFLAGS_head$(BITS).o	+= -fno-stack-protector
-CFLAGS_cc_platform.o	+= -fno-stack-protector
 
 CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace
 
@@ -151,8 +148,6 @@ obj-$(CONFIG_UNWINDER_GUESS)		+= unwind_guess.o
 
 obj-$(CONFIG_AMD_MEM_ENCRYPT)		+= sev.o
 
-obj-$(CONFIG_ARCH_HAS_CC_PLATFORM)	+= cc_platform.o
-
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/kernel/cc_platform.c
deleted file mode 100644
index 6a6ffcd..0000000
--- a/arch/x86/kernel/cc_platform.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Confidential Computing Platform Capability checks
- *
- * Copyright (C) 2021 Advanced Micro Devices, Inc.
- *
- * Author: Tom Lendacky <thomas.lendacky@amd.com>
- */
-
-#include <linux/export.h>
-#include <linux/cc_platform.h>
-#include <linux/mem_encrypt.h>
-
-#include <asm/mshyperv.h>
-#include <asm/processor.h>
-
-static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
-{
-#ifdef CONFIG_INTEL_TDX_GUEST
-	return false;
-#else
-	return false;
-#endif
-}
-
-/*
- * SME and SEV are very similar but they are not the same, so there are
- * times that the kernel will need to distinguish between SME and SEV. The
- * cc_platform_has() function is used for this.  When a distinction isn't
- * needed, the CC_ATTR_MEM_ENCRYPT attribute can be used.
- *
- * The trampoline code is a good example for this requirement.  Before
- * paging is activated, SME will access all memory as decrypted, but SEV
- * will access all memory as encrypted.  So, when APs are being brought
- * up under SME the trampoline area cannot be encrypted, whereas under SEV
- * the trampoline area must be encrypted.
- */
-static bool amd_cc_platform_has(enum cc_attr attr)
-{
-#ifdef CONFIG_AMD_MEM_ENCRYPT
-	switch (attr) {
-	case CC_ATTR_MEM_ENCRYPT:
-		return sme_me_mask;
-
-	case CC_ATTR_HOST_MEM_ENCRYPT:
-		return sme_me_mask && !(sev_status & MSR_AMD64_SEV_ENABLED);
-
-	case CC_ATTR_GUEST_MEM_ENCRYPT:
-		return sev_status & MSR_AMD64_SEV_ENABLED;
-
-	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;
-	}
-#else
-	return false;
-#endif
-}
-
-static bool hyperv_cc_platform_has(enum cc_attr attr)
-{
-	return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
-}
-
-bool cc_platform_has(enum cc_attr attr)
-{
-	if (sme_me_mask)
-		return amd_cc_platform_has(attr);
-
-	if (hv_is_isolation_supported())
-		return hyperv_cc_platform_has(attr);
-
-	return false;
-}
-EXPORT_SYMBOL_GPL(cc_platform_has);

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

end of thread, other threads:[~2022-02-24 11:59 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-22 18:57 [PATCH 0/4] x86: Cleanup and extend computing computing API Kirill A. Shutemov
2022-02-22 18:57 ` [PATCH 1/4] x86/hyperv: Add missing ARCH_HAS_CC_PLATFORM dependency Kirill A. Shutemov
2022-02-22 20:08   ` Borislav Petkov
2022-02-23  7:04     ` Tianyu Lan
2022-02-23 10:41       ` Borislav Petkov
2022-02-23 10:43         ` Tianyu Lan
2022-02-23 10:56           ` Borislav Petkov
2022-02-23 11:02             ` Tianyu Lan
2022-02-23 11:47               ` Kirill A. Shutemov
2022-02-23 14:09                 ` Tianyu Lan
2022-02-23 15:46                   ` Kirill A. Shutemov
2022-02-22 18:57 ` [PATCH 2/4] x86: Rename cc_platform.c to arch/x86/coco/core.c Kirill A. Shutemov
2022-02-22 20:52   ` Borislav Petkov
2022-02-24 11:59   ` [tip: x86/cc] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c} tip-bot2 for Kirill A. Shutemov
2022-02-22 18:57 ` [PATCH 3/4] x86/coco: Explicitly declare type of confidential computing platform Kirill A. Shutemov
2022-02-24 11:59   ` [tip: x86/cc] " tip-bot2 for Kirill A. Shutemov
2022-02-22 18:57 ` [PATCH 4/4] x86/coco: Add API to handle encryption mask Kirill A. Shutemov
2022-02-24 11:59   ` [tip: x86/cc] " tip-bot2 for Kirill A. Shutemov
2022-02-22 21:56 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Tom Lendacky
2022-02-23  4:35 ` [PATCH] x86/mm/cpa: Generalize __set_memory_enc_pgtable() Brijesh Singh
2022-02-23 11:31   ` Borislav Petkov
2022-02-23 11:55     ` Kirill A. Shutemov
2022-02-23 12:13       ` Borislav Petkov
2022-02-23 12:25         ` Kirill A. Shutemov
2022-02-23 12:38           ` Borislav Petkov
2022-02-23 12:54             ` Kirill A. Shutemov
2022-02-23 14:33             ` Brijesh Singh
2022-02-24 11:59   ` [tip: x86/cc] " tip-bot2 for Brijesh Singh
2022-02-23 19:10 ` [PATCH 0/4] x86: Cleanup and extend computing computing API Borislav Petkov
2022-02-23 19:17   ` [PATCH 1/4] x86/cc: Move arch/x86/{kernel/cc_platform.c => coco/core.c} Borislav Petkov
2022-02-23 19:17   ` [PATCH 2/4] x86/coco: Explicitly declare type of confidential computing platform Borislav Petkov
2022-02-23 19:17   ` [PATCH 3/4] x86/coco: Add API to handle encryption mask Borislav Petkov
2022-02-23 19:17   ` [PATCH 4/4] x86/mm/cpa: Generalize __set_memory_enc_pgtable() Borislav Petkov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.