Skip to content
  • Wanpeng Li's avatar
    KVM: x86: Fix potential preemption when get the current kvmclock timestamp · e2c2206a
    Wanpeng Li authored
    
    
     BUG: using __this_cpu_read() in preemptible [00000000] code: qemu-system-x86/2809
     caller is __this_cpu_preempt_check+0x13/0x20
     CPU: 2 PID: 2809 Comm: qemu-system-x86 Not tainted 4.11.0+ #13
     Call Trace:
      dump_stack+0x99/0xce
      check_preemption_disabled+0xf5/0x100
      __this_cpu_preempt_check+0x13/0x20
      get_kvmclock_ns+0x6f/0x110 [kvm]
      get_time_ref_counter+0x5d/0x80 [kvm]
      kvm_hv_process_stimers+0x2a1/0x8a0 [kvm]
      ? kvm_hv_process_stimers+0x2a1/0x8a0 [kvm]
      ? kvm_arch_vcpu_ioctl_run+0xac9/0x1ce0 [kvm]
      kvm_arch_vcpu_ioctl_run+0x5bf/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
      entry_SYSCALL_64_fastpath+0x23/0xc2
     RIP: 0033:0x7f9d164ed357
      ? __this_cpu_preempt_check+0x13/0x20
    
    This can be reproduced by run kvm-unit-tests/hyperv_stimer.flat w/
    CONFIG_PREEMPT and CONFIG_DEBUG_PREEMPT enabled.
    
    Safe access to per-CPU data requires a couple of constraints, though: the
    thread working with the data cannot be preempted and it cannot be migrated
    while it manipulates per-CPU variables. If the thread is preempted, the
    thread that replaces it could try to work with the same variables; migration
    to another CPU could also cause confusion. However there is no preemption
    disable when reads host per-CPU tsc rate to calculate the current kvmclock
    timestamp.
    
    This patch fixes it by utilizing get_cpu/put_cpu pair to guarantee both
    __this_cpu_read() and rdtsc() are not preempted.
    
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Radim Krčmář <rkrcmar@redhat.com>
    Signed-off-by: default avatarWanpeng Li <wanpeng.li@hotmail.com>
    Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
    e2c2206a