• Ard Biesheuvel's avatar
    arm64: mm: install KPTI nG mappings with MMU enabled · 47546a19
    Ard Biesheuvel authored
    In cases where we unmap the kernel while running in user space, we rely
    on ASIDs to distinguish the minimal trampoline from the full kernel
    mapping, and this means we must use non-global attributes for those
    mappings, to ensure they are scoped by ASID and will not hit in the TLB
    inadvertently.
    
    We only do this when needed, as this is generally more costly in terms
    of TLB pressure, and so we boot without these non-global attributes, and
    apply them to all existing kernel mappings once all CPUs are up and we
    know whether or not the non-global attributes are needed. At this point,
    we cannot simply unmap and remap the entire address space, so we have to
    update all existing block and page descriptors in place.
    
    Currently, we go through a lot of trouble to perform these updates with
    the MMU and caches off, to avoid violating break before make (BBM) rules
    imposed by the architecture. Since we make changes to page tables that
    are not covered by the ID map, we gain access to those descriptors by
    disabling translations altogether. This means that the stores to memory
    are issued with device attributes, and require extra care in terms of
    coherency, which is costly. We also rely on the ID map to access a
    shared flag, which requires the ID map to be executable and writable at
    the same time, which is another thing we'd prefer to avoid.
    
    So let's switch to an approach where we replace the kernel mapping with
    a minimal mapping of a few pages that can be used for a minimal, ad-hoc
    fixmap that we can use to map each page table in turn as we traverse the
    hierarchy.
    Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
    Link: https://lore.kernel.org/r/20220609174320.4035379-3-ardb@kernel.orgSigned-off-by: default avatarWill Deacon <will@kernel.org>
    47546a19
mmu.c 44.3 KB