• James Hogan's avatar
    MIPS: KVM: Reset CP0_PageMask during host TLB flush · a700434d
    James Hogan authored
    KVM sometimes flushes host TLB entries, reading each one to check if it
    corresponds to a guest KSeg0 address. In the absence of EntryHi.EHInv
    bits to invalidate the whole entry, the entries will be set to unique
    virtual addresses in KSeg0 (which is not TLB mapped), spaced 2*PAGE_SIZE
    apart.
    
    The TLB read however will clobber the CP0_PageMask register with
    whatever page size that TLB entry had, and that same page size will be
    written back into the TLB entry along with the unique address.
    
    This would cause breakage when transparent huge pages are enabled on
    64-bit host kernels, since huge page entries will overlap other nearby
    entries when separated by only 2*PAGE_SIZE, causing a machine check
    exception.
    
    Fix this by restoring the old CP0_PageMask value (which should be set to
    the normal page size) after reading the TLB entry if we're going to go
    ahead and invalidate it.
    Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: "Radim Krčmář" <rkrcmar@redhat.com>
    Cc: Ralf Baechle <ralf@linux-mips.org>
    Cc: linux-mips@linux-mips.org
    Cc: kvm@vger.kernel.org
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    a700434d
tlb.c 8.91 KB