]> Git Repo - linux.git/blob - arch/powerpc/lib/code-patching.c
Merge tag 'ktest-v4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux.git] / arch / powerpc / lib / code-patching.c
1 /*
2  *  Copyright 2008 Michael Ellerman, IBM Corporation.
3  *
4  *  This program is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU General Public License
6  *  as published by the Free Software Foundation; either version
7  *  2 of the License, or (at your option) any later version.
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/vmalloc.h>
12 #include <linux/init.h>
13 #include <linux/mm.h>
14 #include <asm/page.h>
15 #include <asm/code-patching.h>
16 #include <linux/uaccess.h>
17 #include <linux/kprobes.h>
18
19
20 int patch_instruction(unsigned int *addr, unsigned int instr)
21 {
22         int err;
23
24         __put_user_size(instr, addr, 4, err);
25         if (err)
26                 return err;
27         asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr));
28         return 0;
29 }
30
31 int patch_branch(unsigned int *addr, unsigned long target, int flags)
32 {
33         return patch_instruction(addr, create_branch(addr, target, flags));
34 }
35
36 bool is_offset_in_branch_range(long offset)
37 {
38         /*
39          * Powerpc branch instruction is :
40          *
41          *  0         6                 30   31
42          *  +---------+----------------+---+---+
43          *  | opcode  |     LI         |AA |LK |
44          *  +---------+----------------+---+---+
45          *  Where AA = 0 and LK = 0
46          *
47          * LI is a signed 24 bits integer. The real branch offset is computed
48          * by: imm32 = SignExtend(LI:'0b00', 32);
49          *
50          * So the maximum forward branch should be:
51          *   (0x007fffff << 2) = 0x01fffffc =  0x1fffffc
52          * The maximum backward branch should be:
53          *   (0xff800000 << 2) = 0xfe000000 = -0x2000000
54          */
55         return (offset >= -0x2000000 && offset <= 0x1fffffc && !(offset & 0x3));
56 }
57
58 /*
59  * Helper to check if a given instruction is a conditional branch
60  * Derived from the conditional checks in analyse_instr()
61  */
62 bool __kprobes is_conditional_branch(unsigned int instr)
63 {
64         unsigned int opcode = instr >> 26;
65
66         if (opcode == 16)       /* bc, bca, bcl, bcla */
67                 return true;
68         if (opcode == 19) {
69                 switch ((instr >> 1) & 0x3ff) {
70                 case 16:        /* bclr, bclrl */
71                 case 528:       /* bcctr, bcctrl */
72                 case 560:       /* bctar, bctarl */
73                         return true;
74                 }
75         }
76         return false;
77 }
78
79 unsigned int create_branch(const unsigned int *addr,
80                            unsigned long target, int flags)
81 {
82         unsigned int instruction;
83         long offset;
84
85         offset = target;
86         if (! (flags & BRANCH_ABSOLUTE))
87                 offset = offset - (unsigned long)addr;
88
89         /* Check we can represent the target in the instruction format */
90         if (!is_offset_in_branch_range(offset))
91                 return 0;
92
93         /* Mask out the flags and target, so they don't step on each other. */
94         instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
95
96         return instruction;
97 }
98
99 unsigned int create_cond_branch(const unsigned int *addr,
100                                 unsigned long target, int flags)
101 {
102         unsigned int instruction;
103         long offset;
104
105         offset = target;
106         if (! (flags & BRANCH_ABSOLUTE))
107                 offset = offset - (unsigned long)addr;
108
109         /* Check we can represent the target in the instruction format */
110         if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3)
111                 return 0;
112
113         /* Mask out the flags and target, so they don't step on each other. */
114         instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
115
116         return instruction;
117 }
118
119 static unsigned int branch_opcode(unsigned int instr)
120 {
121         return (instr >> 26) & 0x3F;
122 }
123
124 static int instr_is_branch_iform(unsigned int instr)
125 {
126         return branch_opcode(instr) == 18;
127 }
128
129 static int instr_is_branch_bform(unsigned int instr)
130 {
131         return branch_opcode(instr) == 16;
132 }
133
134 int instr_is_relative_branch(unsigned int instr)
135 {
136         if (instr & BRANCH_ABSOLUTE)
137                 return 0;
138
139         return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
140 }
141
142 static unsigned long branch_iform_target(const unsigned int *instr)
143 {
144         signed long imm;
145
146         imm = *instr & 0x3FFFFFC;
147
148         /* If the top bit of the immediate value is set this is negative */
149         if (imm & 0x2000000)
150                 imm -= 0x4000000;
151
152         if ((*instr & BRANCH_ABSOLUTE) == 0)
153                 imm += (unsigned long)instr;
154
155         return (unsigned long)imm;
156 }
157
158 static unsigned long branch_bform_target(const unsigned int *instr)
159 {
160         signed long imm;
161
162         imm = *instr & 0xFFFC;
163
164         /* If the top bit of the immediate value is set this is negative */
165         if (imm & 0x8000)
166                 imm -= 0x10000;
167
168         if ((*instr & BRANCH_ABSOLUTE) == 0)
169                 imm += (unsigned long)instr;
170
171         return (unsigned long)imm;
172 }
173
174 unsigned long branch_target(const unsigned int *instr)
175 {
176         if (instr_is_branch_iform(*instr))
177                 return branch_iform_target(instr);
178         else if (instr_is_branch_bform(*instr))
179                 return branch_bform_target(instr);
180
181         return 0;
182 }
183
184 int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr)
185 {
186         if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
187                 return branch_target(instr) == addr;
188
189         return 0;
190 }
191
192 unsigned int translate_branch(const unsigned int *dest, const unsigned int *src)
193 {
194         unsigned long target;
195
196         target = branch_target(src);
197
198         if (instr_is_branch_iform(*src))
199                 return create_branch(dest, target, *src);
200         else if (instr_is_branch_bform(*src))
201                 return create_cond_branch(dest, target, *src);
202
203         return 0;
204 }
205
206 #ifdef CONFIG_PPC_BOOK3E_64
207 void __patch_exception(int exc, unsigned long addr)
208 {
209         extern unsigned int interrupt_base_book3e;
210         unsigned int *ibase = &interrupt_base_book3e;
211
212         /* Our exceptions vectors start with a NOP and -then- a branch
213          * to deal with single stepping from userspace which stops on
214          * the second instruction. Thus we need to patch the second
215          * instruction of the exception, not the first one
216          */
217
218         patch_branch(ibase + (exc / 4) + 1, addr, 0);
219 }
220 #endif
221
222 #ifdef CONFIG_CODE_PATCHING_SELFTEST
223
224 static void __init test_trampoline(void)
225 {
226         asm ("nop;\n");
227 }
228
229 #define check(x)        \
230         if (!(x)) printk("code-patching: test failed at line %d\n", __LINE__);
231
232 static void __init test_branch_iform(void)
233 {
234         unsigned int instr;
235         unsigned long addr;
236
237         addr = (unsigned long)&instr;
238
239         /* The simplest case, branch to self, no flags */
240         check(instr_is_branch_iform(0x48000000));
241         /* All bits of target set, and flags */
242         check(instr_is_branch_iform(0x4bffffff));
243         /* High bit of opcode set, which is wrong */
244         check(!instr_is_branch_iform(0xcbffffff));
245         /* Middle bits of opcode set, which is wrong */
246         check(!instr_is_branch_iform(0x7bffffff));
247
248         /* Simplest case, branch to self with link */
249         check(instr_is_branch_iform(0x48000001));
250         /* All bits of targets set */
251         check(instr_is_branch_iform(0x4bfffffd));
252         /* Some bits of targets set */
253         check(instr_is_branch_iform(0x4bff00fd));
254         /* Must be a valid branch to start with */
255         check(!instr_is_branch_iform(0x7bfffffd));
256
257         /* Absolute branch to 0x100 */
258         instr = 0x48000103;
259         check(instr_is_branch_to_addr(&instr, 0x100));
260         /* Absolute branch to 0x420fc */
261         instr = 0x480420ff;
262         check(instr_is_branch_to_addr(&instr, 0x420fc));
263         /* Maximum positive relative branch, + 20MB - 4B */
264         instr = 0x49fffffc;
265         check(instr_is_branch_to_addr(&instr, addr + 0x1FFFFFC));
266         /* Smallest negative relative branch, - 4B */
267         instr = 0x4bfffffc;
268         check(instr_is_branch_to_addr(&instr, addr - 4));
269         /* Largest negative relative branch, - 32 MB */
270         instr = 0x4a000000;
271         check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
272
273         /* Branch to self, with link */
274         instr = create_branch(&instr, addr, BRANCH_SET_LINK);
275         check(instr_is_branch_to_addr(&instr, addr));
276
277         /* Branch to self - 0x100, with link */
278         instr = create_branch(&instr, addr - 0x100, BRANCH_SET_LINK);
279         check(instr_is_branch_to_addr(&instr, addr - 0x100));
280
281         /* Branch to self + 0x100, no link */
282         instr = create_branch(&instr, addr + 0x100, 0);
283         check(instr_is_branch_to_addr(&instr, addr + 0x100));
284
285         /* Maximum relative negative offset, - 32 MB */
286         instr = create_branch(&instr, addr - 0x2000000, BRANCH_SET_LINK);
287         check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
288
289         /* Out of range relative negative offset, - 32 MB + 4*/
290         instr = create_branch(&instr, addr - 0x2000004, BRANCH_SET_LINK);
291         check(instr == 0);
292
293         /* Out of range relative positive offset, + 32 MB */
294         instr = create_branch(&instr, addr + 0x2000000, BRANCH_SET_LINK);
295         check(instr == 0);
296
297         /* Unaligned target */
298         instr = create_branch(&instr, addr + 3, BRANCH_SET_LINK);
299         check(instr == 0);
300
301         /* Check flags are masked correctly */
302         instr = create_branch(&instr, addr, 0xFFFFFFFC);
303         check(instr_is_branch_to_addr(&instr, addr));
304         check(instr == 0x48000000);
305 }
306
307 static void __init test_create_function_call(void)
308 {
309         unsigned int *iptr;
310         unsigned long dest;
311
312         /* Check we can create a function call */
313         iptr = (unsigned int *)ppc_function_entry(test_trampoline);
314         dest = ppc_function_entry(test_create_function_call);
315         patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK));
316         check(instr_is_branch_to_addr(iptr, dest));
317 }
318
319 static void __init test_branch_bform(void)
320 {
321         unsigned long addr;
322         unsigned int *iptr, instr, flags;
323
324         iptr = &instr;
325         addr = (unsigned long)iptr;
326
327         /* The simplest case, branch to self, no flags */
328         check(instr_is_branch_bform(0x40000000));
329         /* All bits of target set, and flags */
330         check(instr_is_branch_bform(0x43ffffff));
331         /* High bit of opcode set, which is wrong */
332         check(!instr_is_branch_bform(0xc3ffffff));
333         /* Middle bits of opcode set, which is wrong */
334         check(!instr_is_branch_bform(0x7bffffff));
335
336         /* Absolute conditional branch to 0x100 */
337         instr = 0x43ff0103;
338         check(instr_is_branch_to_addr(&instr, 0x100));
339         /* Absolute conditional branch to 0x20fc */
340         instr = 0x43ff20ff;
341         check(instr_is_branch_to_addr(&instr, 0x20fc));
342         /* Maximum positive relative conditional branch, + 32 KB - 4B */
343         instr = 0x43ff7ffc;
344         check(instr_is_branch_to_addr(&instr, addr + 0x7FFC));
345         /* Smallest negative relative conditional branch, - 4B */
346         instr = 0x43fffffc;
347         check(instr_is_branch_to_addr(&instr, addr - 4));
348         /* Largest negative relative conditional branch, - 32 KB */
349         instr = 0x43ff8000;
350         check(instr_is_branch_to_addr(&instr, addr - 0x8000));
351
352         /* All condition code bits set & link */
353         flags = 0x3ff000 | BRANCH_SET_LINK;
354
355         /* Branch to self */
356         instr = create_cond_branch(iptr, addr, flags);
357         check(instr_is_branch_to_addr(&instr, addr));
358
359         /* Branch to self - 0x100 */
360         instr = create_cond_branch(iptr, addr - 0x100, flags);
361         check(instr_is_branch_to_addr(&instr, addr - 0x100));
362
363         /* Branch to self + 0x100 */
364         instr = create_cond_branch(iptr, addr + 0x100, flags);
365         check(instr_is_branch_to_addr(&instr, addr + 0x100));
366
367         /* Maximum relative negative offset, - 32 KB */
368         instr = create_cond_branch(iptr, addr - 0x8000, flags);
369         check(instr_is_branch_to_addr(&instr, addr - 0x8000));
370
371         /* Out of range relative negative offset, - 32 KB + 4*/
372         instr = create_cond_branch(iptr, addr - 0x8004, flags);
373         check(instr == 0);
374
375         /* Out of range relative positive offset, + 32 KB */
376         instr = create_cond_branch(iptr, addr + 0x8000, flags);
377         check(instr == 0);
378
379         /* Unaligned target */
380         instr = create_cond_branch(iptr, addr + 3, flags);
381         check(instr == 0);
382
383         /* Check flags are masked correctly */
384         instr = create_cond_branch(iptr, addr, 0xFFFFFFFC);
385         check(instr_is_branch_to_addr(&instr, addr));
386         check(instr == 0x43FF0000);
387 }
388
389 static void __init test_translate_branch(void)
390 {
391         unsigned long addr;
392         unsigned int *p, *q;
393         void *buf;
394
395         buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
396         check(buf);
397         if (!buf)
398                 return;
399
400         /* Simple case, branch to self moved a little */
401         p = buf;
402         addr = (unsigned long)p;
403         patch_branch(p, addr, 0);
404         check(instr_is_branch_to_addr(p, addr));
405         q = p + 1;
406         patch_instruction(q, translate_branch(q, p));
407         check(instr_is_branch_to_addr(q, addr));
408
409         /* Maximum negative case, move b . to addr + 32 MB */
410         p = buf;
411         addr = (unsigned long)p;
412         patch_branch(p, addr, 0);
413         q = buf + 0x2000000;
414         patch_instruction(q, translate_branch(q, p));
415         check(instr_is_branch_to_addr(p, addr));
416         check(instr_is_branch_to_addr(q, addr));
417         check(*q == 0x4a000000);
418
419         /* Maximum positive case, move x to x - 32 MB + 4 */
420         p = buf + 0x2000000;
421         addr = (unsigned long)p;
422         patch_branch(p, addr, 0);
423         q = buf + 4;
424         patch_instruction(q, translate_branch(q, p));
425         check(instr_is_branch_to_addr(p, addr));
426         check(instr_is_branch_to_addr(q, addr));
427         check(*q == 0x49fffffc);
428
429         /* Jump to x + 16 MB moved to x + 20 MB */
430         p = buf;
431         addr = 0x1000000 + (unsigned long)buf;
432         patch_branch(p, addr, BRANCH_SET_LINK);
433         q = buf + 0x1400000;
434         patch_instruction(q, translate_branch(q, p));
435         check(instr_is_branch_to_addr(p, addr));
436         check(instr_is_branch_to_addr(q, addr));
437
438         /* Jump to x + 16 MB moved to x - 16 MB + 4 */
439         p = buf + 0x1000000;
440         addr = 0x2000000 + (unsigned long)buf;
441         patch_branch(p, addr, 0);
442         q = buf + 4;
443         patch_instruction(q, translate_branch(q, p));
444         check(instr_is_branch_to_addr(p, addr));
445         check(instr_is_branch_to_addr(q, addr));
446
447
448         /* Conditional branch tests */
449
450         /* Simple case, branch to self moved a little */
451         p = buf;
452         addr = (unsigned long)p;
453         patch_instruction(p, create_cond_branch(p, addr, 0));
454         check(instr_is_branch_to_addr(p, addr));
455         q = p + 1;
456         patch_instruction(q, translate_branch(q, p));
457         check(instr_is_branch_to_addr(q, addr));
458
459         /* Maximum negative case, move b . to addr + 32 KB */
460         p = buf;
461         addr = (unsigned long)p;
462         patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
463         q = buf + 0x8000;
464         patch_instruction(q, translate_branch(q, p));
465         check(instr_is_branch_to_addr(p, addr));
466         check(instr_is_branch_to_addr(q, addr));
467         check(*q == 0x43ff8000);
468
469         /* Maximum positive case, move x to x - 32 KB + 4 */
470         p = buf + 0x8000;
471         addr = (unsigned long)p;
472         patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
473         q = buf + 4;
474         patch_instruction(q, translate_branch(q, p));
475         check(instr_is_branch_to_addr(p, addr));
476         check(instr_is_branch_to_addr(q, addr));
477         check(*q == 0x43ff7ffc);
478
479         /* Jump to x + 12 KB moved to x + 20 KB */
480         p = buf;
481         addr = 0x3000 + (unsigned long)buf;
482         patch_instruction(p, create_cond_branch(p, addr, BRANCH_SET_LINK));
483         q = buf + 0x5000;
484         patch_instruction(q, translate_branch(q, p));
485         check(instr_is_branch_to_addr(p, addr));
486         check(instr_is_branch_to_addr(q, addr));
487
488         /* Jump to x + 8 KB moved to x - 8 KB + 4 */
489         p = buf + 0x2000;
490         addr = 0x4000 + (unsigned long)buf;
491         patch_instruction(p, create_cond_branch(p, addr, 0));
492         q = buf + 4;
493         patch_instruction(q, translate_branch(q, p));
494         check(instr_is_branch_to_addr(p, addr));
495         check(instr_is_branch_to_addr(q, addr));
496
497         /* Free the buffer we were using */
498         vfree(buf);
499 }
500
501 static int __init test_code_patching(void)
502 {
503         printk(KERN_DEBUG "Running code patching self-tests ...\n");
504
505         test_branch_iform();
506         test_branch_bform();
507         test_create_function_call();
508         test_translate_branch();
509
510         return 0;
511 }
512 late_initcall(test_code_patching);
513
514 #endif /* CONFIG_CODE_PATCHING_SELFTEST */
This page took 0.06397 seconds and 4 git commands to generate.