0001
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
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 }