powerpc: Replace open coded instruction patching with patch_instruction/patch_branch
authorAnton Blanchard <anton@samba.org>
Mon, 4 Apr 2011 23:56:18 +0000 (23:56 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 20 Apr 2011 07:01:18 +0000 (17:01 +1000)
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>
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/slb.c

index 58a022d0f4636908c228fedbb27f2bd977ce00b2..d95d8f484d2f432109c51eedd36d3c583ff0b98e 100644 (file)
@@ -53,6 +53,7 @@
 #include <asm/sections.h>
 #include <asm/spu.h>
 #include <asm/udbg.h>
+#include <asm/code-patching.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -547,15 +548,7 @@ int remove_section_mapping(unsigned long start, unsigned long end)
 }
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
-static inline void make_bl(unsigned int *insn_addr, void *func)
-{
-       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);
-}
+#define FUNCTION_TEXT(A)       ((*(unsigned long *)(A)))
 
 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_updatepp;
 
-       make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
-       make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
-       make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
-       make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
+       patch_branch(ht64_call_hpte_insert1,
+               FUNCTION_TEXT(ppc_md.hpte_insert),
+               BRANCH_SET_LINK);
+       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 */
 
-       make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
-       make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
-       make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
-       make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
+       patch_branch(htab_call_hpte_insert1,
+               FUNCTION_TEXT(ppc_md.hpte_insert),
+               BRANCH_SET_LINK);
+       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)
index 1d98ecc8eecd2d4cabfe08f2d883d75432981684..5500712781d4b1e59481de076867901d1f6a2213 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/firmware.h>
 #include <linux/compiler.h>
 #include <asm/udbg.h>
+#include <asm/code-patching.h>
 
 
 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,
                                      unsigned int immed)
 {
-       *insn_addr = (*insn_addr & 0xffff0000) | immed;
-       flush_icache_range((unsigned long)insn_addr, 4+
-                          (unsigned long)insn_addr);
+       int insn = (*insn_addr & 0xffff0000) | immed;
+       patch_instruction(insn_addr, insn);
 }
 
 void slb_set_size(u16 size)