• Ben Gardon's avatar
    KVM: x86/mmu: Protect TDP MMU page table memory with RCU · 7cca2d0b
    Ben Gardon authored
    In order to enable concurrent modifications to the paging structures in
    the TDP MMU, threads must be able to safely remove pages of page table
    memory while other threads are traversing the same memory. To ensure
    threads do not access PT memory after it is freed, protect PT memory
    with RCU.
    
    Protecting concurrent accesses to page table memory from use-after-free
    bugs could also have been acomplished using
    walk_shadow_page_lockless_begin/end() and READING_SHADOW_PAGE_TABLES,
    coupling with the barriers in a TLB flush. The use of RCU for this case
    has several distinct advantages over that approach.
    1. Disabling interrupts for long running operations is not desirable.
       Future commits will allow operations besides page faults to operate
       without the exclusive protection of the MMU lock and those operations
       are too long to disable iterrupts for their duration.
    2. The use of RCU here avoids long blocking / spinning operations in
       perfromance critical paths. By freeing memory with an asynchronous
       RCU API we avoid the longer wait times TLB flushes experience when
       overlapping with a thread in walk_shadow_page_lockless_begin/end().
    3. RCU provides a separation of concerns when removing memory from the
       paging structure. Because the RCU callback to free memory can be
       scheduled immediately after a TLB flush, there's no need for the
       thread to manually free a queue of pages later, as commit_zap_pages
       does.
    
    Fixes: 95fb5b02 ("kvm: x86/mmu: Support MMIO in the TDP MMU")
    Reviewed-by: default avatarPeter Feiner <pfeiner@google.com>
    Suggested-by: default avatarSean Christopherson <seanjc@google.com>
    Signed-off-by: default avatarBen Gardon <bgardon@google.com>
    
    Message-Id: <20210202185734.1680553-18-bgardon@google.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    7cca2d0b
tdp_mmu.c 35.2 KB