aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2011-04-04 19:56:18 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-04-20 03:01:18 -0400
commitb68a70c49686db0bff4637995d91b4db8abe5281 (patch)
tree1eaca2fe2137ca1581c2bc5fd33ed84fa9a8d63c /arch/powerpc/mm
parentf5be2dc0bd8d27a39d84a89e4ff90ba38cd2b285 (diff)
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>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r--arch/powerpc/mm/hash_utils_64.c44
-rw-r--r--arch/powerpc/mm/slb.c6
2 files changed, 30 insertions, 20 deletions
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 58a022d0f463..d95d8f484d2f 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -53,6 +53,7 @@
53#include <asm/sections.h> 53#include <asm/sections.h>
54#include <asm/spu.h> 54#include <asm/spu.h>
55#include <asm/udbg.h> 55#include <asm/udbg.h>
56#include <asm/code-patching.h>
56 57
57#ifdef DEBUG 58#ifdef DEBUG
58#define DBG(fmt...) udbg_printf(fmt) 59#define DBG(fmt...) udbg_printf(fmt)
@@ -547,15 +548,7 @@ int remove_section_mapping(unsigned long start, unsigned long end)
547} 548}
548#endif /* CONFIG_MEMORY_HOTPLUG */ 549#endif /* CONFIG_MEMORY_HOTPLUG */
549 550
550static inline void make_bl(unsigned int *insn_addr, void *func) 551#define FUNCTION_TEXT(A) ((*(unsigned long *)(A)))
551{
552 unsigned long funcp = *((unsigned long *)func);
553 int offset = funcp - (unsigned long)insn_addr;
554
555 *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
556 flush_icache_range((unsigned long)insn_addr, 4+
557 (unsigned long)insn_addr);
558}
559 552
560static void __init htab_finish_init(void) 553static void __init htab_finish_init(void)
561{ 554{
@@ -570,16 +563,33 @@ static void __init htab_finish_init(void)
570 extern unsigned int *ht64_call_hpte_remove; 563 extern unsigned int *ht64_call_hpte_remove;
571 extern unsigned int *ht64_call_hpte_updatepp; 564 extern unsigned int *ht64_call_hpte_updatepp;
572 565
573 make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); 566 patch_branch(ht64_call_hpte_insert1,
574 make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); 567 FUNCTION_TEXT(ppc_md.hpte_insert),
575 make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); 568 BRANCH_SET_LINK);
576 make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); 569 patch_branch(ht64_call_hpte_insert2,
570 FUNCTION_TEXT(ppc_md.hpte_insert),
571 BRANCH_SET_LINK);
572 patch_branch(ht64_call_hpte_remove,
573 FUNCTION_TEXT(ppc_md.hpte_remove),
574 BRANCH_SET_LINK);
575 patch_branch(ht64_call_hpte_updatepp,
576 FUNCTION_TEXT(ppc_md.hpte_updatepp),
577 BRANCH_SET_LINK);
578
577#endif /* CONFIG_PPC_HAS_HASH_64K */ 579#endif /* CONFIG_PPC_HAS_HASH_64K */
578 580
579 make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); 581 patch_branch(htab_call_hpte_insert1,
580 make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); 582 FUNCTION_TEXT(ppc_md.hpte_insert),
581 make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); 583 BRANCH_SET_LINK);
582 make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); 584 patch_branch(htab_call_hpte_insert2,
585 FUNCTION_TEXT(ppc_md.hpte_insert),
586 BRANCH_SET_LINK);
587 patch_branch(htab_call_hpte_remove,
588 FUNCTION_TEXT(ppc_md.hpte_remove),
589 BRANCH_SET_LINK);
590 patch_branch(htab_call_hpte_updatepp,
591 FUNCTION_TEXT(ppc_md.hpte_updatepp),
592 BRANCH_SET_LINK);
583} 593}
584 594
585static void __init htab_initialize(void) 595static void __init htab_initialize(void)
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 1d98ecc8eecd..5500712781d4 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -24,6 +24,7 @@
24#include <asm/firmware.h> 24#include <asm/firmware.h>
25#include <linux/compiler.h> 25#include <linux/compiler.h>
26#include <asm/udbg.h> 26#include <asm/udbg.h>
27#include <asm/code-patching.h>
27 28
28 29
29extern void slb_allocate_realmode(unsigned long ea); 30extern void slb_allocate_realmode(unsigned long ea);
@@ -249,9 +250,8 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
249static inline void patch_slb_encoding(unsigned int *insn_addr, 250static inline void patch_slb_encoding(unsigned int *insn_addr,
250 unsigned int immed) 251 unsigned int immed)
251{ 252{
252 *insn_addr = (*insn_addr & 0xffff0000) | immed; 253 int insn = (*insn_addr & 0xffff0000) | immed;
253 flush_icache_range((unsigned long)insn_addr, 4+ 254 patch_instruction(insn_addr, insn);
254 (unsigned long)insn_addr);
255} 255}
256 256
257void slb_set_size(u16 size) 257void slb_set_size(u16 size)