[PATCH 1/5] UBUNTU: SAUCE: clocksource: hyper-v: Use InvariantTSC and enable TSC page for TDX VM (WIP)
Tim Gardner
tim.gardner at canonical.com
Mon Jul 24 17:00:13 UTC 2023
From: Dexuan Cui <decui at 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 at microsoft.com>
(cherry picked from commit 2da82f8783279af94eca2f707a87d41ea648f417 https://github.com/dcui/linux)
Signed-off-by: Tim Gardner <tim.gardner at 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
More information about the kernel-team
mailing list