Skip to content

Commit af1a810

Browse files
chleroygregkh
authored andcommitted
powerpc/lib: fix book3s/32 boot failure due to code patching
commit b45ba4a upstream. 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: [email protected] # 4.13+ Signed-off-by: Christophe Leroy <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 609fbed commit af1a810

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
@@ -29,12 +29,6 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
2929
{
3030
int err;
3131

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

152-
int patch_instruction(unsigned int *addr, unsigned int instr)
146+
static int do_patch_instruction(unsigned int *addr, unsigned int instr)
153147
{
154148
int err;
155149
unsigned int *patch_addr = NULL;
@@ -189,12 +183,22 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
189183
}
190184
#else /* !CONFIG_STRICT_KERNEL_RWX */
191185

192-
int patch_instruction(unsigned int *addr, unsigned int instr)
186+
static int do_patch_instruction(unsigned int *addr, unsigned int instr)
193187
{
194188
return raw_patch_instruction(addr, instr);
195189
}
196190

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

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

0 commit comments

Comments
 (0)