Skip to content

Commit 8e5f337

Browse files
dcuijohn-cabaj
authored andcommitted
UBUNTU: SAUCE: clocksource: hyper-v: Use InvariantTSC and enable TSC page for a TDX VM without paravisor
BugLink: https://bugs.launchpad.net/bugs/2052519 Will improve the patch and post to LKML. Signed-off-by: Dexuan Cui <[email protected]> Signed-off-by: Tim Gardner <[email protected]> Acked-by: Ian May <[email protected]> Acked-by: Marcelo Cerri <[email protected]> Signed-off-by: Tim Gardner <[email protected]>
1 parent dd89eed commit 8e5f337

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

arch/x86/entry/vdso/vma.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/time_namespace.h>
1818

1919
#include <asm/pvclock.h>
20+
#include <asm/mshyperv.h>
2021
#include <asm/vgtod.h>
2122
#include <asm/proto.h>
2223
#include <asm/vdso.h>
@@ -189,9 +190,13 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
189190
}
190191
} else if (sym_offset == image->sym_hvclock_page) {
191192
pfn = hv_get_tsc_pfn();
192-
193-
if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK))
194-
return vmf_insert_pfn(vma, vmf->address, pfn);
193+
if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK)) {
194+
if (ms_hyperv.paravisor_present)
195+
return vmf_insert_pfn(vma, vmf->address, pfn);
196+
else
197+
return vmf_insert_pfn_prot(vma, vmf->address,
198+
pfn, pgprot_decrypted(vma->vm_page_prot));
199+
}
195200
} else if (sym_offset == image->sym_timens_page) {
196201
struct page *timens_page = find_timens_vvar_page(vma);
197202

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -507,14 +507,6 @@ static void __init ms_hyperv_init_platform(void)
507507
ms_hyperv.hints &= ~HV_X64_APIC_ACCESS_RECOMMENDED;
508508

509509
if (!ms_hyperv.paravisor_present) {
510-
/*
511-
* Mark the Hyper-V TSC page feature as disabled
512-
* in a TDX VM without paravisor so that the
513-
* Invariant TSC, which is a better clocksource
514-
* anyway, is used instead.
515-
*/
516-
ms_hyperv.features &= ~HV_MSR_REFERENCE_TSC_AVAILABLE;
517-
518510
/*
519511
* The Invariant TSC is expected to be available
520512
* in a TDX VM without paravisor, but if not,

drivers/clocksource/hyperv_timer.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/irq.h>
2323
#include <linux/acpi.h>
2424
#include <linux/hyperv.h>
25+
#include <linux/set_memory.h>
2526
#include <clocksource/hyperv_timer.h>
2627
#include <asm/hyperv-tlfs.h>
2728
#include <asm/mshyperv.h>
@@ -404,8 +405,8 @@ static __always_inline u64 read_hv_clock_msr(void)
404405

405406
static union {
406407
struct ms_hyperv_tsc_page page;
407-
u8 reserved[PAGE_SIZE];
408-
} tsc_pg __bss_decrypted __aligned(PAGE_SIZE);
408+
u8 reserved[SZ_2M];
409+
} tsc_pg __bss_decrypted __aligned(SZ_2M);
409410

410411
static struct ms_hyperv_tsc_page *tsc_page = &tsc_pg.page;
411412
static unsigned long tsc_pfn;
@@ -546,6 +547,7 @@ static __always_inline void hv_setup_sched_clock(void *sched_clock) {}
546547
static void __init hv_init_tsc_clocksource(void)
547548
{
548549
union hv_reference_tsc_msr tsc_msr;
550+
int ret;
549551

550552
/*
551553
* If Hyper-V offers TSC_INVARIANT, then the virtualized TSC correctly
@@ -565,6 +567,12 @@ static void __init hv_init_tsc_clocksource(void)
565567

566568
hv_read_reference_counter = read_hv_clock_tsc;
567569

570+
if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present) {
571+
ret = set_memory_decrypted((unsigned long)tsc_page, SZ_2M/PAGE_SIZE);
572+
BUG_ON(ret);
573+
memset(tsc_page, 0, PAGE_SIZE);
574+
}
575+
568576
/*
569577
* TSC page mapping works differently in root compared to guest.
570578
* - In guest partition the guest PFN has to be passed to the
@@ -588,6 +596,10 @@ static void __init hv_init_tsc_clocksource(void)
588596
tsc_pfn = HVPFN_DOWN(virt_to_phys(tsc_page));
589597
tsc_msr.enable = 1;
590598
tsc_msr.pfn = tsc_pfn;
599+
600+
if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present)
601+
tsc_msr.pfn = PHYS_PFN(cc_mkdec(PFN_PHYS(tsc_msr.pfn)));
602+
591603
hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
592604

593605
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);

0 commit comments

Comments
 (0)