lkml.org 
[lkml]   [2018]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.9 116/281] KVM: X86: Fix preempt the preemption timer cancel
    Date
    From: Wanpeng Li <wanpeng.li@hotmail.com>

    [ 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.

    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Radim Krčmář <rkrcmar@redhat.com>
    Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    arch/x86/kvm/lapic.c | 2 ++
    1 file changed, 2 insertions(+)

    diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
    index b24b3c6d686e..5c3d416fff17 100644
    --- a/arch/x86/kvm/lapic.c
    +++ b/arch/x86/kvm/lapic.c
    @@ -1363,8 +1363,10 @@ EXPORT_SYMBOL_GPL(kvm_lapic_hv_timer_in_use);

    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)
    --
    2.14.1
    \
     
     \ /
      Last update: 2018-03-19 22:18    [W:3.020 / U:0.276 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site