diff mbox series

[1/5] UBUNTU: SAUCE: clocksource: hyper-v: Use InvariantTSC and enable TSC page for TDX VM (WIP)

Message ID 20230724170017.17988-2-tim.gardner@canonical.com
State New
Headers show
Series Azure: TDX updates to support HCL | expand

Commit Message

Tim Gardner July 24, 2023, 5 p.m. UTC
From: Dexuan Cui <decui@microsoft.com>

BugLink: https://bugs.launchpad.net/bugs/2028286

Need to better address the __bss_decrypted attribute of 'tsc_pg'.

(cherry picked from commit 662d8f2222aef359039363eeba856d7a6a8ad87b https://github.com/dcui/linux/commit/662d8f2222aef359039363eeba856d7a6a8ad87b)
Signed-off-by: Dexuan Cui <decui@microsoft.com>
(cherry picked from commit 2da82f8783279af94eca2f707a87d41ea648f417 https://github.com/dcui/linux)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
 arch/x86/entry/vdso/vma.c          | 11 ++++++++---
 arch/x86/kernel/cpu/mshyperv.c     |  4 ----
 drivers/clocksource/hyperv_timer.c | 15 +++++++++++++--
 include/asm-generic/mshyperv.h     |  8 +++++++-
 4 files changed, 28 insertions(+), 10 deletions(-)

Comments

Ian May Aug. 21, 2023, 7:16 p.m. UTC | #1
Acked-by: Ian May <ian.may@canonical.com>

On 2023-07-24 11:00:13 , Tim Gardner wrote:
> From: Dexuan Cui <decui@microsoft.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/2028286
> 
> Need to better address the __bss_decrypted attribute of 'tsc_pg'.
> 
> (cherry picked from commit 662d8f2222aef359039363eeba856d7a6a8ad87b https://github.com/dcui/linux/commit/662d8f2222aef359039363eeba856d7a6a8ad87b)
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> (cherry picked from commit 2da82f8783279af94eca2f707a87d41ea648f417 https://github.com/dcui/linux)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
>  arch/x86/entry/vdso/vma.c          | 11 ++++++++---
>  arch/x86/kernel/cpu/mshyperv.c     |  4 ----
>  drivers/clocksource/hyperv_timer.c | 15 +++++++++++++--
>  include/asm-generic/mshyperv.h     |  8 +++++++-
>  4 files changed, 28 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
> index b8f3f9b9e53c..809eb6644aff 100644
> --- a/arch/x86/entry/vdso/vma.c
> +++ b/arch/x86/entry/vdso/vma.c
> @@ -17,6 +17,7 @@
>  #include <linux/time_namespace.h>
>  
>  #include <asm/pvclock.h>
> +#include <asm/mshyperv.h>
>  #include <asm/vgtod.h>
>  #include <asm/proto.h>
>  #include <asm/vdso.h>
> @@ -188,9 +189,13 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
>  		}
>  	} else if (sym_offset == image->sym_hvclock_page) {
>  		pfn = hv_get_tsc_pfn();
> -
> -		if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK))
> -			return vmf_insert_pfn(vma, vmf->address, pfn);
> +		if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK)) {
> +			if (ms_hyperv.paravisor_present)
> +				return vmf_insert_pfn(vma, vmf->address, pfn);
> +			else
> +				return vmf_insert_pfn_prot(vma, vmf->address,
> +					pfn, pgprot_decrypted(vma->vm_page_prot));
> +		}
>  	} else if (sym_offset == image->sym_timens_page) {
>  		struct page *timens_page = find_timens_vvar_page(vma);
>  
> diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> index 76701edbc0c5..9aad261d2843 100644
> --- a/arch/x86/kernel/cpu/mshyperv.c
> +++ b/arch/x86/kernel/cpu/mshyperv.c
> @@ -440,10 +440,6 @@ static void __init ms_hyperv_init_platform(void)
>  			 */
>  			ms_hyperv.shared_gpa_boundary = cc_mkdec(0);
>  
> -			/* Don't use the unsafe Hyper-V TSC page */
> -			ms_hyperv.features &=
> -				~HV_MSR_REFERENCE_TSC_AVAILABLE;
> -
>  			/* HV_REGISTER_CRASH_CTL is unsupported */
>  			ms_hyperv.misc_features &=
>  				 ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
> diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
> index 7901a88ad918..55f029c39fdf 100644
> --- a/drivers/clocksource/hyperv_timer.c
> +++ b/drivers/clocksource/hyperv_timer.c
> @@ -22,6 +22,7 @@
>  #include <linux/irq.h>
>  #include <linux/acpi.h>
>  #include <linux/hyperv.h>
> +#include <linux/set_memory.h>
>  #include <clocksource/hyperv_timer.h>
>  #include <asm/hyperv-tlfs.h>
>  #include <asm/mshyperv.h>
> @@ -364,8 +365,8 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);
>  
>  static union {
>  	struct ms_hyperv_tsc_page page;
> -	u8 reserved[PAGE_SIZE];
> -} tsc_pg __aligned(PAGE_SIZE);
> +	u8 reserved[SZ_2M];
> +} tsc_pg __bss_decrypted __aligned(SZ_2M);
>  
>  static struct ms_hyperv_tsc_page *tsc_page = &tsc_pg.page;
>  static unsigned long tsc_pfn;
> @@ -505,6 +506,7 @@ static __always_inline void hv_setup_sched_clock(void *sched_clock) {}
>  static bool __init hv_init_tsc_clocksource(void)
>  {
>  	union hv_reference_tsc_msr tsc_msr;
> +	int ret;
>  
>  	/*
>  	 * If Hyper-V offers TSC_INVARIANT, then the virtualized TSC correctly
> @@ -527,6 +529,11 @@ static bool __init hv_init_tsc_clocksource(void)
>  
>  	hv_read_reference_counter = read_hv_clock_tsc;
>  
> +	if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present) {
> +		ret = set_memory_decrypted((unsigned long)tsc_page, SZ_2M/PAGE_SIZE);
> +		BUG_ON(ret);
> +		memset(tsc_page, 0, PAGE_SIZE);
> +	}
>  	/*
>  	 * TSC page mapping works differently in root compared to guest.
>  	 * - In guest partition the guest PFN has to be passed to the
> @@ -550,6 +557,10 @@ static bool __init hv_init_tsc_clocksource(void)
>  		tsc_pfn = HVPFN_DOWN(virt_to_phys(tsc_page));
>  	tsc_msr.enable = 1;
>  	tsc_msr.pfn = tsc_pfn;
> +
> +	if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present)
> +		tsc_msr.pfn = PHYS_PFN(cc_mkdec(PFN_PHYS(tsc_msr.pfn)));
> +
>  	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
>  
>  	clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index ddc1599d17e9..3e48cdc02b74 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -36,7 +36,13 @@ struct ms_hyperv_info {
>  	u32 nested_features;
>  	u32 max_vp_index;
>  	u32 max_lp_index;
> -	u32 isolation_config_a;
> +	union {
> +		u32 isolation_config_a;
> +		struct {
> +			u32 paravisor_present	: 1;
> +			u32 reserved0		: 31;
> +		};
> +	};
>  	union {
>  		u32 isolation_config_b;
>  		struct {
> -- 
> 2.34.1
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
diff mbox series

Patch

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index b8f3f9b9e53c..809eb6644aff 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -17,6 +17,7 @@ 
 #include <linux/time_namespace.h>
 
 #include <asm/pvclock.h>
+#include <asm/mshyperv.h>
 #include <asm/vgtod.h>
 #include <asm/proto.h>
 #include <asm/vdso.h>
@@ -188,9 +189,13 @@  static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 		}
 	} else if (sym_offset == image->sym_hvclock_page) {
 		pfn = hv_get_tsc_pfn();
-
-		if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK))
-			return vmf_insert_pfn(vma, vmf->address, pfn);
+		if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK)) {
+			if (ms_hyperv.paravisor_present)
+				return vmf_insert_pfn(vma, vmf->address, pfn);
+			else
+				return vmf_insert_pfn_prot(vma, vmf->address,
+					pfn, pgprot_decrypted(vma->vm_page_prot));
+		}
 	} else if (sym_offset == image->sym_timens_page) {
 		struct page *timens_page = find_timens_vvar_page(vma);
 
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 76701edbc0c5..9aad261d2843 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -440,10 +440,6 @@  static void __init ms_hyperv_init_platform(void)
 			 */
 			ms_hyperv.shared_gpa_boundary = cc_mkdec(0);
 
-			/* Don't use the unsafe Hyper-V TSC page */
-			ms_hyperv.features &=
-				~HV_MSR_REFERENCE_TSC_AVAILABLE;
-
 			/* HV_REGISTER_CRASH_CTL is unsupported */
 			ms_hyperv.misc_features &=
 				 ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index 7901a88ad918..55f029c39fdf 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -22,6 +22,7 @@ 
 #include <linux/irq.h>
 #include <linux/acpi.h>
 #include <linux/hyperv.h>
+#include <linux/set_memory.h>
 #include <clocksource/hyperv_timer.h>
 #include <asm/hyperv-tlfs.h>
 #include <asm/mshyperv.h>
@@ -364,8 +365,8 @@  EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);
 
 static union {
 	struct ms_hyperv_tsc_page page;
-	u8 reserved[PAGE_SIZE];
-} tsc_pg __aligned(PAGE_SIZE);
+	u8 reserved[SZ_2M];
+} tsc_pg __bss_decrypted __aligned(SZ_2M);
 
 static struct ms_hyperv_tsc_page *tsc_page = &tsc_pg.page;
 static unsigned long tsc_pfn;
@@ -505,6 +506,7 @@  static __always_inline void hv_setup_sched_clock(void *sched_clock) {}
 static bool __init hv_init_tsc_clocksource(void)
 {
 	union hv_reference_tsc_msr tsc_msr;
+	int ret;
 
 	/*
 	 * If Hyper-V offers TSC_INVARIANT, then the virtualized TSC correctly
@@ -527,6 +529,11 @@  static bool __init hv_init_tsc_clocksource(void)
 
 	hv_read_reference_counter = read_hv_clock_tsc;
 
+	if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present) {
+		ret = set_memory_decrypted((unsigned long)tsc_page, SZ_2M/PAGE_SIZE);
+		BUG_ON(ret);
+		memset(tsc_page, 0, PAGE_SIZE);
+	}
 	/*
 	 * TSC page mapping works differently in root compared to guest.
 	 * - In guest partition the guest PFN has to be passed to the
@@ -550,6 +557,10 @@  static bool __init hv_init_tsc_clocksource(void)
 		tsc_pfn = HVPFN_DOWN(virt_to_phys(tsc_page));
 	tsc_msr.enable = 1;
 	tsc_msr.pfn = tsc_pfn;
+
+	if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present)
+		tsc_msr.pfn = PHYS_PFN(cc_mkdec(PFN_PHYS(tsc_msr.pfn)));
+
 	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
 
 	clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index ddc1599d17e9..3e48cdc02b74 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -36,7 +36,13 @@  struct ms_hyperv_info {
 	u32 nested_features;
 	u32 max_vp_index;
 	u32 max_lp_index;
-	u32 isolation_config_a;
+	union {
+		u32 isolation_config_a;
+		struct {
+			u32 paravisor_present	: 1;
+			u32 reserved0		: 31;
+		};
+	};
 	union {
 		u32 isolation_config_b;
 		struct {