Patch "KVM: X86: Fix preempt the preemption timer cancel" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
KVM: X86: Fix preempt the preemption timer cancel
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-x86-fix-preempt-the-preemption-timer-cancel.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Mon Apr 9 17:09:24 CEST 2018
From: Wanpeng Li <[email protected]>
Date: Sat, 20 May 2017 20:32:32 -0700
Subject: KVM: X86: Fix preempt the preemption timer cancel
From: Wanpeng Li <[email protected]>
[ Upstream commit 5acc1ca4fb15f00bfa3d4046e35ca381bc25d580 ]
Preemption can occur during cancel preemption timer, and there will be inconsistent status in lapic, vmx and vmcs field.
CPU0 CPU1
preemption timer vmexit
handle_preemption_timer(vCPU0)
kvm_lapic_expired_hv_timer
vmx_cancel_hv_timer
vmx->hv_deadline_tsc = -1
vmcs_clear_bits
/* hv_timer_in_use still true */
sched_out
sched_in
kvm_arch_vcpu_load
vmx_set_hv_timer
write vmx->hv_deadline_tsc
vmcs_set_bits
/* back in kvm_lapic_expired_hv_timer */
hv_timer_in_use = false
...
vmx_vcpu_run
vmx_arm_hv_run
write preemption timer deadline
spurious preemption timer vmexit
handle_preemption_timer(vCPU0)
kvm_lapic_expired_hv_timer
WARN_ON(!apic->lapic_timer.hv_timer_in_use);This can be reproduced sporadically during boot of L2 on a preemptible L1, causing a splat on L1.
WARNING: CPU: 3 PID: 1952 at arch/x86/kvm/lapic.c:1529 kvm_lapic_expired_hv_timer+0xb5/0xd0 [kvm] CPU: 3 PID: 1952 Comm: qemu-system-x86 Not tainted 4.12.0-rc1+ #24 RIP: 0010:kvm_lapic_expired_hv_timer+0xb5/0xd0 [kvm] Call Trace: handle_preemption_timer+0xe/0x20 [kvm_intel] vmx_handle_exit+0xc9/0x15f0 [kvm_intel] ? lock_acquire+0xdb/0x250 ? lock_acquire+0xdb/0x250 ? kvm_arch_vcpu_ioctl_run+0xdf3/0x1ce0 [kvm] kvm_arch_vcpu_ioctl_run+0xe55/0x1ce0 [kvm] kvm_vcpu_ioctl+0x384/0x7b0 [kvm] ? kvm_vcpu_ioctl+0x384/0x7b0 [kvm] ? __fget+0xf3/0x210 do_vfs_ioctl+0xa4/0x700 ? __fget+0x114/0x210 SyS_ioctl+0x79/0x90 do_syscall_64+0x8f/0x750 ? trace_hardirqs_on_thunk+0x1a/0x1c entry_SYSCALL64_slow_path+0x25/0x25
This patch fixes it by disabling preemption while cancelling preemption timer. This way cancel_hv_timer is atomic with respect to kvm_arch_vcpu_load.
--- arch/x86/kvm/lapic.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/kvm/lapic.c +2 -0
@@ -1363,8 +1363,10 @@ EXPORT_SYMBOL_GPL(kvm_lapic_hv_timer_in_static void cancel_hv_tscdeadline (struct kvm_lapic *apic) { +preempt_disable (); kvm_x86_ops->cancel_hv_timer (apic->vcpu); apic->lapic_timer.hv_timer_in_use = false; +preempt_enable (); }void kvm_lapic_expired_hv_timer (struct kvm_vcpu *vcpu)
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/kvm-x86-fix-preempt-the-preemption-timer-cancel.patch queue-4.9/kvm-nvmx-fix-handling-of-lmsw-instruction.patch