| From foo@baz Tue Jun 8 05:44:24 PM CEST 2021 |
| From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> |
| Date: Mon, 31 May 2021 16:05:25 +0200 |
| Subject: x86/kvm: Disable kvmclock on all CPUs on shutdown |
| To: stable@vger.kernel.org |
| Cc: Andrea Righi <andrea.righi@canonical.com>, Paolo Bonzini <pbonzini@redhat.com>, Vitaly Kuznetsov <vkuznets@redhat.com>, Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> |
| Message-ID: <20210531140526.42932-3-krzysztof.kozlowski@canonical.com> |
| |
| From: Vitaly Kuznetsov <vkuznets@redhat.com> |
| |
| commit c02027b5742b5aa804ef08a4a9db433295533046 upstream. |
| |
| Currenly, we disable kvmclock from machine_shutdown() hook and this |
| only happens for boot CPU. We need to disable it for all CPUs to |
| guard against memory corruption e.g. on restore from hibernate. |
| |
| Note, writing '0' to kvmclock MSR doesn't clear memory location, it |
| just prevents hypervisor from updating the location so for the short |
| while after write and while CPU is still alive, the clock remains usable |
| and correct so we don't need to switch to some other clocksource. |
| |
| Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> |
| Message-Id: <20210414123544.1060604-4-vkuznets@redhat.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Andrea Righi <andrea.righi@canonical.com> |
| Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/include/asm/kvm_para.h | 4 ++-- |
| arch/x86/kernel/kvm.c | 1 + |
| arch/x86/kernel/kvmclock.c | 5 +---- |
| 3 files changed, 4 insertions(+), 6 deletions(-) |
| |
| --- a/arch/x86/include/asm/kvm_para.h |
| +++ b/arch/x86/include/asm/kvm_para.h |
| @@ -7,8 +7,6 @@ |
| #include <linux/interrupt.h> |
| #include <uapi/asm/kvm_para.h> |
| |
| -extern void kvmclock_init(void); |
| - |
| #ifdef CONFIG_KVM_GUEST |
| bool kvm_check_and_clear_guest_paused(void); |
| #else |
| @@ -86,6 +84,8 @@ static inline long kvm_hypercall4(unsign |
| } |
| |
| #ifdef CONFIG_KVM_GUEST |
| +void kvmclock_init(void); |
| +void kvmclock_disable(void); |
| bool kvm_para_available(void); |
| unsigned int kvm_arch_para_features(void); |
| unsigned int kvm_arch_para_hints(void); |
| --- a/arch/x86/kernel/kvm.c |
| +++ b/arch/x86/kernel/kvm.c |
| @@ -468,6 +468,7 @@ static void kvm_guest_cpu_offline(void) |
| wrmsrl(MSR_KVM_PV_EOI_EN, 0); |
| kvm_pv_disable_apf(); |
| apf_task_wake_all(); |
| + kvmclock_disable(); |
| } |
| |
| static int kvm_cpu_online(unsigned int cpu) |
| --- a/arch/x86/kernel/kvmclock.c |
| +++ b/arch/x86/kernel/kvmclock.c |
| @@ -221,11 +221,9 @@ static void kvm_crash_shutdown(struct pt |
| } |
| #endif |
| |
| -static void kvm_shutdown(void) |
| +void kvmclock_disable(void) |
| { |
| native_write_msr(msr_kvm_system_time, 0, 0); |
| - kvm_disable_steal_time(); |
| - native_machine_shutdown(); |
| } |
| |
| static void __init kvmclock_init_mem(void) |
| @@ -352,7 +350,6 @@ void __init kvmclock_init(void) |
| #endif |
| x86_platform.save_sched_clock_state = kvm_save_sched_clock_state; |
| x86_platform.restore_sched_clock_state = kvm_restore_sched_clock_state; |
| - machine_ops.shutdown = kvm_shutdown; |
| #ifdef CONFIG_KEXEC_CORE |
| machine_ops.crash_shutdown = kvm_crash_shutdown; |
| #endif |