powerpc/code-patching: Reorganise do_patch_instruction() to ease error handling
Split do_patch_instruction() in two functions, the caller doing the spin locking and the callee doing everything else. And remove a few unnecessary initialisations and intermediate variables. This allows the callee to return from anywhere in the function. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/dbc85980a0d2a935731b272e8907e8bb1d8fc8c5.1638446239.git.christophe.leroy@csgroup.eu
This commit is contained in:
committed by
Michael Ellerman
parent
a3483c3dd1
commit
6b21af7449
@@ -129,13 +129,30 @@ static void unmap_patch_area(unsigned long addr)
|
|||||||
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
|
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __do_patch_instruction(u32 *addr, ppc_inst_t instr)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
u32 *patch_addr;
|
||||||
|
unsigned long text_poke_addr;
|
||||||
|
|
||||||
|
text_poke_addr = (unsigned long)__this_cpu_read(text_poke_area)->addr;
|
||||||
|
patch_addr = (u32 *)(text_poke_addr + offset_in_page(addr));
|
||||||
|
|
||||||
|
err = map_patch_area(addr, text_poke_addr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = __patch_instruction(addr, instr, patch_addr);
|
||||||
|
|
||||||
|
unmap_patch_area(text_poke_addr);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_patch_instruction(u32 *addr, ppc_inst_t instr)
|
static int do_patch_instruction(u32 *addr, ppc_inst_t instr)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
u32 *patch_addr = NULL;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long text_poke_addr;
|
|
||||||
unsigned long kaddr = (unsigned long)addr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* During early early boot patch_instruction is called
|
* During early early boot patch_instruction is called
|
||||||
@@ -146,19 +163,7 @@ static int do_patch_instruction(u32 *addr, ppc_inst_t instr)
|
|||||||
return raw_patch_instruction(addr, instr);
|
return raw_patch_instruction(addr, instr);
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
err = __do_patch_instruction(addr, instr);
|
||||||
text_poke_addr = (unsigned long)__this_cpu_read(text_poke_area)->addr;
|
|
||||||
err = map_patch_area(addr, text_poke_addr);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
patch_addr = (u32 *)(text_poke_addr + (kaddr & ~PAGE_MASK));
|
|
||||||
|
|
||||||
err = __patch_instruction(addr, instr, patch_addr);
|
|
||||||
|
|
||||||
unmap_patch_area(text_poke_addr);
|
|
||||||
|
|
||||||
out:
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
Reference in New Issue
Block a user