]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - arch/powerpc/mm/slb.c
a9c66feb3c43787c0ce3e164e8ca314753e3365f
[mirror_ubuntu-focal-kernel.git] / arch / powerpc / mm / slb.c
1 /*
2 * PowerPC64 SLB support.
3 *
4 * Copyright (C) 2004 David Gibson <dwg@au.ibm.com>, IBM
5 * Based on earlier code written by:
6 * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
7 * Copyright (c) 2001 Dave Engebretsen
8 * Copyright (C) 2002 Anton Blanchard <anton@au.ibm.com>, IBM
9 *
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17 #include <asm/pgtable.h>
18 #include <asm/mmu.h>
19 #include <asm/mmu_context.h>
20 #include <asm/paca.h>
21 #include <asm/cputable.h>
22 #include <asm/cacheflush.h>
23 #include <asm/smp.h>
24 #include <linux/compiler.h>
25 #include <linux/context_tracking.h>
26 #include <linux/mm_types.h>
27
28 #include <asm/udbg.h>
29 #include <asm/code-patching.h>
30
31 enum slb_index {
32 LINEAR_INDEX = 0, /* Kernel linear map (0xc000000000000000) */
33 VMALLOC_INDEX = 1, /* Kernel virtual map (0xd000000000000000) */
34 KSTACK_INDEX = 2, /* Kernel stack map */
35 };
36
37 extern void slb_allocate(unsigned long ea);
38
39 #define slb_esid_mask(ssize) \
40 (((ssize) == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T)
41
42 static inline unsigned long mk_esid_data(unsigned long ea, int ssize,
43 enum slb_index index)
44 {
45 return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | index;
46 }
47
48 static inline unsigned long mk_vsid_data(unsigned long ea, int ssize,
49 unsigned long flags)
50 {
51 return (get_kernel_vsid(ea, ssize) << slb_vsid_shift(ssize)) | flags |
52 ((unsigned long) ssize << SLB_VSID_SSIZE_SHIFT);
53 }
54
55 static inline void slb_shadow_update(unsigned long ea, int ssize,
56 unsigned long flags,
57 enum slb_index index)
58 {
59 struct slb_shadow *p = get_slb_shadow();
60
61 /*
62 * Clear the ESID first so the entry is not valid while we are
63 * updating it. No write barriers are needed here, provided
64 * we only update the current CPU's SLB shadow buffer.
65 */
66 WRITE_ONCE(p->save_area[index].esid, 0);
67 WRITE_ONCE(p->save_area[index].vsid, cpu_to_be64(mk_vsid_data(ea, ssize, flags)));
68 WRITE_ONCE(p->save_area[index].esid, cpu_to_be64(mk_esid_data(ea, ssize, index)));
69 }
70
71 static inline void slb_shadow_clear(enum slb_index index)
72 {
73 WRITE_ONCE(get_slb_shadow()->save_area[index].esid, cpu_to_be64(index));
74 }
75
76 static inline void create_shadowed_slbe(unsigned long ea, int ssize,
77 unsigned long flags,
78 enum slb_index index)
79 {
80 /*
81 * Updating the shadow buffer before writing the SLB ensures
82 * we don't get a stale entry here if we get preempted by PHYP
83 * between these two statements.
84 */
85 slb_shadow_update(ea, ssize, flags, index);
86
87 asm volatile("slbmte %0,%1" :
88 : "r" (mk_vsid_data(ea, ssize, flags)),
89 "r" (mk_esid_data(ea, ssize, index))
90 : "memory" );
91 }
92
93 /*
94 * Insert bolted entries into SLB (which may not be empty, so don't clear
95 * slb_cache_ptr).
96 */
97 void __slb_restore_bolted_realmode(void)
98 {
99 struct slb_shadow *p = get_slb_shadow();
100 enum slb_index index;
101
102 /* No isync needed because realmode. */
103 for (index = 0; index < SLB_NUM_BOLTED; index++) {
104 asm volatile("slbmte %0,%1" :
105 : "r" (be64_to_cpu(p->save_area[index].vsid)),
106 "r" (be64_to_cpu(p->save_area[index].esid)));
107 }
108 }
109
110 /*
111 * Insert the bolted entries into an empty SLB.
112 * This is not the same as rebolt because the bolted segments are not
113 * changed, just loaded from the shadow area.
114 */
115 void slb_restore_bolted_realmode(void)
116 {
117 __slb_restore_bolted_realmode();
118 get_paca()->slb_cache_ptr = 0;
119 }
120
121 /*
122 * This flushes all SLB entries including 0, so it must be realmode.
123 */
124 void slb_flush_all_realmode(void)
125 {
126 /*
127 * This flushes all SLB entries including 0, so it must be realmode.
128 */
129 asm volatile("slbmte %0,%0; slbia" : : "r" (0));
130 }
131
132 static void __slb_flush_and_rebolt(void)
133 {
134 /* If you change this make sure you change SLB_NUM_BOLTED
135 * and PR KVM appropriately too. */
136 unsigned long linear_llp, vmalloc_llp, lflags, vflags;
137 unsigned long ksp_esid_data, ksp_vsid_data;
138
139 linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
140 vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp;
141 lflags = SLB_VSID_KERNEL | linear_llp;
142 vflags = SLB_VSID_KERNEL | vmalloc_llp;
143
144 ksp_esid_data = mk_esid_data(get_paca()->kstack, mmu_kernel_ssize, KSTACK_INDEX);
145 if ((ksp_esid_data & ~0xfffffffUL) <= PAGE_OFFSET) {
146 ksp_esid_data &= ~SLB_ESID_V;
147 ksp_vsid_data = 0;
148 slb_shadow_clear(KSTACK_INDEX);
149 } else {
150 /* Update stack entry; others don't change */
151 slb_shadow_update(get_paca()->kstack, mmu_kernel_ssize, lflags, KSTACK_INDEX);
152 ksp_vsid_data =
153 be64_to_cpu(get_slb_shadow()->save_area[KSTACK_INDEX].vsid);
154 }
155
156 /* We need to do this all in asm, so we're sure we don't touch
157 * the stack between the slbia and rebolting it. */
158 asm volatile("isync\n"
159 "slbia\n"
160 /* Slot 1 - first VMALLOC segment */
161 "slbmte %0,%1\n"
162 /* Slot 2 - kernel stack */
163 "slbmte %2,%3\n"
164 "isync"
165 :: "r"(mk_vsid_data(VMALLOC_START, mmu_kernel_ssize, vflags)),
166 "r"(mk_esid_data(VMALLOC_START, mmu_kernel_ssize, VMALLOC_INDEX)),
167 "r"(ksp_vsid_data),
168 "r"(ksp_esid_data)
169 : "memory");
170 }
171
172 void slb_flush_and_rebolt(void)
173 {
174
175 WARN_ON(!irqs_disabled());
176
177 /*
178 * We can't take a PMU exception in the following code, so hard
179 * disable interrupts.
180 */
181 hard_irq_disable();
182
183 __slb_flush_and_rebolt();
184 get_paca()->slb_cache_ptr = 0;
185 }
186
187 void slb_save_contents(struct slb_entry *slb_ptr)
188 {
189 int i;
190 unsigned long e, v;
191
192 /* Save slb_cache_ptr value. */
193 get_paca()->slb_save_cache_ptr = get_paca()->slb_cache_ptr;
194
195 if (!slb_ptr)
196 return;
197
198 for (i = 0; i < mmu_slb_size; i++) {
199 asm volatile("slbmfee %0,%1" : "=r" (e) : "r" (i));
200 asm volatile("slbmfev %0,%1" : "=r" (v) : "r" (i));
201 slb_ptr->esid = e;
202 slb_ptr->vsid = v;
203 slb_ptr++;
204 }
205 }
206
207 void slb_dump_contents(struct slb_entry *slb_ptr)
208 {
209 int i, n;
210 unsigned long e, v;
211 unsigned long llp;
212
213 if (!slb_ptr)
214 return;
215
216 pr_err("SLB contents of cpu 0x%x\n", smp_processor_id());
217 pr_err("Last SLB entry inserted at slot %lld\n", get_paca()->stab_rr);
218
219 for (i = 0; i < mmu_slb_size; i++) {
220 e = slb_ptr->esid;
221 v = slb_ptr->vsid;
222 slb_ptr++;
223
224 if (!e && !v)
225 continue;
226
227 pr_err("%02d %016lx %016lx\n", i, e, v);
228
229 if (!(e & SLB_ESID_V)) {
230 pr_err("\n");
231 continue;
232 }
233 llp = v & SLB_VSID_LLP;
234 if (v & SLB_VSID_B_1T) {
235 pr_err(" 1T ESID=%9lx VSID=%13lx LLP:%3lx\n",
236 GET_ESID_1T(e),
237 (v & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T, llp);
238 } else {
239 pr_err(" 256M ESID=%9lx VSID=%13lx LLP:%3lx\n",
240 GET_ESID(e),
241 (v & ~SLB_VSID_B) >> SLB_VSID_SHIFT, llp);
242 }
243 }
244 pr_err("----------------------------------\n");
245
246 /* Dump slb cache entires as well. */
247 pr_err("SLB cache ptr value = %d\n", get_paca()->slb_save_cache_ptr);
248 pr_err("Valid SLB cache entries:\n");
249 n = min_t(int, get_paca()->slb_save_cache_ptr, SLB_CACHE_ENTRIES);
250 for (i = 0; i < n; i++)
251 pr_err("%02d EA[0-35]=%9x\n", i, get_paca()->slb_cache[i]);
252 pr_err("Rest of SLB cache entries:\n");
253 for (i = n; i < SLB_CACHE_ENTRIES; i++)
254 pr_err("%02d EA[0-35]=%9x\n", i, get_paca()->slb_cache[i]);
255 }
256
257 void slb_vmalloc_update(void)
258 {
259 unsigned long vflags;
260
261 vflags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_vmalloc_psize].sllp;
262 slb_shadow_update(VMALLOC_START, mmu_kernel_ssize, vflags, VMALLOC_INDEX);
263 slb_flush_and_rebolt();
264 }
265
266 /* Helper function to compare esids. There are four cases to handle.
267 * 1. The system is not 1T segment size capable. Use the GET_ESID compare.
268 * 2. The system is 1T capable, both addresses are < 1T, use the GET_ESID compare.
269 * 3. The system is 1T capable, only one of the two addresses is > 1T. This is not a match.
270 * 4. The system is 1T capable, both addresses are > 1T, use the GET_ESID_1T macro to compare.
271 */
272 static inline int esids_match(unsigned long addr1, unsigned long addr2)
273 {
274 int esid_1t_count;
275
276 /* System is not 1T segment size capable. */
277 if (!mmu_has_feature(MMU_FTR_1T_SEGMENT))
278 return (GET_ESID(addr1) == GET_ESID(addr2));
279
280 esid_1t_count = (((addr1 >> SID_SHIFT_1T) != 0) +
281 ((addr2 >> SID_SHIFT_1T) != 0));
282
283 /* both addresses are < 1T */
284 if (esid_1t_count == 0)
285 return (GET_ESID(addr1) == GET_ESID(addr2));
286
287 /* One address < 1T, the other > 1T. Not a match */
288 if (esid_1t_count == 1)
289 return 0;
290
291 /* Both addresses are > 1T. */
292 return (GET_ESID_1T(addr1) == GET_ESID_1T(addr2));
293 }
294
295 /* Flush all user entries from the segment table of the current processor. */
296 void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
297 {
298 unsigned long offset;
299 unsigned long pc = KSTK_EIP(tsk);
300 unsigned long stack = KSTK_ESP(tsk);
301 unsigned long exec_base;
302
303 /*
304 * We need interrupts hard-disabled here, not just soft-disabled,
305 * so that a PMU interrupt can't occur, which might try to access
306 * user memory (to get a stack trace) and possible cause an SLB miss
307 * which would update the slb_cache/slb_cache_ptr fields in the PACA.
308 */
309 hard_irq_disable();
310 offset = get_paca()->slb_cache_ptr;
311 if (!mmu_has_feature(MMU_FTR_NO_SLBIE_B) &&
312 offset <= SLB_CACHE_ENTRIES) {
313 unsigned long slbie_data = 0;
314 int i;
315
316 asm volatile("isync" : : : "memory");
317 for (i = 0; i < offset; i++) {
318 slbie_data = (unsigned long)get_paca()->slb_cache[i]
319 << SID_SHIFT; /* EA */
320 slbie_data |= user_segment_size(slbie_data)
321 << SLBIE_SSIZE_SHIFT;
322 slbie_data |= SLBIE_C; /* C set for user addresses */
323 asm volatile("slbie %0" : : "r" (slbie_data));
324 }
325
326 /* Workaround POWER5 < DD2.1 issue */
327 if (!cpu_has_feature(CPU_FTR_ARCH_207S) && offset == 1)
328 asm volatile("slbie %0" : : "r" (slbie_data));
329
330 asm volatile("isync" : : : "memory");
331 } else {
332 __slb_flush_and_rebolt();
333 }
334
335 get_paca()->slb_cache_ptr = 0;
336 copy_mm_to_paca(mm);
337
338 /*
339 * preload some userspace segments into the SLB.
340 * Almost all 32 and 64bit PowerPC executables are linked at
341 * 0x10000000 so it makes sense to preload this segment.
342 */
343 exec_base = 0x10000000;
344
345 if (is_kernel_addr(pc) || is_kernel_addr(stack) ||
346 is_kernel_addr(exec_base))
347 return;
348
349 slb_allocate(pc);
350
351 if (!esids_match(pc, stack))
352 slb_allocate(stack);
353
354 if (!esids_match(pc, exec_base) &&
355 !esids_match(stack, exec_base))
356 slb_allocate(exec_base);
357 }
358
359 static inline void patch_slb_encoding(unsigned int *insn_addr,
360 unsigned int immed)
361 {
362
363 /*
364 * This function patches either an li or a cmpldi instruction with
365 * a new immediate value. This relies on the fact that both li
366 * (which is actually addi) and cmpldi both take a 16-bit immediate
367 * value, and it is situated in the same location in the instruction,
368 * ie. bits 16-31 (Big endian bit order) or the lower 16 bits.
369 * The signedness of the immediate operand differs between the two
370 * instructions however this code is only ever patching a small value,
371 * much less than 1 << 15, so we can get away with it.
372 * To patch the value we read the existing instruction, clear the
373 * immediate value, and or in our new value, then write the instruction
374 * back.
375 */
376 unsigned int insn = (*insn_addr & 0xffff0000) | immed;
377 patch_instruction(insn_addr, insn);
378 }
379
380 extern u32 slb_miss_kernel_load_linear[];
381 extern u32 slb_miss_kernel_load_io[];
382 extern u32 slb_compare_rr_to_size[];
383 extern u32 slb_miss_kernel_load_vmemmap[];
384
385 void slb_set_size(u16 size)
386 {
387 if (mmu_slb_size == size)
388 return;
389
390 mmu_slb_size = size;
391 patch_slb_encoding(slb_compare_rr_to_size, mmu_slb_size);
392 }
393
394 void slb_initialize(void)
395 {
396 unsigned long linear_llp, vmalloc_llp, io_llp;
397 unsigned long lflags, vflags;
398 static int slb_encoding_inited;
399 #ifdef CONFIG_SPARSEMEM_VMEMMAP
400 unsigned long vmemmap_llp;
401 #endif
402
403 /* Prepare our SLB miss handler based on our page size */
404 linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
405 io_llp = mmu_psize_defs[mmu_io_psize].sllp;
406 vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp;
407 get_paca()->vmalloc_sllp = SLB_VSID_KERNEL | vmalloc_llp;
408 #ifdef CONFIG_SPARSEMEM_VMEMMAP
409 vmemmap_llp = mmu_psize_defs[mmu_vmemmap_psize].sllp;
410 #endif
411 if (!slb_encoding_inited) {
412 slb_encoding_inited = 1;
413 patch_slb_encoding(slb_miss_kernel_load_linear,
414 SLB_VSID_KERNEL | linear_llp);
415 patch_slb_encoding(slb_miss_kernel_load_io,
416 SLB_VSID_KERNEL | io_llp);
417 patch_slb_encoding(slb_compare_rr_to_size,
418 mmu_slb_size);
419
420 pr_devel("SLB: linear LLP = %04lx\n", linear_llp);
421 pr_devel("SLB: io LLP = %04lx\n", io_llp);
422
423 #ifdef CONFIG_SPARSEMEM_VMEMMAP
424 patch_slb_encoding(slb_miss_kernel_load_vmemmap,
425 SLB_VSID_KERNEL | vmemmap_llp);
426 pr_devel("SLB: vmemmap LLP = %04lx\n", vmemmap_llp);
427 #endif
428 }
429
430 get_paca()->stab_rr = SLB_NUM_BOLTED - 1;
431
432 lflags = SLB_VSID_KERNEL | linear_llp;
433 vflags = SLB_VSID_KERNEL | vmalloc_llp;
434
435 /* Invalidate the entire SLB (even entry 0) & all the ERATS */
436 asm volatile("isync":::"memory");
437 asm volatile("slbmte %0,%0"::"r" (0) : "memory");
438 asm volatile("isync; slbia; isync":::"memory");
439 create_shadowed_slbe(PAGE_OFFSET, mmu_kernel_ssize, lflags, LINEAR_INDEX);
440 create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, VMALLOC_INDEX);
441
442 /* For the boot cpu, we're running on the stack in init_thread_union,
443 * which is in the first segment of the linear mapping, and also
444 * get_paca()->kstack hasn't been initialized yet.
445 * For secondary cpus, we need to bolt the kernel stack entry now.
446 */
447 slb_shadow_clear(KSTACK_INDEX);
448 if (raw_smp_processor_id() != boot_cpuid &&
449 (get_paca()->kstack & slb_esid_mask(mmu_kernel_ssize)) > PAGE_OFFSET)
450 create_shadowed_slbe(get_paca()->kstack,
451 mmu_kernel_ssize, lflags, KSTACK_INDEX);
452
453 asm volatile("isync":::"memory");
454 }
455
456 static void insert_slb_entry(unsigned long vsid, unsigned long ea,
457 int bpsize, int ssize)
458 {
459 unsigned long flags, vsid_data, esid_data;
460 enum slb_index index;
461 int slb_cache_index;
462
463 /*
464 * We are irq disabled, hence should be safe to access PACA.
465 */
466 VM_WARN_ON(!irqs_disabled());
467
468 /*
469 * We can't take a PMU exception in the following code, so hard
470 * disable interrupts.
471 */
472 hard_irq_disable();
473
474 index = get_paca()->stab_rr;
475
476 /*
477 * simple round-robin replacement of slb starting at SLB_NUM_BOLTED.
478 */
479 if (index < (mmu_slb_size - 1))
480 index++;
481 else
482 index = SLB_NUM_BOLTED;
483
484 get_paca()->stab_rr = index;
485
486 flags = SLB_VSID_USER | mmu_psize_defs[bpsize].sllp;
487 vsid_data = (vsid << slb_vsid_shift(ssize)) | flags |
488 ((unsigned long) ssize << SLB_VSID_SSIZE_SHIFT);
489 esid_data = mk_esid_data(ea, ssize, index);
490
491 /*
492 * No need for an isync before or after this slbmte. The exception
493 * we enter with and the rfid we exit with are context synchronizing.
494 * Also we only handle user segments here.
495 */
496 asm volatile("slbmte %0, %1" : : "r" (vsid_data), "r" (esid_data)
497 : "memory");
498
499 /*
500 * Now update slb cache entries
501 */
502 slb_cache_index = get_paca()->slb_cache_ptr;
503 if (slb_cache_index < SLB_CACHE_ENTRIES) {
504 /*
505 * We have space in slb cache for optimized switch_slb().
506 * Top 36 bits from esid_data as per ISA
507 */
508 get_paca()->slb_cache[slb_cache_index++] = esid_data >> 28;
509 get_paca()->slb_cache_ptr++;
510 } else {
511 /*
512 * Our cache is full and the current cache content strictly
513 * doesn't indicate the active SLB conents. Bump the ptr
514 * so that switch_slb() will ignore the cache.
515 */
516 get_paca()->slb_cache_ptr = SLB_CACHE_ENTRIES + 1;
517 }
518 }
519
520 static void handle_multi_context_slb_miss(int context_id, unsigned long ea)
521 {
522 struct mm_struct *mm = current->mm;
523 unsigned long vsid;
524 int bpsize;
525
526 /*
527 * We are always above 1TB, hence use high user segment size.
528 */
529 vsid = get_vsid(context_id, ea, mmu_highuser_ssize);
530 bpsize = get_slice_psize(mm, ea);
531 insert_slb_entry(vsid, ea, bpsize, mmu_highuser_ssize);
532 }
533
534 void slb_miss_large_addr(struct pt_regs *regs)
535 {
536 enum ctx_state prev_state = exception_enter();
537 unsigned long ea = regs->dar;
538 int context;
539
540 if (REGION_ID(ea) != USER_REGION_ID)
541 goto slb_bad_addr;
542
543 /*
544 * Are we beyound what the page table layout supports ?
545 */
546 if ((ea & ~REGION_MASK) >= H_PGTABLE_RANGE)
547 goto slb_bad_addr;
548
549 /* Lower address should have been handled by asm code */
550 if (ea < (1UL << MAX_EA_BITS_PER_CONTEXT))
551 goto slb_bad_addr;
552
553 /*
554 * consider this as bad access if we take a SLB miss
555 * on an address above addr limit.
556 */
557 if (ea >= current->mm->context.slb_addr_limit)
558 goto slb_bad_addr;
559
560 context = get_ea_context(&current->mm->context, ea);
561 if (!context)
562 goto slb_bad_addr;
563
564 handle_multi_context_slb_miss(context, ea);
565 exception_exit(prev_state);
566 return;
567
568 slb_bad_addr:
569 if (user_mode(regs))
570 _exception(SIGSEGV, regs, SEGV_BNDERR, ea);
571 else
572 bad_page_fault(regs, ea, SIGSEGV);
573 exception_exit(prev_state);
574 }