Include as much of the read-only data in the replication as we can without needing to move away from the generic RO_DATA() macro in the linker script. Unfortunately, the read-only data section is immedaitely followed by the read-only after init data with no page alignment, which means we can't have separate mappings for the read-only data section and everything else. Changing that would mean replacing the generic RO_DATA() macro which increases the maintenance burden. however, this is likely not worth the effort as the majority of read-only data will be covered. Signed-off-by: Russell King (Oracle) <rmk+kernel@xxxxxxxxxxxxxxx> --- arch/arm64/mm/ktext.c | 2 +- arch/arm64/mm/mmu.c | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/arm64/mm/ktext.c b/arch/arm64/mm/ktext.c index 6692759e78a8..6265a2db449b 100644 --- a/arch/arm64/mm/ktext.c +++ b/arch/arm64/mm/ktext.c @@ -101,7 +101,7 @@ void ktext_replication_patch_alternative(__le32 *src, int nr_inst) /* Allocate page tables and memory for the replicated kernel texts. */ void __init ktext_replication_init(void) { - size_t size = _etext - _stext; + size_t size = __end_rodata - _stext; int kidx = pgd_index((phys_addr_t)KERNEL_START); int nid; diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index fb9c476605d1..bf674bdaf336 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -752,11 +752,26 @@ static pgprot_t __init kernel_text_pgprot(void) #ifdef CONFIG_REPLICATE_KTEXT void __init create_kernel_nid_map(pgd_t *pgdp, void *ktext) { + phys_addr_t pa_ktext; + size_t ro_offset; + void *ro_end; pgprot_t text_prot = kernel_text_pgprot(); - create_kernel_mapping(pgdp, __pa(ktext), _stext, _etext, text_prot, 0); - create_kernel_mapping(pgdp, __pa_symbol(__start_rodata), - __start_rodata, __inittext_begin, + pa_ktext = __pa(ktext); + ro_offset = __pa_symbol(__start_rodata) - __pa_symbol(_stext); + /* + * We must not cover the read-only data after init, since this + * is written to during boot, and thus must be shared between + * the NUMA nodes. + */ + ro_end = PTR_ALIGN_DOWN((void *)__start_ro_after_init, PAGE_SIZE); + + create_kernel_mapping(pgdp, pa_ktext, _stext, _etext, text_prot, 0); + create_kernel_mapping(pgdp, pa_ktext + ro_offset, + __start_rodata, ro_end, + PAGE_KERNEL, NO_CONT_MAPPINGS); + create_kernel_mapping(pgdp, __pa_symbol(ro_end), + ro_end, __inittext_begin, PAGE_KERNEL, NO_CONT_MAPPINGS); create_kernel_mapping(pgdp, __pa_symbol(__inittext_begin), __inittext_begin, __inittext_end, -- 2.30.2