aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/lib/code-patching.c
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@c-s.fr>2017-11-24 02:31:07 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2018-01-20 23:06:25 -0500
commit8cf4c05712f04a405f0dacebcca8f042b391694a (patch)
treebb7f637ed13b5237114e1b8c6f5476ae19d50fef /arch/powerpc/lib/code-patching.c
parent4ec591e51a4b0aedb6c7f1a8cd722aa58d7f61ba (diff)
powerpc/lib/code-patching: refactor patch_instruction()
patch_instruction() uses almost the same sequence as __patch_instruction() This patch refactor it so that patch_instruction() uses __patch_instruction() instead of duplicating code. Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Acked-by: Balbir Singh <bsingharora@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/lib/code-patching.c')
-rw-r--r--arch/powerpc/lib/code-patching.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 096d4e4d31e6..e1c58937281f 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -23,19 +23,26 @@
23#include <asm/code-patching.h> 23#include <asm/code-patching.h>
24#include <asm/setup.h> 24#include <asm/setup.h>
25 25
26static int __patch_instruction(unsigned int *addr, unsigned int instr) 26static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
27 unsigned int *patch_addr)
27{ 28{
28 int err; 29 int err;
29 30
30 __put_user_size(instr, addr, 4, err); 31 __put_user_size(instr, patch_addr, 4, err);
31 if (err) 32 if (err)
32 return err; 33 return err;
33 34
34 asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" :: "r" (addr)); 35 asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
36 "r" (exec_addr));
35 37
36 return 0; 38 return 0;
37} 39}
38 40
41static int raw_patch_instruction(unsigned int *addr, unsigned int instr)
42{
43 return __patch_instruction(addr, instr, addr);
44}
45
39#ifdef CONFIG_STRICT_KERNEL_RWX 46#ifdef CONFIG_STRICT_KERNEL_RWX
40static DEFINE_PER_CPU(struct vm_struct *, text_poke_area); 47static DEFINE_PER_CPU(struct vm_struct *, text_poke_area);
41 48
@@ -138,7 +145,7 @@ static inline int unmap_patch_area(unsigned long addr)
138int patch_instruction(unsigned int *addr, unsigned int instr) 145int patch_instruction(unsigned int *addr, unsigned int instr)
139{ 146{
140 int err; 147 int err;
141 unsigned int *dest = NULL; 148 unsigned int *patch_addr = NULL;
142 unsigned long flags; 149 unsigned long flags;
143 unsigned long text_poke_addr; 150 unsigned long text_poke_addr;
144 unsigned long kaddr = (unsigned long)addr; 151 unsigned long kaddr = (unsigned long)addr;
@@ -149,7 +156,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
149 * to allow patching. We just do the plain old patching 156 * to allow patching. We just do the plain old patching
150 */ 157 */
151 if (!this_cpu_read(*PTRRELOC(&text_poke_area))) 158 if (!this_cpu_read(*PTRRELOC(&text_poke_area)))
152 return __patch_instruction(addr, instr); 159 return raw_patch_instruction(addr, instr);
153 160
154 local_irq_save(flags); 161 local_irq_save(flags);
155 162
@@ -159,17 +166,10 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
159 goto out; 166 goto out;
160 } 167 }
161 168
162 dest = (unsigned int *)(text_poke_addr) + 169 patch_addr = (unsigned int *)(text_poke_addr) +
163 ((kaddr & ~PAGE_MASK) / sizeof(unsigned int)); 170 ((kaddr & ~PAGE_MASK) / sizeof(unsigned int));
164 171
165 /* 172 __patch_instruction(addr, instr, patch_addr);
166 * We use __put_user_size so that we can handle faults while
167 * writing to dest and return err to handle faults gracefully
168 */
169 __put_user_size(instr, dest, 4, err);
170 if (!err)
171 asm ("dcbst 0, %0; sync; icbi 0,%0; icbi 0,%1; sync; isync"
172 ::"r" (dest), "r"(addr));
173 173
174 err = unmap_patch_area(text_poke_addr); 174 err = unmap_patch_area(text_poke_addr);
175 if (err) 175 if (err)
@@ -184,7 +184,7 @@ out:
184 184
185int patch_instruction(unsigned int *addr, unsigned int instr) 185int patch_instruction(unsigned int *addr, unsigned int instr)
186{ 186{
187 return __patch_instruction(addr, instr); 187 return raw_patch_instruction(addr, instr);
188} 188}
189 189
190#endif /* CONFIG_STRICT_KERNEL_RWX */ 190#endif /* CONFIG_STRICT_KERNEL_RWX */