aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/lib/code-patching.c
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2018-07-23 11:07:52 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2018-08-07 10:32:25 -0400
commit06d0bbc6d0f56dacac3a79900e9a9a0d5972d818 (patch)
treec5a1e7711581553f63c1f382945248ce1b1120ab /arch/powerpc/lib/code-patching.c
parent26cb1f36c43ee6e89d2a9f48a5a7500d5248f836 (diff)
powerpc/asm: Add a patch_site macro & helpers for patching instructions
Add a macro and some helper C functions for patching single asm instructions. The gas macro means we can do something like: 1: nop patch_site 1b, patch__foo Which is less visually distracting than defining a GLOBAL symbol at 1, and also doesn't pollute the symbol table which can confuse eg. perf. These are obviously similar to our existing feature sections, but are not automatically patched based on CPU/MMU features, rather they are designed to be manually patched by C code at some arbitrary point. 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.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index e0d881ab304e..850f3b8f4da5 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -195,6 +195,22 @@ int patch_branch(unsigned int *addr, unsigned long target, int flags)
195 return patch_instruction(addr, create_branch(addr, target, flags)); 195 return patch_instruction(addr, create_branch(addr, target, flags));
196} 196}
197 197
198int patch_branch_site(s32 *site, unsigned long target, int flags)
199{
200 unsigned int *addr;
201
202 addr = (unsigned int *)((unsigned long)site + *site);
203 return patch_instruction(addr, create_branch(addr, target, flags));
204}
205
206int patch_instruction_site(s32 *site, unsigned int instr)
207{
208 unsigned int *addr;
209
210 addr = (unsigned int *)((unsigned long)site + *site);
211 return patch_instruction(addr, instr);
212}
213
198bool is_offset_in_branch_range(long offset) 214bool is_offset_in_branch_range(long offset)
199{ 215{
200 /* 216 /*