summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2022-06-17 13:23:39 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-01-08 12:33:01 +0000
commit21c388e7260bf32359fc6239e5ff81d1d1527985 (patch)
tree861d2857e87c3226fa42da19476278d0aa8d6723
parentd5fd3d14b39b256e76a37df77ef88712d1943dec (diff)
arm64: text replication: include most of read-only data as well
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@armlinux.org.uk>
-rw-r--r--arch/arm64/mm/ktext.c2
-rw-r--r--arch/arm64/mm/mmu.c21
2 files changed, 19 insertions, 4 deletions
diff --git a/arch/arm64/mm/ktext.c b/arch/arm64/mm/ktext.c
index a07a03f36519..6ca7c4730893 100644
--- a/arch/arm64/mm/ktext.c
+++ b/arch/arm64/mm/ktext.c
@@ -122,7 +122,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 42ca0bc2865e..d1df530b2755 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -753,11 +753,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,