Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/types.h>
0003 #include <linux/tick.h>
0004 #include <linux/percpu-defs.h>
0005 
0006 #include <xen/xen.h>
0007 #include <xen/interface/xen.h>
0008 #include <xen/grant_table.h>
0009 #include <xen/events.h>
0010 
0011 #include <asm/cpufeatures.h>
0012 #include <asm/msr-index.h>
0013 #include <asm/xen/hypercall.h>
0014 #include <asm/xen/page.h>
0015 #include <asm/fixmap.h>
0016 
0017 #include "xen-ops.h"
0018 #include "mmu.h"
0019 #include "pmu.h"
0020 
0021 static DEFINE_PER_CPU(u64, spec_ctrl);
0022 
0023 void xen_arch_pre_suspend(void)
0024 {
0025     xen_save_time_memory_area();
0026 
0027     if (xen_pv_domain())
0028         xen_pv_pre_suspend();
0029 }
0030 
0031 void xen_arch_post_suspend(int cancelled)
0032 {
0033     if (xen_pv_domain())
0034         xen_pv_post_suspend(cancelled);
0035     else
0036         xen_hvm_post_suspend(cancelled);
0037 
0038     xen_restore_time_memory_area();
0039 }
0040 
0041 static void xen_vcpu_notify_restore(void *data)
0042 {
0043     if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL))
0044         wrmsrl(MSR_IA32_SPEC_CTRL, this_cpu_read(spec_ctrl));
0045 
0046     /* Boot processor notified via generic timekeeping_resume() */
0047     if (smp_processor_id() == 0)
0048         return;
0049 
0050     tick_resume_local();
0051 }
0052 
0053 static void xen_vcpu_notify_suspend(void *data)
0054 {
0055     u64 tmp;
0056 
0057     tick_suspend_local();
0058 
0059     if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL)) {
0060         rdmsrl(MSR_IA32_SPEC_CTRL, tmp);
0061         this_cpu_write(spec_ctrl, tmp);
0062         wrmsrl(MSR_IA32_SPEC_CTRL, 0);
0063     }
0064 }
0065 
0066 void xen_arch_resume(void)
0067 {
0068     int cpu;
0069 
0070     on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
0071 
0072     for_each_online_cpu(cpu)
0073         xen_pmu_init(cpu);
0074 }
0075 
0076 void xen_arch_suspend(void)
0077 {
0078     int cpu;
0079 
0080     for_each_online_cpu(cpu)
0081         xen_pmu_finish(cpu);
0082 
0083     on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
0084 }