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