linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part)
@ 2023-08-24  8:07 Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 01/10] x86/hyperv: Add hv_isolation_type_tdx() to detect TDX guests Dexuan Cui
                   ` (10 more replies)
  0 siblings, 11 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

Hyper-V provides two modes for running Intel TDX VMs:

1) TD Partitioning mode with a paravisor (see [1]).
2) In "fully enlightened" mode with normal TDX shared bit control
   over page encryption, and no paravisor

The first mode is similar to AMD SEV-SNP's vTOM mode.
The second is similar to AMD SEV-SNP's C-bit mode.

For #2, the v6 patchset was [2], which is later split into 2 parts:
the generic TDX part (see [3][4]), and the Hyper-V specific part, i.e.
the first 5 patches of this patchset. For the second part, I rebased
the patches to Tianyu's fully enlighted SNP patchset (which has been
in the Hyper-V tree's hyperv-next branch). Since this is mostly a
straightforward rebasing, I keep the existing Acked-by and
Reviewed-by in the v6 patchset [2].

The next 3 patches of this patchset add the support for #1.

The last 2 patches (the 9th and the 10th) just make some cleanup.

Please review all the 10 patches, which are also on my github
branch [5]. The patches can apply cleanly on hyperv-next.

I tested the patches for a regular VM, a VBS VM, a SNP VM
with the paravisor, and a TDX VM with the paravisor and a TDX
VM without the paravisor, and an ARM64 VM. All the VMs worked
as expected.

Thanks,
Dexuan

References:
[1] Intel TDX Module v1.5 TD Partitioning Architecture Specification
[2] https://lwn.net/ml/linux-kernel/20230504225351.10765-1-decui@microsoft.com/
[3] https://lwn.net/ml/linux-kernel/20230811214826.9609-1-decui%40microsoft.com/
[4] https://github.com/dcui/tdx/commits/decui/mainline/x86/tdx/v10
[5] https://github.com/dcui/tdx/commits/decui/mainline/x86/hyperv/tdx-v3

Dexuan Cui (10):
  x86/hyperv: Add hv_isolation_type_tdx() to detect TDX guests
  x86/hyperv: Support hypercalls for fully enlightened TDX guests
  Drivers: hv: vmbus: Support fully enlightened TDX guests
  x86/hyperv: Fix serial console interrupts for fully enlightened TDX
    guests
  Drivers: hv: vmbus: Support >64 VPs for a fully enlightened TDX/SNP VM
  x86/hyperv: Introduce a global variable hyperv_paravisor_present
  Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the
    paravisor
  x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM with the
    paravisor
  x86/hyperv: Remove hv_isolation_type_en_snp
  x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's

 arch/x86/hyperv/hv_apic.c          |  15 +-
 arch/x86/hyperv/hv_init.c          |  59 ++++-
 arch/x86/hyperv/ivm.c              | 374 ++++++++++++++++++-----------
 arch/x86/include/asm/hyperv-tlfs.h |   3 +-
 arch/x86/include/asm/mshyperv.h    |  43 +++-
 arch/x86/kernel/cpu/mshyperv.c     |  65 ++++-
 drivers/hv/connection.c            |  15 +-
 drivers/hv/hv.c                    |  78 +++++-
 drivers/hv/hv_common.c             |  43 +++-
 drivers/hv/hyperv_vmbus.h          |  11 +
 include/asm-generic/mshyperv.h     |   5 +-
 11 files changed, 505 insertions(+), 206 deletions(-)

-- 
2.25.1


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

* [PATCH v3 01/10] x86/hyperv: Add hv_isolation_type_tdx() to detect TDX guests
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 02/10] x86/hyperv: Support hypercalls for fully enlightened " Dexuan Cui
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

No logic change to SNP/VBS guests.

hv_isolation_type_tdx() will be used to instruct a TDX guest on Hyper-V to
do some TDX-specific operations, e.g. for a fully enlightened TDX guest
(i.e. without the paravisor), hv_do_hypercall() should use
__tdx_hypercall() and such a guest on Hyper-V should handle the Hyper-V
Event/Message/Monitor pages specially.

Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2:
  Added Tianyu's Reviewed-by.

Changes in v3: None.

 arch/x86/hyperv/ivm.c              | 9 +++++++++
 arch/x86/include/asm/hyperv-tlfs.h | 3 ++-
 arch/x86/include/asm/mshyperv.h    | 3 +++
 arch/x86/kernel/cpu/mshyperv.c     | 2 ++
 drivers/hv/hv_common.c             | 6 ++++++
 include/asm-generic/mshyperv.h     | 1 +
 6 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index cbbd3af4c3da..afdae1a8a117 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -562,3 +562,12 @@ bool hv_isolation_type_en_snp(void)
 	return static_branch_unlikely(&isolation_type_en_snp);
 }
 
+DEFINE_STATIC_KEY_FALSE(isolation_type_tdx);
+/*
+ * hv_isolation_type_tdx - Check if the system runs in an Intel TDX based
+ * isolated VM.
+ */
+bool hv_isolation_type_tdx(void)
+{
+	return static_branch_unlikely(&isolation_type_tdx);
+}
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 4bf0b315b0ce..2ff26f53cd62 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -169,7 +169,8 @@
 enum hv_isolation_type {
 	HV_ISOLATION_TYPE_NONE	= 0,
 	HV_ISOLATION_TYPE_VBS	= 1,
-	HV_ISOLATION_TYPE_SNP	= 2
+	HV_ISOLATION_TYPE_SNP	= 2,
+	HV_ISOLATION_TYPE_TDX	= 3
 };
 
 /* Hyper-V specific model specific registers (MSRs) */
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index b6be267ff3d0..3feb4e36851e 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -27,6 +27,7 @@ union hv_ghcb;
 
 DECLARE_STATIC_KEY_FALSE(isolation_type_snp);
 DECLARE_STATIC_KEY_FALSE(isolation_type_en_snp);
+DECLARE_STATIC_KEY_FALSE(isolation_type_tdx);
 
 typedef int (*hyperv_fill_flush_list_func)(
 		struct hv_guest_mapping_flush_list *flush,
@@ -49,6 +50,8 @@ extern u64 hv_current_partition_id;
 extern union hv_ghcb * __percpu *hv_ghcb_pg;
 
 extern bool hv_isolation_type_en_snp(void);
+bool hv_isolation_type_tdx(void);
+
 /*
  * DEFAULT INIT GPAT and SEGMENT LIMIT value in struct VMSA
  * to start AP in enlightened SEV guest.
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index c8d3ca2b0e0e..63093870ec33 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -418,6 +418,8 @@ static void __init ms_hyperv_init_platform(void)
 				static_branch_enable(&isolation_type_snp);
 			else
 				static_branch_enable(&isolation_type_en_snp);
+		} else if (hv_get_isolation_type() == HV_ISOLATION_TYPE_TDX) {
+			static_branch_enable(&isolation_type_tdx);
 		}
 	}
 
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 2d43ba2bc925..da3307533f4d 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -521,6 +521,12 @@ bool __weak hv_isolation_type_en_snp(void)
 }
 EXPORT_SYMBOL_GPL(hv_isolation_type_en_snp);
 
+bool __weak hv_isolation_type_tdx(void)
+{
+	return false;
+}
+EXPORT_SYMBOL_GPL(hv_isolation_type_tdx);
+
 void __weak hv_setup_vmbus_handler(void (*handler)(void))
 {
 }
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index efd0d2aedad3..82eba2d5fc4c 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -66,6 +66,7 @@ extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
 extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
 extern bool hv_isolation_type_snp(void);
 extern bool hv_isolation_type_en_snp(void);
+bool hv_isolation_type_tdx(void);
 
 /* Helper functions that provide a consistent pattern for checking Hyper-V hypercall status. */
 static inline int hv_result(u64 status)
-- 
2.25.1


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

* [PATCH v3 02/10] x86/hyperv: Support hypercalls for fully enlightened TDX guests
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 01/10] x86/hyperv: Add hv_isolation_type_tdx() to detect TDX guests Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 03/10] Drivers: hv: vmbus: Support " Dexuan Cui
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

A fully enlightened TDX guest on Hyper-V (i.e. without the paravisor) only
uses the GHCI call rather than hv_hypercall_pg. Do not initialize
hypercall_pg for such a guest.

In hv_common_cpu_init(), the hyperv_pcpu_input_arg page needs to be
decrypted in such a guest.

Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2:
  Included asm/coco.h in arch/x86/include/asm/mshyperv.h to avoid a
    gcc warning: "implicit declaration of cc_mkdec"

Changes in v3:
  Added Tianyu's Reviewed-by.
  Removed the cc_mkdec() from hv_do_hypercall(). This is no longer
    needed on generally available Hyper-V.
  Removed the inclusion of coco.h

 arch/x86/hyperv/hv_init.c       |  8 ++++++++
 arch/x86/hyperv/ivm.c           | 17 +++++++++++++++++
 arch/x86/include/asm/mshyperv.h | 14 ++++++++++++++
 drivers/hv/hv_common.c          | 10 ++++++++--
 include/asm-generic/mshyperv.h  |  1 +
 5 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index bcfbcda8b050..255e02ec467e 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -476,6 +476,10 @@ void __init hyperv_init(void)
 	/* Hyper-V requires to write guest os id via ghcb in SNP IVM. */
 	hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, guest_id);
 
+	/* A TDX guest uses the GHCI call rather than hv_hypercall_pg. */
+	if (hv_isolation_type_tdx())
+		goto skip_hypercall_pg_init;
+
 	hv_hypercall_pg = __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START,
 			VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX,
 			VM_FLUSH_RESET_PERMS, NUMA_NO_NODE,
@@ -515,6 +519,7 @@ void __init hyperv_init(void)
 		wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 	}
 
+skip_hypercall_pg_init:
 	/*
 	 * hyperv_init() is called before LAPIC is initialized: see
 	 * apic_intr_mode_init() -> x86_platform.apic_post_init() and
@@ -642,6 +647,9 @@ bool hv_is_hyperv_initialized(void)
 	if (x86_hyper_type != X86_HYPER_MS_HYPERV)
 		return false;
 
+	/* A TDX guest uses the GHCI call rather than hv_hypercall_pg. */
+	if (hv_isolation_type_tdx())
+		return true;
 	/*
 	 * Verify that earlier initialization succeeded by checking
 	 * that the hypercall page is setup
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index afdae1a8a117..6c7598d9e68a 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -571,3 +571,20 @@ bool hv_isolation_type_tdx(void)
 {
 	return static_branch_unlikely(&isolation_type_tdx);
 }
+
+#ifdef CONFIG_INTEL_TDX_GUEST
+
+u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2)
+{
+	struct tdx_hypercall_args args = { };
+
+	args.r10 = control;
+	args.rdx = param1;
+	args.r8  = param2;
+
+	(void)__tdx_hypercall_ret(&args);
+
+	return args.r11;
+}
+
+#endif
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 3feb4e36851e..6a9e00c4730b 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -51,6 +51,7 @@ extern union hv_ghcb * __percpu *hv_ghcb_pg;
 
 extern bool hv_isolation_type_en_snp(void);
 bool hv_isolation_type_tdx(void);
+u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 
 /*
  * DEFAULT INIT GPAT and SEGMENT LIMIT value in struct VMSA
@@ -63,6 +64,10 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
 int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
 
+/*
+ * If the hypercall involves no input or output parameters, the hypervisor
+ * ignores the corresponding GPA pointer.
+ */
 static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
 	u64 input_address = input ? virt_to_phys(input) : 0;
@@ -70,6 +75,9 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
 	u64 hv_status;
 
 #ifdef CONFIG_X86_64
+	if (hv_isolation_type_tdx())
+		return hv_tdx_hypercall(control, input_address, output_address);
+
 	if (hv_isolation_type_en_snp()) {
 		__asm__ __volatile__("mov %4, %%r8\n"
 				     "vmmcall"
@@ -123,6 +131,9 @@ static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
 	u64 hv_status;
 
 #ifdef CONFIG_X86_64
+	if (hv_isolation_type_tdx())
+		return hv_tdx_hypercall(control, input1, 0);
+
 	if (hv_isolation_type_en_snp()) {
 		__asm__ __volatile__(
 				"vmmcall"
@@ -174,6 +185,9 @@ static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
 	u64 hv_status;
 
 #ifdef CONFIG_X86_64
+	if (hv_isolation_type_tdx())
+		return hv_tdx_hypercall(control, input1, input2);
+
 	if (hv_isolation_type_en_snp()) {
 		__asm__ __volatile__("mov %4, %%r8\n"
 				     "vmmcall"
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index da3307533f4d..897bbb96f411 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -381,10 +381,10 @@ int hv_common_cpu_init(unsigned int cpu)
 			*outputarg = (char *)(*inputarg) + HV_HYP_PAGE_SIZE;
 		}
 
-		if (hv_isolation_type_en_snp()) {
+		if (hv_isolation_type_en_snp() || hv_isolation_type_tdx()) {
 			ret = set_memory_decrypted((unsigned long)*inputarg, pgcount);
 			if (ret) {
-				kfree(*inputarg);
+				/* It may be unsafe to free *inputarg */
 				*inputarg = NULL;
 				return ret;
 			}
@@ -567,3 +567,9 @@ u64 __weak hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_s
 	return HV_STATUS_INVALID_PARAMETER;
 }
 EXPORT_SYMBOL_GPL(hv_ghcb_hypercall);
+
+u64 __weak hv_tdx_hypercall(u64 control, u64 param1, u64 param2)
+{
+	return HV_STATUS_INVALID_PARAMETER;
+}
+EXPORT_SYMBOL_GPL(hv_tdx_hypercall);
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 82eba2d5fc4c..f577eff58ea0 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -283,6 +283,7 @@ enum hv_isolation_type hv_get_isolation_type(void);
 bool hv_is_isolation_supported(void);
 bool hv_isolation_type_snp(void);
 u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size);
+u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 void hyperv_cleanup(void);
 bool hv_query_ext_cap(u64 cap_query);
 void hv_setup_dma_ops(struct device *dev, bool coherent);
-- 
2.25.1


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

* [PATCH v3 03/10] Drivers: hv: vmbus: Support fully enlightened TDX guests
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 01/10] x86/hyperv: Add hv_isolation_type_tdx() to detect TDX guests Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 02/10] x86/hyperv: Support hypercalls for fully enlightened " Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 04/10] x86/hyperv: Fix serial console interrupts for " Dexuan Cui
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

Add Hyper-V specific code so that a fully enlightened TDX guest (i.e.
without the paravisor) can run on Hyper-V:
  Don't use hv_vp_assist_page. Use GHCI instead.
  Don't try to use the unsupported HV_REGISTER_CRASH_CTL.
  Don't trust (use) Hyper-V's TLB-flushing hypercalls.
  Don't use lazy EOI.
  Share the SynIC Event/Message pages with the hypervisor.
  Don't use the Hyper-V TSC page for now, because non-trivial work is
    required to share the page with the hypervisor.

Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2: None

Changes in v3:
  ms_hyperv_init_platform(): Removed cc_mkdec(0).
  hv_synic_alloc(), hv_synic_enable_regs():
    Removed "|= ms_hyperv.shared_gpa_boundary": No longer needed on GA Hyper-V.

 arch/x86/hyperv/hv_apic.c      | 15 ++++++++++++---
 arch/x86/hyperv/hv_init.c      | 19 +++++++++++++++----
 arch/x86/kernel/cpu/mshyperv.c | 14 ++++++++++++++
 drivers/hv/hv.c                |  9 +++++++--
 4 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 1fbda2f94184..cb7429046d18 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -177,8 +177,11 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector,
 	    (exclude_self && weight == 1 && cpumask_test_cpu(this_cpu, mask)))
 		return true;
 
-	if (!hv_hypercall_pg)
-		return false;
+	/* A fully enlightened TDX VM uses GHCI rather than hv_hypercall_pg. */
+	if (!hv_hypercall_pg) {
+		if (ms_hyperv.paravisor_present || !hv_isolation_type_tdx())
+			return false;
+	}
 
 	if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
 		return false;
@@ -231,9 +234,15 @@ static bool __send_ipi_one(int cpu, int vector)
 
 	trace_hyperv_send_ipi_one(cpu, vector);
 
-	if (!hv_hypercall_pg || (vp == VP_INVAL))
+	if (vp == VP_INVAL)
 		return false;
 
+	/* A fully enlightened TDX VM uses GHCI rather than hv_hypercall_pg. */
+	if (!hv_hypercall_pg) {
+		if (ms_hyperv.paravisor_present || !hv_isolation_type_tdx())
+			return false;
+	}
+
 	if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
 		return false;
 
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 255e02ec467e..c1c1b4e1502f 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -80,7 +80,7 @@ static int hyperv_init_ghcb(void)
 static int hv_cpu_init(unsigned int cpu)
 {
 	union hv_vp_assist_msr_contents msr = { 0 };
-	struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu];
+	struct hv_vp_assist_page **hvp;
 	int ret;
 
 	ret = hv_common_cpu_init(cpu);
@@ -90,6 +90,7 @@ static int hv_cpu_init(unsigned int cpu)
 	if (!hv_vp_assist_page)
 		return 0;
 
+	hvp = &hv_vp_assist_page[cpu];
 	if (hv_root_partition) {
 		/*
 		 * For root partition we get the hypervisor provided VP assist
@@ -442,11 +443,21 @@ void __init hyperv_init(void)
 	if (hv_common_init())
 		return;
 
-	hv_vp_assist_page = kcalloc(num_possible_cpus(),
-				    sizeof(*hv_vp_assist_page), GFP_KERNEL);
+	/*
+	 * The VP assist page is useless to a TDX guest: the only use we
+	 * would have for it is lazy EOI, which can not be used with TDX.
+	 */
+	if (hv_isolation_type_tdx())
+		hv_vp_assist_page = NULL;
+	else
+		hv_vp_assist_page = kcalloc(num_possible_cpus(),
+					    sizeof(*hv_vp_assist_page),
+					    GFP_KERNEL);
 	if (!hv_vp_assist_page) {
 		ms_hyperv.hints &= ~HV_X64_ENLIGHTENED_VMCS_RECOMMENDED;
-		goto common_free;
+
+		if (!hv_isolation_type_tdx())
+			goto common_free;
 	}
 
 	if (hv_isolation_type_snp()) {
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 63093870ec33..ff3d9c5de19c 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -420,6 +420,20 @@ static void __init ms_hyperv_init_platform(void)
 				static_branch_enable(&isolation_type_en_snp);
 		} else if (hv_get_isolation_type() == HV_ISOLATION_TYPE_TDX) {
 			static_branch_enable(&isolation_type_tdx);
+
+			/* A TDX VM must use x2APIC and doesn't use lazy EOI. */
+			ms_hyperv.hints &= ~HV_X64_APIC_ACCESS_RECOMMENDED;
+
+			if (!ms_hyperv.paravisor_present) {
+				/* To be supported: more work is required.  */
+				ms_hyperv.features &= ~HV_MSR_REFERENCE_TSC_AVAILABLE;
+
+				/* HV_REGISTER_CRASH_CTL is unsupported. */
+				ms_hyperv.misc_features &= ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
+
+				/* Don't trust Hyper-V's TLB-flushing hypercalls. */
+				ms_hyperv.hints &= ~HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED;
+			}
 		}
 	}
 
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index ec6e35a0d9bf..d1064118a72f 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -121,11 +121,15 @@ int hv_synic_alloc(void)
 				(void *)get_zeroed_page(GFP_ATOMIC);
 			if (hv_cpu->synic_event_page == NULL) {
 				pr_err("Unable to allocate SYNIC event page\n");
+
+				free_page((unsigned long)hv_cpu->synic_message_page);
+				hv_cpu->synic_message_page = NULL;
 				goto err;
 			}
 		}
 
-		if (hv_isolation_type_en_snp()) {
+		if (!ms_hyperv.paravisor_present &&
+		    (hv_isolation_type_en_snp() || hv_isolation_type_tdx())) {
 			ret = set_memory_decrypted((unsigned long)
 				hv_cpu->synic_message_page, 1);
 			if (ret) {
@@ -174,7 +178,8 @@ void hv_synic_free(void)
 			= per_cpu_ptr(hv_context.cpu_context, cpu);
 
 		/* It's better to leak the page if the encryption fails. */
-		if (hv_isolation_type_en_snp()) {
+		if (!ms_hyperv.paravisor_present &&
+		    (hv_isolation_type_en_snp() || hv_isolation_type_tdx())) {
 			if (hv_cpu->synic_message_page) {
 				ret = set_memory_encrypted((unsigned long)
 					hv_cpu->synic_message_page, 1);
-- 
2.25.1


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

* [PATCH v3 04/10] x86/hyperv: Fix serial console interrupts for fully enlightened TDX guests
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
                   ` (2 preceding siblings ...)
  2023-08-24  8:07 ` [PATCH v3 03/10] Drivers: hv: vmbus: Support " Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 05/10] Drivers: hv: vmbus: Support >64 VPs for a fully enlightened TDX/SNP VM Dexuan Cui
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

When a fully enlightened TDX guest runs on Hyper-V, the UEFI firmware sets
the HW_REDUCED flag and consequently ttyS0 interrupts can't work. Fix the
issue by overriding x86_init.acpi.reduced_hw_early_init().

Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2: None

Changes in v3:
  Added Tianyu's Reviewed-by.

 arch/x86/kernel/cpu/mshyperv.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index ff3d9c5de19c..fe5393d759d3 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -323,6 +323,26 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
 }
 #endif
 
+/*
+ * When a fully enlightened TDX VM runs on Hyper-V, the firmware sets the
+ * HW_REDUCED flag: refer to acpi_tb_create_local_fadt(). Consequently ttyS0
+ * interrupts can't work because request_irq() -> ... -> irq_to_desc() returns
+ * NULL for ttyS0. This happens because mp_config_acpi_legacy_irqs() sees a
+ * nr_legacy_irqs() of 0, so it doesn't initialize the array 'mp_irqs[]', and
+ * later setup_IO_APIC_irqs() -> find_irq_entry() fails to find the legacy irqs
+ * from the array and hence doesn't create the necessary irq description info.
+ *
+ * Clone arch/x86/kernel/acpi/boot.c: acpi_generic_reduced_hw_init() here,
+ * except don't change 'legacy_pic', which keeps its default value
+ * 'default_legacy_pic'. This way, mp_config_acpi_legacy_irqs() sees a non-zero
+ * nr_legacy_irqs() and eventually serial console interrupts works properly.
+ */
+static void __init reduced_hw_init(void)
+{
+	x86_init.timers.timer_init	= x86_init_noop;
+	x86_init.irqs.pre_vector_init	= x86_init_noop;
+}
+
 static void __init ms_hyperv_init_platform(void)
 {
 	int hv_max_functions_eax;
@@ -433,6 +453,8 @@ static void __init ms_hyperv_init_platform(void)
 
 				/* Don't trust Hyper-V's TLB-flushing hypercalls. */
 				ms_hyperv.hints &= ~HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED;
+
+				x86_init.acpi.reduced_hw_early_init = reduced_hw_init;
 			}
 		}
 	}
-- 
2.25.1


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

* [PATCH v3 05/10] Drivers: hv: vmbus: Support >64 VPs for a fully enlightened TDX/SNP VM
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
                   ` (3 preceding siblings ...)
  2023-08-24  8:07 ` [PATCH v3 04/10] x86/hyperv: Fix serial console interrupts for " Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24  8:07 ` [PATCH v3 06/10] x86/hyperv: Introduce a global variable hyperv_paravisor_present Dexuan Cui
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

Don't set *this_cpu_ptr(hyperv_pcpu_input_arg) before the function
set_memory_decrypted() returns, otherwise we run into this ticky issue:

For a fully enlightened TDX/SNP VM, in hv_common_cpu_init(),
*this_cpu_ptr(hyperv_pcpu_input_arg) is an encrypted page before
the set_memory_decrypted() returns.

When such a VM has more than 64 VPs, if the hyperv_pcpu_input_arg is not
NULL, hv_common_cpu_init() -> set_memory_decrypted() -> ... ->
cpa_flush() -> on_each_cpu() -> ... -> hv_send_ipi_mask() -> ... ->
__send_ipi_mask_ex() tries to call hv_do_rep_hypercall() with the
hyperv_pcpu_input_arg as the hypercall input page, which must be a
decrypted page in such a VM, but the page is still encrypted at this
point, and a fatal fault is triggered.

Fix the issue by setting *this_cpu_ptr(hyperv_pcpu_input_arg) after
set_memory_decrypted(): if the hyperv_pcpu_input_arg is NULL,
__send_ipi_mask_ex() returns HV_STATUS_INVALID_PARAMETER immediately,
and hv_send_ipi_mask() falls back to orig_apic.send_IPI_mask(),
which can use x2apic_send_IPI_all(), which may be slightly slower than
the hypercall but still works correctly in such a VM.

Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2: None

Changes in v3:
  Added Michael's and Tianyu's Reviewed-by
  Fixed a typo in the changelog:
    hv_do_fast_hypercall16 -> hv_do_rep_hypercall

 drivers/hv/hv_common.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 897bbb96f411..4c858e1636da 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -360,6 +360,7 @@ int hv_common_cpu_init(unsigned int cpu)
 	u64 msr_vp_index;
 	gfp_t flags;
 	int pgcount = hv_root_partition ? 2 : 1;
+	void *mem;
 	int ret;
 
 	/* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
@@ -372,25 +373,40 @@ int hv_common_cpu_init(unsigned int cpu)
 	 * allocated if this CPU was previously online and then taken offline
 	 */
 	if (!*inputarg) {
-		*inputarg = kmalloc(pgcount * HV_HYP_PAGE_SIZE, flags);
-		if (!(*inputarg))
+		mem = kmalloc(pgcount * HV_HYP_PAGE_SIZE, flags);
+		if (!mem)
 			return -ENOMEM;
 
 		if (hv_root_partition) {
 			outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
-			*outputarg = (char *)(*inputarg) + HV_HYP_PAGE_SIZE;
+			*outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
 		}
 
 		if (hv_isolation_type_en_snp() || hv_isolation_type_tdx()) {
-			ret = set_memory_decrypted((unsigned long)*inputarg, pgcount);
+			ret = set_memory_decrypted((unsigned long)mem, pgcount);
 			if (ret) {
-				/* It may be unsafe to free *inputarg */
-				*inputarg = NULL;
+				/* It may be unsafe to free 'mem' */
 				return ret;
 			}
 
-			memset(*inputarg, 0x00, pgcount * PAGE_SIZE);
+			memset(mem, 0x00, pgcount * HV_HYP_PAGE_SIZE);
 		}
+
+		/*
+		 * In a fully enlightened TDX/SNP VM with more than 64 VPs, if
+		 * hyperv_pcpu_input_arg is not NULL, set_memory_decrypted() ->
+		 * ... -> cpa_flush()-> ... -> __send_ipi_mask_ex() tries to
+		 * use hyperv_pcpu_input_arg as the hypercall input page, which
+		 * must be a decrypted page in such a VM, but the page is still
+		 * encrypted before set_memory_decrypted() returns. Fix this by
+		 * setting *inputarg after the above set_memory_decrypted(): if
+		 * hyperv_pcpu_input_arg is NULL, __send_ipi_mask_ex() returns
+		 * HV_STATUS_INVALID_PARAMETER immediately, and the function
+		 * hv_send_ipi_mask() falls back to orig_apic.send_IPI_mask(),
+		 * which may be slightly slower than the hypercall, but still
+		 * works correctly in such a VM.
+		 */
+		*inputarg = mem;
 	}
 
 	msr_vp_index = hv_get_register(HV_REGISTER_VP_INDEX);
-- 
2.25.1


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

* [PATCH v3 06/10] x86/hyperv: Introduce a global variable hyperv_paravisor_present
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
                   ` (4 preceding siblings ...)
  2023-08-24  8:07 ` [PATCH v3 05/10] Drivers: hv: vmbus: Support >64 VPs for a fully enlightened TDX/SNP VM Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24 14:06   ` Michael Kelley (LINUX)
  2023-08-24 14:41   ` Tianyu Lan
  2023-08-24  8:07 ` [PATCH v3 07/10] Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the paravisor Dexuan Cui
                   ` (4 subsequent siblings)
  10 siblings, 2 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

The new variable hyperv_paravisor_present is set only when the VM
is a SNP/TDX VM with the paravisor running: see ms_hyperv_init_platform().

We introduce hyperv_paravisor_present because we can not use
ms_hyperv.paravisor_present in arch/x86/include/asm/mshyperv.h:

struct ms_hyperv_info is defined in include/asm-generic/mshyperv.h, which
is included at the end of arch/x86/include/asm/mshyperv.h, but at the
beginning of arch/x86/include/asm/mshyperv.h, we would already need to use
struct ms_hyperv_info in hv_do_hypercall().

We use hyperv_paravisor_present only in include/asm-generic/mshyperv.h,
and use ms_hyperv.paravisor_present elsewhere. In the future, we'll
introduce a hypercall function structure for different VM types, and
at boot time, the right function pointers would be written into the
structure so that runtime testing of TDX vs. SNP vs. normal will be
avoided and hyperv_paravisor_present will no longer be needed.

Call hv_vtom_init() when it's a VBS VM or when ms_hyperv.paravisor_present
is true, i.e. the VM is a SNP VM or TDX VM with the paravisor.

Enhance hv_vtom_init() for a TDX VM with the paravisor.

In hv_common_cpu_init(), don't decrypt the hyperv_pcpu_input_arg
for a TDX VM with the paravisor, just like we don't decrypt the page
for a SNP VM with the paravisor.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2: None

Changes in v3:
  Improved the changelog
  Use ms_hyperv.paravisor_present in general and only use
    hyperv_paravisor_present in arch/x86/include/asm/mshyperv.h
  Fixed the build when CONFIG_AMD_MEM_ENCRYPT and/or
     CONFIG_INTEL_TDX_GUEST are not set.
  Updated arch/x86/include/asm/mshyperv.h accordingly  
  hv_vtom_init(): Fixed/added the comments
  Handled the TDX special case directly in vmbus_set_event().

 arch/x86/hyperv/hv_init.c       |  4 ++--
 arch/x86/hyperv/ivm.c           | 38 ++++++++++++++++++++++++++++++---
 arch/x86/include/asm/mshyperv.h | 15 ++++++++-----
 arch/x86/kernel/cpu/mshyperv.c  |  9 ++++++--
 drivers/hv/connection.c         | 15 +++++++++----
 drivers/hv/hv.c                 | 10 ++++-----
 drivers/hv/hv_common.c          |  3 ++-
 7 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index c1c1b4e1502f..eca5c4b7e3b5 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -658,8 +658,8 @@ bool hv_is_hyperv_initialized(void)
 	if (x86_hyper_type != X86_HYPER_MS_HYPERV)
 		return false;
 
-	/* A TDX guest uses the GHCI call rather than hv_hypercall_pg. */
-	if (hv_isolation_type_tdx())
+	/* A TDX VM with no paravisor uses TDX GHCI call rather than hv_hypercall_pg */
+	if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present)
 		return true;
 	/*
 	 * Verify that earlier initialization succeeded by checking
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 6c7598d9e68a..7bd0359d5e38 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -248,6 +248,9 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
 }
 EXPORT_SYMBOL_GPL(hv_ghcb_msr_read);
 
+#endif /* CONFIG_AMD_MEM_ENCRYPT */
+
+#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
 /*
  * hv_mark_gpa_visibility - Set pages visible to host via hvcall.
  *
@@ -368,6 +371,10 @@ static bool hv_is_private_mmio(u64 addr)
 	return false;
 }
 
+#endif /* defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST) */
+
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+
 #define hv_populate_vmcb_seg(seg, gdtr_base)			\
 do {								\
 	if (seg.selector) {					\
@@ -495,15 +502,40 @@ int hv_snp_boot_ap(int cpu, unsigned long start_ip)
 	return ret;
 }
 
+#endif /* CONFIG_AMD_MEM_ENCRYPT */
+
+#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
+
 void __init hv_vtom_init(void)
 {
+	enum hv_isolation_type type = hv_get_isolation_type();
+
+	switch (type) {
+	case HV_ISOLATION_TYPE_VBS:
+		fallthrough;
 	/*
 	 * By design, a VM using vTOM doesn't see the SEV setting,
 	 * so SEV initialization is bypassed and sev_status isn't set.
 	 * Set it here to indicate a vTOM VM.
+	 *
+	 * Note: if CONFIG_AMD_MEM_ENCRYPT is not set, sev_status is
+	 * defined as 0ULL, to which we can't assigned a value.
 	 */
-	sev_status = MSR_AMD64_SNP_VTOM;
-	cc_vendor = CC_VENDOR_AMD;
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+	case HV_ISOLATION_TYPE_SNP:
+		sev_status = MSR_AMD64_SNP_VTOM;
+		cc_vendor = CC_VENDOR_AMD;
+		break;
+#endif
+
+	case HV_ISOLATION_TYPE_TDX:
+		cc_vendor = CC_VENDOR_INTEL;
+		break;
+
+	default:
+		panic("hv_vtom_init: unsupported isolation type %d\n", type);
+	}
+
 	cc_set_mask(ms_hyperv.shared_gpa_boundary);
 	physical_mask &= ms_hyperv.shared_gpa_boundary - 1;
 
@@ -516,7 +548,7 @@ void __init hv_vtom_init(void)
 	mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK);
 }
 
-#endif /* CONFIG_AMD_MEM_ENCRYPT */
+#endif /* defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST) */
 
 enum hv_isolation_type hv_get_isolation_type(void)
 {
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 6a9e00c4730b..a9f453c39371 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -42,6 +42,7 @@ static inline unsigned char hv_get_nmi_reason(void)
 
 #if IS_ENABLED(CONFIG_HYPERV)
 extern int hyperv_init_cpuhp;
+extern bool hyperv_paravisor_present;
 
 extern void *hv_hypercall_pg;
 
@@ -75,7 +76,7 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
 	u64 hv_status;
 
 #ifdef CONFIG_X86_64
-	if (hv_isolation_type_tdx())
+	if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
 		return hv_tdx_hypercall(control, input_address, output_address);
 
 	if (hv_isolation_type_en_snp()) {
@@ -131,7 +132,7 @@ static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
 	u64 hv_status;
 
 #ifdef CONFIG_X86_64
-	if (hv_isolation_type_tdx())
+	if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
 		return hv_tdx_hypercall(control, input1, 0);
 
 	if (hv_isolation_type_en_snp()) {
@@ -185,7 +186,7 @@ static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
 	u64 hv_status;
 
 #ifdef CONFIG_X86_64
-	if (hv_isolation_type_tdx())
+	if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
 		return hv_tdx_hypercall(control, input1, input2);
 
 	if (hv_isolation_type_en_snp()) {
@@ -278,19 +279,23 @@ void hv_ghcb_msr_write(u64 msr, u64 value);
 void hv_ghcb_msr_read(u64 msr, u64 *value);
 bool hv_ghcb_negotiate_protocol(void);
 void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
-void hv_vtom_init(void);
 int hv_snp_boot_ap(int cpu, unsigned long start_ip);
 #else
 static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
 static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
 static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
 static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
-static inline void hv_vtom_init(void) {}
 static inline int hv_snp_boot_ap(int cpu, unsigned long start_ip) { return 0; }
 #endif
 
 extern bool hv_isolation_type_snp(void);
 
+#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
+void hv_vtom_init(void);
+#else
+static inline void hv_vtom_init(void) {}
+#endif
+
 static inline bool hv_is_synic_reg(unsigned int reg)
 {
 	return (reg >= HV_REGISTER_SCONTROL) &&
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index fe5393d759d3..4c5a174935ca 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -40,6 +40,10 @@ bool hv_root_partition;
 bool hv_nested;
 struct ms_hyperv_info ms_hyperv;
 
+/* Used in modules via hv_do_hypercall(): see arch/x86/include/asm/mshyperv.h */
+bool hyperv_paravisor_present __ro_after_init;
+EXPORT_SYMBOL_GPL(hyperv_paravisor_present);
+
 #if IS_ENABLED(CONFIG_HYPERV)
 static inline unsigned int hv_get_nested_reg(unsigned int reg)
 {
@@ -429,6 +433,8 @@ static void __init ms_hyperv_init_platform(void)
 			ms_hyperv.shared_gpa_boundary =
 				BIT_ULL(ms_hyperv.shared_gpa_boundary_bits);
 
+		hyperv_paravisor_present = !!ms_hyperv.paravisor_present;
+
 		pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n",
 			ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b);
 
@@ -526,8 +532,7 @@ static void __init ms_hyperv_init_platform(void)
 
 #if IS_ENABLED(CONFIG_HYPERV)
 	if ((hv_get_isolation_type() == HV_ISOLATION_TYPE_VBS) ||
-	    ((hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP) &&
-	    ms_hyperv.paravisor_present))
+	    ms_hyperv.paravisor_present)
 		hv_vtom_init();
 	/*
 	 * Setup the hook to get control post apic initialization.
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 02b54f85dc60..2dd972ca85dd 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -484,10 +484,17 @@ void vmbus_set_event(struct vmbus_channel *channel)
 
 	++channel->sig_events;
 
-	if (hv_isolation_type_snp())
-		hv_ghcb_hypercall(HVCALL_SIGNAL_EVENT, &channel->sig_event,
-				NULL, sizeof(channel->sig_event));
-	else
+	if (ms_hyperv.paravisor_present) {
+		if (hv_isolation_type_snp())
+			hv_ghcb_hypercall(HVCALL_SIGNAL_EVENT, &channel->sig_event,
+					  NULL, sizeof(channel->sig_event));
+		else if (hv_isolation_type_tdx())
+			hv_tdx_hypercall(HVCALL_SIGNAL_EVENT | HV_HYPERCALL_FAST_BIT,
+					 channel->sig_event, 0);
+		else
+			WARN_ON_ONCE(1);
+	} else {
 		hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
+	}
 }
 EXPORT_SYMBOL_GPL(vmbus_set_event);
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index d1064118a72f..48b1623112f0 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -109,7 +109,7 @@ int hv_synic_alloc(void)
 		 * Synic message and event pages are allocated by paravisor.
 		 * Skip these pages allocation here.
 		 */
-		if (!hv_isolation_type_snp() && !hv_root_partition) {
+		if (!ms_hyperv.paravisor_present && !hv_root_partition) {
 			hv_cpu->synic_message_page =
 				(void *)get_zeroed_page(GFP_ATOMIC);
 			if (hv_cpu->synic_message_page == NULL) {
@@ -226,7 +226,7 @@ void hv_synic_enable_regs(unsigned int cpu)
 	simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP);
 	simp.simp_enabled = 1;
 
-	if (hv_isolation_type_snp() || hv_root_partition) {
+	if (ms_hyperv.paravisor_present || hv_root_partition) {
 		/* Mask out vTOM bit. ioremap_cache() maps decrypted */
 		u64 base = (simp.base_simp_gpa << HV_HYP_PAGE_SHIFT) &
 				~ms_hyperv.shared_gpa_boundary;
@@ -245,7 +245,7 @@ void hv_synic_enable_regs(unsigned int cpu)
 	siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP);
 	siefp.siefp_enabled = 1;
 
-	if (hv_isolation_type_snp() || hv_root_partition) {
+	if (ms_hyperv.paravisor_present || hv_root_partition) {
 		/* Mask out vTOM bit. ioremap_cache() maps decrypted */
 		u64 base = (siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT) &
 				~ms_hyperv.shared_gpa_boundary;
@@ -328,7 +328,7 @@ void hv_synic_disable_regs(unsigned int cpu)
 	 * addresses.
 	 */
 	simp.simp_enabled = 0;
-	if (hv_isolation_type_snp() || hv_root_partition) {
+	if (ms_hyperv.paravisor_present || hv_root_partition) {
 		iounmap(hv_cpu->synic_message_page);
 		hv_cpu->synic_message_page = NULL;
 	} else {
@@ -340,7 +340,7 @@ void hv_synic_disable_regs(unsigned int cpu)
 	siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP);
 	siefp.siefp_enabled = 0;
 
-	if (hv_isolation_type_snp() || hv_root_partition) {
+	if (ms_hyperv.paravisor_present || hv_root_partition) {
 		iounmap(hv_cpu->synic_event_page);
 		hv_cpu->synic_event_page = NULL;
 	} else {
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 4c858e1636da..e62d64753902 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -382,7 +382,8 @@ int hv_common_cpu_init(unsigned int cpu)
 			*outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
 		}
 
-		if (hv_isolation_type_en_snp() || hv_isolation_type_tdx()) {
+		if (!ms_hyperv.paravisor_present &&
+		    (hv_isolation_type_en_snp() || hv_isolation_type_tdx())) {
 			ret = set_memory_decrypted((unsigned long)mem, pgcount);
 			if (ret) {
 				/* It may be unsafe to free 'mem' */
-- 
2.25.1


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

* [PATCH v3 07/10] Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the paravisor
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
                   ` (5 preceding siblings ...)
  2023-08-24  8:07 ` [PATCH v3 06/10] x86/hyperv: Introduce a global variable hyperv_paravisor_present Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24 14:07   ` Michael Kelley (LINUX)
  2023-08-24 14:40   ` Tianyu Lan
  2023-08-24  8:07 ` [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM " Dexuan Cui
                   ` (3 subsequent siblings)
  10 siblings, 2 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

The post_msg_page was removed in
commit 9a6b1a170ca8 ("Drivers: hv: vmbus: Remove the per-CPU post_msg_page")

However, it turns out that we need to bring it back, but only for a TDX VM
with the paravisor: in such a VM, the hyperv_pcpu_input_arg is not decrypted,
but the HVCALL_POST_MESSAGE in such a VM needs a decrypted page as the
hypercall input page: see the comments in hyperv_init() for a detailed
explanation.

Except for HVCALL_POST_MESSAGE and HVCALL_SIGNAL_EVENT, the other hypercalls
in a TDX VM with the paravisor still use hv_hypercall_pg and must use the
hyperv_pcpu_input_arg (which is encrypted in such a VM), when a hypercall
input page is used.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2: None

Changes in v3:
  hyperv_paravisor_present -> ms_hyperv.paravisor_present

 arch/x86/hyperv/hv_init.c | 20 +++++++++++--
 drivers/hv/hv.c           | 59 +++++++++++++++++++++++++++++++++++----
 drivers/hv/hyperv_vmbus.h | 11 ++++++++
 3 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index eca5c4b7e3b5..3729eee21e47 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -480,6 +480,22 @@ void __init hyperv_init(void)
 	 * Setup the hypercall page and enable hypercalls.
 	 * 1. Register the guest ID
 	 * 2. Enable the hypercall and register the hypercall page
+	 *
+	 * A TDX VM with no paravisor only uses TDX GHCI rather than hv_hypercall_pg:
+	 * when the hypercall input is a page, such a VM must pass a decrypted
+	 * page to Hyper-V, e.g. hv_post_message() uses the per-CPU page
+	 * hyperv_pcpu_input_arg, which is decrypted if no paravisor is present.
+	 *
+	 * A TDX VM with the paravisor uses hv_hypercall_pg for most hypercalls,
+	 * which are handled by the paravisor and the VM must use an encrypted
+	 * input page: in such a VM, the hyperv_pcpu_input_arg is encrypted and
+	 * used in the hypercalls, e.g. see hv_mark_gpa_visibility() and
+	 * hv_arch_irq_unmask(). Such a VM uses TDX GHCI for two hypercalls:
+	 * 1. HVCALL_SIGNAL_EVENT: see vmbus_set_event() and _hv_do_fast_hypercall8().
+	 * 2. HVCALL_POST_MESSAGE: the input page must be a decrypted page, i.e.
+	 * hv_post_message() in such a VM can't use the encrypted hyperv_pcpu_input_arg;
+	 * instead, hv_post_message() uses the post_msg_page, which is decrypted
+	 * in such a VM and is only used in such a VM.
 	 */
 	guest_id = hv_generate_guest_id(LINUX_VERSION_CODE);
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id);
@@ -487,8 +503,8 @@ void __init hyperv_init(void)
 	/* Hyper-V requires to write guest os id via ghcb in SNP IVM. */
 	hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, guest_id);
 
-	/* A TDX guest uses the GHCI call rather than hv_hypercall_pg. */
-	if (hv_isolation_type_tdx())
+	/* A TDX VM with no paravisor only uses TDX GHCI rather than hv_hypercall_pg */
+	if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present)
 		goto skip_hypercall_pg_init;
 
 	hv_hypercall_pg = __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START,
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 48b1623112f0..523c5d99f375 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -57,20 +57,37 @@ int hv_post_message(union hv_connection_id connection_id,
 
 	local_irq_save(flags);
 
-	aligned_msg = *this_cpu_ptr(hyperv_pcpu_input_arg);
+	/*
+	 * A TDX VM with the paravisor must use the decrypted post_msg_page: see
+	 * the comment in struct hv_per_cpu_context. A SNP VM with the paravisor
+	 * can use the encrypted hyperv_pcpu_input_arg because it copies the
+	 * input into the GHCB page, which has been decrypted by the paravisor.
+	 */
+	if (hv_isolation_type_tdx() && ms_hyperv.paravisor_present)
+		aligned_msg = this_cpu_ptr(hv_context.cpu_context)->post_msg_page;
+	else
+		aligned_msg = *this_cpu_ptr(hyperv_pcpu_input_arg);
+
 	aligned_msg->connectionid = connection_id;
 	aligned_msg->reserved = 0;
 	aligned_msg->message_type = message_type;
 	aligned_msg->payload_size = payload_size;
 	memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-	if (hv_isolation_type_snp())
-		status = hv_ghcb_hypercall(HVCALL_POST_MESSAGE,
-				(void *)aligned_msg, NULL,
-				sizeof(*aligned_msg));
-	else
+	if (ms_hyperv.paravisor_present) {
+		if (hv_isolation_type_tdx())
+			status = hv_tdx_hypercall(HVCALL_POST_MESSAGE,
+						  virt_to_phys(aligned_msg), 0);
+		else if (hv_isolation_type_snp())
+			status = hv_ghcb_hypercall(HVCALL_POST_MESSAGE,
+						   aligned_msg, NULL,
+						   sizeof(*aligned_msg));
+		else
+			status = HV_STATUS_INVALID_PARAMETER;
+	} else {
 		status = hv_do_hypercall(HVCALL_POST_MESSAGE,
 				aligned_msg, NULL);
+	}
 
 	local_irq_restore(flags);
 
@@ -105,6 +122,24 @@ int hv_synic_alloc(void)
 		tasklet_init(&hv_cpu->msg_dpc,
 			     vmbus_on_msg_dpc, (unsigned long) hv_cpu);
 
+		if (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) {
+			hv_cpu->post_msg_page = (void *)get_zeroed_page(GFP_ATOMIC);
+			if (hv_cpu->post_msg_page == NULL) {
+				pr_err("Unable to allocate post msg page\n");
+				goto err;
+			}
+
+			ret = set_memory_decrypted((unsigned long)hv_cpu->post_msg_page, 1);
+			if (ret) {
+				pr_err("Failed to decrypt post msg page: %d\n", ret);
+				/* Just leak the page, as it's unsafe to free the page. */
+				hv_cpu->post_msg_page = NULL;
+				goto err;
+			}
+
+			memset(hv_cpu->post_msg_page, 0, PAGE_SIZE);
+		}
+
 		/*
 		 * Synic message and event pages are allocated by paravisor.
 		 * Skip these pages allocation here.
@@ -178,6 +213,17 @@ void hv_synic_free(void)
 			= per_cpu_ptr(hv_context.cpu_context, cpu);
 
 		/* It's better to leak the page if the encryption fails. */
+		if (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) {
+			if (hv_cpu->post_msg_page) {
+				ret = set_memory_encrypted((unsigned long)
+					hv_cpu->post_msg_page, 1);
+				if (ret) {
+					pr_err("Failed to encrypt post msg page: %d\n", ret);
+					hv_cpu->post_msg_page = NULL;
+				}
+			}
+		}
+
 		if (!ms_hyperv.paravisor_present &&
 		    (hv_isolation_type_en_snp() || hv_isolation_type_tdx())) {
 			if (hv_cpu->synic_message_page) {
@@ -199,6 +245,7 @@ void hv_synic_free(void)
 			}
 		}
 
+		free_page((unsigned long)hv_cpu->post_msg_page);
 		free_page((unsigned long)hv_cpu->synic_event_page);
 		free_page((unsigned long)hv_cpu->synic_message_page);
 	}
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 55f2086841ae..f6b1e710f805 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -123,6 +123,17 @@ struct hv_per_cpu_context {
 	void *synic_message_page;
 	void *synic_event_page;
 
+	/*
+	 * The page is only used in hv_post_message() for a TDX VM (with the
+	 * paravisor) to post a messages to Hyper-V: when such a VM calls
+	 * HVCALL_POST_MESSAGE, it can't use the hyperv_pcpu_input_arg (which
+	 * is encrypted in such a VM) as the hypercall input page, because
+	 * the input page for HVCALL_POST_MESSAGE must be decrypted in such a
+	 * VM, so post_msg_page (which is decrypted in hv_synic_alloc()) is
+	 * introduced for this purpose. See hyperv_init() for more comments.
+	 */
+	void *post_msg_page;
+
 	/*
 	 * Starting with win8, we can take channel interrupts on any CPU;
 	 * we will manage the tasklet that handles events messages on a per CPU
-- 
2.25.1


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

* [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM with the paravisor
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
                   ` (6 preceding siblings ...)
  2023-08-24  8:07 ` [PATCH v3 07/10] Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the paravisor Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24 14:08   ` Michael Kelley (LINUX)
                     ` (2 more replies)
  2023-08-24  8:07 ` [PATCH v3 09/10] x86/hyperv: Remove hv_isolation_type_en_snp Dexuan Cui
                   ` (2 subsequent siblings)
  10 siblings, 3 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

When the paravisor is present, a SNP VM must use GHCB to access some
special MSRs, including HV_X64_MSR_GUEST_OS_ID and some SynIC MSRs.

Similarly, when the paravisor is present, a TDX VM must use TDX GHCI
to access the same MSRs.

Implement hv_tdx_msr_write() and hv_tdx_msr_read(), and use the helper
functions hv_ivm_msr_read() and hv_ivm_msr_write() to access the MSRs
in a unified way for SNP/TDX VMs with the paravisor.

Do not export hv_tdx_msr_write() and hv_tdx_msr_read(), because we never
really used hv_ghcb_msr_write() and hv_ghcb_msr_read() in any module.

Update arch/x86/include/asm/mshyperv.h so that the kernel can still build
if CONFIG_AMD_MEM_ENCRYPT or CONFIG_INTEL_TDX_GUEST is not set, or
neither is set.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2: None

Changes in v3:
  hv_tdx_read_msr -> hv_tdx_msr_read
  hv_tdx_write_msr -> hv_tdx_msr_write
  Do not export hv_tdx_msr_write() and hv_tdx_msr_read().
  included <uapi/asm/vmx.h>
  Updated arch/x86/include/asm/mshyperv.h so that the kernel
    can still build if CONFIG_AMD_MEM_ENCRYPT and/or
    CONFIG_INTEL_TDX_GUEST are not set.

 arch/x86/hyperv/hv_init.c       |  8 ++--
 arch/x86/hyperv/ivm.c           | 69 +++++++++++++++++++++++++++++++--
 arch/x86/include/asm/mshyperv.h |  8 ++--
 arch/x86/kernel/cpu/mshyperv.c  |  8 ++--
 4 files changed, 77 insertions(+), 16 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 3729eee21e47..c4cffa3b1c3c 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -500,8 +500,8 @@ void __init hyperv_init(void)
 	guest_id = hv_generate_guest_id(LINUX_VERSION_CODE);
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id);
 
-	/* Hyper-V requires to write guest os id via ghcb in SNP IVM. */
-	hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, guest_id);
+	/* With the paravisor, the VM must also write the ID via GHCB/GHCI */
+	hv_ivm_msr_write(HV_X64_MSR_GUEST_OS_ID, guest_id);
 
 	/* A TDX VM with no paravisor only uses TDX GHCI rather than hv_hypercall_pg */
 	if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present)
@@ -590,7 +590,7 @@ void __init hyperv_init(void)
 
 clean_guest_os_id:
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
-	hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
+	hv_ivm_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
 	cpuhp_remove_state(cpuhp);
 free_ghcb_page:
 	free_percpu(hv_ghcb_pg);
@@ -611,7 +611,7 @@ void hyperv_cleanup(void)
 
 	/* Reset our OS id */
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
-	hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
+	hv_ivm_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
 
 	/*
 	 * Reset hypercall page reference before reset the page,
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 7bd0359d5e38..fbc07493fcb4 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -24,6 +24,7 @@
 #include <asm/realmode.h>
 #include <asm/e820/api.h>
 #include <asm/desc.h>
+#include <uapi/asm/vmx.h>
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
 
@@ -186,7 +187,7 @@ bool hv_ghcb_negotiate_protocol(void)
 	return true;
 }
 
-void hv_ghcb_msr_write(u64 msr, u64 value)
+static void hv_ghcb_msr_write(u64 msr, u64 value)
 {
 	union hv_ghcb *hv_ghcb;
 	void **ghcb_base;
@@ -214,9 +215,8 @@ void hv_ghcb_msr_write(u64 msr, u64 value)
 
 	local_irq_restore(flags);
 }
-EXPORT_SYMBOL_GPL(hv_ghcb_msr_write);
 
-void hv_ghcb_msr_read(u64 msr, u64 *value)
+static void hv_ghcb_msr_read(u64 msr, u64 *value)
 {
 	union hv_ghcb *hv_ghcb;
 	void **ghcb_base;
@@ -246,10 +246,71 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
 			| ((u64)lower_32_bits(hv_ghcb->ghcb.save.rdx) << 32);
 	local_irq_restore(flags);
 }
-EXPORT_SYMBOL_GPL(hv_ghcb_msr_read);
 
+#else
+static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
+static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
 #endif /* CONFIG_AMD_MEM_ENCRYPT */
 
+#ifdef CONFIG_INTEL_TDX_GUEST
+static void hv_tdx_msr_write(u64 msr, u64 val)
+{
+	struct tdx_hypercall_args args = {
+		.r10 = TDX_HYPERCALL_STANDARD,
+		.r11 = EXIT_REASON_MSR_WRITE,
+		.r12 = msr,
+		.r13 = val,
+	};
+
+	u64 ret = __tdx_hypercall(&args);
+
+	WARN_ONCE(ret, "Failed to emulate MSR write: %lld\n", ret);
+}
+
+static void hv_tdx_msr_read(u64 msr, u64 *val)
+{
+	struct tdx_hypercall_args args = {
+		.r10 = TDX_HYPERCALL_STANDARD,
+		.r11 = EXIT_REASON_MSR_READ,
+		.r12 = msr,
+	};
+
+	u64 ret = __tdx_hypercall_ret(&args);
+
+	if (WARN_ONCE(ret, "Failed to emulate MSR read: %lld\n", ret))
+		*val = 0;
+	else
+		*val = args.r11;
+}
+#else
+static inline void hv_tdx_msr_write(u64 msr, u64 value) {}
+static inline void hv_tdx_msr_read(u64 msr, u64 *value) {}
+#endif /* CONFIG_INTEL_TDX_GUEST */
+
+#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
+void hv_ivm_msr_write(u64 msr, u64 value)
+{
+	if (!ms_hyperv.paravisor_present)
+		return;
+
+	if (hv_isolation_type_tdx())
+		hv_tdx_msr_write(msr, value);
+	else if (hv_isolation_type_snp())
+		hv_ghcb_msr_write(msr, value);
+}
+
+void hv_ivm_msr_read(u64 msr, u64 *value)
+{
+	if (!ms_hyperv.paravisor_present)
+		return;
+
+	if (hv_isolation_type_tdx())
+		hv_tdx_msr_read(msr, value);
+	else if (hv_isolation_type_snp())
+		hv_ghcb_msr_read(msr, value);
+}
+#endif
+
 #if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
 /*
  * hv_mark_gpa_visibility - Set pages visible to host via hvcall.
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index a9f453c39371..101f71b85cfd 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -275,14 +275,10 @@ int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
 int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
-void hv_ghcb_msr_write(u64 msr, u64 value);
-void hv_ghcb_msr_read(u64 msr, u64 *value);
 bool hv_ghcb_negotiate_protocol(void);
 void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
 int hv_snp_boot_ap(int cpu, unsigned long start_ip);
 #else
-static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
-static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
 static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
 static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
 static inline int hv_snp_boot_ap(int cpu, unsigned long start_ip) { return 0; }
@@ -292,8 +288,12 @@ extern bool hv_isolation_type_snp(void);
 
 #if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
 void hv_vtom_init(void);
+void hv_ivm_msr_write(u64 msr, u64 value);
+void hv_ivm_msr_read(u64 msr, u64 *value);
 #else
 static inline void hv_vtom_init(void) {}
+static inline void hv_ivm_msr_write(u64 msr, u64 value) {}
+static inline void hv_ivm_msr_read(u64 msr, u64 *value) {}
 #endif
 
 static inline bool hv_is_synic_reg(unsigned int reg)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 4c5a174935ca..4f51dac9eeb2 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -70,8 +70,8 @@ u64 hv_get_non_nested_register(unsigned int reg)
 {
 	u64 value;
 
-	if (hv_is_synic_reg(reg) && hv_isolation_type_snp())
-		hv_ghcb_msr_read(reg, &value);
+	if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present)
+		hv_ivm_msr_read(reg, &value);
 	else
 		rdmsrl(reg, value);
 	return value;
@@ -80,8 +80,8 @@ EXPORT_SYMBOL_GPL(hv_get_non_nested_register);
 
 void hv_set_non_nested_register(unsigned int reg, u64 value)
 {
-	if (hv_is_synic_reg(reg) && hv_isolation_type_snp()) {
-		hv_ghcb_msr_write(reg, value);
+	if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) {
+		hv_ivm_msr_write(reg, value);
 
 		/* Write proxy bit via wrmsl instruction */
 		if (hv_is_sint_reg(reg))
-- 
2.25.1


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

* [PATCH v3 09/10] x86/hyperv: Remove hv_isolation_type_en_snp
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
                   ` (7 preceding siblings ...)
  2023-08-24  8:07 ` [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM " Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24 14:09   ` Michael Kelley (LINUX)
  2023-08-24 14:45   ` Tianyu Lan
  2023-08-24  8:07 ` [PATCH v3 10/10] x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's Dexuan Cui
  2023-08-25  0:05 ` [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Wei Liu
  10 siblings, 2 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

In ms_hyperv_init_platform(), do not distinguish between a SNP VM with
the paravisor and a SNP VM without the paravisor.

Replace hv_isolation_type_en_snp() with
!ms_hyperv.paravisor_present && hv_isolation_type_snp().

The hv_isolation_type_en_snp() in drivers/hv/hv.c and
drivers/hv/hv_common.c can be changed to hv_isolation_type_snp() since
we know !ms_hyperv.paravisor_present is true there.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

Changes in v2:
  Rebased to Tianyu's v7 SNP patchset: the changes are small.
    In hyperv_init_ghcb() and hyperv_init(), added the test of
hyperv_paravisor_present, which was missed in v1.
    Updated the test before the call of get_vtl().
    Updated the test in hv_do_hypercall() and friends.
    Updated the test for hv_smp_prepare_cpus().

Changes in v3:
  hyperv_paravisor_present -> ms_hyperv.paravisor_present
  

 arch/x86/hyperv/hv_init.c       |  8 ++++----
 arch/x86/hyperv/ivm.c           | 12 +-----------
 arch/x86/include/asm/mshyperv.h | 11 ++++-------
 arch/x86/kernel/cpu/mshyperv.c  | 10 ++++------
 drivers/hv/hv.c                 |  4 ++--
 drivers/hv/hv_common.c          |  8 +-------
 include/asm-generic/mshyperv.h  |  3 +--
 7 files changed, 17 insertions(+), 39 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index c4cffa3b1c3c..2b0124394e24 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -52,7 +52,7 @@ static int hyperv_init_ghcb(void)
 	void *ghcb_va;
 	void **ghcb_base;
 
-	if (!hv_isolation_type_snp())
+	if (!ms_hyperv.paravisor_present || !hv_isolation_type_snp())
 		return 0;
 
 	if (!hv_ghcb_pg)
@@ -117,7 +117,7 @@ static int hv_cpu_init(unsigned int cpu)
 			 * is blocked to run in Confidential VM. So only decrypt assist
 			 * page in non-root partition here.
 			 */
-			if (*hvp && hv_isolation_type_en_snp()) {
+			if (*hvp && !ms_hyperv.paravisor_present && hv_isolation_type_snp()) {
 				WARN_ON_ONCE(set_memory_decrypted((unsigned long)(*hvp), 1));
 				memset(*hvp, 0, PAGE_SIZE);
 			}
@@ -460,7 +460,7 @@ void __init hyperv_init(void)
 			goto common_free;
 	}
 
-	if (hv_isolation_type_snp()) {
+	if (ms_hyperv.paravisor_present && hv_isolation_type_snp()) {
 		/* Negotiate GHCB Version. */
 		if (!hv_ghcb_negotiate_protocol())
 			hv_ghcb_terminate(SEV_TERM_SET_GEN,
@@ -583,7 +583,7 @@ void __init hyperv_init(void)
 	hv_query_ext_cap(0);
 
 	/* Find the VTL */
-	if (hv_isolation_type_en_snp())
+	if (!ms_hyperv.paravisor_present && hv_isolation_type_snp())
 		ms_hyperv.vtl = get_vtl();
 
 	return;
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index fbc07493fcb4..3d48f823582c 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -637,7 +637,7 @@ bool hv_is_isolation_supported(void)
 DEFINE_STATIC_KEY_FALSE(isolation_type_snp);
 
 /*
- * hv_isolation_type_snp - Check system runs in the AMD SEV-SNP based
+ * hv_isolation_type_snp - Check if the system runs in an AMD SEV-SNP based
  * isolation VM.
  */
 bool hv_isolation_type_snp(void)
@@ -645,16 +645,6 @@ bool hv_isolation_type_snp(void)
 	return static_branch_unlikely(&isolation_type_snp);
 }
 
-DEFINE_STATIC_KEY_FALSE(isolation_type_en_snp);
-/*
- * hv_isolation_type_en_snp - Check system runs in the AMD SEV-SNP based
- * isolation enlightened VM.
- */
-bool hv_isolation_type_en_snp(void)
-{
-	return static_branch_unlikely(&isolation_type_en_snp);
-}
-
 DEFINE_STATIC_KEY_FALSE(isolation_type_tdx);
 /*
  * hv_isolation_type_tdx - Check if the system runs in an Intel TDX based
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 101f71b85cfd..66ca641a164a 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -26,7 +26,6 @@
 union hv_ghcb;
 
 DECLARE_STATIC_KEY_FALSE(isolation_type_snp);
-DECLARE_STATIC_KEY_FALSE(isolation_type_en_snp);
 DECLARE_STATIC_KEY_FALSE(isolation_type_tdx);
 
 typedef int (*hyperv_fill_flush_list_func)(
@@ -50,7 +49,7 @@ extern u64 hv_current_partition_id;
 
 extern union hv_ghcb * __percpu *hv_ghcb_pg;
 
-extern bool hv_isolation_type_en_snp(void);
+bool hv_isolation_type_snp(void);
 bool hv_isolation_type_tdx(void);
 u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 
@@ -79,7 +78,7 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
 	if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
 		return hv_tdx_hypercall(control, input_address, output_address);
 
-	if (hv_isolation_type_en_snp()) {
+	if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
 		__asm__ __volatile__("mov %4, %%r8\n"
 				     "vmmcall"
 				     : "=a" (hv_status), ASM_CALL_CONSTRAINT,
@@ -135,7 +134,7 @@ static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
 	if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
 		return hv_tdx_hypercall(control, input1, 0);
 
-	if (hv_isolation_type_en_snp()) {
+	if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
 		__asm__ __volatile__(
 				"vmmcall"
 				: "=a" (hv_status), ASM_CALL_CONSTRAINT,
@@ -189,7 +188,7 @@ static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
 	if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
 		return hv_tdx_hypercall(control, input1, input2);
 
-	if (hv_isolation_type_en_snp()) {
+	if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
 		__asm__ __volatile__("mov %4, %%r8\n"
 				     "vmmcall"
 				     : "=a" (hv_status), ASM_CALL_CONSTRAINT,
@@ -284,8 +283,6 @@ static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
 static inline int hv_snp_boot_ap(int cpu, unsigned long start_ip) { return 0; }
 #endif
 
-extern bool hv_isolation_type_snp(void);
-
 #if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
 void hv_vtom_init(void);
 void hv_ivm_msr_write(u64 msr, u64 value);
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 4f51dac9eeb2..b63590ffc777 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -304,7 +304,7 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
 	 *  Override wakeup_secondary_cpu_64 callback for SEV-SNP
 	 *  enlightened guest.
 	 */
-	if (hv_isolation_type_en_snp()) {
+	if (!ms_hyperv.paravisor_present && hv_isolation_type_snp()) {
 		apic->wakeup_secondary_cpu_64 = hv_snp_boot_ap;
 		return;
 	}
@@ -440,10 +440,7 @@ static void __init ms_hyperv_init_platform(void)
 
 
 		if (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP) {
-			if (ms_hyperv.paravisor_present)
-				static_branch_enable(&isolation_type_snp);
-			else
-				static_branch_enable(&isolation_type_en_snp);
+			static_branch_enable(&isolation_type_snp);
 		} else if (hv_get_isolation_type() == HV_ISOLATION_TYPE_TDX) {
 			static_branch_enable(&isolation_type_tdx);
 
@@ -556,7 +553,8 @@ static void __init ms_hyperv_init_platform(void)
 
 # ifdef CONFIG_SMP
 	smp_ops.smp_prepare_boot_cpu = hv_smp_prepare_boot_cpu;
-	if (hv_root_partition || hv_isolation_type_en_snp())
+	if (hv_root_partition ||
+	    (!ms_hyperv.paravisor_present && hv_isolation_type_snp()))
 		smp_ops.smp_prepare_cpus = hv_smp_prepare_cpus;
 # endif
 
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 523c5d99f375..51e5018ac9b2 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -164,7 +164,7 @@ int hv_synic_alloc(void)
 		}
 
 		if (!ms_hyperv.paravisor_present &&
-		    (hv_isolation_type_en_snp() || hv_isolation_type_tdx())) {
+		    (hv_isolation_type_snp() || hv_isolation_type_tdx())) {
 			ret = set_memory_decrypted((unsigned long)
 				hv_cpu->synic_message_page, 1);
 			if (ret) {
@@ -225,7 +225,7 @@ void hv_synic_free(void)
 		}
 
 		if (!ms_hyperv.paravisor_present &&
-		    (hv_isolation_type_en_snp() || hv_isolation_type_tdx())) {
+		    (hv_isolation_type_snp() || hv_isolation_type_tdx())) {
 			if (hv_cpu->synic_message_page) {
 				ret = set_memory_encrypted((unsigned long)
 					hv_cpu->synic_message_page, 1);
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index e62d64753902..81aa8be3e0df 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -383,7 +383,7 @@ int hv_common_cpu_init(unsigned int cpu)
 		}
 
 		if (!ms_hyperv.paravisor_present &&
-		    (hv_isolation_type_en_snp() || hv_isolation_type_tdx())) {
+		    (hv_isolation_type_snp() || hv_isolation_type_tdx())) {
 			ret = set_memory_decrypted((unsigned long)mem, pgcount);
 			if (ret) {
 				/* It may be unsafe to free 'mem' */
@@ -532,12 +532,6 @@ bool __weak hv_isolation_type_snp(void)
 }
 EXPORT_SYMBOL_GPL(hv_isolation_type_snp);
 
-bool __weak hv_isolation_type_en_snp(void)
-{
-	return false;
-}
-EXPORT_SYMBOL_GPL(hv_isolation_type_en_snp);
-
 bool __weak hv_isolation_type_tdx(void)
 {
 	return false;
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index f577eff58ea0..e7ecf03f675e 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -64,8 +64,7 @@ extern void * __percpu *hyperv_pcpu_output_arg;
 
 extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
 extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
-extern bool hv_isolation_type_snp(void);
-extern bool hv_isolation_type_en_snp(void);
+bool hv_isolation_type_snp(void);
 bool hv_isolation_type_tdx(void);
 
 /* Helper functions that provide a consistent pattern for checking Hyper-V hypercall status. */
-- 
2.25.1


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

* [PATCH v3 10/10] x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
                   ` (8 preceding siblings ...)
  2023-08-24  8:07 ` [PATCH v3 09/10] x86/hyperv: Remove hv_isolation_type_en_snp Dexuan Cui
@ 2023-08-24  8:07 ` Dexuan Cui
  2023-08-24 14:10   ` Michael Kelley (LINUX)
  2023-08-24 14:46   ` Tianyu Lan
  2023-08-25  0:05 ` [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Wei Liu
  10 siblings, 2 replies; 24+ messages in thread
From: Dexuan Cui @ 2023-08-24  8:07 UTC (permalink / raw)
  To: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li, Dexuan Cui

Group the code this way so that we can avoid too many ifdef's:

  Data only used in an SNP VM with the paravisor;
  Functions only used in an SNP VM with the paravisor;

  Data only used in an SNP VM without the paravisor;
  Functions only used in an SNP VM without the paravisor;

  Functions only used in a TDX VM, with and without the paravisor;

  Functions used in an SNP or TDX VM, when the paravisor is present;

  Functions always used, even in a regular non-CoCo VM.

No functional change.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

   This patch appears the first time in v3.

 arch/x86/hyperv/ivm.c | 309 ++++++++++++++++++++----------------------
 1 file changed, 150 insertions(+), 159 deletions(-)

diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 3d48f823582c..8fb3b28670e9 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -30,9 +30,6 @@
 
 #define GHCB_USAGE_HYPERV_CALL	1
 
-static u8 ap_start_input_arg[PAGE_SIZE] __bss_decrypted __aligned(PAGE_SIZE);
-static u8 ap_start_stack[PAGE_SIZE] __aligned(PAGE_SIZE);
-
 union hv_ghcb {
 	struct ghcb ghcb;
 	struct {
@@ -66,10 +63,10 @@ union hv_ghcb {
 	} hypercall;
 } __packed __aligned(HV_HYP_PAGE_SIZE);
 
-static DEFINE_PER_CPU(struct sev_es_save_area *, hv_sev_vmsa);
-
+/* Only used in an SNP VM with the paravisor */
 static u16 hv_ghcb_version __ro_after_init;
 
+/* Functions only used in an SNP VM with the paravisor go here. */
 u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size)
 {
 	union hv_ghcb *hv_ghcb;
@@ -247,6 +244,140 @@ static void hv_ghcb_msr_read(u64 msr, u64 *value)
 	local_irq_restore(flags);
 }
 
+/* Only used in a fully enlightened SNP VM, i.e. without the paravisor */
+static u8 ap_start_input_arg[PAGE_SIZE] __bss_decrypted __aligned(PAGE_SIZE);
+static u8 ap_start_stack[PAGE_SIZE] __aligned(PAGE_SIZE);
+static DEFINE_PER_CPU(struct sev_es_save_area *, hv_sev_vmsa);
+
+/* Functions only used in an SNP VM without the paravisor go here. */
+
+#define hv_populate_vmcb_seg(seg, gdtr_base)			\
+do {								\
+	if (seg.selector) {					\
+		seg.base = 0;					\
+		seg.limit = HV_AP_SEGMENT_LIMIT;		\
+		seg.attrib = *(u16 *)(gdtr_base + seg.selector + 5);	\
+		seg.attrib = (seg.attrib & 0xFF) | ((seg.attrib >> 4) & 0xF00); \
+	}							\
+} while (0)							\
+
+static int snp_set_vmsa(void *va, bool vmsa)
+{
+	u64 attrs;
+
+	/*
+	 * Running at VMPL0 allows the kernel to change the VMSA bit for a page
+	 * using the RMPADJUST instruction. However, for the instruction to
+	 * succeed it must target the permissions of a lesser privileged
+	 * (higher numbered) VMPL level, so use VMPL1 (refer to the RMPADJUST
+	 * instruction in the AMD64 APM Volume 3).
+	 */
+	attrs = 1;
+	if (vmsa)
+		attrs |= RMPADJUST_VMSA_PAGE_BIT;
+
+	return rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs);
+}
+
+static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa)
+{
+	int err;
+
+	err = snp_set_vmsa(vmsa, false);
+	if (err)
+		pr_err("clear VMSA page failed (%u), leaking page\n", err);
+	else
+		free_page((unsigned long)vmsa);
+}
+
+int hv_snp_boot_ap(int cpu, unsigned long start_ip)
+{
+	struct sev_es_save_area *vmsa = (struct sev_es_save_area *)
+		__get_free_page(GFP_KERNEL | __GFP_ZERO);
+	struct sev_es_save_area *cur_vmsa;
+	struct desc_ptr gdtr;
+	u64 ret, retry = 5;
+	struct hv_enable_vp_vtl *start_vp_input;
+	unsigned long flags;
+
+	if (!vmsa)
+		return -ENOMEM;
+
+	native_store_gdt(&gdtr);
+
+	vmsa->gdtr.base = gdtr.address;
+	vmsa->gdtr.limit = gdtr.size;
+
+	asm volatile("movl %%es, %%eax;" : "=a" (vmsa->es.selector));
+	hv_populate_vmcb_seg(vmsa->es, vmsa->gdtr.base);
+
+	asm volatile("movl %%cs, %%eax;" : "=a" (vmsa->cs.selector));
+	hv_populate_vmcb_seg(vmsa->cs, vmsa->gdtr.base);
+
+	asm volatile("movl %%ss, %%eax;" : "=a" (vmsa->ss.selector));
+	hv_populate_vmcb_seg(vmsa->ss, vmsa->gdtr.base);
+
+	asm volatile("movl %%ds, %%eax;" : "=a" (vmsa->ds.selector));
+	hv_populate_vmcb_seg(vmsa->ds, vmsa->gdtr.base);
+
+	vmsa->efer = native_read_msr(MSR_EFER);
+
+	asm volatile("movq %%cr4, %%rax;" : "=a" (vmsa->cr4));
+	asm volatile("movq %%cr3, %%rax;" : "=a" (vmsa->cr3));
+	asm volatile("movq %%cr0, %%rax;" : "=a" (vmsa->cr0));
+
+	vmsa->xcr0 = 1;
+	vmsa->g_pat = HV_AP_INIT_GPAT_DEFAULT;
+	vmsa->rip = (u64)secondary_startup_64_no_verify;
+	vmsa->rsp = (u64)&ap_start_stack[PAGE_SIZE];
+
+	/*
+	 * Set the SNP-specific fields for this VMSA:
+	 *   VMPL level
+	 *   SEV_FEATURES (matches the SEV STATUS MSR right shifted 2 bits)
+	 */
+	vmsa->vmpl = 0;
+	vmsa->sev_features = sev_status >> 2;
+
+	ret = snp_set_vmsa(vmsa, true);
+	if (!ret) {
+		pr_err("RMPADJUST(%llx) failed: %llx\n", (u64)vmsa, ret);
+		free_page((u64)vmsa);
+		return ret;
+	}
+
+	local_irq_save(flags);
+	start_vp_input = (struct hv_enable_vp_vtl *)ap_start_input_arg;
+	memset(start_vp_input, 0, sizeof(*start_vp_input));
+	start_vp_input->partition_id = -1;
+	start_vp_input->vp_index = cpu;
+	start_vp_input->target_vtl.target_vtl = ms_hyperv.vtl;
+	*(u64 *)&start_vp_input->vp_context = __pa(vmsa) | 1;
+
+	do {
+		ret = hv_do_hypercall(HVCALL_START_VP,
+				      start_vp_input, NULL);
+	} while (hv_result(ret) == HV_STATUS_TIME_OUT && retry--);
+
+	local_irq_restore(flags);
+
+	if (!hv_result_success(ret)) {
+		pr_err("HvCallStartVirtualProcessor failed: %llx\n", ret);
+		snp_cleanup_vmsa(vmsa);
+		vmsa = NULL;
+	}
+
+	cur_vmsa = per_cpu(hv_sev_vmsa, cpu);
+	/* Free up any previous VMSA page */
+	if (cur_vmsa)
+		snp_cleanup_vmsa(cur_vmsa);
+
+	/* Record the current VMSA page */
+	per_cpu(hv_sev_vmsa, cpu) = vmsa;
+
+	return ret;
+}
+
 #else
 static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
 static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
@@ -282,6 +413,20 @@ static void hv_tdx_msr_read(u64 msr, u64 *val)
 	else
 		*val = args.r11;
 }
+
+u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2)
+{
+	struct tdx_hypercall_args args = { };
+
+	args.r10 = control;
+	args.rdx = param1;
+	args.r8  = param2;
+
+	(void)__tdx_hypercall_ret(&args);
+
+	return args.r11;
+}
+
 #else
 static inline void hv_tdx_msr_write(u64 msr, u64 value) {}
 static inline void hv_tdx_msr_read(u64 msr, u64 *value) {}
@@ -309,9 +454,7 @@ void hv_ivm_msr_read(u64 msr, u64 *value)
 	else if (hv_isolation_type_snp())
 		hv_ghcb_msr_read(msr, value);
 }
-#endif
 
-#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
 /*
  * hv_mark_gpa_visibility - Set pages visible to host via hvcall.
  *
@@ -432,141 +575,6 @@ static bool hv_is_private_mmio(u64 addr)
 	return false;
 }
 
-#endif /* defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST) */
-
-#ifdef CONFIG_AMD_MEM_ENCRYPT
-
-#define hv_populate_vmcb_seg(seg, gdtr_base)			\
-do {								\
-	if (seg.selector) {					\
-		seg.base = 0;					\
-		seg.limit = HV_AP_SEGMENT_LIMIT;		\
-		seg.attrib = *(u16 *)(gdtr_base + seg.selector + 5);	\
-		seg.attrib = (seg.attrib & 0xFF) | ((seg.attrib >> 4) & 0xF00); \
-	}							\
-} while (0)							\
-
-static int snp_set_vmsa(void *va, bool vmsa)
-{
-	u64 attrs;
-
-	/*
-	 * Running at VMPL0 allows the kernel to change the VMSA bit for a page
-	 * using the RMPADJUST instruction. However, for the instruction to
-	 * succeed it must target the permissions of a lesser privileged
-	 * (higher numbered) VMPL level, so use VMPL1 (refer to the RMPADJUST
-	 * instruction in the AMD64 APM Volume 3).
-	 */
-	attrs = 1;
-	if (vmsa)
-		attrs |= RMPADJUST_VMSA_PAGE_BIT;
-
-	return rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs);
-}
-
-static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa)
-{
-	int err;
-
-	err = snp_set_vmsa(vmsa, false);
-	if (err)
-		pr_err("clear VMSA page failed (%u), leaking page\n", err);
-	else
-		free_page((unsigned long)vmsa);
-}
-
-int hv_snp_boot_ap(int cpu, unsigned long start_ip)
-{
-	struct sev_es_save_area *vmsa = (struct sev_es_save_area *)
-		__get_free_page(GFP_KERNEL | __GFP_ZERO);
-	struct sev_es_save_area *cur_vmsa;
-	struct desc_ptr gdtr;
-	u64 ret, retry = 5;
-	struct hv_enable_vp_vtl *start_vp_input;
-	unsigned long flags;
-
-	if (!vmsa)
-		return -ENOMEM;
-
-	native_store_gdt(&gdtr);
-
-	vmsa->gdtr.base = gdtr.address;
-	vmsa->gdtr.limit = gdtr.size;
-
-	asm volatile("movl %%es, %%eax;" : "=a" (vmsa->es.selector));
-	hv_populate_vmcb_seg(vmsa->es, vmsa->gdtr.base);
-
-	asm volatile("movl %%cs, %%eax;" : "=a" (vmsa->cs.selector));
-	hv_populate_vmcb_seg(vmsa->cs, vmsa->gdtr.base);
-
-	asm volatile("movl %%ss, %%eax;" : "=a" (vmsa->ss.selector));
-	hv_populate_vmcb_seg(vmsa->ss, vmsa->gdtr.base);
-
-	asm volatile("movl %%ds, %%eax;" : "=a" (vmsa->ds.selector));
-	hv_populate_vmcb_seg(vmsa->ds, vmsa->gdtr.base);
-
-	vmsa->efer = native_read_msr(MSR_EFER);
-
-	asm volatile("movq %%cr4, %%rax;" : "=a" (vmsa->cr4));
-	asm volatile("movq %%cr3, %%rax;" : "=a" (vmsa->cr3));
-	asm volatile("movq %%cr0, %%rax;" : "=a" (vmsa->cr0));
-
-	vmsa->xcr0 = 1;
-	vmsa->g_pat = HV_AP_INIT_GPAT_DEFAULT;
-	vmsa->rip = (u64)secondary_startup_64_no_verify;
-	vmsa->rsp = (u64)&ap_start_stack[PAGE_SIZE];
-
-	/*
-	 * Set the SNP-specific fields for this VMSA:
-	 *   VMPL level
-	 *   SEV_FEATURES (matches the SEV STATUS MSR right shifted 2 bits)
-	 */
-	vmsa->vmpl = 0;
-	vmsa->sev_features = sev_status >> 2;
-
-	ret = snp_set_vmsa(vmsa, true);
-	if (!ret) {
-		pr_err("RMPADJUST(%llx) failed: %llx\n", (u64)vmsa, ret);
-		free_page((u64)vmsa);
-		return ret;
-	}
-
-	local_irq_save(flags);
-	start_vp_input = (struct hv_enable_vp_vtl *)ap_start_input_arg;
-	memset(start_vp_input, 0, sizeof(*start_vp_input));
-	start_vp_input->partition_id = -1;
-	start_vp_input->vp_index = cpu;
-	start_vp_input->target_vtl.target_vtl = ms_hyperv.vtl;
-	*(u64 *)&start_vp_input->vp_context = __pa(vmsa) | 1;
-
-	do {
-		ret = hv_do_hypercall(HVCALL_START_VP,
-				      start_vp_input, NULL);
-	} while (hv_result(ret) == HV_STATUS_TIME_OUT && retry--);
-
-	local_irq_restore(flags);
-
-	if (!hv_result_success(ret)) {
-		pr_err("HvCallStartVirtualProcessor failed: %llx\n", ret);
-		snp_cleanup_vmsa(vmsa);
-		vmsa = NULL;
-	}
-
-	cur_vmsa = per_cpu(hv_sev_vmsa, cpu);
-	/* Free up any previous VMSA page */
-	if (cur_vmsa)
-		snp_cleanup_vmsa(cur_vmsa);
-
-	/* Record the current VMSA page */
-	per_cpu(hv_sev_vmsa, cpu) = vmsa;
-
-	return ret;
-}
-
-#endif /* CONFIG_AMD_MEM_ENCRYPT */
-
-#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
-
 void __init hv_vtom_init(void)
 {
 	enum hv_isolation_type type = hv_get_isolation_type();
@@ -654,20 +662,3 @@ bool hv_isolation_type_tdx(void)
 {
 	return static_branch_unlikely(&isolation_type_tdx);
 }
-
-#ifdef CONFIG_INTEL_TDX_GUEST
-
-u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2)
-{
-	struct tdx_hypercall_args args = { };
-
-	args.r10 = control;
-	args.rdx = param1;
-	args.r8  = param2;
-
-	(void)__tdx_hypercall_ret(&args);
-
-	return args.r11;
-}
-
-#endif
-- 
2.25.1


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

* RE: [PATCH v3 06/10] x86/hyperv: Introduce a global variable hyperv_paravisor_present
  2023-08-24  8:07 ` [PATCH v3 06/10] x86/hyperv: Introduce a global variable hyperv_paravisor_present Dexuan Cui
@ 2023-08-24 14:06   ` Michael Kelley (LINUX)
  2023-08-24 14:41   ` Tianyu Lan
  1 sibling, 0 replies; 24+ messages in thread
From: Michael Kelley (LINUX) @ 2023-08-24 14:06 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, Haiyang Zhang, hpa, jane.chu,
	kirill.shutemov, KY Srinivasan, linux-hyperv, luto, mingo,
	peterz, rostedt, sathyanarayanan.kuppuswamy, seanjc, tglx,
	tony.luck, wei.liu, jason, nik.borisov
  Cc: x86, linux-kernel, linux-arch, Tianyu Lan, rick.p.edgecombe,
	Anthony Davis, Mark Heslin, vkuznets, xiaoyao.li

From: Dexuan Cui <decui@microsoft.com> Sent: Thursday, August 24, 2023 1:07 AM
> 
> The new variable hyperv_paravisor_present is set only when the VM
> is a SNP/TDX VM with the paravisor running: see ms_hyperv_init_platform().
> 
> We introduce hyperv_paravisor_present because we can not use
> ms_hyperv.paravisor_present in arch/x86/include/asm/mshyperv.h:
> 
> struct ms_hyperv_info is defined in include/asm-generic/mshyperv.h, which
> is included at the end of arch/x86/include/asm/mshyperv.h, but at the
> beginning of arch/x86/include/asm/mshyperv.h, we would already need to use
> struct ms_hyperv_info in hv_do_hypercall().
> 
> We use hyperv_paravisor_present only in include/asm-generic/mshyperv.h,
> and use ms_hyperv.paravisor_present elsewhere. In the future, we'll
> introduce a hypercall function structure for different VM types, and
> at boot time, the right function pointers would be written into the
> structure so that runtime testing of TDX vs. SNP vs. normal will be
> avoided and hyperv_paravisor_present will no longer be needed.
> 
> Call hv_vtom_init() when it's a VBS VM or when ms_hyperv.paravisor_present
> is true, i.e. the VM is a SNP VM or TDX VM with the paravisor.
> 
> Enhance hv_vtom_init() for a TDX VM with the paravisor.
> 
> In hv_common_cpu_init(), don't decrypt the hyperv_pcpu_input_arg
> for a TDX VM with the paravisor, just like we don't decrypt the page
> for a SNP VM with the paravisor.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> ---
> 
> Changes in v2: None
> 
> Changes in v3:
>   Improved the changelog
>   Use ms_hyperv.paravisor_present in general and only use
>     hyperv_paravisor_present in arch/x86/include/asm/mshyperv.h
>   Fixed the build when CONFIG_AMD_MEM_ENCRYPT and/or
>      CONFIG_INTEL_TDX_GUEST are not set.
>   Updated arch/x86/include/asm/mshyperv.h accordingly
>   hv_vtom_init(): Fixed/added the comments
>   Handled the TDX special case directly in vmbus_set_event().
> 
>  arch/x86/hyperv/hv_init.c       |  4 ++--
>  arch/x86/hyperv/ivm.c           | 38 ++++++++++++++++++++++++++++++---
>  arch/x86/include/asm/mshyperv.h | 15 ++++++++-----
>  arch/x86/kernel/cpu/mshyperv.c  |  9 ++++++--
>  drivers/hv/connection.c         | 15 +++++++++----
>  drivers/hv/hv.c                 | 10 ++++-----
>  drivers/hv/hv_common.c          |  3 ++-
>  7 files changed, 72 insertions(+), 22 deletions(-)

Reviewed-by: Michael Kelley <mikelley@microsoft.com>

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

* RE: [PATCH v3 07/10] Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the paravisor
  2023-08-24  8:07 ` [PATCH v3 07/10] Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the paravisor Dexuan Cui
@ 2023-08-24 14:07   ` Michael Kelley (LINUX)
  2023-08-24 14:40   ` Tianyu Lan
  1 sibling, 0 replies; 24+ messages in thread
From: Michael Kelley (LINUX) @ 2023-08-24 14:07 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, Haiyang Zhang, hpa, jane.chu,
	kirill.shutemov, KY Srinivasan, linux-hyperv, luto, mingo,
	peterz, rostedt, sathyanarayanan.kuppuswamy, seanjc, tglx,
	tony.luck, wei.liu, jason, nik.borisov
  Cc: x86, linux-kernel, linux-arch, Tianyu Lan, rick.p.edgecombe,
	Anthony Davis, Mark Heslin, vkuznets, xiaoyao.li

From: Dexuan Cui <decui@microsoft.com> Sent: Thursday, August 24, 2023 1:07 AM
> 
> The post_msg_page was removed in
> commit 9a6b1a170ca8 ("Drivers: hv: vmbus: Remove the per-CPU post_msg_page")
> 
> However, it turns out that we need to bring it back, but only for a TDX VM
> with the paravisor: in such a VM, the hyperv_pcpu_input_arg is not decrypted,
> but the HVCALL_POST_MESSAGE in such a VM needs a decrypted page as the
> hypercall input page: see the comments in hyperv_init() for a detailed
> explanation.
> 
> Except for HVCALL_POST_MESSAGE and HVCALL_SIGNAL_EVENT, the other hypercalls
> in a TDX VM with the paravisor still use hv_hypercall_pg and must use the
> hyperv_pcpu_input_arg (which is encrypted in such a VM), when a hypercall
> input page is used.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> ---
> 
> Changes in v2: None
> 
> Changes in v3:
>   hyperv_paravisor_present -> ms_hyperv.paravisor_present
> 
>  arch/x86/hyperv/hv_init.c | 20 +++++++++++--
>  drivers/hv/hv.c           | 59 +++++++++++++++++++++++++++++++++++----
>  drivers/hv/hyperv_vmbus.h | 11 ++++++++
>  3 files changed, 82 insertions(+), 8 deletions(-)
> 

Reviewed-by: Michael Kelley <mikelley@microsoft.com>

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

* RE: [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM with the paravisor
  2023-08-24  8:07 ` [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM " Dexuan Cui
@ 2023-08-24 14:08   ` Michael Kelley (LINUX)
  2023-08-24 14:44   ` Tianyu Lan
  2023-12-04 15:10   ` Dave Hansen
  2 siblings, 0 replies; 24+ messages in thread
From: Michael Kelley (LINUX) @ 2023-08-24 14:08 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, Haiyang Zhang, hpa, jane.chu,
	kirill.shutemov, KY Srinivasan, linux-hyperv, luto, mingo,
	peterz, rostedt, sathyanarayanan.kuppuswamy, seanjc, tglx,
	tony.luck, wei.liu, jason, nik.borisov
  Cc: x86, linux-kernel, linux-arch, Tianyu Lan, rick.p.edgecombe,
	Anthony Davis, Mark Heslin, vkuznets, xiaoyao.li

From: Dexuan Cui <decui@microsoft.com> Sent: Thursday, August 24, 2023 1:07 AM
> 
> When the paravisor is present, a SNP VM must use GHCB to access some
> special MSRs, including HV_X64_MSR_GUEST_OS_ID and some SynIC MSRs.
> 
> Similarly, when the paravisor is present, a TDX VM must use TDX GHCI
> to access the same MSRs.
> 
> Implement hv_tdx_msr_write() and hv_tdx_msr_read(), and use the helper
> functions hv_ivm_msr_read() and hv_ivm_msr_write() to access the MSRs
> in a unified way for SNP/TDX VMs with the paravisor.
> 
> Do not export hv_tdx_msr_write() and hv_tdx_msr_read(), because we never
> really used hv_ghcb_msr_write() and hv_ghcb_msr_read() in any module.
> 
> Update arch/x86/include/asm/mshyperv.h so that the kernel can still build
> if CONFIG_AMD_MEM_ENCRYPT or CONFIG_INTEL_TDX_GUEST is not set, or
> neither is set.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> ---
> 
> Changes in v2: None
> 
> Changes in v3:
>   hv_tdx_read_msr -> hv_tdx_msr_read
>   hv_tdx_write_msr -> hv_tdx_msr_write
>   Do not export hv_tdx_msr_write() and hv_tdx_msr_read().
>   included <uapi/asm/vmx.h>
>   Updated arch/x86/include/asm/mshyperv.h so that the kernel
>     can still build if CONFIG_AMD_MEM_ENCRYPT and/or
>     CONFIG_INTEL_TDX_GUEST are not set.
> 
>  arch/x86/hyperv/hv_init.c       |  8 ++--
>  arch/x86/hyperv/ivm.c           | 69 +++++++++++++++++++++++++++++++--
>  arch/x86/include/asm/mshyperv.h |  8 ++--
>  arch/x86/kernel/cpu/mshyperv.c  |  8 ++--
>  4 files changed, 77 insertions(+), 16 deletions(-)

Reviewed-by: Michael Kelley <mikelley@microsoft.com>

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

* RE: [PATCH v3 09/10] x86/hyperv: Remove hv_isolation_type_en_snp
  2023-08-24  8:07 ` [PATCH v3 09/10] x86/hyperv: Remove hv_isolation_type_en_snp Dexuan Cui
@ 2023-08-24 14:09   ` Michael Kelley (LINUX)
  2023-08-24 14:45   ` Tianyu Lan
  1 sibling, 0 replies; 24+ messages in thread
From: Michael Kelley (LINUX) @ 2023-08-24 14:09 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, Haiyang Zhang, hpa, jane.chu,
	kirill.shutemov, KY Srinivasan, linux-hyperv, luto, mingo,
	peterz, rostedt, sathyanarayanan.kuppuswamy, seanjc, tglx,
	tony.luck, wei.liu, jason, nik.borisov
  Cc: x86, linux-kernel, linux-arch, Tianyu Lan, rick.p.edgecombe,
	Anthony Davis, Mark Heslin, vkuznets, xiaoyao.li

From: Dexuan Cui <decui@microsoft.com> Sent: Thursday, August 24, 2023 1:07 AM
> 
> In ms_hyperv_init_platform(), do not distinguish between a SNP VM with
> the paravisor and a SNP VM without the paravisor.
> 
> Replace hv_isolation_type_en_snp() with
> !ms_hyperv.paravisor_present && hv_isolation_type_snp().
> 
> The hv_isolation_type_en_snp() in drivers/hv/hv.c and
> drivers/hv/hv_common.c can be changed to hv_isolation_type_snp() since
> we know !ms_hyperv.paravisor_present is true there.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> ---
> 
> Changes in v2:
>   Rebased to Tianyu's v7 SNP patchset: the changes are small.
>     In hyperv_init_ghcb() and hyperv_init(), added the test of
> hyperv_paravisor_present, which was missed in v1.
>     Updated the test before the call of get_vtl().
>     Updated the test in hv_do_hypercall() and friends.
>     Updated the test for hv_smp_prepare_cpus().
> 
> Changes in v3:
>   hyperv_paravisor_present -> ms_hyperv.paravisor_present
> 
> 
>  arch/x86/hyperv/hv_init.c       |  8 ++++----
>  arch/x86/hyperv/ivm.c           | 12 +-----------
>  arch/x86/include/asm/mshyperv.h | 11 ++++-------
>  arch/x86/kernel/cpu/mshyperv.c  | 10 ++++------
>  drivers/hv/hv.c                 |  4 ++--
>  drivers/hv/hv_common.c          |  8 +-------
>  include/asm-generic/mshyperv.h  |  3 +--
>  7 files changed, 17 insertions(+), 39 deletions(-)
> 

Reviewed-by: Michael Kelley <mikelley@microsoft.com>

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

* RE: [PATCH v3 10/10] x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's
  2023-08-24  8:07 ` [PATCH v3 10/10] x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's Dexuan Cui
@ 2023-08-24 14:10   ` Michael Kelley (LINUX)
  2023-08-24 14:46   ` Tianyu Lan
  1 sibling, 0 replies; 24+ messages in thread
From: Michael Kelley (LINUX) @ 2023-08-24 14:10 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, Haiyang Zhang, hpa, jane.chu,
	kirill.shutemov, KY Srinivasan, linux-hyperv, luto, mingo,
	peterz, rostedt, sathyanarayanan.kuppuswamy, seanjc, tglx,
	tony.luck, wei.liu, jason, nik.borisov
  Cc: x86, linux-kernel, linux-arch, Tianyu Lan, rick.p.edgecombe,
	Anthony Davis, Mark Heslin, vkuznets, xiaoyao.li

From: Dexuan Cui <decui@microsoft.com> Sent: Thursday, August 24, 2023 1:07 AM
> 
> Group the code this way so that we can avoid too many ifdef's:
> 
>   Data only used in an SNP VM with the paravisor;
>   Functions only used in an SNP VM with the paravisor;
> 
>   Data only used in an SNP VM without the paravisor;
>   Functions only used in an SNP VM without the paravisor;
> 
>   Functions only used in a TDX VM, with and without the paravisor;
> 
>   Functions used in an SNP or TDX VM, when the paravisor is present;
> 
>   Functions always used, even in a regular non-CoCo VM.
> 
> No functional change.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> ---
> 
>    This patch appears the first time in v3.
> 
>  arch/x86/hyperv/ivm.c | 309 ++++++++++++++++++++----------------------
>  1 file changed, 150 insertions(+), 159 deletions(-)
> 

Reviewed-by: Michael Kelley <mikelley@microsoft.com>

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

* Re: [PATCH v3 07/10] Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the paravisor
  2023-08-24  8:07 ` [PATCH v3 07/10] Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the paravisor Dexuan Cui
  2023-08-24 14:07   ` Michael Kelley (LINUX)
@ 2023-08-24 14:40   ` Tianyu Lan
  1 sibling, 0 replies; 24+ messages in thread
From: Tianyu Lan @ 2023-08-24 14:40 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, haiyangz, hpa, jane.chu,
	kirill.shutemov, kys, linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li



On 8/24/2023 4:07 PM, Dexuan Cui wrote:
> The post_msg_page was removed in
> commit 9a6b1a170ca8 ("Drivers: hv: vmbus: Remove the per-CPU post_msg_page")
> 
> However, it turns out that we need to bring it back, but only for a TDX VM
> with the paravisor: in such a VM, the hyperv_pcpu_input_arg is not decrypted,
> but the HVCALL_POST_MESSAGE in such a VM needs a decrypted page as the
> hypercall input page: see the comments in hyperv_init() for a detailed
> explanation.
> 
> Except for HVCALL_POST_MESSAGE and HVCALL_SIGNAL_EVENT, the other hypercalls
> in a TDX VM with the paravisor still use hv_hypercall_pg and must use the
> hyperv_pcpu_input_arg (which is encrypted in such a VM), when a hypercall
> input page is used.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>

Reviewed-by: Tianyu Lan <tiala@microsoft.com>

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

* Re: [PATCH v3 06/10] x86/hyperv: Introduce a global variable hyperv_paravisor_present
  2023-08-24  8:07 ` [PATCH v3 06/10] x86/hyperv: Introduce a global variable hyperv_paravisor_present Dexuan Cui
  2023-08-24 14:06   ` Michael Kelley (LINUX)
@ 2023-08-24 14:41   ` Tianyu Lan
  1 sibling, 0 replies; 24+ messages in thread
From: Tianyu Lan @ 2023-08-24 14:41 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, haiyangz, hpa, jane.chu,
	kirill.shutemov, kys, linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li

On 8/24/2023 4:07 PM, Dexuan Cui wrote:
> The new variable hyperv_paravisor_present is set only when the VM
> is a SNP/TDX VM with the paravisor running: see ms_hyperv_init_platform().
> 
> We introduce hyperv_paravisor_present because we can not use
> ms_hyperv.paravisor_present in arch/x86/include/asm/mshyperv.h:
> 
> struct ms_hyperv_info is defined in include/asm-generic/mshyperv.h, which
> is included at the end of arch/x86/include/asm/mshyperv.h, but at the
> beginning of arch/x86/include/asm/mshyperv.h, we would already need to use
> struct ms_hyperv_info in hv_do_hypercall().
> 
> We use hyperv_paravisor_present only in include/asm-generic/mshyperv.h,
> and use ms_hyperv.paravisor_present elsewhere. In the future, we'll
> introduce a hypercall function structure for different VM types, and
> at boot time, the right function pointers would be written into the
> structure so that runtime testing of TDX vs. SNP vs. normal will be
> avoided and hyperv_paravisor_present will no longer be needed.
> 
> Call hv_vtom_init() when it's a VBS VM or when ms_hyperv.paravisor_present
> is true, i.e. the VM is a SNP VM or TDX VM with the paravisor.
> 
> Enhance hv_vtom_init() for a TDX VM with the paravisor.
> 
> In hv_common_cpu_init(), don't decrypt the hyperv_pcpu_input_arg
> for a TDX VM with the paravisor, just like we don't decrypt the page
> for a SNP VM with the paravisor.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>

Reviewed-by: Tianyu Lan <tiala@microsoft.com>


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

* Re: [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM with the paravisor
  2023-08-24  8:07 ` [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM " Dexuan Cui
  2023-08-24 14:08   ` Michael Kelley (LINUX)
@ 2023-08-24 14:44   ` Tianyu Lan
  2023-12-04 15:10   ` Dave Hansen
  2 siblings, 0 replies; 24+ messages in thread
From: Tianyu Lan @ 2023-08-24 14:44 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, haiyangz, hpa, jane.chu,
	kirill.shutemov, kys, linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li

On 8/24/2023 4:07 PM, Dexuan Cui wrote:
> When the paravisor is present, a SNP VM must use GHCB to access some
> special MSRs, including HV_X64_MSR_GUEST_OS_ID and some SynIC MSRs.
> 
> Similarly, when the paravisor is present, a TDX VM must use TDX GHCI
> to access the same MSRs.
> 
> Implement hv_tdx_msr_write() and hv_tdx_msr_read(), and use the helper
> functions hv_ivm_msr_read() and hv_ivm_msr_write() to access the MSRs
> in a unified way for SNP/TDX VMs with the paravisor.
> 
> Do not export hv_tdx_msr_write() and hv_tdx_msr_read(), because we never
> really used hv_ghcb_msr_write() and hv_ghcb_msr_read() in any module.
> 
> Update arch/x86/include/asm/mshyperv.h so that the kernel can still build
> if CONFIG_AMD_MEM_ENCRYPT or CONFIG_INTEL_TDX_GUEST is not set, or
> neither is set.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>

Reviewed-by: Tianyu Lan <tiala@microsoft.com>

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

* Re: [PATCH v3 09/10] x86/hyperv: Remove hv_isolation_type_en_snp
  2023-08-24  8:07 ` [PATCH v3 09/10] x86/hyperv: Remove hv_isolation_type_en_snp Dexuan Cui
  2023-08-24 14:09   ` Michael Kelley (LINUX)
@ 2023-08-24 14:45   ` Tianyu Lan
  1 sibling, 0 replies; 24+ messages in thread
From: Tianyu Lan @ 2023-08-24 14:45 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, haiyangz, hpa, jane.chu,
	kirill.shutemov, kys, linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li

On 8/24/2023 4:07 PM, Dexuan Cui wrote:
> In ms_hyperv_init_platform(), do not distinguish between a SNP VM with
> the paravisor and a SNP VM without the paravisor.
> 
> Replace hv_isolation_type_en_snp() with
> !ms_hyperv.paravisor_present && hv_isolation_type_snp().
> 
> The hv_isolation_type_en_snp() in drivers/hv/hv.c and
> drivers/hv/hv_common.c can be changed to hv_isolation_type_snp() since
> we know !ms_hyperv.paravisor_present is true there.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>

Reviewed-by: Tianyu Lan <tiala@microsoft.com>

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

* Re: [PATCH v3 10/10] x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's
  2023-08-24  8:07 ` [PATCH v3 10/10] x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's Dexuan Cui
  2023-08-24 14:10   ` Michael Kelley (LINUX)
@ 2023-08-24 14:46   ` Tianyu Lan
  1 sibling, 0 replies; 24+ messages in thread
From: Tianyu Lan @ 2023-08-24 14:46 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, dave.hansen, haiyangz, hpa, jane.chu,
	kirill.shutemov, kys, linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li

On 8/24/2023 4:07 PM, Dexuan Cui wrote:
> Group the code this way so that we can avoid too many ifdef's:
> 
>    Data only used in an SNP VM with the paravisor;
>    Functions only used in an SNP VM with the paravisor;
> 
>    Data only used in an SNP VM without the paravisor;
>    Functions only used in an SNP VM without the paravisor;
> 
>    Functions only used in a TDX VM, with and without the paravisor;
> 
>    Functions used in an SNP or TDX VM, when the paravisor is present;
> 
>    Functions always used, even in a regular non-CoCo VM.
> 
> No functional change.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>

Reviewed-by: Tianyu Lan <tiala@microsoft.com>

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

* Re: [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part)
  2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
                   ` (9 preceding siblings ...)
  2023-08-24  8:07 ` [PATCH v3 10/10] x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's Dexuan Cui
@ 2023-08-25  0:05 ` Wei Liu
  10 siblings, 0 replies; 24+ messages in thread
From: Wei Liu @ 2023-08-25  0:05 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: ak, arnd, bp, brijesh.singh, dan.j.williams, dave.hansen,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley, x86, linux-kernel, linux-arch,
	Tianyu.Lan, rick.p.edgecombe, andavis, mheslin, vkuznets,
	xiaoyao.li

On Thu, Aug 24, 2023 at 01:07:02AM -0700, Dexuan Cui wrote:
> Dexuan Cui (10):
>   x86/hyperv: Add hv_isolation_type_tdx() to detect TDX guests
>   x86/hyperv: Support hypercalls for fully enlightened TDX guests
>   Drivers: hv: vmbus: Support fully enlightened TDX guests
>   x86/hyperv: Fix serial console interrupts for fully enlightened TDX
>     guests
>   Drivers: hv: vmbus: Support >64 VPs for a fully enlightened TDX/SNP VM
>   x86/hyperv: Introduce a global variable hyperv_paravisor_present
>   Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the
>     paravisor
>   x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM with the
>     paravisor
>   x86/hyperv: Remove hv_isolation_type_en_snp
>   x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's
> 
>  arch/x86/hyperv/hv_apic.c          |  15 +-
>  arch/x86/hyperv/hv_init.c          |  59 ++++-
>  arch/x86/hyperv/ivm.c              | 374 ++++++++++++++++++-----------
>  arch/x86/include/asm/hyperv-tlfs.h |   3 +-
>  arch/x86/include/asm/mshyperv.h    |  43 +++-
>  arch/x86/kernel/cpu/mshyperv.c     |  65 ++++-
>  drivers/hv/connection.c            |  15 +-
>  drivers/hv/hv.c                    |  78 +++++-
>  drivers/hv/hv_common.c             |  43 +++-
>  drivers/hv/hyperv_vmbus.h          |  11 +
>  include/asm-generic/mshyperv.h     |   5 +-
>  11 files changed, 505 insertions(+), 206 deletions(-)

Applied to hyperv-next, thanks!

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

* Re: [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM with the paravisor
  2023-08-24  8:07 ` [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM " Dexuan Cui
  2023-08-24 14:08   ` Michael Kelley (LINUX)
  2023-08-24 14:44   ` Tianyu Lan
@ 2023-12-04 15:10   ` Dave Hansen
  2024-01-17  2:22     ` Wei Liu
  2 siblings, 1 reply; 24+ messages in thread
From: Dave Hansen @ 2023-12-04 15:10 UTC (permalink / raw)
  To: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley
  Cc: x86, linux-kernel, linux-arch, Tianyu.Lan, rick.p.edgecombe,
	andavis, mheslin, vkuznets, xiaoyao.li

On 8/24/23 01:07, Dexuan Cui wrote:
> +#ifdef CONFIG_INTEL_TDX_GUEST
> +static void hv_tdx_msr_write(u64 msr, u64 val)
> +{
> +	struct tdx_hypercall_args args = {
> +		.r10 = TDX_HYPERCALL_STANDARD,
> +		.r11 = EXIT_REASON_MSR_WRITE,
> +		.r12 = msr,
> +		.r13 = val,
> +	};
> +
> +	u64 ret = __tdx_hypercall(&args);
> +
> +	WARN_ONCE(ret, "Failed to emulate MSR write: %lld\n", ret);
> +}

First of all, I'd really appreciate if you could seek out explicit acks
for this kind of stuff before merging it.  This surprised me.

Can you please merge these generic things back into the main TDX code?
There's nothing Hyper-V specific about any of this code.  Basically, you
can make a hv_tdx_whatever() variant, but make _that_ in the generic TDX
code and then export only _that_.

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

* Re: [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM with the paravisor
  2023-12-04 15:10   ` Dave Hansen
@ 2024-01-17  2:22     ` Wei Liu
  0 siblings, 0 replies; 24+ messages in thread
From: Wei Liu @ 2024-01-17  2:22 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Dexuan Cui, ak, arnd, bp, brijesh.singh, dan.j.williams,
	dave.hansen, haiyangz, hpa, jane.chu, kirill.shutemov, kys,
	linux-hyperv, luto, mingo, peterz, rostedt,
	sathyanarayanan.kuppuswamy, seanjc, tglx, tony.luck, wei.liu,
	Jason, nik.borisov, mikelley, x86, linux-kernel, linux-arch,
	Tianyu.Lan, rick.p.edgecombe, andavis, mheslin, vkuznets,
	xiaoyao.li

Hi Dave

I was away and only saw your email now. Sorry for the late reply.

On Mon, Dec 04, 2023 at 07:10:29AM -0800, Dave Hansen wrote:
> On 8/24/23 01:07, Dexuan Cui wrote:
> > +#ifdef CONFIG_INTEL_TDX_GUEST
> > +static void hv_tdx_msr_write(u64 msr, u64 val)
> > +{
> > +	struct tdx_hypercall_args args = {
> > +		.r10 = TDX_HYPERCALL_STANDARD,
> > +		.r11 = EXIT_REASON_MSR_WRITE,
> > +		.r12 = msr,
> > +		.r13 = val,
> > +	};
> > +
> > +	u64 ret = __tdx_hypercall(&args);
> > +
> > +	WARN_ONCE(ret, "Failed to emulate MSR write: %lld\n", ret);
> > +}
> 
> First of all, I'd really appreciate if you could seek out explicit acks
> for this kind of stuff before merging it.  This surprised me.
> 

I eyeballed the code and thought it only touched only the Hyper-V files,
so I merged this series without waiting.

> Can you please merge these generic things back into the main TDX code?
> There's nothing Hyper-V specific about any of this code.  Basically, you
> can make a hv_tdx_whatever() variant, but make _that_ in the generic TDX
> code and then export only _that_.

The code is still there. Dexuan, can you send a patch to do the
refactoring?

Wei.

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

end of thread, other threads:[~2024-01-17  2:22 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-24  8:07 [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Dexuan Cui
2023-08-24  8:07 ` [PATCH v3 01/10] x86/hyperv: Add hv_isolation_type_tdx() to detect TDX guests Dexuan Cui
2023-08-24  8:07 ` [PATCH v3 02/10] x86/hyperv: Support hypercalls for fully enlightened " Dexuan Cui
2023-08-24  8:07 ` [PATCH v3 03/10] Drivers: hv: vmbus: Support " Dexuan Cui
2023-08-24  8:07 ` [PATCH v3 04/10] x86/hyperv: Fix serial console interrupts for " Dexuan Cui
2023-08-24  8:07 ` [PATCH v3 05/10] Drivers: hv: vmbus: Support >64 VPs for a fully enlightened TDX/SNP VM Dexuan Cui
2023-08-24  8:07 ` [PATCH v3 06/10] x86/hyperv: Introduce a global variable hyperv_paravisor_present Dexuan Cui
2023-08-24 14:06   ` Michael Kelley (LINUX)
2023-08-24 14:41   ` Tianyu Lan
2023-08-24  8:07 ` [PATCH v3 07/10] Drivers: hv: vmbus: Bring the post_msg_page back for TDX VMs with the paravisor Dexuan Cui
2023-08-24 14:07   ` Michael Kelley (LINUX)
2023-08-24 14:40   ` Tianyu Lan
2023-08-24  8:07 ` [PATCH v3 08/10] x86/hyperv: Use TDX GHCI to access some MSRs in a TDX VM " Dexuan Cui
2023-08-24 14:08   ` Michael Kelley (LINUX)
2023-08-24 14:44   ` Tianyu Lan
2023-12-04 15:10   ` Dave Hansen
2024-01-17  2:22     ` Wei Liu
2023-08-24  8:07 ` [PATCH v3 09/10] x86/hyperv: Remove hv_isolation_type_en_snp Dexuan Cui
2023-08-24 14:09   ` Michael Kelley (LINUX)
2023-08-24 14:45   ` Tianyu Lan
2023-08-24  8:07 ` [PATCH v3 10/10] x86/hyperv: Move the code in ivm.c around to avoid unnecessary ifdef's Dexuan Cui
2023-08-24 14:10   ` Michael Kelley (LINUX)
2023-08-24 14:46   ` Tianyu Lan
2023-08-25  0:05 ` [PATCH v3 00/10] Support TDX guests on Hyper-V (the Hyper-V specific part) Wei Liu

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