On Fri, 8 May 2026, at 19:02, Jann Horn wrote: > On Mon, Apr 27, 2026 at 5:44 PM Ard Biesheuvel <[email protected]> wrote: >> The empty zero page is used to back any kernel or user space mapping >> that is supposed to remain cleared, and so the page itself is never >> supposed to be modified. >> >> So make it __ro_after_init rather than __page_aligned_bss: on most >> architectures, this ensures that both the kernel's mapping of it and any >> aliases that are accessible via the kernel direct (linear) map are >> mapped read-only, and cannot be used (inadvertently or maliciously) to >> corrupt the contents of the zero page. >> >> Signed-off-by: Ard Biesheuvel <[email protected]> > > Reviewed-by: Jann Horn <[email protected]> >
Thanks > Sorry, I should have looked at this properly earlier instead of ending > up duplicating this patch with > <https://lore.kernel.org/all/[email protected]/>. > No worries. I might borrow some of that rationale btw >> --- >> mm/mm_init.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/mm/mm_init.c b/mm/mm_init.c >> index f9f8e1af921c..6ca01ed2a5a4 100644 >> --- a/mm/mm_init.c >> +++ b/mm/mm_init.c >> @@ -57,7 +57,7 @@ unsigned long zero_page_pfn __ro_after_init; >> EXPORT_SYMBOL(zero_page_pfn); >> >> #ifndef __HAVE_COLOR_ZERO_PAGE >> -uint8_t empty_zero_page[PAGE_SIZE] __page_aligned_bss; >> +uint8_t empty_zero_page[PAGE_SIZE] __ro_after_init __aligned(PAGE_SIZE); > > I think this is fine as-is; but FWIW: > "__ro_after_init __aligned(PAGE_SIZE)" means that this will land > in the middle of the .data..ro_after_init section, with padding in > front of it to create 4K alignment. So this probably wastes some > RAM on padding. > > Looking at "nm ../linux-out/vmlinux | sort" with this patch applied > (from a build without any LTO or such), I see this: > ``` > [...] > ffffffff8473d378 d shmem_inode_cachep > ffffffff8473d380 d user_buckets > ffffffff8473e000 D zero_page_pfn > ffffffff8473f000 D empty_zero_page > ffffffff84740000 D __zero_page > ffffffff84740008 D pcpu_reserved_chunk > [...] > ``` > So I think there are almost 4K of padding between zero_page_pfn and > empty_zero_page for alignment; and I think when the linker linked > mm-init.o with the rest of the kernel, it also had to align the > compilation unit's entire .data..ro_after_init section to 4K, which is > why I also got ~3K of padding before zero_page_pfn, resulting in a > total of ~7K of padding. > > If you want to change this: > I searched through the arch-specific linker scripts, and I think they > all rely on the generic RO_DATA() macro for emitting the rodata > section; so creating an analogous page-aligned rodata section should > be as simple as adding "*(.rodata..page_aligned)" directly after > "__start_rodata = .;", as I did in my duplicate patch. I think we should simply do something along the lines of the below, considering that the size of a data object tends to correlate with its minimum alignment. I do find it rather puzzling that the compiler emits empty_zero_page *after* zero_page_pfn - ideally, we'd combine the below with -fdata-sections so that the linker sees all individual objects, but I suspect that would create some problems elsewhere. --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -452,7 +452,7 @@ #define RO_AFTER_INIT_DATA \ . = ALIGN(8); \ __start_ro_after_init = .; \ - *(.data..ro_after_init) \ + *(SORT_BY_ALIGNMENT(.data..ro_after_init)) \ JUMP_TABLE_DATA \ STATIC_CALL_DATA \ __end_ro_after_init = .;

