From: Anirudh Rayabharam <anrayabh@xxxxxxxxxxxxxxxxxxx> Sent: Thursday, October 27, 2022 2:57 AM > > Add a data structure to represent the reference TSC MSR similar to > other MSRs. This simplifies the code for updating the MSR. > > Signed-off-by: Anirudh Rayabharam <anrayabh@xxxxxxxxxxxxxxxxxxx> > --- > drivers/clocksource/hyperv_timer.c | 28 ++++++++++++++-------------- > include/asm-generic/hyperv-tlfs.h | 9 +++++++++ > 2 files changed, 23 insertions(+), 14 deletions(-) > > diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c > index bb47610bbd1c..11332c82d1af 100644 > --- a/drivers/clocksource/hyperv_timer.c > +++ b/drivers/clocksource/hyperv_timer.c > @@ -395,25 +395,25 @@ static u64 notrace read_hv_sched_clock_tsc(void) > > static void suspend_hv_clock_tsc(struct clocksource *arg) > { > - u64 tsc_msr; > + union hv_reference_tsc_msr tsc_msr; > > /* Disable the TSC page */ > - tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC); > - tsc_msr &= ~BIT_ULL(0); > - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr); > + tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); > + tsc_msr.enable = 0; > + hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); > } > > > static void resume_hv_clock_tsc(struct clocksource *arg) > { > phys_addr_t phys_addr = virt_to_phys(&tsc_pg); > - u64 tsc_msr; > + union hv_reference_tsc_msr tsc_msr; > > /* Re-enable the TSC page */ > - tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC); > - tsc_msr &= GENMASK_ULL(11, 0); > - tsc_msr |= BIT_ULL(0) | (u64)phys_addr; > - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr); > + tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); > + tsc_msr.enable = 1; > + tsc_msr.pfn = __phys_to_pfn(phys_addr); > + hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); > } > > #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK > @@ -495,7 +495,7 @@ static __always_inline void hv_setup_sched_clock(void > *sched_clock) {} > > static bool __init hv_init_tsc_clocksource(void) > { > - u64 tsc_msr; > + union hv_reference_tsc_msr tsc_msr; > phys_addr_t phys_addr; > > if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE)) > @@ -530,10 +530,10 @@ static bool __init hv_init_tsc_clocksource(void) > * (which already has at least the low 12 bits set to zero since > * it is page aligned). Also set the "enable" bit, which is bit 0. > */ > - tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC); > - tsc_msr &= GENMASK_ULL(11, 0); > - tsc_msr = tsc_msr | 0x1 | (u64)phys_addr; > - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr); > + tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); > + tsc_msr.enable = 1; > + tsc_msr.pfn = __phys_to_pfn(phys_addr); > + 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/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h > index fdce7a4cfc6f..b17c6eeb9afa 100644 > --- a/include/asm-generic/hyperv-tlfs.h > +++ b/include/asm-generic/hyperv-tlfs.h > @@ -102,6 +102,15 @@ struct ms_hyperv_tsc_page { > volatile s64 tsc_offset; > } __packed; > > +union hv_reference_tsc_msr { > + u64 as_uint64; > + struct { > + u64 enable:1; > + u64 reserved:11; > + u64 pfn:52; > + } __packed; > +}; > + > /* > * The guest OS needs to register the guest ID with the hypervisor. > * The guest ID is a 64 bit entity and the structure of this ID is > -- > 2.34.1 Reviewed-by: Michael Kelley <mikelley@xxxxxxxxxxxxx>