• Takuya Yoshikawa's avatar
    KVM: Fix write protection race during dirty logging · 6dbf79e7
    Takuya Yoshikawa authored
    This patch fixes a race introduced by:
    
      commit 95d4c16c
      KVM: Optimize dirty logging by rmap_write_protect()
    
    During protecting pages for dirty logging, other threads may also try
    to protect a page in mmu_sync_children() or kvm_mmu_get_page().
    
    In such a case, because get_dirty_log releases mmu_lock before flushing
    TLB's, the following race condition can happen:
    
      A (get_dirty_log)     B (another thread)
    
      lock(mmu_lock)
      clear pte.w
      unlock(mmu_lock)
                            lock(mmu_lock)
                            pte.w is already cleared
                            unlock(mmu_lock)
                            skip TLB flush
                            return
      ...
      TLB flush
    
    Though thread B assumes the page has already been protected when it
    returns, the remaining TLB entry will break that assumption.
    
    This patch fixes this problem by making get_dirty_log hold the mmu_lock
    until it flushes the TLB's.
    Signed-off-by: default avatarTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
    Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
    Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
    6dbf79e7
x86.c 162 KB