• Mark Rutland's avatar
    arm64: mm: always map fixmap at page granularity · 414c109b
    Mark Rutland authored
    Today the fixmap code largely maps elements at PAGE_SIZE granularity,
    but we special-case the FDT mapping such that it can be mapped with 2M
    block mappings when 4K pages are in use. The original rationale for this
    was simplicity, but it has some unfortunate side-effects, and
    complicates portions of the fixmap code (i.e. is not so simple after
    all).
    
    The FDT can be up to 2M in size but is only required to have 8-byte
    alignment, and so it may straddle a 2M boundary. Thus when using 2M
    block mappings we may map up to 4M of memory surrounding the FDT. This
    is unfortunate as most of that memory will be unrelated to the FDT, and
    any pages which happen to share a 2M block with the FDT will by mapped
    with Normal Write-Back Cacheable attributes, which might not be what we
    want elsewhere (e.g. for carve-outs using Non-Cacheable attributes).
    
    The logic to handle mapping the FDT with 2M blocks requires some special
    cases in the fixmap code, and ties it to the early page table
    configuration by virtue of the SWAPPER_TABLE_SHIFT and
    SWAPPER_BLOCK_SIZE constants used to determine the granularity used to
    map the FDT.
    
    This patch simplifies the FDT logic and removes the unnecessary mappings
    of surrounding pages by always mapping the FDT at page granularity as
    with all other fixmap mappings. To do so we statically reserve multiple
    PTE tables to cover the fixmap VA range. Since the FDT can be at most
    2M, for 4K pages we only need to allocate a single additional PTE table,
    and for 16K and 64K pages the existing single PTE table is sufficient.
    
    The PTE table allocation scales with the number of slots reserved in the
    fixmap, and so this also makes it easier to add more fixmap entries if
    we require those in future.
    
    Our VA layout means that the fixmap will always fall within a single PMD
    table (and consequently, within a single PUD/P4D/PGD entry), which we
    can verify at compile time with a static_assert(). With that assert a
    number of runtime warnings become impossible, and are removed.
    
    I've boot-tested this patch with both 4K and 64K pages.
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Cc: Anshuman Khandual <anshuman.khandual@arm.com>
    Cc: Ard Biesheuvel <ardb@kernel.org>
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: Ryan Roberts <ryan.roberts@arm.com>
    Cc: Will Deacon <will@kernel.org>
    Reviewed-by: default avatarRyan Roberts <ryan.roberts@arm.com>
    Link: https://lore.kernel.org/r/20230406152759.4164229-4-mark.rutland@arm.comSigned-off-by: default avatarWill Deacon <will@kernel.org>
    414c109b
kernel-pgtable.h 5.2 KB