powerpc/lib: fix book3s/32 boot failure due to code patching
Commit51c3c62b58
("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:51c3c62b58
("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>
This commit is contained in:
parent
242cdad873
commit
b45ba4a51c
|
@ -28,12 +28,6 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
|
|||
{
|
||||
int err;
|
||||
|
||||
/* Make sure we aren't patching a freed init section */
|
||||
if (init_mem_is_free && init_section_contains(exec_addr, 4)) {
|
||||
pr_debug("Skipping init section patching addr: 0x%px\n", exec_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__put_user_size(instr, patch_addr, 4, err);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -148,7 +142,7 @@ static inline int unmap_patch_area(unsigned long addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int patch_instruction(unsigned int *addr, unsigned int instr)
|
||||
static int do_patch_instruction(unsigned int *addr, unsigned int instr)
|
||||
{
|
||||
int err;
|
||||
unsigned int *patch_addr = NULL;
|
||||
|
@ -188,12 +182,22 @@ out:
|
|||
}
|
||||
#else /* !CONFIG_STRICT_KERNEL_RWX */
|
||||
|
||||
int patch_instruction(unsigned int *addr, unsigned int instr)
|
||||
static int do_patch_instruction(unsigned int *addr, unsigned int instr)
|
||||
{
|
||||
return raw_patch_instruction(addr, instr);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_STRICT_KERNEL_RWX */
|
||||
|
||||
int patch_instruction(unsigned int *addr, unsigned int instr)
|
||||
{
|
||||
/* Make sure we aren't patching a freed init section */
|
||||
if (init_mem_is_free && init_section_contains(addr, 4)) {
|
||||
pr_debug("Skipping init section patching addr: 0x%px\n", addr);
|
||||
return 0;
|
||||
}
|
||||
return do_patch_instruction(addr, instr);
|
||||
}
|
||||
NOKPROBE_SYMBOL(patch_instruction);
|
||||
|
||||
int patch_branch(unsigned int *addr, unsigned long target, int flags)
|
||||
|
|
Loading…
Reference in New Issue