1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun #include <linux/types.h> 3*4882a593Smuzhiyun #include <linux/tick.h> 4*4882a593Smuzhiyun #include <linux/percpu-defs.h> 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #include <xen/xen.h> 7*4882a593Smuzhiyun #include <xen/interface/xen.h> 8*4882a593Smuzhiyun #include <xen/grant_table.h> 9*4882a593Smuzhiyun #include <xen/events.h> 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #include <asm/cpufeatures.h> 12*4882a593Smuzhiyun #include <asm/msr-index.h> 13*4882a593Smuzhiyun #include <asm/xen/hypercall.h> 14*4882a593Smuzhiyun #include <asm/xen/page.h> 15*4882a593Smuzhiyun #include <asm/fixmap.h> 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #include "xen-ops.h" 18*4882a593Smuzhiyun #include "mmu.h" 19*4882a593Smuzhiyun #include "pmu.h" 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun static DEFINE_PER_CPU(u64, spec_ctrl); 22*4882a593Smuzhiyun xen_arch_pre_suspend(void)23*4882a593Smuzhiyunvoid xen_arch_pre_suspend(void) 24*4882a593Smuzhiyun { 25*4882a593Smuzhiyun xen_save_time_memory_area(); 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun if (xen_pv_domain()) 28*4882a593Smuzhiyun xen_pv_pre_suspend(); 29*4882a593Smuzhiyun } 30*4882a593Smuzhiyun xen_arch_post_suspend(int cancelled)31*4882a593Smuzhiyunvoid xen_arch_post_suspend(int cancelled) 32*4882a593Smuzhiyun { 33*4882a593Smuzhiyun if (xen_pv_domain()) 34*4882a593Smuzhiyun xen_pv_post_suspend(cancelled); 35*4882a593Smuzhiyun else 36*4882a593Smuzhiyun xen_hvm_post_suspend(cancelled); 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun xen_restore_time_memory_area(); 39*4882a593Smuzhiyun } 40*4882a593Smuzhiyun xen_vcpu_notify_restore(void * data)41*4882a593Smuzhiyunstatic void xen_vcpu_notify_restore(void *data) 42*4882a593Smuzhiyun { 43*4882a593Smuzhiyun if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL)) 44*4882a593Smuzhiyun wrmsrl(MSR_IA32_SPEC_CTRL, this_cpu_read(spec_ctrl)); 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun /* Boot processor notified via generic timekeeping_resume() */ 47*4882a593Smuzhiyun if (smp_processor_id() == 0) 48*4882a593Smuzhiyun return; 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun tick_resume_local(); 51*4882a593Smuzhiyun } 52*4882a593Smuzhiyun xen_vcpu_notify_suspend(void * data)53*4882a593Smuzhiyunstatic void xen_vcpu_notify_suspend(void *data) 54*4882a593Smuzhiyun { 55*4882a593Smuzhiyun u64 tmp; 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun tick_suspend_local(); 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL)) { 60*4882a593Smuzhiyun rdmsrl(MSR_IA32_SPEC_CTRL, tmp); 61*4882a593Smuzhiyun this_cpu_write(spec_ctrl, tmp); 62*4882a593Smuzhiyun wrmsrl(MSR_IA32_SPEC_CTRL, 0); 63*4882a593Smuzhiyun } 64*4882a593Smuzhiyun } 65*4882a593Smuzhiyun xen_arch_resume(void)66*4882a593Smuzhiyunvoid xen_arch_resume(void) 67*4882a593Smuzhiyun { 68*4882a593Smuzhiyun int cpu; 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun on_each_cpu(xen_vcpu_notify_restore, NULL, 1); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun for_each_online_cpu(cpu) 73*4882a593Smuzhiyun xen_pmu_init(cpu); 74*4882a593Smuzhiyun } 75*4882a593Smuzhiyun xen_arch_suspend(void)76*4882a593Smuzhiyunvoid xen_arch_suspend(void) 77*4882a593Smuzhiyun { 78*4882a593Smuzhiyun int cpu; 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun for_each_online_cpu(cpu) 81*4882a593Smuzhiyun xen_pmu_finish(cpu); 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun on_each_cpu(xen_vcpu_notify_suspend, NULL, 1); 84*4882a593Smuzhiyun } 85