xref: /OK3568_Linux_fs/kernel/arch/powerpc/mm/book3s64/slb.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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