Skip to content

Commit 8b79fef

Browse files
vittyvkbonzini
authored andcommitted
x86/kvm: Teardown PV features on boot CPU as well
Various PV features (Async PF, PV EOI, steal time) work through memory shared with hypervisor and when we restore from hibernation we must properly teardown all these features to make sure hypervisor doesn't write to stale locations after we jump to the previously hibernated kernel (which can try to place anything there). For secondary CPUs the job is already done by kvm_cpu_down_prepare(), register syscore ops to do the same for boot CPU. Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Message-Id: <20210414123544.1060604-3-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 0a269a0 commit 8b79fef

File tree

1 file changed

+40
-16
lines changed

1 file changed

+40
-16
lines changed

arch/x86/kernel/kvm.c

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <linux/kprobes.h>
2727
#include <linux/nmi.h>
2828
#include <linux/swait.h>
29+
#include <linux/syscore_ops.h>
2930
#include <asm/timer.h>
3031
#include <asm/cpu.h>
3132
#include <asm/traps.h>
@@ -451,6 +452,25 @@ static void __init sev_map_percpu_data(void)
451452
}
452453
}
453454

455+
static void kvm_guest_cpu_offline(void)
456+
{
457+
kvm_disable_steal_time();
458+
if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
459+
wrmsrl(MSR_KVM_PV_EOI_EN, 0);
460+
kvm_pv_disable_apf();
461+
apf_task_wake_all();
462+
}
463+
464+
static int kvm_cpu_online(unsigned int cpu)
465+
{
466+
unsigned long flags;
467+
468+
local_irq_save(flags);
469+
kvm_guest_cpu_init();
470+
local_irq_restore(flags);
471+
return 0;
472+
}
473+
454474
#ifdef CONFIG_SMP
455475

456476
static DEFINE_PER_CPU(cpumask_var_t, __pv_cpu_mask);
@@ -635,32 +655,34 @@ static void __init kvm_smp_prepare_boot_cpu(void)
635655
kvm_spinlock_init();
636656
}
637657

638-
static void kvm_guest_cpu_offline(void)
658+
static int kvm_cpu_down_prepare(unsigned int cpu)
639659
{
640-
kvm_disable_steal_time();
641-
if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
642-
wrmsrl(MSR_KVM_PV_EOI_EN, 0);
643-
kvm_pv_disable_apf();
644-
apf_task_wake_all();
645-
}
660+
unsigned long flags;
646661

647-
static int kvm_cpu_online(unsigned int cpu)
648-
{
649-
local_irq_disable();
650-
kvm_guest_cpu_init();
651-
local_irq_enable();
662+
local_irq_save(flags);
663+
kvm_guest_cpu_offline();
664+
local_irq_restore(flags);
652665
return 0;
653666
}
654667

655-
static int kvm_cpu_down_prepare(unsigned int cpu)
668+
#endif
669+
670+
static int kvm_suspend(void)
656671
{
657-
local_irq_disable();
658672
kvm_guest_cpu_offline();
659-
local_irq_enable();
673+
660674
return 0;
661675
}
662676

663-
#endif
677+
static void kvm_resume(void)
678+
{
679+
kvm_cpu_online(raw_smp_processor_id());
680+
}
681+
682+
static struct syscore_ops kvm_syscore_ops = {
683+
.suspend = kvm_suspend,
684+
.resume = kvm_resume,
685+
};
664686

665687
static void __init kvm_guest_init(void)
666688
{
@@ -704,6 +726,8 @@ static void __init kvm_guest_init(void)
704726
kvm_guest_cpu_init();
705727
#endif
706728

729+
register_syscore_ops(&kvm_syscore_ops);
730+
707731
/*
708732
* Hard lockup detection is enabled by default. Disable it, as guests
709733
* can get false positives too easily, for example if the host is

0 commit comments

Comments
 (0)