Skip to content

Commit 2e8cff0

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64: fix rodata=full
On arm64, "rodata=full" has been suppored (but not documented) since commit: c55191e ("arm64: mm: apply r/o permissions of VM areas to its linear alias as well") As it's necessary to determine the rodata configuration early during boot, arm64 has an early_param() handler for this, whereas init/main.c has a __setup() handler which is run later. Unfortunately, this split meant that since commit: f9a40b0 ("init/main.c: return 1 from handled __setup() functions") ... passing "rodata=full" would result in a spurious warning from the __setup() handler (though RO permissions would be configured appropriately). Further, "rodata=full" has been broken since commit: 0d6ea3a ("lib/kstrtox.c: add "false"/"true" support to kstrtobool()") ... which caused strtobool() to parse "full" as false (in addition to many other values not documented for the "rodata=" kernel parameter. This patch fixes this breakage by: * Moving the core parameter parser to an __early_param(), such that it is available early. * Adding an (optional) arch hook which arm64 can use to parse "full". * Updating the documentation to mention that "full" is valid for arm64. * Having the core parameter parser handle "on" and "off" explicitly, such that any undocumented values (e.g. typos such as "ful") are reported as errors rather than being silently accepted. Note that __setup() and early_param() have opposite conventions for their return values, where __setup() uses 1 to indicate a parameter was handled and early_param() uses 0 to indicate a parameter was handled. Fixes: f9a40b0 ("init/main.c: return 1 from handled __setup() functions") Fixes: 0d6ea3a ("lib/kstrtox.c: add "false"/"true" support to kstrtobool()") Signed-off-by: Mark Rutland <[email protected]> Cc: Andy Shevchenko <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Jagdish Gediya <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Randy Dunlap <[email protected]> Cc: Will Deacon <[email protected]> Reviewed-by: Ard Biesheuvel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 729a916 commit 2e8cff0

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5331,6 +5331,8 @@
53315331
rodata= [KNL]
53325332
on Mark read-only kernel memory as read-only (default).
53335333
off Leave read-only kernel memory writable for debugging.
5334+
full Mark read-only kernel memory and aliases as read-only
5335+
[arm64]
53345336

53355337
rockchip.usb_uart
53365338
Enable the uart passthrough on the designated usb port

arch/arm64/include/asm/setup.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#ifndef __ARM64_ASM_SETUP_H
44
#define __ARM64_ASM_SETUP_H
55

6+
#include <linux/string.h>
7+
68
#include <uapi/asm/setup.h>
79

810
void *get_early_fdt_ptr(void);
@@ -14,4 +16,19 @@ void early_fdt_map(u64 dt_phys);
1416
extern phys_addr_t __fdt_pointer __initdata;
1517
extern u64 __cacheline_aligned boot_args[4];
1618

19+
static inline bool arch_parse_debug_rodata(char *arg)
20+
{
21+
extern bool rodata_enabled;
22+
extern bool rodata_full;
23+
24+
if (arg && !strcmp(arg, "full")) {
25+
rodata_enabled = true;
26+
rodata_full = true;
27+
return true;
28+
}
29+
30+
return false;
31+
}
32+
#define arch_parse_debug_rodata arch_parse_debug_rodata
33+
1734
#endif

arch/arm64/mm/mmu.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -642,24 +642,6 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
642642
vm_area_add_early(vma);
643643
}
644644

645-
static int __init parse_rodata(char *arg)
646-
{
647-
int ret = strtobool(arg, &rodata_enabled);
648-
if (!ret) {
649-
rodata_full = false;
650-
return 0;
651-
}
652-
653-
/* permit 'full' in addition to boolean options */
654-
if (strcmp(arg, "full"))
655-
return -EINVAL;
656-
657-
rodata_enabled = true;
658-
rodata_full = true;
659-
return 0;
660-
}
661-
early_param("rodata", parse_rodata);
662-
663645
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
664646
static int __init map_entry_trampoline(void)
665647
{

init/main.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,13 +1446,25 @@ static noinline void __init kernel_init_freeable(void);
14461446

14471447
#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
14481448
bool rodata_enabled __ro_after_init = true;
1449+
1450+
#ifndef arch_parse_debug_rodata
1451+
static inline bool arch_parse_debug_rodata(char *str) { return false; }
1452+
#endif
1453+
14491454
static int __init set_debug_rodata(char *str)
14501455
{
1451-
if (strtobool(str, &rodata_enabled))
1456+
if (arch_parse_debug_rodata(str))
1457+
return 0;
1458+
1459+
if (str && !strcmp(str, "on"))
1460+
rodata_enabled = true;
1461+
else if (str && !strcmp(str, "off"))
1462+
rodata_enabled = false;
1463+
else
14521464
pr_warn("Invalid option string for rodata: '%s'\n", str);
1453-
return 1;
1465+
return 0;
14541466
}
1455-
__setup("rodata=", set_debug_rodata);
1467+
early_param("rodata", set_debug_rodata);
14561468
#endif
14571469

14581470
#ifdef CONFIG_STRICT_KERNEL_RWX

0 commit comments

Comments
 (0)