powerpc/64: use interrupt restart table to speed up return from interrupt
[linux-2.6-microblaze.git] / arch / powerpc / lib / feature-fixups.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
4  *
5  *  Modifications for ppc64:
6  *      Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
7  *
8  *  Copyright 2008 Michael Ellerman, IBM Corporation.
9  */
10
11 #include <linux/types.h>
12 #include <linux/jump_label.h>
13 #include <linux/kernel.h>
14 #include <linux/string.h>
15 #include <linux/init.h>
16 #include <linux/sched/mm.h>
17 #include <linux/stop_machine.h>
18 #include <asm/cputable.h>
19 #include <asm/code-patching.h>
20 #include <asm/interrupt.h>
21 #include <asm/page.h>
22 #include <asm/sections.h>
23 #include <asm/setup.h>
24 #include <asm/security_features.h>
25 #include <asm/firmware.h>
26 #include <asm/inst.h>
27
28 struct fixup_entry {
29         unsigned long   mask;
30         unsigned long   value;
31         long            start_off;
32         long            end_off;
33         long            alt_start_off;
34         long            alt_end_off;
35 };
36
37 static u32 *calc_addr(struct fixup_entry *fcur, long offset)
38 {
39         /*
40          * We store the offset to the code as a negative offset from
41          * the start of the alt_entry, to support the VDSO. This
42          * routine converts that back into an actual address.
43          */
44         return (u32 *)((unsigned long)fcur + offset);
45 }
46
47 static int patch_alt_instruction(u32 *src, u32 *dest, u32 *alt_start, u32 *alt_end)
48 {
49         int err;
50         struct ppc_inst instr;
51
52         instr = ppc_inst_read(src);
53
54         if (instr_is_relative_branch(ppc_inst_read(src))) {
55                 u32 *target = (u32 *)branch_target(src);
56
57                 /* Branch within the section doesn't need translating */
58                 if (target < alt_start || target > alt_end) {
59                         err = translate_branch(&instr, dest, src);
60                         if (err)
61                                 return 1;
62                 }
63         }
64
65         raw_patch_instruction(dest, instr);
66
67         return 0;
68 }
69
70 static int patch_feature_section(unsigned long value, struct fixup_entry *fcur)
71 {
72         u32 *start, *end, *alt_start, *alt_end, *src, *dest;
73
74         start = calc_addr(fcur, fcur->start_off);
75         end = calc_addr(fcur, fcur->end_off);
76         alt_start = calc_addr(fcur, fcur->alt_start_off);
77         alt_end = calc_addr(fcur, fcur->alt_end_off);
78
79         if ((alt_end - alt_start) > (end - start))
80                 return 1;
81
82         if ((value & fcur->mask) == fcur->value)
83                 return 0;
84
85         src = alt_start;
86         dest = start;
87
88         for (; src < alt_end; src = ppc_inst_next(src, src),
89                               dest = ppc_inst_next(dest, dest)) {
90                 if (patch_alt_instruction(src, dest, alt_start, alt_end))
91                         return 1;
92         }
93
94         for (; dest < end; dest++)
95                 raw_patch_instruction(dest, ppc_inst(PPC_RAW_NOP()));
96
97         return 0;
98 }
99
100 void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
101 {
102         struct fixup_entry *fcur, *fend;
103
104         fcur = fixup_start;
105         fend = fixup_end;
106
107         for (; fcur < fend; fcur++) {
108                 if (patch_feature_section(value, fcur)) {
109                         WARN_ON(1);
110                         printk("Unable to patch feature section at %p - %p" \
111                                 " with %p - %p\n",
112                                 calc_addr(fcur, fcur->start_off),
113                                 calc_addr(fcur, fcur->end_off),
114                                 calc_addr(fcur, fcur->alt_start_off),
115                                 calc_addr(fcur, fcur->alt_end_off));
116                 }
117         }
118 }
119
120 #ifdef CONFIG_PPC_BOOK3S_64
121 static void do_stf_entry_barrier_fixups(enum stf_barrier_type types)
122 {
123         unsigned int instrs[3], *dest;
124         long *start, *end;
125         int i;
126
127         start = PTRRELOC(&__start___stf_entry_barrier_fixup);
128         end = PTRRELOC(&__stop___stf_entry_barrier_fixup);
129
130         instrs[0] = PPC_RAW_NOP();
131         instrs[1] = PPC_RAW_NOP();
132         instrs[2] = PPC_RAW_NOP();
133
134         i = 0;
135         if (types & STF_BARRIER_FALLBACK) {
136                 instrs[i++] = PPC_RAW_MFLR(_R10);
137                 instrs[i++] = PPC_RAW_NOP(); /* branch patched below */
138                 instrs[i++] = PPC_RAW_MTLR(_R10);
139         } else if (types & STF_BARRIER_EIEIO) {
140                 instrs[i++] = PPC_RAW_EIEIO() | 0x02000000; /* eieio + bit 6 hint */
141         } else if (types & STF_BARRIER_SYNC_ORI) {
142                 instrs[i++] = PPC_RAW_SYNC();
143                 instrs[i++] = PPC_RAW_LD(_R10, _R13, 0);
144                 instrs[i++] = PPC_RAW_ORI(_R31, _R31, 0); /* speculation barrier */
145         }
146
147         for (i = 0; start < end; start++, i++) {
148                 dest = (void *)start + *start;
149
150                 pr_devel("patching dest %lx\n", (unsigned long)dest);
151
152                 // See comment in do_entry_flush_fixups() RE order of patching
153                 if (types & STF_BARRIER_FALLBACK) {
154                         patch_instruction(dest, ppc_inst(instrs[0]));
155                         patch_instruction(dest + 2, ppc_inst(instrs[2]));
156                         patch_branch(dest + 1,
157                                      (unsigned long)&stf_barrier_fallback, BRANCH_SET_LINK);
158                 } else {
159                         patch_instruction(dest + 1, ppc_inst(instrs[1]));
160                         patch_instruction(dest + 2, ppc_inst(instrs[2]));
161                         patch_instruction(dest, ppc_inst(instrs[0]));
162                 }
163         }
164
165         printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i,
166                 (types == STF_BARRIER_NONE)                  ? "no" :
167                 (types == STF_BARRIER_FALLBACK)              ? "fallback" :
168                 (types == STF_BARRIER_EIEIO)                 ? "eieio" :
169                 (types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
170                                                            : "unknown");
171 }
172
173 static void do_stf_exit_barrier_fixups(enum stf_barrier_type types)
174 {
175         unsigned int instrs[6], *dest;
176         long *start, *end;
177         int i;
178
179         start = PTRRELOC(&__start___stf_exit_barrier_fixup);
180         end = PTRRELOC(&__stop___stf_exit_barrier_fixup);
181
182         instrs[0] = PPC_RAW_NOP();
183         instrs[1] = PPC_RAW_NOP();
184         instrs[2] = PPC_RAW_NOP();
185         instrs[3] = PPC_RAW_NOP();
186         instrs[4] = PPC_RAW_NOP();
187         instrs[5] = PPC_RAW_NOP();
188
189         i = 0;
190         if (types & STF_BARRIER_FALLBACK || types & STF_BARRIER_SYNC_ORI) {
191                 if (cpu_has_feature(CPU_FTR_HVMODE)) {
192                         instrs[i++] = PPC_RAW_MTSPR(SPRN_HSPRG1, _R13);
193                         instrs[i++] = PPC_RAW_MFSPR(_R13, SPRN_HSPRG0);
194                 } else {
195                         instrs[i++] = PPC_RAW_MTSPR(SPRN_SPRG2, _R13);
196                         instrs[i++] = PPC_RAW_MFSPR(_R13, SPRN_SPRG1);
197                 }
198                 instrs[i++] = PPC_RAW_SYNC();
199                 instrs[i++] = PPC_RAW_LD(_R13, _R13, 0);
200                 instrs[i++] = PPC_RAW_ORI(_R31, _R31, 0); /* speculation barrier */
201                 if (cpu_has_feature(CPU_FTR_HVMODE))
202                         instrs[i++] = PPC_RAW_MFSPR(_R13, SPRN_HSPRG1);
203                 else
204                         instrs[i++] = PPC_RAW_MFSPR(_R13, SPRN_SPRG2);
205         } else if (types & STF_BARRIER_EIEIO) {
206                 instrs[i++] = PPC_RAW_EIEIO() | 0x02000000; /* eieio + bit 6 hint */
207         }
208
209         for (i = 0; start < end; start++, i++) {
210                 dest = (void *)start + *start;
211
212                 pr_devel("patching dest %lx\n", (unsigned long)dest);
213
214                 patch_instruction(dest, ppc_inst(instrs[0]));
215                 patch_instruction(dest + 1, ppc_inst(instrs[1]));
216                 patch_instruction(dest + 2, ppc_inst(instrs[2]));
217                 patch_instruction(dest + 3, ppc_inst(instrs[3]));
218                 patch_instruction(dest + 4, ppc_inst(instrs[4]));
219                 patch_instruction(dest + 5, ppc_inst(instrs[5]));
220         }
221         printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s barrier)\n", i,
222                 (types == STF_BARRIER_NONE)                  ? "no" :
223                 (types == STF_BARRIER_FALLBACK)              ? "fallback" :
224                 (types == STF_BARRIER_EIEIO)                 ? "eieio" :
225                 (types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
226                                                            : "unknown");
227 }
228
229 static bool stf_exit_reentrant = false;
230 static bool rfi_exit_reentrant = false;
231
232 static int __do_stf_barrier_fixups(void *data)
233 {
234         enum stf_barrier_type *types = data;
235
236         do_stf_entry_barrier_fixups(*types);
237         do_stf_exit_barrier_fixups(*types);
238
239         return 0;
240 }
241
242 void do_stf_barrier_fixups(enum stf_barrier_type types)
243 {
244         /*
245          * The call to the fallback entry flush, and the fallback/sync-ori exit
246          * flush can not be safely patched in/out while other CPUs are
247          * executing them. So call __do_stf_barrier_fixups() on one CPU while
248          * all other CPUs spin in the stop machine core with interrupts hard
249          * disabled.
250          *
251          * The branch to mark interrupt exits non-reentrant is enabled first,
252          * then stop_machine runs which will ensure all CPUs are out of the
253          * low level interrupt exit code before patching. After the patching,
254          * if allowed, then flip the branch to allow fast exits.
255          */
256         static_branch_enable(&interrupt_exit_not_reentrant);
257
258         stop_machine(__do_stf_barrier_fixups, &types, NULL);
259
260         if ((types & STF_BARRIER_FALLBACK) || (types & STF_BARRIER_SYNC_ORI))
261                 stf_exit_reentrant = false;
262         else
263                 stf_exit_reentrant = true;
264
265         if (stf_exit_reentrant && rfi_exit_reentrant)
266                 static_branch_disable(&interrupt_exit_not_reentrant);
267 }
268
269 void do_uaccess_flush_fixups(enum l1d_flush_type types)
270 {
271         unsigned int instrs[4], *dest;
272         long *start, *end;
273         int i;
274
275         start = PTRRELOC(&__start___uaccess_flush_fixup);
276         end = PTRRELOC(&__stop___uaccess_flush_fixup);
277
278         instrs[0] = PPC_RAW_NOP();
279         instrs[1] = PPC_RAW_NOP();
280         instrs[2] = PPC_RAW_NOP();
281         instrs[3] = PPC_RAW_BLR();
282
283         i = 0;
284         if (types == L1D_FLUSH_FALLBACK) {
285                 instrs[3] = PPC_RAW_NOP();
286                 /* fallthrough to fallback flush */
287         }
288
289         if (types & L1D_FLUSH_ORI) {
290                 instrs[i++] = PPC_RAW_ORI(_R31, _R31, 0); /* speculation barrier */
291                 instrs[i++] = PPC_RAW_ORI(_R30, _R30, 0); /* L1d flush */
292         }
293
294         if (types & L1D_FLUSH_MTTRIG)
295                 instrs[i++] = PPC_RAW_MTSPR(SPRN_TRIG2, _R0);
296
297         for (i = 0; start < end; start++, i++) {
298                 dest = (void *)start + *start;
299
300                 pr_devel("patching dest %lx\n", (unsigned long)dest);
301
302                 patch_instruction(dest, ppc_inst(instrs[0]));
303
304                 patch_instruction(dest + 1, ppc_inst(instrs[1]));
305                 patch_instruction(dest + 2, ppc_inst(instrs[2]));
306                 patch_instruction(dest + 3, ppc_inst(instrs[3]));
307         }
308
309         printk(KERN_DEBUG "uaccess-flush: patched %d locations (%s flush)\n", i,
310                 (types == L1D_FLUSH_NONE)       ? "no" :
311                 (types == L1D_FLUSH_FALLBACK)   ? "fallback displacement" :
312                 (types &  L1D_FLUSH_ORI)        ? (types & L1D_FLUSH_MTTRIG)
313                                                         ? "ori+mttrig type"
314                                                         : "ori type" :
315                 (types &  L1D_FLUSH_MTTRIG)     ? "mttrig type"
316                                                 : "unknown");
317 }
318
319 static int __do_entry_flush_fixups(void *data)
320 {
321         enum l1d_flush_type types = *(enum l1d_flush_type *)data;
322         unsigned int instrs[3], *dest;
323         long *start, *end;
324         int i;
325
326         instrs[0] = PPC_RAW_NOP();
327         instrs[1] = PPC_RAW_NOP();
328         instrs[2] = PPC_RAW_NOP();
329
330         i = 0;
331         if (types == L1D_FLUSH_FALLBACK) {
332                 instrs[i++] = PPC_RAW_MFLR(_R10);
333                 instrs[i++] = PPC_RAW_NOP(); /* branch patched below */
334                 instrs[i++] = PPC_RAW_MTLR(_R10);
335         }
336
337         if (types & L1D_FLUSH_ORI) {
338                 instrs[i++] = PPC_RAW_ORI(_R31, _R31, 0); /* speculation barrier */
339                 instrs[i++] = PPC_RAW_ORI(_R30, _R30, 0); /* L1d flush */
340         }
341
342         if (types & L1D_FLUSH_MTTRIG)
343                 instrs[i++] = PPC_RAW_MTSPR(SPRN_TRIG2, _R0);
344
345         /*
346          * If we're patching in or out the fallback flush we need to be careful about the
347          * order in which we patch instructions. That's because it's possible we could
348          * take a page fault after patching one instruction, so the sequence of
349          * instructions must be safe even in a half patched state.
350          *
351          * To make that work, when patching in the fallback flush we patch in this order:
352          *  - the mflr          (dest)
353          *  - the mtlr          (dest + 2)
354          *  - the branch        (dest + 1)
355          *
356          * That ensures the sequence is safe to execute at any point. In contrast if we
357          * patch the mtlr last, it's possible we could return from the branch and not
358          * restore LR, leading to a crash later.
359          *
360          * When patching out the fallback flush (either with nops or another flush type),
361          * we patch in this order:
362          *  - the branch        (dest + 1)
363          *  - the mtlr          (dest + 2)
364          *  - the mflr          (dest)
365          *
366          * Note we are protected by stop_machine() from other CPUs executing the code in a
367          * semi-patched state.
368          */
369
370         start = PTRRELOC(&__start___entry_flush_fixup);
371         end = PTRRELOC(&__stop___entry_flush_fixup);
372         for (i = 0; start < end; start++, i++) {
373                 dest = (void *)start + *start;
374
375                 pr_devel("patching dest %lx\n", (unsigned long)dest);
376
377                 if (types == L1D_FLUSH_FALLBACK) {
378                         patch_instruction(dest, ppc_inst(instrs[0]));
379                         patch_instruction(dest + 2, ppc_inst(instrs[2]));
380                         patch_branch(dest + 1,
381                                      (unsigned long)&entry_flush_fallback, BRANCH_SET_LINK);
382                 } else {
383                         patch_instruction(dest + 1, ppc_inst(instrs[1]));
384                         patch_instruction(dest + 2, ppc_inst(instrs[2]));
385                         patch_instruction(dest, ppc_inst(instrs[0]));
386                 }
387         }
388
389         start = PTRRELOC(&__start___scv_entry_flush_fixup);
390         end = PTRRELOC(&__stop___scv_entry_flush_fixup);
391         for (; start < end; start++, i++) {
392                 dest = (void *)start + *start;
393
394                 pr_devel("patching dest %lx\n", (unsigned long)dest);
395
396                 if (types == L1D_FLUSH_FALLBACK) {
397                         patch_instruction(dest, ppc_inst(instrs[0]));
398                         patch_instruction(dest + 2, ppc_inst(instrs[2]));
399                         patch_branch(dest + 1,
400                                      (unsigned long)&scv_entry_flush_fallback, BRANCH_SET_LINK);
401                 } else {
402                         patch_instruction(dest + 1, ppc_inst(instrs[1]));
403                         patch_instruction(dest + 2, ppc_inst(instrs[2]));
404                         patch_instruction(dest, ppc_inst(instrs[0]));
405                 }
406         }
407
408
409         printk(KERN_DEBUG "entry-flush: patched %d locations (%s flush)\n", i,
410                 (types == L1D_FLUSH_NONE)       ? "no" :
411                 (types == L1D_FLUSH_FALLBACK)   ? "fallback displacement" :
412                 (types &  L1D_FLUSH_ORI)        ? (types & L1D_FLUSH_MTTRIG)
413                                                         ? "ori+mttrig type"
414                                                         : "ori type" :
415                 (types &  L1D_FLUSH_MTTRIG)     ? "mttrig type"
416                                                 : "unknown");
417
418         return 0;
419 }
420
421 void do_entry_flush_fixups(enum l1d_flush_type types)
422 {
423         /*
424          * The call to the fallback flush can not be safely patched in/out while
425          * other CPUs are executing it. So call __do_entry_flush_fixups() on one
426          * CPU while all other CPUs spin in the stop machine core with interrupts
427          * hard disabled.
428          */
429         stop_machine(__do_entry_flush_fixups, &types, NULL);
430 }
431
432 static int __do_rfi_flush_fixups(void *data)
433 {
434         enum l1d_flush_type types = *(enum l1d_flush_type *)data;
435         unsigned int instrs[3], *dest;
436         long *start, *end;
437         int i;
438
439         start = PTRRELOC(&__start___rfi_flush_fixup);
440         end = PTRRELOC(&__stop___rfi_flush_fixup);
441
442         instrs[0] = PPC_RAW_NOP();
443         instrs[1] = PPC_RAW_NOP();
444         instrs[2] = PPC_RAW_NOP();
445
446         if (types & L1D_FLUSH_FALLBACK)
447                 /* b .+16 to fallback flush */
448                 instrs[0] = PPC_INST_BRANCH | 16;
449
450         i = 0;
451         if (types & L1D_FLUSH_ORI) {
452                 instrs[i++] = PPC_RAW_ORI(_R31, _R31, 0); /* speculation barrier */
453                 instrs[i++] = PPC_RAW_ORI(_R30, _R30, 0); /* L1d flush */
454         }
455
456         if (types & L1D_FLUSH_MTTRIG)
457                 instrs[i++] = PPC_RAW_MTSPR(SPRN_TRIG2, _R0);
458
459         for (i = 0; start < end; start++, i++) {
460                 dest = (void *)start + *start;
461
462                 pr_devel("patching dest %lx\n", (unsigned long)dest);
463
464                 patch_instruction(dest, ppc_inst(instrs[0]));
465                 patch_instruction(dest + 1, ppc_inst(instrs[1]));
466                 patch_instruction(dest + 2, ppc_inst(instrs[2]));
467         }
468
469         printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
470                 (types == L1D_FLUSH_NONE)       ? "no" :
471                 (types == L1D_FLUSH_FALLBACK)   ? "fallback displacement" :
472                 (types &  L1D_FLUSH_ORI)        ? (types & L1D_FLUSH_MTTRIG)
473                                                         ? "ori+mttrig type"
474                                                         : "ori type" :
475                 (types &  L1D_FLUSH_MTTRIG)     ? "mttrig type"
476                                                 : "unknown");
477
478         return 0;
479 }
480
481 void do_rfi_flush_fixups(enum l1d_flush_type types)
482 {
483         /*
484          * stop_machine gets all CPUs out of the interrupt exit handler same
485          * as do_stf_barrier_fixups. do_rfi_flush_fixups patching can run
486          * without stop_machine, so this could be achieved with a broadcast
487          * IPI instead, but this matches the stf sequence.
488          */
489         static_branch_enable(&interrupt_exit_not_reentrant);
490
491         stop_machine(__do_rfi_flush_fixups, &types, NULL);
492
493         if (types & L1D_FLUSH_FALLBACK)
494                 rfi_exit_reentrant = false;
495         else
496                 rfi_exit_reentrant = true;
497
498         if (stf_exit_reentrant && rfi_exit_reentrant)
499                 static_branch_disable(&interrupt_exit_not_reentrant);
500 }
501
502 void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end)
503 {
504         unsigned int instr, *dest;
505         long *start, *end;
506         int i;
507
508         start = fixup_start;
509         end = fixup_end;
510
511         instr = PPC_RAW_NOP();
512
513         if (enable) {
514                 pr_info("barrier-nospec: using ORI speculation barrier\n");
515                 instr = PPC_RAW_ORI(_R31, _R31, 0); /* speculation barrier */
516         }
517
518         for (i = 0; start < end; start++, i++) {
519                 dest = (void *)start + *start;
520
521                 pr_devel("patching dest %lx\n", (unsigned long)dest);
522                 patch_instruction(dest, ppc_inst(instr));
523         }
524
525         printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
526 }
527
528 #endif /* CONFIG_PPC_BOOK3S_64 */
529
530 #ifdef CONFIG_PPC_BARRIER_NOSPEC
531 void do_barrier_nospec_fixups(bool enable)
532 {
533         void *start, *end;
534
535         start = PTRRELOC(&__start___barrier_nospec_fixup);
536         end = PTRRELOC(&__stop___barrier_nospec_fixup);
537
538         do_barrier_nospec_fixups_range(enable, start, end);
539 }
540 #endif /* CONFIG_PPC_BARRIER_NOSPEC */
541
542 #ifdef CONFIG_PPC_FSL_BOOK3E
543 void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end)
544 {
545         unsigned int instr[2], *dest;
546         long *start, *end;
547         int i;
548
549         start = fixup_start;
550         end = fixup_end;
551
552         instr[0] = PPC_RAW_NOP();
553         instr[1] = PPC_RAW_NOP();
554
555         if (enable) {
556                 pr_info("barrier-nospec: using isync; sync as speculation barrier\n");
557                 instr[0] = PPC_RAW_ISYNC();
558                 instr[1] = PPC_RAW_SYNC();
559         }
560
561         for (i = 0; start < end; start++, i++) {
562                 dest = (void *)start + *start;
563
564                 pr_devel("patching dest %lx\n", (unsigned long)dest);
565                 patch_instruction(dest, ppc_inst(instr[0]));
566                 patch_instruction(dest + 1, ppc_inst(instr[1]));
567         }
568
569         printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
570 }
571
572 static void patch_btb_flush_section(long *curr)
573 {
574         unsigned int *start, *end;
575
576         start = (void *)curr + *curr;
577         end = (void *)curr + *(curr + 1);
578         for (; start < end; start++) {
579                 pr_devel("patching dest %lx\n", (unsigned long)start);
580                 patch_instruction(start, ppc_inst(PPC_RAW_NOP()));
581         }
582 }
583
584 void do_btb_flush_fixups(void)
585 {
586         long *start, *end;
587
588         start = PTRRELOC(&__start__btb_flush_fixup);
589         end = PTRRELOC(&__stop__btb_flush_fixup);
590
591         for (; start < end; start += 2)
592                 patch_btb_flush_section(start);
593 }
594 #endif /* CONFIG_PPC_FSL_BOOK3E */
595
596 void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
597 {
598         long *start, *end;
599         u32 *dest;
600
601         if (!(value & CPU_FTR_LWSYNC))
602                 return ;
603
604         start = fixup_start;
605         end = fixup_end;
606
607         for (; start < end; start++) {
608                 dest = (void *)start + *start;
609                 raw_patch_instruction(dest, ppc_inst(PPC_INST_LWSYNC));
610         }
611 }
612
613 static void do_final_fixups(void)
614 {
615 #if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE)
616         struct ppc_inst inst;
617         u32 *src, *dest, *end;
618
619         if (PHYSICAL_START == 0)
620                 return;
621
622         src = (u32 *)(KERNELBASE + PHYSICAL_START);
623         dest = (u32 *)KERNELBASE;
624         end = (void *)src + (__end_interrupts - _stext);
625
626         while (src < end) {
627                 inst = ppc_inst_read(src);
628                 raw_patch_instruction(dest, inst);
629                 src = ppc_inst_next(src, src);
630                 dest = ppc_inst_next(dest, dest);
631         }
632 #endif
633 }
634
635 static unsigned long __initdata saved_cpu_features;
636 static unsigned int __initdata saved_mmu_features;
637 #ifdef CONFIG_PPC64
638 static unsigned long __initdata saved_firmware_features;
639 #endif
640
641 void __init apply_feature_fixups(void)
642 {
643         struct cpu_spec *spec = PTRRELOC(*PTRRELOC(&cur_cpu_spec));
644
645         *PTRRELOC(&saved_cpu_features) = spec->cpu_features;
646         *PTRRELOC(&saved_mmu_features) = spec->mmu_features;
647
648         /*
649          * Apply the CPU-specific and firmware specific fixups to kernel text
650          * (nop out sections not relevant to this CPU or this firmware).
651          */
652         do_feature_fixups(spec->cpu_features,
653                           PTRRELOC(&__start___ftr_fixup),
654                           PTRRELOC(&__stop___ftr_fixup));
655
656         do_feature_fixups(spec->mmu_features,
657                           PTRRELOC(&__start___mmu_ftr_fixup),
658                           PTRRELOC(&__stop___mmu_ftr_fixup));
659
660         do_lwsync_fixups(spec->cpu_features,
661                          PTRRELOC(&__start___lwsync_fixup),
662                          PTRRELOC(&__stop___lwsync_fixup));
663
664 #ifdef CONFIG_PPC64
665         saved_firmware_features = powerpc_firmware_features;
666         do_feature_fixups(powerpc_firmware_features,
667                           &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
668 #endif
669         do_final_fixups();
670 }
671
672 void __init setup_feature_keys(void)
673 {
674         /*
675          * Initialise jump label. This causes all the cpu/mmu_has_feature()
676          * checks to take on their correct polarity based on the current set of
677          * CPU/MMU features.
678          */
679         jump_label_init();
680         cpu_feature_keys_init();
681         mmu_feature_keys_init();
682 }
683
684 static int __init check_features(void)
685 {
686         WARN(saved_cpu_features != cur_cpu_spec->cpu_features,
687              "CPU features changed after feature patching!\n");
688         WARN(saved_mmu_features != cur_cpu_spec->mmu_features,
689              "MMU features changed after feature patching!\n");
690 #ifdef CONFIG_PPC64
691         WARN(saved_firmware_features != powerpc_firmware_features,
692              "Firmware features changed after feature patching!\n");
693 #endif
694
695         return 0;
696 }
697 late_initcall(check_features);
698
699 #ifdef CONFIG_FTR_FIXUP_SELFTEST
700
701 #define check(x)        \
702         if (!(x)) printk("feature-fixups: test failed at line %d\n", __LINE__);
703
704 /* This must be after the text it fixes up, vmlinux.lds.S enforces that atm */
705 static struct fixup_entry fixup;
706
707 static long calc_offset(struct fixup_entry *entry, unsigned int *p)
708 {
709         return (unsigned long)p - (unsigned long)entry;
710 }
711
712 static void test_basic_patching(void)
713 {
714         extern unsigned int ftr_fixup_test1[];
715         extern unsigned int end_ftr_fixup_test1[];
716         extern unsigned int ftr_fixup_test1_orig[];
717         extern unsigned int ftr_fixup_test1_expected[];
718         int size = 4 * (end_ftr_fixup_test1 - ftr_fixup_test1);
719
720         fixup.value = fixup.mask = 8;
721         fixup.start_off = calc_offset(&fixup, ftr_fixup_test1 + 1);
722         fixup.end_off = calc_offset(&fixup, ftr_fixup_test1 + 2);
723         fixup.alt_start_off = fixup.alt_end_off = 0;
724
725         /* Sanity check */
726         check(memcmp(ftr_fixup_test1, ftr_fixup_test1_orig, size) == 0);
727
728         /* Check we don't patch if the value matches */
729         patch_feature_section(8, &fixup);
730         check(memcmp(ftr_fixup_test1, ftr_fixup_test1_orig, size) == 0);
731
732         /* Check we do patch if the value doesn't match */
733         patch_feature_section(0, &fixup);
734         check(memcmp(ftr_fixup_test1, ftr_fixup_test1_expected, size) == 0);
735
736         /* Check we do patch if the mask doesn't match */
737         memcpy(ftr_fixup_test1, ftr_fixup_test1_orig, size);
738         check(memcmp(ftr_fixup_test1, ftr_fixup_test1_orig, size) == 0);
739         patch_feature_section(~8, &fixup);
740         check(memcmp(ftr_fixup_test1, ftr_fixup_test1_expected, size) == 0);
741 }
742
743 static void test_alternative_patching(void)
744 {
745         extern unsigned int ftr_fixup_test2[];
746         extern unsigned int end_ftr_fixup_test2[];
747         extern unsigned int ftr_fixup_test2_orig[];
748         extern unsigned int ftr_fixup_test2_alt[];
749         extern unsigned int ftr_fixup_test2_expected[];
750         int size = 4 * (end_ftr_fixup_test2 - ftr_fixup_test2);
751
752         fixup.value = fixup.mask = 0xF;
753         fixup.start_off = calc_offset(&fixup, ftr_fixup_test2 + 1);
754         fixup.end_off = calc_offset(&fixup, ftr_fixup_test2 + 2);
755         fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_test2_alt);
756         fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_test2_alt + 1);
757
758         /* Sanity check */
759         check(memcmp(ftr_fixup_test2, ftr_fixup_test2_orig, size) == 0);
760
761         /* Check we don't patch if the value matches */
762         patch_feature_section(0xF, &fixup);
763         check(memcmp(ftr_fixup_test2, ftr_fixup_test2_orig, size) == 0);
764
765         /* Check we do patch if the value doesn't match */
766         patch_feature_section(0, &fixup);
767         check(memcmp(ftr_fixup_test2, ftr_fixup_test2_expected, size) == 0);
768
769         /* Check we do patch if the mask doesn't match */
770         memcpy(ftr_fixup_test2, ftr_fixup_test2_orig, size);
771         check(memcmp(ftr_fixup_test2, ftr_fixup_test2_orig, size) == 0);
772         patch_feature_section(~0xF, &fixup);
773         check(memcmp(ftr_fixup_test2, ftr_fixup_test2_expected, size) == 0);
774 }
775
776 static void test_alternative_case_too_big(void)
777 {
778         extern unsigned int ftr_fixup_test3[];
779         extern unsigned int end_ftr_fixup_test3[];
780         extern unsigned int ftr_fixup_test3_orig[];
781         extern unsigned int ftr_fixup_test3_alt[];
782         int size = 4 * (end_ftr_fixup_test3 - ftr_fixup_test3);
783
784         fixup.value = fixup.mask = 0xC;
785         fixup.start_off = calc_offset(&fixup, ftr_fixup_test3 + 1);
786         fixup.end_off = calc_offset(&fixup, ftr_fixup_test3 + 2);
787         fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_test3_alt);
788         fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_test3_alt + 2);
789
790         /* Sanity check */
791         check(memcmp(ftr_fixup_test3, ftr_fixup_test3_orig, size) == 0);
792
793         /* Expect nothing to be patched, and the error returned to us */
794         check(patch_feature_section(0xF, &fixup) == 1);
795         check(memcmp(ftr_fixup_test3, ftr_fixup_test3_orig, size) == 0);
796         check(patch_feature_section(0, &fixup) == 1);
797         check(memcmp(ftr_fixup_test3, ftr_fixup_test3_orig, size) == 0);
798         check(patch_feature_section(~0xF, &fixup) == 1);
799         check(memcmp(ftr_fixup_test3, ftr_fixup_test3_orig, size) == 0);
800 }
801
802 static void test_alternative_case_too_small(void)
803 {
804         extern unsigned int ftr_fixup_test4[];
805         extern unsigned int end_ftr_fixup_test4[];
806         extern unsigned int ftr_fixup_test4_orig[];
807         extern unsigned int ftr_fixup_test4_alt[];
808         extern unsigned int ftr_fixup_test4_expected[];
809         int size = 4 * (end_ftr_fixup_test4 - ftr_fixup_test4);
810         unsigned long flag;
811
812         /* Check a high-bit flag */
813         flag = 1UL << ((sizeof(unsigned long) - 1) * 8);
814         fixup.value = fixup.mask = flag;
815         fixup.start_off = calc_offset(&fixup, ftr_fixup_test4 + 1);
816         fixup.end_off = calc_offset(&fixup, ftr_fixup_test4 + 5);
817         fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_test4_alt);
818         fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_test4_alt + 2);
819
820         /* Sanity check */
821         check(memcmp(ftr_fixup_test4, ftr_fixup_test4_orig, size) == 0);
822
823         /* Check we don't patch if the value matches */
824         patch_feature_section(flag, &fixup);
825         check(memcmp(ftr_fixup_test4, ftr_fixup_test4_orig, size) == 0);
826
827         /* Check we do patch if the value doesn't match */
828         patch_feature_section(0, &fixup);
829         check(memcmp(ftr_fixup_test4, ftr_fixup_test4_expected, size) == 0);
830
831         /* Check we do patch if the mask doesn't match */
832         memcpy(ftr_fixup_test4, ftr_fixup_test4_orig, size);
833         check(memcmp(ftr_fixup_test4, ftr_fixup_test4_orig, size) == 0);
834         patch_feature_section(~flag, &fixup);
835         check(memcmp(ftr_fixup_test4, ftr_fixup_test4_expected, size) == 0);
836 }
837
838 static void test_alternative_case_with_branch(void)
839 {
840         extern unsigned int ftr_fixup_test5[];
841         extern unsigned int end_ftr_fixup_test5[];
842         extern unsigned int ftr_fixup_test5_expected[];
843         int size = 4 * (end_ftr_fixup_test5 - ftr_fixup_test5);
844
845         check(memcmp(ftr_fixup_test5, ftr_fixup_test5_expected, size) == 0);
846 }
847
848 static void test_alternative_case_with_external_branch(void)
849 {
850         extern unsigned int ftr_fixup_test6[];
851         extern unsigned int end_ftr_fixup_test6[];
852         extern unsigned int ftr_fixup_test6_expected[];
853         int size = 4 * (end_ftr_fixup_test6 - ftr_fixup_test6);
854
855         check(memcmp(ftr_fixup_test6, ftr_fixup_test6_expected, size) == 0);
856 }
857
858 static void test_alternative_case_with_branch_to_end(void)
859 {
860         extern unsigned int ftr_fixup_test7[];
861         extern unsigned int end_ftr_fixup_test7[];
862         extern unsigned int ftr_fixup_test7_expected[];
863         int size = 4 * (end_ftr_fixup_test7 - ftr_fixup_test7);
864
865         check(memcmp(ftr_fixup_test7, ftr_fixup_test7_expected, size) == 0);
866 }
867
868 static void test_cpu_macros(void)
869 {
870         extern u8 ftr_fixup_test_FTR_macros[];
871         extern u8 ftr_fixup_test_FTR_macros_expected[];
872         unsigned long size = ftr_fixup_test_FTR_macros_expected -
873                              ftr_fixup_test_FTR_macros;
874
875         /* The fixups have already been done for us during boot */
876         check(memcmp(ftr_fixup_test_FTR_macros,
877                      ftr_fixup_test_FTR_macros_expected, size) == 0);
878 }
879
880 static void test_fw_macros(void)
881 {
882 #ifdef CONFIG_PPC64
883         extern u8 ftr_fixup_test_FW_FTR_macros[];
884         extern u8 ftr_fixup_test_FW_FTR_macros_expected[];
885         unsigned long size = ftr_fixup_test_FW_FTR_macros_expected -
886                              ftr_fixup_test_FW_FTR_macros;
887
888         /* The fixups have already been done for us during boot */
889         check(memcmp(ftr_fixup_test_FW_FTR_macros,
890                      ftr_fixup_test_FW_FTR_macros_expected, size) == 0);
891 #endif
892 }
893
894 static void test_lwsync_macros(void)
895 {
896         extern u8 lwsync_fixup_test[];
897         extern u8 end_lwsync_fixup_test[];
898         extern u8 lwsync_fixup_test_expected_LWSYNC[];
899         extern u8 lwsync_fixup_test_expected_SYNC[];
900         unsigned long size = end_lwsync_fixup_test -
901                              lwsync_fixup_test;
902
903         /* The fixups have already been done for us during boot */
904         if (cur_cpu_spec->cpu_features & CPU_FTR_LWSYNC) {
905                 check(memcmp(lwsync_fixup_test,
906                              lwsync_fixup_test_expected_LWSYNC, size) == 0);
907         } else {
908                 check(memcmp(lwsync_fixup_test,
909                              lwsync_fixup_test_expected_SYNC, size) == 0);
910         }
911 }
912
913 #ifdef CONFIG_PPC64
914 static void __init test_prefix_patching(void)
915 {
916         extern unsigned int ftr_fixup_prefix1[];
917         extern unsigned int end_ftr_fixup_prefix1[];
918         extern unsigned int ftr_fixup_prefix1_orig[];
919         extern unsigned int ftr_fixup_prefix1_expected[];
920         int size = sizeof(unsigned int) * (end_ftr_fixup_prefix1 - ftr_fixup_prefix1);
921
922         fixup.value = fixup.mask = 8;
923         fixup.start_off = calc_offset(&fixup, ftr_fixup_prefix1 + 1);
924         fixup.end_off = calc_offset(&fixup, ftr_fixup_prefix1 + 3);
925         fixup.alt_start_off = fixup.alt_end_off = 0;
926
927         /* Sanity check */
928         check(memcmp(ftr_fixup_prefix1, ftr_fixup_prefix1_orig, size) == 0);
929
930         patch_feature_section(0, &fixup);
931         check(memcmp(ftr_fixup_prefix1, ftr_fixup_prefix1_expected, size) == 0);
932         check(memcmp(ftr_fixup_prefix1, ftr_fixup_prefix1_orig, size) != 0);
933 }
934
935 static void __init test_prefix_alt_patching(void)
936 {
937         extern unsigned int ftr_fixup_prefix2[];
938         extern unsigned int end_ftr_fixup_prefix2[];
939         extern unsigned int ftr_fixup_prefix2_orig[];
940         extern unsigned int ftr_fixup_prefix2_expected[];
941         extern unsigned int ftr_fixup_prefix2_alt[];
942         int size = sizeof(unsigned int) * (end_ftr_fixup_prefix2 - ftr_fixup_prefix2);
943
944         fixup.value = fixup.mask = 8;
945         fixup.start_off = calc_offset(&fixup, ftr_fixup_prefix2 + 1);
946         fixup.end_off = calc_offset(&fixup, ftr_fixup_prefix2 + 3);
947         fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_prefix2_alt);
948         fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_prefix2_alt + 2);
949         /* Sanity check */
950         check(memcmp(ftr_fixup_prefix2, ftr_fixup_prefix2_orig, size) == 0);
951
952         patch_feature_section(0, &fixup);
953         check(memcmp(ftr_fixup_prefix2, ftr_fixup_prefix2_expected, size) == 0);
954         check(memcmp(ftr_fixup_prefix2, ftr_fixup_prefix2_orig, size) != 0);
955 }
956
957 static void __init test_prefix_word_alt_patching(void)
958 {
959         extern unsigned int ftr_fixup_prefix3[];
960         extern unsigned int end_ftr_fixup_prefix3[];
961         extern unsigned int ftr_fixup_prefix3_orig[];
962         extern unsigned int ftr_fixup_prefix3_expected[];
963         extern unsigned int ftr_fixup_prefix3_alt[];
964         int size = sizeof(unsigned int) * (end_ftr_fixup_prefix3 - ftr_fixup_prefix3);
965
966         fixup.value = fixup.mask = 8;
967         fixup.start_off = calc_offset(&fixup, ftr_fixup_prefix3 + 1);
968         fixup.end_off = calc_offset(&fixup, ftr_fixup_prefix3 + 4);
969         fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_prefix3_alt);
970         fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_prefix3_alt + 3);
971         /* Sanity check */
972         check(memcmp(ftr_fixup_prefix3, ftr_fixup_prefix3_orig, size) == 0);
973
974         patch_feature_section(0, &fixup);
975         check(memcmp(ftr_fixup_prefix3, ftr_fixup_prefix3_expected, size) == 0);
976         patch_feature_section(0, &fixup);
977         check(memcmp(ftr_fixup_prefix3, ftr_fixup_prefix3_orig, size) != 0);
978 }
979 #else
980 static inline void test_prefix_patching(void) {}
981 static inline void test_prefix_alt_patching(void) {}
982 static inline void test_prefix_word_alt_patching(void) {}
983 #endif /* CONFIG_PPC64 */
984
985 static int __init test_feature_fixups(void)
986 {
987         printk(KERN_DEBUG "Running feature fixup self-tests ...\n");
988
989         test_basic_patching();
990         test_alternative_patching();
991         test_alternative_case_too_big();
992         test_alternative_case_too_small();
993         test_alternative_case_with_branch();
994         test_alternative_case_with_external_branch();
995         test_alternative_case_with_branch_to_end();
996         test_cpu_macros();
997         test_fw_macros();
998         test_lwsync_macros();
999         test_prefix_patching();
1000         test_prefix_alt_patching();
1001         test_prefix_word_alt_patching();
1002
1003         return 0;
1004 }
1005 late_initcall(test_feature_fixups);
1006
1007 #endif /* CONFIG_FTR_FIXUP_SELFTEST */