1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * PowerPC64 SLB support.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2004 David Gibson <dwg@au.ibm.com>, IBM
6*4882a593Smuzhiyun * Based on earlier code written by:
7*4882a593Smuzhiyun * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
8*4882a593Smuzhiyun * Copyright (c) 2001 Dave Engebretsen
9*4882a593Smuzhiyun * Copyright (C) 2002 Anton Blanchard <anton@au.ibm.com>, IBM
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <asm/asm-prototypes.h>
13*4882a593Smuzhiyun #include <asm/mmu.h>
14*4882a593Smuzhiyun #include <asm/mmu_context.h>
15*4882a593Smuzhiyun #include <asm/paca.h>
16*4882a593Smuzhiyun #include <asm/ppc-opcode.h>
17*4882a593Smuzhiyun #include <asm/cputable.h>
18*4882a593Smuzhiyun #include <asm/cacheflush.h>
19*4882a593Smuzhiyun #include <asm/smp.h>
20*4882a593Smuzhiyun #include <linux/compiler.h>
21*4882a593Smuzhiyun #include <linux/context_tracking.h>
22*4882a593Smuzhiyun #include <linux/mm_types.h>
23*4882a593Smuzhiyun #include <linux/pgtable.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #include <asm/udbg.h>
26*4882a593Smuzhiyun #include <asm/code-patching.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #include "internal.h"
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun enum slb_index {
32*4882a593Smuzhiyun LINEAR_INDEX = 0, /* Kernel linear map (0xc000000000000000) */
33*4882a593Smuzhiyun KSTACK_INDEX = 1, /* Kernel stack map */
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun static long slb_allocate_user(struct mm_struct *mm, unsigned long ea);
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #define slb_esid_mask(ssize) \
39*4882a593Smuzhiyun (((ssize) == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T)
40*4882a593Smuzhiyun
mk_esid_data(unsigned long ea,int ssize,enum slb_index index)41*4882a593Smuzhiyun static inline unsigned long mk_esid_data(unsigned long ea, int ssize,
42*4882a593Smuzhiyun enum slb_index index)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | index;
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun
__mk_vsid_data(unsigned long vsid,int ssize,unsigned long flags)47*4882a593Smuzhiyun static inline unsigned long __mk_vsid_data(unsigned long vsid, int ssize,
48*4882a593Smuzhiyun unsigned long flags)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun return (vsid << slb_vsid_shift(ssize)) | flags |
51*4882a593Smuzhiyun ((unsigned long) ssize << SLB_VSID_SSIZE_SHIFT);
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun
mk_vsid_data(unsigned long ea,int ssize,unsigned long flags)54*4882a593Smuzhiyun static inline unsigned long mk_vsid_data(unsigned long ea, int ssize,
55*4882a593Smuzhiyun unsigned long flags)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun return __mk_vsid_data(get_kernel_vsid(ea, ssize), ssize, flags);
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun bool stress_slb_enabled __initdata;
61*4882a593Smuzhiyun
parse_stress_slb(char * p)62*4882a593Smuzhiyun static int __init parse_stress_slb(char *p)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun stress_slb_enabled = true;
65*4882a593Smuzhiyun return 0;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun early_param("stress_slb", parse_stress_slb);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun __ro_after_init DEFINE_STATIC_KEY_FALSE(stress_slb_key);
70*4882a593Smuzhiyun
assert_slb_presence(bool present,unsigned long ea)71*4882a593Smuzhiyun static void assert_slb_presence(bool present, unsigned long ea)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_VM
74*4882a593Smuzhiyun unsigned long tmp;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun WARN_ON_ONCE(mfmsr() & MSR_EE);
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun if (!cpu_has_feature(CPU_FTR_ARCH_206))
79*4882a593Smuzhiyun return;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /*
82*4882a593Smuzhiyun * slbfee. requires bit 24 (PPC bit 39) be clear in RB. Hardware
83*4882a593Smuzhiyun * ignores all other bits from 0-27, so just clear them all.
84*4882a593Smuzhiyun */
85*4882a593Smuzhiyun ea &= ~((1UL << SID_SHIFT) - 1);
86*4882a593Smuzhiyun asm volatile(__PPC_SLBFEE_DOT(%0, %1) : "=r"(tmp) : "r"(ea) : "cr0");
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun WARN_ON(present == (tmp == 0));
89*4882a593Smuzhiyun #endif
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun
slb_shadow_update(unsigned long ea,int ssize,unsigned long flags,enum slb_index index)92*4882a593Smuzhiyun static inline void slb_shadow_update(unsigned long ea, int ssize,
93*4882a593Smuzhiyun unsigned long flags,
94*4882a593Smuzhiyun enum slb_index index)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun struct slb_shadow *p = get_slb_shadow();
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /*
99*4882a593Smuzhiyun * Clear the ESID first so the entry is not valid while we are
100*4882a593Smuzhiyun * updating it. No write barriers are needed here, provided
101*4882a593Smuzhiyun * we only update the current CPU's SLB shadow buffer.
102*4882a593Smuzhiyun */
103*4882a593Smuzhiyun WRITE_ONCE(p->save_area[index].esid, 0);
104*4882a593Smuzhiyun WRITE_ONCE(p->save_area[index].vsid, cpu_to_be64(mk_vsid_data(ea, ssize, flags)));
105*4882a593Smuzhiyun WRITE_ONCE(p->save_area[index].esid, cpu_to_be64(mk_esid_data(ea, ssize, index)));
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
slb_shadow_clear(enum slb_index index)108*4882a593Smuzhiyun static inline void slb_shadow_clear(enum slb_index index)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun WRITE_ONCE(get_slb_shadow()->save_area[index].esid, cpu_to_be64(index));
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
create_shadowed_slbe(unsigned long ea,int ssize,unsigned long flags,enum slb_index index)113*4882a593Smuzhiyun static inline void create_shadowed_slbe(unsigned long ea, int ssize,
114*4882a593Smuzhiyun unsigned long flags,
115*4882a593Smuzhiyun enum slb_index index)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun /*
118*4882a593Smuzhiyun * Updating the shadow buffer before writing the SLB ensures
119*4882a593Smuzhiyun * we don't get a stale entry here if we get preempted by PHYP
120*4882a593Smuzhiyun * between these two statements.
121*4882a593Smuzhiyun */
122*4882a593Smuzhiyun slb_shadow_update(ea, ssize, flags, index);
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun assert_slb_presence(false, ea);
125*4882a593Smuzhiyun asm volatile("slbmte %0,%1" :
126*4882a593Smuzhiyun : "r" (mk_vsid_data(ea, ssize, flags)),
127*4882a593Smuzhiyun "r" (mk_esid_data(ea, ssize, index))
128*4882a593Smuzhiyun : "memory" );
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /*
132*4882a593Smuzhiyun * Insert bolted entries into SLB (which may not be empty, so don't clear
133*4882a593Smuzhiyun * slb_cache_ptr).
134*4882a593Smuzhiyun */
__slb_restore_bolted_realmode(void)135*4882a593Smuzhiyun void __slb_restore_bolted_realmode(void)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun struct slb_shadow *p = get_slb_shadow();
138*4882a593Smuzhiyun enum slb_index index;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun /* No isync needed because realmode. */
141*4882a593Smuzhiyun for (index = 0; index < SLB_NUM_BOLTED; index++) {
142*4882a593Smuzhiyun asm volatile("slbmte %0,%1" :
143*4882a593Smuzhiyun : "r" (be64_to_cpu(p->save_area[index].vsid)),
144*4882a593Smuzhiyun "r" (be64_to_cpu(p->save_area[index].esid)));
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun assert_slb_presence(true, local_paca->kstack);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun /*
151*4882a593Smuzhiyun * Insert the bolted entries into an empty SLB.
152*4882a593Smuzhiyun */
slb_restore_bolted_realmode(void)153*4882a593Smuzhiyun void slb_restore_bolted_realmode(void)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun __slb_restore_bolted_realmode();
156*4882a593Smuzhiyun get_paca()->slb_cache_ptr = 0;
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun get_paca()->slb_kern_bitmap = (1U << SLB_NUM_BOLTED) - 1;
159*4882a593Smuzhiyun get_paca()->slb_used_bitmap = get_paca()->slb_kern_bitmap;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun /*
163*4882a593Smuzhiyun * This flushes all SLB entries including 0, so it must be realmode.
164*4882a593Smuzhiyun */
slb_flush_all_realmode(void)165*4882a593Smuzhiyun void slb_flush_all_realmode(void)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun asm volatile("slbmte %0,%0; slbia" : : "r" (0));
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
__slb_flush_and_restore_bolted(bool preserve_kernel_lookaside)170*4882a593Smuzhiyun static __always_inline void __slb_flush_and_restore_bolted(bool preserve_kernel_lookaside)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun struct slb_shadow *p = get_slb_shadow();
173*4882a593Smuzhiyun unsigned long ksp_esid_data, ksp_vsid_data;
174*4882a593Smuzhiyun u32 ih;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /*
177*4882a593Smuzhiyun * SLBIA IH=1 on ISA v2.05 and newer processors may preserve lookaside
178*4882a593Smuzhiyun * information created with Class=0 entries, which we use for kernel
179*4882a593Smuzhiyun * SLB entries (the SLB entries themselves are still invalidated).
180*4882a593Smuzhiyun *
181*4882a593Smuzhiyun * Older processors will ignore this optimisation. Over-invalidation
182*4882a593Smuzhiyun * is fine because we never rely on lookaside information existing.
183*4882a593Smuzhiyun */
184*4882a593Smuzhiyun if (preserve_kernel_lookaside)
185*4882a593Smuzhiyun ih = 1;
186*4882a593Smuzhiyun else
187*4882a593Smuzhiyun ih = 0;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun ksp_esid_data = be64_to_cpu(p->save_area[KSTACK_INDEX].esid);
190*4882a593Smuzhiyun ksp_vsid_data = be64_to_cpu(p->save_area[KSTACK_INDEX].vsid);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun asm volatile(PPC_SLBIA(%0)" \n"
193*4882a593Smuzhiyun "slbmte %1, %2 \n"
194*4882a593Smuzhiyun :: "i" (ih),
195*4882a593Smuzhiyun "r" (ksp_vsid_data),
196*4882a593Smuzhiyun "r" (ksp_esid_data)
197*4882a593Smuzhiyun : "memory");
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun /*
201*4882a593Smuzhiyun * This flushes non-bolted entries, it can be run in virtual mode. Must
202*4882a593Smuzhiyun * be called with interrupts disabled.
203*4882a593Smuzhiyun */
slb_flush_and_restore_bolted(void)204*4882a593Smuzhiyun void slb_flush_and_restore_bolted(void)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun BUILD_BUG_ON(SLB_NUM_BOLTED != 2);
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun WARN_ON(!irqs_disabled());
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun /*
211*4882a593Smuzhiyun * We can't take a PMU exception in the following code, so hard
212*4882a593Smuzhiyun * disable interrupts.
213*4882a593Smuzhiyun */
214*4882a593Smuzhiyun hard_irq_disable();
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun isync();
217*4882a593Smuzhiyun __slb_flush_and_restore_bolted(false);
218*4882a593Smuzhiyun isync();
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun assert_slb_presence(true, get_paca()->kstack);
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun get_paca()->slb_cache_ptr = 0;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun get_paca()->slb_kern_bitmap = (1U << SLB_NUM_BOLTED) - 1;
225*4882a593Smuzhiyun get_paca()->slb_used_bitmap = get_paca()->slb_kern_bitmap;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
slb_save_contents(struct slb_entry * slb_ptr)228*4882a593Smuzhiyun void slb_save_contents(struct slb_entry *slb_ptr)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun int i;
231*4882a593Smuzhiyun unsigned long e, v;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /* Save slb_cache_ptr value. */
234*4882a593Smuzhiyun get_paca()->slb_save_cache_ptr = get_paca()->slb_cache_ptr;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun if (!slb_ptr)
237*4882a593Smuzhiyun return;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun for (i = 0; i < mmu_slb_size; i++) {
240*4882a593Smuzhiyun asm volatile("slbmfee %0,%1" : "=r" (e) : "r" (i));
241*4882a593Smuzhiyun asm volatile("slbmfev %0,%1" : "=r" (v) : "r" (i));
242*4882a593Smuzhiyun slb_ptr->esid = e;
243*4882a593Smuzhiyun slb_ptr->vsid = v;
244*4882a593Smuzhiyun slb_ptr++;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
slb_dump_contents(struct slb_entry * slb_ptr)248*4882a593Smuzhiyun void slb_dump_contents(struct slb_entry *slb_ptr)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun int i, n;
251*4882a593Smuzhiyun unsigned long e, v;
252*4882a593Smuzhiyun unsigned long llp;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun if (!slb_ptr)
255*4882a593Smuzhiyun return;
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun pr_err("SLB contents of cpu 0x%x\n", smp_processor_id());
258*4882a593Smuzhiyun pr_err("Last SLB entry inserted at slot %d\n", get_paca()->stab_rr);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun for (i = 0; i < mmu_slb_size; i++) {
261*4882a593Smuzhiyun e = slb_ptr->esid;
262*4882a593Smuzhiyun v = slb_ptr->vsid;
263*4882a593Smuzhiyun slb_ptr++;
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun if (!e && !v)
266*4882a593Smuzhiyun continue;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun pr_err("%02d %016lx %016lx\n", i, e, v);
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun if (!(e & SLB_ESID_V)) {
271*4882a593Smuzhiyun pr_err("\n");
272*4882a593Smuzhiyun continue;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun llp = v & SLB_VSID_LLP;
275*4882a593Smuzhiyun if (v & SLB_VSID_B_1T) {
276*4882a593Smuzhiyun pr_err(" 1T ESID=%9lx VSID=%13lx LLP:%3lx\n",
277*4882a593Smuzhiyun GET_ESID_1T(e),
278*4882a593Smuzhiyun (v & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T, llp);
279*4882a593Smuzhiyun } else {
280*4882a593Smuzhiyun pr_err(" 256M ESID=%9lx VSID=%13lx LLP:%3lx\n",
281*4882a593Smuzhiyun GET_ESID(e),
282*4882a593Smuzhiyun (v & ~SLB_VSID_B) >> SLB_VSID_SHIFT, llp);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun pr_err("----------------------------------\n");
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun /* Dump slb cache entires as well. */
288*4882a593Smuzhiyun pr_err("SLB cache ptr value = %d\n", get_paca()->slb_save_cache_ptr);
289*4882a593Smuzhiyun pr_err("Valid SLB cache entries:\n");
290*4882a593Smuzhiyun n = min_t(int, get_paca()->slb_save_cache_ptr, SLB_CACHE_ENTRIES);
291*4882a593Smuzhiyun for (i = 0; i < n; i++)
292*4882a593Smuzhiyun pr_err("%02d EA[0-35]=%9x\n", i, get_paca()->slb_cache[i]);
293*4882a593Smuzhiyun pr_err("Rest of SLB cache entries:\n");
294*4882a593Smuzhiyun for (i = n; i < SLB_CACHE_ENTRIES; i++)
295*4882a593Smuzhiyun pr_err("%02d EA[0-35]=%9x\n", i, get_paca()->slb_cache[i]);
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
slb_vmalloc_update(void)298*4882a593Smuzhiyun void slb_vmalloc_update(void)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun /*
301*4882a593Smuzhiyun * vmalloc is not bolted, so just have to flush non-bolted.
302*4882a593Smuzhiyun */
303*4882a593Smuzhiyun slb_flush_and_restore_bolted();
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
preload_hit(struct thread_info * ti,unsigned long esid)306*4882a593Smuzhiyun static bool preload_hit(struct thread_info *ti, unsigned long esid)
307*4882a593Smuzhiyun {
308*4882a593Smuzhiyun unsigned char i;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun for (i = 0; i < ti->slb_preload_nr; i++) {
311*4882a593Smuzhiyun unsigned char idx;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun idx = (ti->slb_preload_tail + i) % SLB_PRELOAD_NR;
314*4882a593Smuzhiyun if (esid == ti->slb_preload_esid[idx])
315*4882a593Smuzhiyun return true;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun return false;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun
preload_add(struct thread_info * ti,unsigned long ea)320*4882a593Smuzhiyun static bool preload_add(struct thread_info *ti, unsigned long ea)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun unsigned char idx;
323*4882a593Smuzhiyun unsigned long esid;
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) {
326*4882a593Smuzhiyun /* EAs are stored >> 28 so 256MB segments don't need clearing */
327*4882a593Smuzhiyun if (ea & ESID_MASK_1T)
328*4882a593Smuzhiyun ea &= ESID_MASK_1T;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun esid = ea >> SID_SHIFT;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun if (preload_hit(ti, esid))
334*4882a593Smuzhiyun return false;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun idx = (ti->slb_preload_tail + ti->slb_preload_nr) % SLB_PRELOAD_NR;
337*4882a593Smuzhiyun ti->slb_preload_esid[idx] = esid;
338*4882a593Smuzhiyun if (ti->slb_preload_nr == SLB_PRELOAD_NR)
339*4882a593Smuzhiyun ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR;
340*4882a593Smuzhiyun else
341*4882a593Smuzhiyun ti->slb_preload_nr++;
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun return true;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun
preload_age(struct thread_info * ti)346*4882a593Smuzhiyun static void preload_age(struct thread_info *ti)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun if (!ti->slb_preload_nr)
349*4882a593Smuzhiyun return;
350*4882a593Smuzhiyun ti->slb_preload_nr--;
351*4882a593Smuzhiyun ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
slb_setup_new_exec(void)354*4882a593Smuzhiyun void slb_setup_new_exec(void)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun struct thread_info *ti = current_thread_info();
357*4882a593Smuzhiyun struct mm_struct *mm = current->mm;
358*4882a593Smuzhiyun unsigned long exec = 0x10000000;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun WARN_ON(irqs_disabled());
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun /*
363*4882a593Smuzhiyun * preload cache can only be used to determine whether a SLB
364*4882a593Smuzhiyun * entry exists if it does not start to overflow.
365*4882a593Smuzhiyun */
366*4882a593Smuzhiyun if (ti->slb_preload_nr + 2 > SLB_PRELOAD_NR)
367*4882a593Smuzhiyun return;
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun hard_irq_disable();
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun /*
372*4882a593Smuzhiyun * We have no good place to clear the slb preload cache on exec,
373*4882a593Smuzhiyun * flush_thread is about the earliest arch hook but that happens
374*4882a593Smuzhiyun * after we switch to the mm and have aleady preloaded the SLBEs.
375*4882a593Smuzhiyun *
376*4882a593Smuzhiyun * For the most part that's probably okay to use entries from the
377*4882a593Smuzhiyun * previous exec, they will age out if unused. It may turn out to
378*4882a593Smuzhiyun * be an advantage to clear the cache before switching to it,
379*4882a593Smuzhiyun * however.
380*4882a593Smuzhiyun */
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun /*
383*4882a593Smuzhiyun * preload some userspace segments into the SLB.
384*4882a593Smuzhiyun * Almost all 32 and 64bit PowerPC executables are linked at
385*4882a593Smuzhiyun * 0x10000000 so it makes sense to preload this segment.
386*4882a593Smuzhiyun */
387*4882a593Smuzhiyun if (!is_kernel_addr(exec)) {
388*4882a593Smuzhiyun if (preload_add(ti, exec))
389*4882a593Smuzhiyun slb_allocate_user(mm, exec);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /* Libraries and mmaps. */
393*4882a593Smuzhiyun if (!is_kernel_addr(mm->mmap_base)) {
394*4882a593Smuzhiyun if (preload_add(ti, mm->mmap_base))
395*4882a593Smuzhiyun slb_allocate_user(mm, mm->mmap_base);
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun /* see switch_slb */
399*4882a593Smuzhiyun asm volatile("isync" : : : "memory");
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun local_irq_enable();
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
preload_new_slb_context(unsigned long start,unsigned long sp)404*4882a593Smuzhiyun void preload_new_slb_context(unsigned long start, unsigned long sp)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun struct thread_info *ti = current_thread_info();
407*4882a593Smuzhiyun struct mm_struct *mm = current->mm;
408*4882a593Smuzhiyun unsigned long heap = mm->start_brk;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun WARN_ON(irqs_disabled());
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun /* see above */
413*4882a593Smuzhiyun if (ti->slb_preload_nr + 3 > SLB_PRELOAD_NR)
414*4882a593Smuzhiyun return;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun hard_irq_disable();
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun /* Userspace entry address. */
419*4882a593Smuzhiyun if (!is_kernel_addr(start)) {
420*4882a593Smuzhiyun if (preload_add(ti, start))
421*4882a593Smuzhiyun slb_allocate_user(mm, start);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun /* Top of stack, grows down. */
425*4882a593Smuzhiyun if (!is_kernel_addr(sp)) {
426*4882a593Smuzhiyun if (preload_add(ti, sp))
427*4882a593Smuzhiyun slb_allocate_user(mm, sp);
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun /* Bottom of heap, grows up. */
431*4882a593Smuzhiyun if (heap && !is_kernel_addr(heap)) {
432*4882a593Smuzhiyun if (preload_add(ti, heap))
433*4882a593Smuzhiyun slb_allocate_user(mm, heap);
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun /* see switch_slb */
437*4882a593Smuzhiyun asm volatile("isync" : : : "memory");
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun local_irq_enable();
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun
slb_cache_slbie_kernel(unsigned int index)442*4882a593Smuzhiyun static void slb_cache_slbie_kernel(unsigned int index)
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun unsigned long slbie_data = get_paca()->slb_cache[index];
445*4882a593Smuzhiyun unsigned long ksp = get_paca()->kstack;
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun slbie_data <<= SID_SHIFT;
448*4882a593Smuzhiyun slbie_data |= 0xc000000000000000ULL;
449*4882a593Smuzhiyun if ((ksp & slb_esid_mask(mmu_kernel_ssize)) == slbie_data)
450*4882a593Smuzhiyun return;
451*4882a593Smuzhiyun slbie_data |= mmu_kernel_ssize << SLBIE_SSIZE_SHIFT;
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun asm volatile("slbie %0" : : "r" (slbie_data));
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun
slb_cache_slbie_user(unsigned int index)456*4882a593Smuzhiyun static void slb_cache_slbie_user(unsigned int index)
457*4882a593Smuzhiyun {
458*4882a593Smuzhiyun unsigned long slbie_data = get_paca()->slb_cache[index];
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun slbie_data <<= SID_SHIFT;
461*4882a593Smuzhiyun slbie_data |= user_segment_size(slbie_data) << SLBIE_SSIZE_SHIFT;
462*4882a593Smuzhiyun slbie_data |= SLBIE_C; /* user slbs have C=1 */
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun asm volatile("slbie %0" : : "r" (slbie_data));
465*4882a593Smuzhiyun }
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun /* Flush all user entries from the segment table of the current processor. */
switch_slb(struct task_struct * tsk,struct mm_struct * mm)468*4882a593Smuzhiyun void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun struct thread_info *ti = task_thread_info(tsk);
471*4882a593Smuzhiyun unsigned char i;
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun /*
474*4882a593Smuzhiyun * We need interrupts hard-disabled here, not just soft-disabled,
475*4882a593Smuzhiyun * so that a PMU interrupt can't occur, which might try to access
476*4882a593Smuzhiyun * user memory (to get a stack trace) and possible cause an SLB miss
477*4882a593Smuzhiyun * which would update the slb_cache/slb_cache_ptr fields in the PACA.
478*4882a593Smuzhiyun */
479*4882a593Smuzhiyun hard_irq_disable();
480*4882a593Smuzhiyun isync();
481*4882a593Smuzhiyun if (stress_slb()) {
482*4882a593Smuzhiyun __slb_flush_and_restore_bolted(false);
483*4882a593Smuzhiyun isync();
484*4882a593Smuzhiyun get_paca()->slb_cache_ptr = 0;
485*4882a593Smuzhiyun get_paca()->slb_kern_bitmap = (1U << SLB_NUM_BOLTED) - 1;
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun } else if (cpu_has_feature(CPU_FTR_ARCH_300)) {
488*4882a593Smuzhiyun /*
489*4882a593Smuzhiyun * SLBIA IH=3 invalidates all Class=1 SLBEs and their
490*4882a593Smuzhiyun * associated lookaside structures, which matches what
491*4882a593Smuzhiyun * switch_slb wants. So ARCH_300 does not use the slb
492*4882a593Smuzhiyun * cache.
493*4882a593Smuzhiyun */
494*4882a593Smuzhiyun asm volatile(PPC_SLBIA(3));
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun } else {
497*4882a593Smuzhiyun unsigned long offset = get_paca()->slb_cache_ptr;
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun if (!mmu_has_feature(MMU_FTR_NO_SLBIE_B) &&
500*4882a593Smuzhiyun offset <= SLB_CACHE_ENTRIES) {
501*4882a593Smuzhiyun /*
502*4882a593Smuzhiyun * Could assert_slb_presence(true) here, but
503*4882a593Smuzhiyun * hypervisor or machine check could have come
504*4882a593Smuzhiyun * in and removed the entry at this point.
505*4882a593Smuzhiyun */
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun for (i = 0; i < offset; i++)
508*4882a593Smuzhiyun slb_cache_slbie_user(i);
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun /* Workaround POWER5 < DD2.1 issue */
511*4882a593Smuzhiyun if (!cpu_has_feature(CPU_FTR_ARCH_207S) && offset == 1)
512*4882a593Smuzhiyun slb_cache_slbie_user(0);
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun } else {
515*4882a593Smuzhiyun /* Flush but retain kernel lookaside information */
516*4882a593Smuzhiyun __slb_flush_and_restore_bolted(true);
517*4882a593Smuzhiyun isync();
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun get_paca()->slb_kern_bitmap = (1U << SLB_NUM_BOLTED) - 1;
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun get_paca()->slb_cache_ptr = 0;
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun get_paca()->slb_used_bitmap = get_paca()->slb_kern_bitmap;
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun copy_mm_to_paca(mm);
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun /*
529*4882a593Smuzhiyun * We gradually age out SLBs after a number of context switches to
530*4882a593Smuzhiyun * reduce reload overhead of unused entries (like we do with FP/VEC
531*4882a593Smuzhiyun * reload). Each time we wrap 256 switches, take an entry out of the
532*4882a593Smuzhiyun * SLB preload cache.
533*4882a593Smuzhiyun */
534*4882a593Smuzhiyun tsk->thread.load_slb++;
535*4882a593Smuzhiyun if (!tsk->thread.load_slb) {
536*4882a593Smuzhiyun unsigned long pc = KSTK_EIP(tsk);
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun preload_age(ti);
539*4882a593Smuzhiyun preload_add(ti, pc);
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun for (i = 0; i < ti->slb_preload_nr; i++) {
543*4882a593Smuzhiyun unsigned char idx;
544*4882a593Smuzhiyun unsigned long ea;
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun idx = (ti->slb_preload_tail + i) % SLB_PRELOAD_NR;
547*4882a593Smuzhiyun ea = (unsigned long)ti->slb_preload_esid[idx] << SID_SHIFT;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun slb_allocate_user(mm, ea);
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun /*
553*4882a593Smuzhiyun * Synchronize slbmte preloads with possible subsequent user memory
554*4882a593Smuzhiyun * address accesses by the kernel (user mode won't happen until
555*4882a593Smuzhiyun * rfid, which is safe).
556*4882a593Smuzhiyun */
557*4882a593Smuzhiyun isync();
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
slb_set_size(u16 size)560*4882a593Smuzhiyun void slb_set_size(u16 size)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun mmu_slb_size = size;
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun
slb_initialize(void)565*4882a593Smuzhiyun void slb_initialize(void)
566*4882a593Smuzhiyun {
567*4882a593Smuzhiyun unsigned long linear_llp, vmalloc_llp, io_llp;
568*4882a593Smuzhiyun unsigned long lflags;
569*4882a593Smuzhiyun static int slb_encoding_inited;
570*4882a593Smuzhiyun #ifdef CONFIG_SPARSEMEM_VMEMMAP
571*4882a593Smuzhiyun unsigned long vmemmap_llp;
572*4882a593Smuzhiyun #endif
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun /* Prepare our SLB miss handler based on our page size */
575*4882a593Smuzhiyun linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
576*4882a593Smuzhiyun io_llp = mmu_psize_defs[mmu_io_psize].sllp;
577*4882a593Smuzhiyun vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp;
578*4882a593Smuzhiyun get_paca()->vmalloc_sllp = SLB_VSID_KERNEL | vmalloc_llp;
579*4882a593Smuzhiyun #ifdef CONFIG_SPARSEMEM_VMEMMAP
580*4882a593Smuzhiyun vmemmap_llp = mmu_psize_defs[mmu_vmemmap_psize].sllp;
581*4882a593Smuzhiyun #endif
582*4882a593Smuzhiyun if (!slb_encoding_inited) {
583*4882a593Smuzhiyun slb_encoding_inited = 1;
584*4882a593Smuzhiyun pr_devel("SLB: linear LLP = %04lx\n", linear_llp);
585*4882a593Smuzhiyun pr_devel("SLB: io LLP = %04lx\n", io_llp);
586*4882a593Smuzhiyun #ifdef CONFIG_SPARSEMEM_VMEMMAP
587*4882a593Smuzhiyun pr_devel("SLB: vmemmap LLP = %04lx\n", vmemmap_llp);
588*4882a593Smuzhiyun #endif
589*4882a593Smuzhiyun }
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun get_paca()->stab_rr = SLB_NUM_BOLTED - 1;
592*4882a593Smuzhiyun get_paca()->slb_kern_bitmap = (1U << SLB_NUM_BOLTED) - 1;
593*4882a593Smuzhiyun get_paca()->slb_used_bitmap = get_paca()->slb_kern_bitmap;
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun lflags = SLB_VSID_KERNEL | linear_llp;
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun /* Invalidate the entire SLB (even entry 0) & all the ERATS */
598*4882a593Smuzhiyun asm volatile("isync":::"memory");
599*4882a593Smuzhiyun asm volatile("slbmte %0,%0"::"r" (0) : "memory");
600*4882a593Smuzhiyun asm volatile("isync; slbia; isync":::"memory");
601*4882a593Smuzhiyun create_shadowed_slbe(PAGE_OFFSET, mmu_kernel_ssize, lflags, LINEAR_INDEX);
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun /*
604*4882a593Smuzhiyun * For the boot cpu, we're running on the stack in init_thread_union,
605*4882a593Smuzhiyun * which is in the first segment of the linear mapping, and also
606*4882a593Smuzhiyun * get_paca()->kstack hasn't been initialized yet.
607*4882a593Smuzhiyun * For secondary cpus, we need to bolt the kernel stack entry now.
608*4882a593Smuzhiyun */
609*4882a593Smuzhiyun slb_shadow_clear(KSTACK_INDEX);
610*4882a593Smuzhiyun if (raw_smp_processor_id() != boot_cpuid &&
611*4882a593Smuzhiyun (get_paca()->kstack & slb_esid_mask(mmu_kernel_ssize)) > PAGE_OFFSET)
612*4882a593Smuzhiyun create_shadowed_slbe(get_paca()->kstack,
613*4882a593Smuzhiyun mmu_kernel_ssize, lflags, KSTACK_INDEX);
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun asm volatile("isync":::"memory");
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun
slb_cache_update(unsigned long esid_data)618*4882a593Smuzhiyun static void slb_cache_update(unsigned long esid_data)
619*4882a593Smuzhiyun {
620*4882a593Smuzhiyun int slb_cache_index;
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun if (cpu_has_feature(CPU_FTR_ARCH_300))
623*4882a593Smuzhiyun return; /* ISAv3.0B and later does not use slb_cache */
624*4882a593Smuzhiyun
625*4882a593Smuzhiyun if (stress_slb())
626*4882a593Smuzhiyun return;
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun /*
629*4882a593Smuzhiyun * Now update slb cache entries
630*4882a593Smuzhiyun */
631*4882a593Smuzhiyun slb_cache_index = local_paca->slb_cache_ptr;
632*4882a593Smuzhiyun if (slb_cache_index < SLB_CACHE_ENTRIES) {
633*4882a593Smuzhiyun /*
634*4882a593Smuzhiyun * We have space in slb cache for optimized switch_slb().
635*4882a593Smuzhiyun * Top 36 bits from esid_data as per ISA
636*4882a593Smuzhiyun */
637*4882a593Smuzhiyun local_paca->slb_cache[slb_cache_index++] = esid_data >> SID_SHIFT;
638*4882a593Smuzhiyun local_paca->slb_cache_ptr++;
639*4882a593Smuzhiyun } else {
640*4882a593Smuzhiyun /*
641*4882a593Smuzhiyun * Our cache is full and the current cache content strictly
642*4882a593Smuzhiyun * doesn't indicate the active SLB conents. Bump the ptr
643*4882a593Smuzhiyun * so that switch_slb() will ignore the cache.
644*4882a593Smuzhiyun */
645*4882a593Smuzhiyun local_paca->slb_cache_ptr = SLB_CACHE_ENTRIES + 1;
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun
alloc_slb_index(bool kernel)649*4882a593Smuzhiyun static enum slb_index alloc_slb_index(bool kernel)
650*4882a593Smuzhiyun {
651*4882a593Smuzhiyun enum slb_index index;
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun /*
654*4882a593Smuzhiyun * The allocation bitmaps can become out of synch with the SLB
655*4882a593Smuzhiyun * when the _switch code does slbie when bolting a new stack
656*4882a593Smuzhiyun * segment and it must not be anywhere else in the SLB. This leaves
657*4882a593Smuzhiyun * a kernel allocated entry that is unused in the SLB. With very
658*4882a593Smuzhiyun * large systems or small segment sizes, the bitmaps could slowly
659*4882a593Smuzhiyun * fill with these entries. They will eventually be cleared out
660*4882a593Smuzhiyun * by the round robin allocator in that case, so it's probably not
661*4882a593Smuzhiyun * worth accounting for.
662*4882a593Smuzhiyun */
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun /*
665*4882a593Smuzhiyun * SLBs beyond 32 entries are allocated with stab_rr only
666*4882a593Smuzhiyun * POWER7/8/9 have 32 SLB entries, this could be expanded if a
667*4882a593Smuzhiyun * future CPU has more.
668*4882a593Smuzhiyun */
669*4882a593Smuzhiyun if (local_paca->slb_used_bitmap != U32_MAX) {
670*4882a593Smuzhiyun index = ffz(local_paca->slb_used_bitmap);
671*4882a593Smuzhiyun local_paca->slb_used_bitmap |= 1U << index;
672*4882a593Smuzhiyun if (kernel)
673*4882a593Smuzhiyun local_paca->slb_kern_bitmap |= 1U << index;
674*4882a593Smuzhiyun } else {
675*4882a593Smuzhiyun /* round-robin replacement of slb starting at SLB_NUM_BOLTED. */
676*4882a593Smuzhiyun index = local_paca->stab_rr;
677*4882a593Smuzhiyun if (index < (mmu_slb_size - 1))
678*4882a593Smuzhiyun index++;
679*4882a593Smuzhiyun else
680*4882a593Smuzhiyun index = SLB_NUM_BOLTED;
681*4882a593Smuzhiyun local_paca->stab_rr = index;
682*4882a593Smuzhiyun if (index < 32) {
683*4882a593Smuzhiyun if (kernel)
684*4882a593Smuzhiyun local_paca->slb_kern_bitmap |= 1U << index;
685*4882a593Smuzhiyun else
686*4882a593Smuzhiyun local_paca->slb_kern_bitmap &= ~(1U << index);
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun BUG_ON(index < SLB_NUM_BOLTED);
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun return index;
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun
slb_insert_entry(unsigned long ea,unsigned long context,unsigned long flags,int ssize,bool kernel)694*4882a593Smuzhiyun static long slb_insert_entry(unsigned long ea, unsigned long context,
695*4882a593Smuzhiyun unsigned long flags, int ssize, bool kernel)
696*4882a593Smuzhiyun {
697*4882a593Smuzhiyun unsigned long vsid;
698*4882a593Smuzhiyun unsigned long vsid_data, esid_data;
699*4882a593Smuzhiyun enum slb_index index;
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun vsid = get_vsid(context, ea, ssize);
702*4882a593Smuzhiyun if (!vsid)
703*4882a593Smuzhiyun return -EFAULT;
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun /*
706*4882a593Smuzhiyun * There must not be a kernel SLB fault in alloc_slb_index or before
707*4882a593Smuzhiyun * slbmte here or the allocation bitmaps could get out of whack with
708*4882a593Smuzhiyun * the SLB.
709*4882a593Smuzhiyun *
710*4882a593Smuzhiyun * User SLB faults or preloads take this path which might get inlined
711*4882a593Smuzhiyun * into the caller, so add compiler barriers here to ensure unsafe
712*4882a593Smuzhiyun * memory accesses do not come between.
713*4882a593Smuzhiyun */
714*4882a593Smuzhiyun barrier();
715*4882a593Smuzhiyun
716*4882a593Smuzhiyun index = alloc_slb_index(kernel);
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun vsid_data = __mk_vsid_data(vsid, ssize, flags);
719*4882a593Smuzhiyun esid_data = mk_esid_data(ea, ssize, index);
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun /*
722*4882a593Smuzhiyun * No need for an isync before or after this slbmte. The exception
723*4882a593Smuzhiyun * we enter with and the rfid we exit with are context synchronizing.
724*4882a593Smuzhiyun * User preloads should add isync afterwards in case the kernel
725*4882a593Smuzhiyun * accesses user memory before it returns to userspace with rfid.
726*4882a593Smuzhiyun */
727*4882a593Smuzhiyun assert_slb_presence(false, ea);
728*4882a593Smuzhiyun if (stress_slb()) {
729*4882a593Smuzhiyun int slb_cache_index = local_paca->slb_cache_ptr;
730*4882a593Smuzhiyun
731*4882a593Smuzhiyun /*
732*4882a593Smuzhiyun * stress_slb() does not use slb cache, repurpose as a
733*4882a593Smuzhiyun * cache of inserted (non-bolted) kernel SLB entries. All
734*4882a593Smuzhiyun * non-bolted kernel entries are flushed on any user fault,
735*4882a593Smuzhiyun * or if there are already 3 non-boled kernel entries.
736*4882a593Smuzhiyun */
737*4882a593Smuzhiyun BUILD_BUG_ON(SLB_CACHE_ENTRIES < 3);
738*4882a593Smuzhiyun if (!kernel || slb_cache_index == 3) {
739*4882a593Smuzhiyun int i;
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun for (i = 0; i < slb_cache_index; i++)
742*4882a593Smuzhiyun slb_cache_slbie_kernel(i);
743*4882a593Smuzhiyun slb_cache_index = 0;
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun if (kernel)
747*4882a593Smuzhiyun local_paca->slb_cache[slb_cache_index++] = esid_data >> SID_SHIFT;
748*4882a593Smuzhiyun local_paca->slb_cache_ptr = slb_cache_index;
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun asm volatile("slbmte %0, %1" : : "r" (vsid_data), "r" (esid_data));
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun barrier();
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun if (!kernel)
755*4882a593Smuzhiyun slb_cache_update(esid_data);
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun return 0;
758*4882a593Smuzhiyun }
759*4882a593Smuzhiyun
slb_allocate_kernel(unsigned long ea,unsigned long id)760*4882a593Smuzhiyun static long slb_allocate_kernel(unsigned long ea, unsigned long id)
761*4882a593Smuzhiyun {
762*4882a593Smuzhiyun unsigned long context;
763*4882a593Smuzhiyun unsigned long flags;
764*4882a593Smuzhiyun int ssize;
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun if (id == LINEAR_MAP_REGION_ID) {
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun /* We only support upto H_MAX_PHYSMEM_BITS */
769*4882a593Smuzhiyun if ((ea & EA_MASK) > (1UL << H_MAX_PHYSMEM_BITS))
770*4882a593Smuzhiyun return -EFAULT;
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_linear_psize].sllp;
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun #ifdef CONFIG_SPARSEMEM_VMEMMAP
775*4882a593Smuzhiyun } else if (id == VMEMMAP_REGION_ID) {
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun if (ea >= H_VMEMMAP_END)
778*4882a593Smuzhiyun return -EFAULT;
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_vmemmap_psize].sllp;
781*4882a593Smuzhiyun #endif
782*4882a593Smuzhiyun } else if (id == VMALLOC_REGION_ID) {
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun if (ea >= H_VMALLOC_END)
785*4882a593Smuzhiyun return -EFAULT;
786*4882a593Smuzhiyun
787*4882a593Smuzhiyun flags = local_paca->vmalloc_sllp;
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun } else if (id == IO_REGION_ID) {
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun if (ea >= H_KERN_IO_END)
792*4882a593Smuzhiyun return -EFAULT;
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_io_psize].sllp;
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun } else {
797*4882a593Smuzhiyun return -EFAULT;
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun ssize = MMU_SEGSIZE_1T;
801*4882a593Smuzhiyun if (!mmu_has_feature(MMU_FTR_1T_SEGMENT))
802*4882a593Smuzhiyun ssize = MMU_SEGSIZE_256M;
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun context = get_kernel_context(ea);
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun return slb_insert_entry(ea, context, flags, ssize, true);
807*4882a593Smuzhiyun }
808*4882a593Smuzhiyun
slb_allocate_user(struct mm_struct * mm,unsigned long ea)809*4882a593Smuzhiyun static long slb_allocate_user(struct mm_struct *mm, unsigned long ea)
810*4882a593Smuzhiyun {
811*4882a593Smuzhiyun unsigned long context;
812*4882a593Smuzhiyun unsigned long flags;
813*4882a593Smuzhiyun int bpsize;
814*4882a593Smuzhiyun int ssize;
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun /*
817*4882a593Smuzhiyun * consider this as bad access if we take a SLB miss
818*4882a593Smuzhiyun * on an address above addr limit.
819*4882a593Smuzhiyun */
820*4882a593Smuzhiyun if (ea >= mm_ctx_slb_addr_limit(&mm->context))
821*4882a593Smuzhiyun return -EFAULT;
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun context = get_user_context(&mm->context, ea);
824*4882a593Smuzhiyun if (!context)
825*4882a593Smuzhiyun return -EFAULT;
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun if (unlikely(ea >= H_PGTABLE_RANGE)) {
828*4882a593Smuzhiyun WARN_ON(1);
829*4882a593Smuzhiyun return -EFAULT;
830*4882a593Smuzhiyun }
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun ssize = user_segment_size(ea);
833*4882a593Smuzhiyun
834*4882a593Smuzhiyun bpsize = get_slice_psize(mm, ea);
835*4882a593Smuzhiyun flags = SLB_VSID_USER | mmu_psize_defs[bpsize].sllp;
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun return slb_insert_entry(ea, context, flags, ssize, false);
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun
do_slb_fault(struct pt_regs * regs,unsigned long ea)840*4882a593Smuzhiyun long do_slb_fault(struct pt_regs *regs, unsigned long ea)
841*4882a593Smuzhiyun {
842*4882a593Smuzhiyun unsigned long id = get_region_id(ea);
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun /* IRQs are not reconciled here, so can't check irqs_disabled */
845*4882a593Smuzhiyun VM_WARN_ON(mfmsr() & MSR_EE);
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun if (unlikely(!(regs->msr & MSR_RI)))
848*4882a593Smuzhiyun return -EINVAL;
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun /*
851*4882a593Smuzhiyun * SLB kernel faults must be very careful not to touch anything
852*4882a593Smuzhiyun * that is not bolted. E.g., PACA and global variables are okay,
853*4882a593Smuzhiyun * mm->context stuff is not.
854*4882a593Smuzhiyun *
855*4882a593Smuzhiyun * SLB user faults can access all of kernel memory, but must be
856*4882a593Smuzhiyun * careful not to touch things like IRQ state because it is not
857*4882a593Smuzhiyun * "reconciled" here. The difficulty is that we must use
858*4882a593Smuzhiyun * fast_exception_return to return from kernel SLB faults without
859*4882a593Smuzhiyun * looking at possible non-bolted memory. We could test user vs
860*4882a593Smuzhiyun * kernel faults in the interrupt handler asm and do a full fault,
861*4882a593Smuzhiyun * reconcile, ret_from_except for user faults which would make them
862*4882a593Smuzhiyun * first class kernel code. But for performance it's probably nicer
863*4882a593Smuzhiyun * if they go via fast_exception_return too.
864*4882a593Smuzhiyun */
865*4882a593Smuzhiyun if (id >= LINEAR_MAP_REGION_ID) {
866*4882a593Smuzhiyun long err;
867*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_VM
868*4882a593Smuzhiyun /* Catch recursive kernel SLB faults. */
869*4882a593Smuzhiyun BUG_ON(local_paca->in_kernel_slb_handler);
870*4882a593Smuzhiyun local_paca->in_kernel_slb_handler = 1;
871*4882a593Smuzhiyun #endif
872*4882a593Smuzhiyun err = slb_allocate_kernel(ea, id);
873*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_VM
874*4882a593Smuzhiyun local_paca->in_kernel_slb_handler = 0;
875*4882a593Smuzhiyun #endif
876*4882a593Smuzhiyun return err;
877*4882a593Smuzhiyun } else {
878*4882a593Smuzhiyun struct mm_struct *mm = current->mm;
879*4882a593Smuzhiyun long err;
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun if (unlikely(!mm))
882*4882a593Smuzhiyun return -EFAULT;
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun err = slb_allocate_user(mm, ea);
885*4882a593Smuzhiyun if (!err)
886*4882a593Smuzhiyun preload_add(current_thread_info(), ea);
887*4882a593Smuzhiyun
888*4882a593Smuzhiyun return err;
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun }
891*4882a593Smuzhiyun
do_bad_slb_fault(struct pt_regs * regs,unsigned long ea,long err)892*4882a593Smuzhiyun void do_bad_slb_fault(struct pt_regs *regs, unsigned long ea, long err)
893*4882a593Smuzhiyun {
894*4882a593Smuzhiyun if (err == -EFAULT) {
895*4882a593Smuzhiyun if (user_mode(regs))
896*4882a593Smuzhiyun _exception(SIGSEGV, regs, SEGV_BNDERR, ea);
897*4882a593Smuzhiyun else
898*4882a593Smuzhiyun bad_page_fault(regs, ea, SIGSEGV);
899*4882a593Smuzhiyun } else if (err == -EINVAL) {
900*4882a593Smuzhiyun unrecoverable_exception(regs);
901*4882a593Smuzhiyun } else {
902*4882a593Smuzhiyun BUG();
903*4882a593Smuzhiyun }
904*4882a593Smuzhiyun }
905