• Ard Biesheuvel's avatar
    ARM/arm64: KVM: test properly for a PTE's uncachedness · e6fab544
    Ard Biesheuvel authored
    The open coded tests for checking whether a PTE maps a page as
    uncached use a flawed '(pte_val(xxx) & CONST) != CONST' pattern,
    which is not guaranteed to work since the type of a mapping is
    not a set of mutually exclusive bits
    
    For HYP mappings, the type is an index into the MAIR table (i.e, the
    index itself does not contain any information whatsoever about the
    type of the mapping), and for stage-2 mappings it is a bit field where
    normal memory and device types are defined as follows:
    
        #define MT_S2_NORMAL            0xf
        #define MT_S2_DEVICE_nGnRE      0x1
    
    I.e., masking *and* comparing with the latter matches on the former,
    and we have been getting lucky merely because the S2 device mappings
    also have the PTE_UXN bit set, or we would misidentify memory mappings
    as device mappings.
    
    Since the unmap_range() code path (which contains one instance of the
    flawed test) is used both for HYP mappings and stage-2 mappings, and
    considering the difference between the two, it is non-trivial to fix
    this by rewriting the tests in place, as it would involve passing
    down the type of mapping through all the functions.
    
    However, since HYP mappings and stage-2 mappings both deal with host
    physical addresses, we can simply check whether the mapping is backed
    by memory that is managed by the host kernel, and only perform the
    D-cache maintenance if this is the case.
    
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
    Tested-by: default avatarPavel Fedin <p.fedin@samsung.com>
    Reviewed-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
    Signed-off-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
    e6fab544
mmu.c 50.2 KB