• Sean Christopherson's avatar
    KVM: x86: Invalidate all PGDs for the current PCID on MOV CR3 w/ flush · 21823fbd
    Sean Christopherson authored
    Flush and sync all PGDs for the current/target PCID on MOV CR3 with a
    TLB flush, i.e. without PCID_NOFLUSH set.  Paraphrasing Intel's SDM
    regarding the behavior of MOV to CR3:
    
      - If CR4.PCIDE = 0, invalidates all TLB entries associated with PCID
        000H and all entries in all paging-structure caches associated with
        PCID 000H.
    
      - If CR4.PCIDE = 1 and NOFLUSH=0, invalidates all TLB entries
        associated with the PCID specified in bits 11:0, and all entries in
        all paging-structure caches associated with that PCID. It is not
        required to invalidate entries in the TLBs and paging-structure
        caches that are associated with other PCIDs.
    
      - If CR4.PCIDE=1 and NOFLUSH=1, is not required to invalidate any TLB
        entries or entries in paging-structure caches.
    
    Extract and reuse the logic for INVPCID(single) which is effectively the
    same flow and works even if CR4.PCIDE=0, as the current PCID will be '0'
    in that case, thus honoring the requirement of flushing PCID=0.
    
    Continue passing skip_tlb_flush to kvm_mmu_new_pgd() even though it
    _should_ be redundant; the clean up will be done in a future patch.  The
    overhead of an unnecessary nop sync is minimal (especially compared to
    the actual sync), and the TLB flush is handled via request.  Avoiding the
    the negligible overhead is not worth the risk of breaking kernels that
    backport the fix.
    
    Fixes: 956bf353 ("kvm: x86: Skip shadow page resync on CR3 switch when indicated by guest")
    Cc: Junaid Shahid <junaids@google.com>
    Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
    Message-Id: <20210609234235.1244004-5-seanjc@google.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    21823fbd
x86.c 318 KB