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 Vrabelvoid 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 Vrabelvoid 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 Campbellstatic 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 Ostrovskystatic 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 Yamahatavoid 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 Ostrovskyvoid 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