• Sean Christopherson's avatar
    KVM: x86/mmu: Persist gfn_lpage_is_disallowed() to max_level · 2f57b705
    Sean Christopherson authored
    Persist the max page level calculated via gfn_lpage_is_disallowed() to
    the max level "returned" by mapping_level() so that its naturally taken
    into account by the max level check that conditions calling
    transparent_hugepage_adjust().
    
    Drop the gfn_lpage_is_disallowed() check in thp_adjust() as it's now
    handled by mapping_level() and its callers.
    
    Add a comment to document the behavior of host_mapping_level() and its
    interaction with max level and transparent huge pages.
    
    Note, transferring the gfn_lpage_is_disallowed() from thp_adjust() to
    mapping_level() superficially affects how changes to a memslot's
    disallow_lpage count will be handled due to thp_adjust() being run while
    holding mmu_lock.
    
    In the more common case where a different vCPU increments the count via
    account_shadowed(), gfn_lpage_is_disallowed() is rechecked by set_spte()
    to ensure a writable large page isn't created.
    
    In the less common case where the count is decremented to zero due to
    all shadow pages in the memslot being zapped, THP behavior now matches
    hugetlbfs behavior in the sense that a small page will be created when a
    large page could be used if the count reaches zero in the miniscule
    window between mapping_level() and acquiring mmu_lock.
    
    Lastly, the new THP behavior also follows hugetlbfs behavior in the
    absurdly unlikely scenario of a memslot being moved such that the
    memslot's compatibility with respect to large pages changes, but without
    changing the validity of the gpf->pfn walk.  I.e. if a memslot is moved
    between mapping_level() and snapshotting mmu_seq, it's theoretically
    possible to consume a stale disallow_lpage count.  But, since KVM zaps
    all shadow pages when moving a memslot and forces all vCPUs to reload a
    new MMU, the inserted spte will always be thrown away prior to
    completing the memslot move, i.e. whether or not the spte accurately
    reflects disallow_lpage is irrelevant.
    Signed-off-by: default avatarSean Christopherson <sean.j.christopherson@intel.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    2f57b705
mmu.c 171 KB