From: Dexuan Cui <decui@xxxxxxxxxxxxx> Sent: Monday, July 8, 2019 10:29 PM > > This is needed for hibernation, e.g. when we resume the old kernel, we need > to disable the "current" kernel's hypercall page and then resume the old > kernel's. > > Signed-off-by: Dexuan Cui <decui@xxxxxxxxxxxxx> > --- > arch/x86/hyperv/hv_init.c | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c > index 0e033ef..3005871 100644 > --- a/arch/x86/hyperv/hv_init.c > +++ b/arch/x86/hyperv/hv_init.c > @@ -20,6 +20,7 @@ > #include <linux/hyperv.h> > #include <linux/slab.h> > #include <linux/cpuhotplug.h> > +#include <linux/syscore_ops.h> > #include <clocksource/hyperv_timer.h> > > void *hv_hypercall_pg; > @@ -214,6 +215,34 @@ static int __init hv_pci_init(void) > return 1; > } > > +static int hv_suspend(void) > +{ > + union hv_x64_msr_hypercall_contents hypercall_msr; > + > + /* Reset the hypercall page */ > + rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); > + hypercall_msr.enable = 0; > + wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); > + > + return 0; > +} > + > +static void hv_resume(void) > +{ > + union hv_x64_msr_hypercall_contents hypercall_msr; > + > + /* Re-enable the hypercall page */ > + rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); > + hypercall_msr.enable = 1; > + hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg); > + wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); > +} > + > +static struct syscore_ops hv_syscore_ops = { > + .suspend = hv_suspend, > + .resume = hv_resume, > +}; > + > /* > * This function is to be invoked early in the boot sequence after the > * hypervisor has been detected. > @@ -294,6 +323,9 @@ void __init hyperv_init(void) > > /* Register Hyper-V specific clocksource */ > hv_init_clocksource(); > + > + register_syscore_ops(&hv_syscore_ops); > + > return; > > remove_cpuhp_state: > @@ -313,6 +345,8 @@ void hyperv_cleanup(void) > { > union hv_x64_msr_hypercall_contents hypercall_msr; > > + unregister_syscore_ops(&hv_syscore_ops); > + > /* Reset our OS id */ > wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); > > -- > 1.8.3.1 Reviewed-by: Michael Kelley <mikelley@xxxxxxxxxxxxx>