• Sean Christopherson's avatar
    KVM: x86: fix L1TF's MMIO GFN calculation · daa07cbc
    Sean Christopherson authored
    One defense against L1TF in KVM is to always set the upper five bits
    of the *legal* physical address in the SPTEs for non-present and
    reserved SPTEs, e.g. MMIO SPTEs.  In the MMIO case, the GFN of the
    MMIO SPTE may overlap with the upper five bits that are being usurped
    to defend against L1TF.  To preserve the GFN, the bits of the GFN that
    overlap with the repurposed bits are shifted left into the reserved
    bits, i.e. the GFN in the SPTE will be split into high and low parts.
    When retrieving the GFN from the MMIO SPTE, e.g. to check for an MMIO
    access, get_mmio_spte_gfn() unshifts the affected bits and restores
    the original GFN for comparison.  Unfortunately, get_mmio_spte_gfn()
    neglects to mask off the reserved bits in the SPTE that were used to
    store the upper chunk of the GFN.  As a result, KVM fails to detect
    MMIO accesses whose GPA overlaps the repurprosed bits, which in turn
    causes guest panics and hangs.
    
    Fix the bug by generating a mask that covers the lower chunk of the
    GFN, i.e. the bits that aren't shifted by the L1TF mitigation.  The
    alternative approach would be to explicitly zero the five reserved
    bits that are used to store the upper chunk of the GFN, but that
    requires additional run-time computation and makes an already-ugly
    bit of code even more inscrutable.
    
    I considered adding a WARN_ON_ONCE(low_phys_bits-1 <= PAGE_SHIFT) to
    warn if GENMASK_ULL() generated a nonsensical value, but that seemed
    silly since that would mean a system that supports VMX has less than
    18 bits of physical address space...
    Reported-by: default avatarSakari Ailus <sakari.ailus@iki.fi>
    Fixes: d9b47449c1a1 ("kvm: x86: Set highest physical address bits in non-present/reserved SPTEs")
    Cc: Junaid Shahid <junaids@google.com>
    Cc: Jim Mattson <jmattson@google.com>
    Cc: stable@vger.kernel.org
    Reviewed-by: default avatarJunaid Shahid <junaids@google.com>
    Tested-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
    Signed-off-by: default avatarSean Christopherson <sean.j.christopherson@intel.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    daa07cbc
mmu.c 154 KB