powerpc: Replace open coded instruction patching with patch_instruction/patch_branch
There are a few places we patch instructions without using patch_instruction and patch_branch, probably because they predated it. Fix it. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
committed by
Benjamin Herrenschmidt
parent
f5be2dc0bd
commit
b68a70c496
@@ -53,6 +53,7 @@
|
|||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/spu.h>
|
#include <asm/spu.h>
|
||||||
#include <asm/udbg.h>
|
#include <asm/udbg.h>
|
||||||
|
#include <asm/code-patching.h>
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define DBG(fmt...) udbg_printf(fmt)
|
#define DBG(fmt...) udbg_printf(fmt)
|
||||||
@@ -547,15 +548,7 @@ int remove_section_mapping(unsigned long start, unsigned long end)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_MEMORY_HOTPLUG */
|
#endif /* CONFIG_MEMORY_HOTPLUG */
|
||||||
|
|
||||||
static inline void make_bl(unsigned int *insn_addr, void *func)
|
#define FUNCTION_TEXT(A) ((*(unsigned long *)(A)))
|
||||||
{
|
|
||||||
unsigned long funcp = *((unsigned long *)func);
|
|
||||||
int offset = funcp - (unsigned long)insn_addr;
|
|
||||||
|
|
||||||
*insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
|
|
||||||
flush_icache_range((unsigned long)insn_addr, 4+
|
|
||||||
(unsigned long)insn_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init htab_finish_init(void)
|
static void __init htab_finish_init(void)
|
||||||
{
|
{
|
||||||
@@ -570,16 +563,33 @@ static void __init htab_finish_init(void)
|
|||||||
extern unsigned int *ht64_call_hpte_remove;
|
extern unsigned int *ht64_call_hpte_remove;
|
||||||
extern unsigned int *ht64_call_hpte_updatepp;
|
extern unsigned int *ht64_call_hpte_updatepp;
|
||||||
|
|
||||||
make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
|
patch_branch(ht64_call_hpte_insert1,
|
||||||
make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
|
FUNCTION_TEXT(ppc_md.hpte_insert),
|
||||||
make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
|
BRANCH_SET_LINK);
|
||||||
make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
|
patch_branch(ht64_call_hpte_insert2,
|
||||||
|
FUNCTION_TEXT(ppc_md.hpte_insert),
|
||||||
|
BRANCH_SET_LINK);
|
||||||
|
patch_branch(ht64_call_hpte_remove,
|
||||||
|
FUNCTION_TEXT(ppc_md.hpte_remove),
|
||||||
|
BRANCH_SET_LINK);
|
||||||
|
patch_branch(ht64_call_hpte_updatepp,
|
||||||
|
FUNCTION_TEXT(ppc_md.hpte_updatepp),
|
||||||
|
BRANCH_SET_LINK);
|
||||||
|
|
||||||
#endif /* CONFIG_PPC_HAS_HASH_64K */
|
#endif /* CONFIG_PPC_HAS_HASH_64K */
|
||||||
|
|
||||||
make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
|
patch_branch(htab_call_hpte_insert1,
|
||||||
make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
|
FUNCTION_TEXT(ppc_md.hpte_insert),
|
||||||
make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
|
BRANCH_SET_LINK);
|
||||||
make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
|
patch_branch(htab_call_hpte_insert2,
|
||||||
|
FUNCTION_TEXT(ppc_md.hpte_insert),
|
||||||
|
BRANCH_SET_LINK);
|
||||||
|
patch_branch(htab_call_hpte_remove,
|
||||||
|
FUNCTION_TEXT(ppc_md.hpte_remove),
|
||||||
|
BRANCH_SET_LINK);
|
||||||
|
patch_branch(htab_call_hpte_updatepp,
|
||||||
|
FUNCTION_TEXT(ppc_md.hpte_updatepp),
|
||||||
|
BRANCH_SET_LINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init htab_initialize(void)
|
static void __init htab_initialize(void)
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <asm/udbg.h>
|
#include <asm/udbg.h>
|
||||||
|
#include <asm/code-patching.h>
|
||||||
|
|
||||||
|
|
||||||
extern void slb_allocate_realmode(unsigned long ea);
|
extern void slb_allocate_realmode(unsigned long ea);
|
||||||
@@ -249,9 +250,8 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
|
|||||||
static inline void patch_slb_encoding(unsigned int *insn_addr,
|
static inline void patch_slb_encoding(unsigned int *insn_addr,
|
||||||
unsigned int immed)
|
unsigned int immed)
|
||||||
{
|
{
|
||||||
*insn_addr = (*insn_addr & 0xffff0000) | immed;
|
int insn = (*insn_addr & 0xffff0000) | immed;
|
||||||
flush_icache_range((unsigned long)insn_addr, 4+
|
patch_instruction(insn_addr, insn);
|
||||||
(unsigned long)insn_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void slb_set_size(u16 size)
|
void slb_set_size(u16 size)
|
||||||
|
Reference in New Issue
Block a user