Message ID | 20230724170017.17988-2-tim.gardner@canonical.com |
---|---|
State | New |
Headers | show |
Series | Azure: TDX updates to support HCL | expand |
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 --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 {