xref: /openbmc/linux/arch/x86/xen/suspend.c (revision 101cfc9f787d8ca22866a178f2c1684fb10f8c7a)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
20e91398fSJeremy Fitzhardinge #include <linux/types.h>
34ffee521SThomas Gleixner #include <linux/tick.h>
4*71c208ddSJuergen Gross #include <linux/percpu-defs.h>
50e91398fSJeremy Fitzhardinge 
6facca616SAndrew Morton #include <xen/xen.h>
70e91398fSJeremy Fitzhardinge #include <xen/interface/xen.h>
80e91398fSJeremy Fitzhardinge #include <xen/grant_table.h>
90e91398fSJeremy Fitzhardinge #include <xen/events.h>
100e91398fSJeremy Fitzhardinge 
11*71c208ddSJuergen Gross #include <asm/cpufeatures.h>
12*71c208ddSJuergen Gross #include <asm/msr-index.h>
130e91398fSJeremy Fitzhardinge #include <asm/xen/hypercall.h>
140e91398fSJeremy Fitzhardinge #include <asm/xen/page.h>
1599d0000fSIngo Molnar #include <asm/fixmap.h>
160e91398fSJeremy Fitzhardinge 
170e91398fSJeremy Fitzhardinge #include "xen-ops.h"
180e91398fSJeremy Fitzhardinge #include "mmu.h"
1965d0cf0bSBoris Ostrovsky #include "pmu.h"
200e91398fSJeremy Fitzhardinge 
21*71c208ddSJuergen Gross static DEFINE_PER_CPU(u64, spec_ctrl);
22*71c208ddSJuergen Gross 
xen_arch_pre_suspend(void)23aa8532c3SDavid Vrabel void xen_arch_pre_suspend(void)
24aa8532c3SDavid Vrabel {
252229f70bSJoao Martins 	xen_save_time_memory_area();
262229f70bSJoao Martins 
27aa8532c3SDavid Vrabel 	if (xen_pv_domain())
28aa8532c3SDavid Vrabel 		xen_pv_pre_suspend();
29aa8532c3SDavid Vrabel }
30aa8532c3SDavid Vrabel 
xen_arch_post_suspend(int cancelled)31aa8532c3SDavid Vrabel void xen_arch_post_suspend(int cancelled)
32aa8532c3SDavid Vrabel {
33aa8532c3SDavid Vrabel 	if (xen_pv_domain())
34aa8532c3SDavid Vrabel 		xen_pv_post_suspend(cancelled);
35aa8532c3SDavid Vrabel 	else
36aa8532c3SDavid Vrabel 		xen_hvm_post_suspend(cancelled);
372229f70bSJoao Martins 
382229f70bSJoao Martins 	xen_restore_time_memory_area();
390e91398fSJeremy Fitzhardinge }
400e91398fSJeremy Fitzhardinge 
xen_vcpu_notify_restore(void * data)41f6eafe36SIan Campbell static void xen_vcpu_notify_restore(void *data)
42f6eafe36SIan Campbell {
43*71c208ddSJuergen Gross 	if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL))
44*71c208ddSJuergen Gross 		wrmsrl(MSR_IA32_SPEC_CTRL, this_cpu_read(spec_ctrl));
45*71c208ddSJuergen Gross 
46f6eafe36SIan Campbell 	/* Boot processor notified via generic timekeeping_resume() */
47f6eafe36SIan Campbell 	if (smp_processor_id() == 0)
48f6eafe36SIan Campbell 		return;
49f6eafe36SIan Campbell 
50f46481d0SThomas Gleixner 	tick_resume_local();
51f6eafe36SIan Campbell }
52f6eafe36SIan Campbell 
xen_vcpu_notify_suspend(void * data)532b953a5eSBoris Ostrovsky static void xen_vcpu_notify_suspend(void *data)
542b953a5eSBoris Ostrovsky {
55*71c208ddSJuergen Gross 	u64 tmp;
56*71c208ddSJuergen Gross 
572b953a5eSBoris Ostrovsky 	tick_suspend_local();
58*71c208ddSJuergen Gross 
59*71c208ddSJuergen Gross 	if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL)) {
60*71c208ddSJuergen Gross 		rdmsrl(MSR_IA32_SPEC_CTRL, tmp);
61*71c208ddSJuergen Gross 		this_cpu_write(spec_ctrl, tmp);
62*71c208ddSJuergen Gross 		wrmsrl(MSR_IA32_SPEC_CTRL, 0);
63*71c208ddSJuergen Gross 	}
642b953a5eSBoris Ostrovsky }
652b953a5eSBoris Ostrovsky 
xen_arch_resume(void)66ad55db9fSIsaku Yamahata void xen_arch_resume(void)
67ad55db9fSIsaku Yamahata {
68de0afc9bSBoris Ostrovsky 	int cpu;
69de0afc9bSBoris Ostrovsky 
704ffee521SThomas Gleixner 	on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
71de0afc9bSBoris Ostrovsky 
72de0afc9bSBoris Ostrovsky 	for_each_online_cpu(cpu)
73de0afc9bSBoris Ostrovsky 		xen_pmu_init(cpu);
74ad55db9fSIsaku Yamahata }
752b953a5eSBoris Ostrovsky 
xen_arch_suspend(void)762b953a5eSBoris Ostrovsky void xen_arch_suspend(void)
772b953a5eSBoris Ostrovsky {
78de0afc9bSBoris Ostrovsky 	int cpu;
79de0afc9bSBoris Ostrovsky 
80de0afc9bSBoris Ostrovsky 	for_each_online_cpu(cpu)
81de0afc9bSBoris Ostrovsky 		xen_pmu_finish(cpu);
82de0afc9bSBoris Ostrovsky 
832b953a5eSBoris Ostrovsky 	on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
842b953a5eSBoris Ostrovsky }
85