Skip to content

Commit 90d77b3

Browse files
groeckarndb
authored andcommitted
ARM: integrator: Fix early initialization
Starting with commit bdb249f ("ARM: integrator: read counter using syscon/regmap"), intcp_init_early calls syscon_regmap_lookup_by_compatible which in turn calls of_syscon_register. This function allocates memory. Since the memory management code has not been initialized at that time, the call always fails. It either returns -ENOMEM or crashes as follows. Unable to handle kernel NULL pointer dereference at virtual address 0000000c when read [0000000c] *pgd=00000000 Internal error: Oops: 5 [#1] ARM Modules linked in: CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.15.0-rc5-00026-g5fcc9bf84ee5 #1 PREEMPT Hardware name: ARM Integrator/CP (Device Tree) PC is at __kmalloc_cache_noprof+0xec/0x39c LR is at __kmalloc_cache_noprof+0x34/0x39c ... Call trace: __kmalloc_cache_noprof from of_syscon_register+0x7c/0x310 of_syscon_register from device_node_get_regmap+0xa4/0xb0 device_node_get_regmap from intcp_init_early+0xc/0x40 intcp_init_early from start_kernel+0x60/0x688 start_kernel from 0x0 The crash is seen due to a dereferenced pointer which is not supposed to be NULL but is NULL if the memory management subsystem has not been initialized. The crash is not seen with all versions of gcc. Some versions such as gcc 9.x apparently do not dereference the pointer, presumably if tracing is disabled. The problem has been reproduced with gcc 10.x, 11.x, and 13.x. Either case, if the crash is not seen, the call to syscon_regmap_lookup_by_compatible returns -ENOMEM, and sched_clock_register is never called. Fix the problem by moving the early initialization code into the standard machine initialization code. Fixes: bdb249f ("ARM: integrator: read counter using syscon/regmap") Cc: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Link: https://lore.kernel.org/20250518164118.3859567-1-linux@roeck-us.net Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20260505-integrator-fixes-v1-1-56ab9aac59db@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
1 parent b94e0e3 commit 90d77b3

1 file changed

Lines changed: 4 additions & 9 deletions

File tree

arch/arm/mach-versatile/integrator_cp.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,6 @@ static u64 notrace intcp_read_sched_clock(void)
8686
return val;
8787
}
8888

89-
static void __init intcp_init_early(void)
90-
{
91-
cm_map = syscon_regmap_lookup_by_compatible("arm,core-module-integrator");
92-
if (IS_ERR(cm_map))
93-
return;
94-
sched_clock_register(intcp_read_sched_clock, 32, 24000000);
95-
}
96-
9789
static void __init intcp_init_irq_of(void)
9890
{
9991
cm_init();
@@ -119,6 +111,10 @@ static void __init intcp_init_of(void)
119111
{
120112
struct device_node *cpcon;
121113

114+
cm_map = syscon_regmap_lookup_by_compatible("arm,core-module-integrator");
115+
if (!IS_ERR(cm_map))
116+
sched_clock_register(intcp_read_sched_clock, 32, 24000000);
117+
122118
cpcon = of_find_matching_node(NULL, intcp_syscon_match);
123119
if (!cpcon)
124120
return;
@@ -138,7 +134,6 @@ static const char * intcp_dt_board_compat[] = {
138134
DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
139135
.reserve = integrator_reserve,
140136
.map_io = intcp_map_io,
141-
.init_early = intcp_init_early,
142137
.init_irq = intcp_init_irq_of,
143138
.init_machine = intcp_init_of,
144139
.dt_compat = intcp_dt_board_compat,

0 commit comments

Comments
 (0)