diff options
author | Anton Blanchard <anton@samba.org> | 2011-04-04 19:56:18 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-04-20 03:01:18 -0400 |
commit | b68a70c49686db0bff4637995d91b4db8abe5281 (patch) | |
tree | 1eaca2fe2137ca1581c2bc5fd33ed84fa9a8d63c /arch/powerpc | |
parent | f5be2dc0bd8d27a39d84a89e4ff90ba38cd2b285 (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')
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 44 | ||||
-rw-r--r-- | arch/powerpc/mm/slb.c | 6 |
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 | ||
550 | static 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 | ||
560 | static void __init htab_finish_init(void) | 553 | static 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 | ||
585 | static void __init htab_initialize(void) | 595 | static 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 | ||
29 | extern void slb_allocate_realmode(unsigned long ea); | 30 | extern void slb_allocate_realmode(unsigned long ea); |
@@ -249,9 +250,8 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) | |||
249 | static inline void patch_slb_encoding(unsigned int *insn_addr, | 250 | static 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 | ||
257 | void slb_set_size(u16 size) | 257 | void slb_set_size(u16 size) |