summaryrefslogtreecommitdiff
path: root/arch/arm64/mm/ktext.c
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2022-06-17 13:25:15 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-01-08 12:33:02 +0000
commit4c888ada40d97fe926ced7a8adcad36533f404be (patch)
treea379dd3dd1936bba8189a48f5d208ea8af5ab05a /arch/arm64/mm/ktext.c
parent6f9c4de225ec7830b9529eea0d14a84295629408 (diff)
arm64: text replication: add test module
Add a module to allow kernel text replication to be tested; this exposes some data in procfs which can be used to verify that: (a) we're using different page tables in TTBR1 on CPUs in different NUMA nodes (b) that CPUs in different NUMA nodes are indeed accessing different copies of the kernel Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'arch/arm64/mm/ktext.c')
-rw-r--r--arch/arm64/mm/ktext.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/arm64/mm/ktext.c b/arch/arm64/mm/ktext.c
index 4ab04f531c81..d29497c37da9 100644
--- a/arch/arm64/mm/ktext.c
+++ b/arch/arm64/mm/ktext.c
@@ -22,6 +22,11 @@ struct pgtables *pgtables[MAX_NUMNODES] = {
static void *kernel_texts[MAX_NUMNODES];
+#if IS_ENABLED(CONFIG_TEST_KTEXT_REPLICATE)
+const char ktext_nid[32] = "0";
+EXPORT_SYMBOL_GPL(ktext_nid);
+#endif
+
static pgd_t *__swapper_pg_dir_node(int nid)
{
return pgtables[nid]->swapper_pg_dir;
@@ -131,6 +136,9 @@ early_param("ktext", parse_ktext);
void __init ktext_replication_init(void)
{
size_t size = __end_rodata - _stext;
+#if IS_ENABLED(CONFIG_TEST_KTEXT_REPLICATE)
+ size_t kt_nid = ktext_nid - _stext;
+#endif
int kidx = pgd_index((phys_addr_t)KERNEL_START);
int nid;
@@ -159,6 +167,13 @@ void __init ktext_replication_init(void)
/* Allocate and copy initial kernel text for this node */
kernel_texts[nid] = memblock_alloc_node(size, PAGE_SIZE, nid);
memcpy(kernel_texts[nid], _stext, size);
+
+#if IS_ENABLED(CONFIG_TEST_KTEXT_REPLICATE)
+ /* Update the node ID in each copy of the kernel text/rodata */
+ snprintf(kernel_texts[nid] + kt_nid, sizeof(kernel_texts[nid]),
+ "%u", nid);
+#endif
+
caches_clean_inval_pou((u64)kernel_texts[nid],
(u64)kernel_texts[nid] + size);