From: Sasha Levin <sashal@xxxxxxxxxx> Sent: Friday, November 18, 2022 6:11 PM > > From: Anirudh Rayabharam <anrayabh@xxxxxxxxxxxxxxxxxxx> > > [ Upstream commit 4ad1aa571214e8d6468a1806794d987b374b5a08 ] > > 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> > Reviewed-by: Michael Kelley <mikelley@xxxxxxxxxxxxx> > Link: https://lore.kernel.org/all/20221027095729.1676394-2-anrayabh@xxxxxxxxxxxxxxxxxxx/ > Signed-off-by: Wei Liu <wei.liu@xxxxxxxxxx> > Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> Sasha -- I don't think this patch needs to be backported to any stable versions. Anirudh or Wei Liu, can you confirm? The patch is more about enabling a new scenario than fixing a bug. Michael > --- > drivers/clocksource/hyperv_timer.c | 29 +++++++++++++++-------------- > include/asm-generic/hyperv-tlfs.h | 9 +++++++++ > 2 files changed, 24 insertions(+), 14 deletions(-) > > diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c > index bb47610bbd1c..18de1f439ffd 100644 > --- a/drivers/clocksource/hyperv_timer.c > +++ b/drivers/clocksource/hyperv_timer.c > @@ -21,6 +21,7 @@ > #include <linux/interrupt.h> > #include <linux/irq.h> > #include <linux/acpi.h> > +#include <linux/hyperv.h> > #include <clocksource/hyperv_timer.h> > #include <asm/hyperv-tlfs.h> > #include <asm/mshyperv.h> > @@ -395,25 +396,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 = HVPFN_DOWN(phys_addr); > + hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); > } > > #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK > @@ -495,7 +496,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 +531,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 = HVPFN_DOWN(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.35.1