Skip to content

Commit b45ba4a

Browse files
chleroympe
authored andcommitted
powerpc/lib: fix book3s/32 boot failure due to code patching
Commit 51c3c62 ("powerpc: Avoid code patching freed init sections") accesses 'init_mem_is_free' flag too early, before the kernel is relocated. This provokes early boot failure (before the console is active). As it is not necessary to do this verification that early, this patch moves the test into patch_instruction() instead of __patch_instruction(). This modification also has the advantage of avoiding unnecessary remappings. Fixes: 51c3c62 ("powerpc: Avoid code patching freed init sections") Cc: stable@vger.kernel.org # 4.13+ Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 242cdad commit b45ba4a

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

arch/powerpc/lib/code-patching.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
2828
{
2929
int err;
3030

31-
/* Make sure we aren't patching a freed init section */
32-
if (init_mem_is_free && init_section_contains(exec_addr, 4)) {
33-
pr_debug("Skipping init section patching addr: 0x%px\n", exec_addr);
34-
return 0;
35-
}
36-
3731
__put_user_size(instr, patch_addr, 4, err);
3832
if (err)
3933
return err;
@@ -148,7 +142,7 @@ static inline int unmap_patch_area(unsigned long addr)
148142
return 0;
149143
}
150144

151-
int patch_instruction(unsigned int *addr, unsigned int instr)
145+
static int do_patch_instruction(unsigned int *addr, unsigned int instr)
152146
{
153147
int err;
154148
unsigned int *patch_addr = NULL;
@@ -188,12 +182,22 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
188182
}
189183
#else /* !CONFIG_STRICT_KERNEL_RWX */
190184

191-
int patch_instruction(unsigned int *addr, unsigned int instr)
185+
static int do_patch_instruction(unsigned int *addr, unsigned int instr)
192186
{
193187
return raw_patch_instruction(addr, instr);
194188
}
195189

196190
#endif /* CONFIG_STRICT_KERNEL_RWX */
191+
192+
int patch_instruction(unsigned int *addr, unsigned int instr)
193+
{
194+
/* Make sure we aren't patching a freed init section */
195+
if (init_mem_is_free && init_section_contains(addr, 4)) {
196+
pr_debug("Skipping init section patching addr: 0x%px\n", addr);
197+
return 0;
198+
}
199+
return do_patch_instruction(addr, instr);
200+
}
197201
NOKPROBE_SYMBOL(patch_instruction);
198202

199203
int patch_branch(unsigned int *addr, unsigned long target, int flags)

0 commit comments

Comments
 (0)