On 26/05/2026 19:58, Ard Biesheuvel wrote: > From: Ard Biesheuvel <[email protected]> > > On systems where the bootloader adheres to the original arm64 boot > protocol, the placement of the kernel in the physical address space is > highly predictable, and this makes the placement of its linear alias in > the kernel virtual address space equally predictable, given the lack of > randomization of the linear map. > > The linear aliases of the kernel text and rodata regions are already > mapped read-only, but the kernel data and bss are mapped read-write in > this region. This is not needed, so map them read-only as well. > > Note that the statically allocated kernel page tables do need to be > modifiable via the linear map, so leave these mapped read-write. > > Signed-off-by: Ard Biesheuvel <[email protected]>
Reviewed-by: Kevin Brodsky <[email protected]> > --- > arch/arm64/mm/mmu.c | 15 +++++++++++++-- > 1 file changed, 13 insertions(+), 2 deletions(-) > > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c > index b20c76b8381d..e7ca53d20b87 100644 > --- a/arch/arm64/mm/mmu.c > +++ b/arch/arm64/mm/mmu.c > @@ -1138,7 +1138,9 @@ static void __init map_mem(void) > { > static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN); > phys_addr_t kernel_start = __pa_symbol(_text); > - phys_addr_t kernel_end = __pa_symbol(__init_begin); > + phys_addr_t init_begin = __pa_symbol(__init_begin); > + phys_addr_t init_end = __pa_symbol(__init_end); > + phys_addr_t kernel_end = __pa_symbol(__bss_stop); > phys_addr_t start, end; > int flags = NO_EXEC_MAPPINGS; > u64 i; > @@ -1171,7 +1173,11 @@ static void __init map_mem(void) > * of the region accessible to subsystems such as hibernate, > * but protects it from inadvertent modification or execution. > */ > - __map_memblock(kernel_start, kernel_end, PAGE_KERNEL, flags); > + __map_memblock(kernel_start, init_begin, PAGE_KERNEL, flags); > + > + /* Map the kernel data/bss so it can be remapped later */ > + __map_memblock(init_end, kernel_end, pgprot_tagged(PAGE_KERNEL), > + flags); > > /* map all the memory banks */ > for_each_mem_range(i, &start, &end) { > @@ -1183,6 +1189,11 @@ static void __init map_mem(void) > __map_memblock(start, end, pgprot_tagged(PAGE_KERNEL), > flags); > } > + > + /* Map the kernel data/bss read-only in the linear map */ > + __map_memblock(init_end, kernel_end, PAGE_KERNEL_RO, flags); > + flush_tlb_kernel_range((unsigned long)lm_alias(__init_end), > + (unsigned long)lm_alias(__bss_stop)); > } > > void mark_rodata_ro(void)

