xref: /titanic_51/usr/src/uts/sun4v/vm/mach_vm_dep.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /*	All Rights Reserved   */
29 
30 /*
31  * Portions of this source code were derived from Berkeley 4.3 BSD
32  * under license from the Regents of the University of California.
33  */
34 
35 #pragma ident	"%Z%%M%	%I%	%E% SMI"
36 
37 /*
38  * UNIX machine dependent virtual memory support.
39  */
40 
41 #include <sys/vm.h>
42 #include <sys/exec.h>
43 #include <sys/cmn_err.h>
44 #include <sys/cpu_module.h>
45 #include <sys/cpu.h>
46 #include <sys/elf_SPARC.h>
47 #include <sys/archsystm.h>
48 #include <vm/hat_sfmmu.h>
49 #include <sys/memnode.h>
50 #include <sys/mem_cage.h>
51 #include <vm/vm_dep.h>
52 #include <sys/error.h>
53 #include <sys/machsystm.h>
54 #include <vm/seg_kmem.h>
55 
56 uint_t page_colors = 0;
57 uint_t page_colors_mask = 0;
58 uint_t page_coloring_shift = 0;
59 int consistent_coloring;
60 
61 uint_t mmu_page_sizes = MMU_PAGE_SIZES;
62 uint_t max_mmu_page_sizes = MMU_PAGE_SIZES;
63 uint_t mmu_hashcnt = MAX_HASHCNT;
64 uint_t max_mmu_hashcnt = MAX_HASHCNT;
65 size_t mmu_ism_pagesize = DEFAULT_ISM_PAGESIZE;
66 
67 /*
68  * A bitmask of the page sizes supported by hardware based upon szc.
69  * The base pagesize (p_szc == 0) must always be supported by the hardware.
70  */
71 int mmu_exported_pagesize_mask;
72 uint_t mmu_exported_page_sizes;
73 
74 uint_t szc_2_userszc[MMU_PAGE_SIZES];
75 uint_t userszc_2_szc[MMU_PAGE_SIZES];
76 
77 extern uint_t vac_colors_mask;
78 extern int vac_shift;
79 
80 hw_pagesize_t hw_page_array[] = {
81 	{MMU_PAGESIZE, MMU_PAGESHIFT, MMU_PAGESIZE >> MMU_PAGESHIFT},
82 	{MMU_PAGESIZE64K, MMU_PAGESHIFT64K, MMU_PAGESIZE64K >> MMU_PAGESHIFT},
83 	{MMU_PAGESIZE512K, MMU_PAGESHIFT512K,
84 	    MMU_PAGESIZE512K >> MMU_PAGESHIFT},
85 	{MMU_PAGESIZE4M, MMU_PAGESHIFT4M, MMU_PAGESIZE4M >> MMU_PAGESHIFT},
86 	{MMU_PAGESIZE32M, MMU_PAGESHIFT32M, MMU_PAGESIZE32M >> MMU_PAGESHIFT},
87 	{MMU_PAGESIZE256M, MMU_PAGESHIFT256M,
88 	    MMU_PAGESIZE256M >> MMU_PAGESHIFT},
89 	{0, 0, 0}
90 };
91 
92 /*
93  * Enable usage of 64k/4M pages for text and 64k pages for initdata for
94  * all sun4v platforms. These variables can be overwritten by the platmod
95  * or the CPU module. User can also change the setting via /etc/system.
96  */
97 
98 int	use_text_pgsz64k = 1;
99 int	use_text_pgsz4m = 1;
100 int	use_initdata_pgsz64k = 1;
101 
102 /*
103  * disable_text_largepages and disable_initdata_largepages bitmaks reflect
104  * both unconfigured and undesirable page sizes. Current implementation
105  * supports 64K and 4M page sizes for text and only 64K for data. Rest of
106  * the page sizes are not currently supported, hence disabled below. In
107  * future, when support is added for any other page size, it should be
108  * reflected below.
109  *
110  * Note that these bitmask can be set in platform or CPU specific code to
111  * disable page sizes that should not be used. These variables normally
112  * shouldn't be changed via /etc/system.
113  *
114  * These bitmasks are also updated within hat_init to reflect unsupported
115  * page sizes on a sun4v processor per mmu_exported_pagesize_mask global
116  * variable.
117  */
118 
119 int disable_text_largepages =
120 	(1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M) | (1 << TTE2G) |
121 	(1 << TTE16G);
122 int disable_initdata_largepages =
123 	(1 << TTE512K) | (1 << TTE4M) | (1 << TTE32M) | (1 << TTE256M) |
124 	(1 << TTE2G) | (1 << TTE16G);
125 
126 /*
127  * Minimum segment size tunables before 64K or 4M large pages
128  * should be used to map it.
129  */
130 size_t text_pgsz64k_minsize = MMU_PAGESIZE64K;
131 size_t text_pgsz4m_minsize = MMU_PAGESIZE4M;
132 size_t initdata_pgsz64k_minsize = MMU_PAGESIZE64K;
133 
134 /*
135  * map_addr_proc() is the routine called when the system is to
136  * choose an address for the user.  We will pick an address
137  * range which is just below the current stack limit.  The
138  * algorithm used for cache consistency on machines with virtual
139  * address caches is such that offset 0 in the vnode is always
140  * on a shm_alignment'ed aligned address.  Unfortunately, this
141  * means that vnodes which are demand paged will not be mapped
142  * cache consistently with the executable images.  When the
143  * cache alignment for a given object is inconsistent, the
144  * lower level code must manage the translations so that this
145  * is not seen here (at the cost of efficiency, of course).
146  *
147  * addrp is a value/result parameter.
148  *	On input it is a hint from the user to be used in a completely
149  *	machine dependent fashion.  For MAP_ALIGN, addrp contains the
150  *	minimal alignment.
151  *
152  *	On output it is NULL if no address can be found in the current
153  *	processes address space or else an address that is currently
154  *	not mapped for len bytes with a page of red zone on either side.
155  *	If vacalign is true, then the selected address will obey the alignment
156  *	constraints of a vac machine based on the given off value.
157  */
158 /*ARGSUSED3*/
159 void
160 map_addr_proc(caddr_t *addrp, size_t len, offset_t off, int vacalign,
161     caddr_t userlimit, struct proc *p, uint_t flags)
162 {
163 	struct as *as = p->p_as;
164 	caddr_t addr;
165 	caddr_t base;
166 	size_t slen;
167 	uintptr_t align_amount;
168 	int allow_largepage_alignment = 1;
169 
170 	base = p->p_brkbase;
171 	if (userlimit < as->a_userlimit) {
172 		/*
173 		 * This happens when a program wants to map something in
174 		 * a range that's accessible to a program in a smaller
175 		 * address space.  For example, a 64-bit program might
176 		 * be calling mmap32(2) to guarantee that the returned
177 		 * address is below 4Gbytes.
178 		 */
179 		ASSERT(userlimit > base);
180 		slen = userlimit - base;
181 	} else {
182 		slen = p->p_usrstack - base - (((size_t)rctl_enforced_value(
183 		    rctlproc_legacy[RLIMIT_STACK], p->p_rctls, p) + PAGEOFFSET)
184 		    & PAGEMASK);
185 	}
186 	len = (len + PAGEOFFSET) & PAGEMASK;
187 
188 	/*
189 	 * Redzone for each side of the request. This is done to leave
190 	 * one page unmapped between segments. This is not required, but
191 	 * it's useful for the user because if their program strays across
192 	 * a segment boundary, it will catch a fault immediately making
193 	 * debugging a little easier.
194 	 */
195 	len += (2 * PAGESIZE);
196 
197 	/*
198 	 *  If the request is larger than the size of a particular
199 	 *  mmu level, then we use that level to map the request.
200 	 *  But this requires that both the virtual and the physical
201 	 *  addresses be aligned with respect to that level, so we
202 	 *  do the virtual bit of nastiness here.
203 	 *
204 	 *  For 32-bit processes, only those which have specified
205 	 *  MAP_ALIGN or an addr will be aligned on a page size > 4MB. Otherwise
206 	 *  we can potentially waste up to 256MB of the 4G process address
207 	 *  space just for alignment.
208 	 *
209 	 * XXXQ Should iterate trough hw_page_array here to catch
210 	 * all supported pagesizes
211 	 */
212 	if (p->p_model == DATAMODEL_ILP32 && ((flags & MAP_ALIGN) == 0 ||
213 	    ((uintptr_t)*addrp) != 0)) {
214 		allow_largepage_alignment = 0;
215 	}
216 	if ((mmu_page_sizes == max_mmu_page_sizes) &&
217 	    allow_largepage_alignment &&
218 		(len >= MMU_PAGESIZE256M)) {	/* 256MB mappings */
219 		align_amount = MMU_PAGESIZE256M;
220 	} else if ((mmu_page_sizes == max_mmu_page_sizes) &&
221 	    allow_largepage_alignment &&
222 		(len >= MMU_PAGESIZE32M)) {	/* 32MB mappings */
223 		align_amount = MMU_PAGESIZE32M;
224 	} else if (len >= MMU_PAGESIZE4M) {  /* 4MB mappings */
225 		align_amount = MMU_PAGESIZE4M;
226 	} else if (len >= MMU_PAGESIZE512K) { /* 512KB mappings */
227 		align_amount = MMU_PAGESIZE512K;
228 	} else if (len >= MMU_PAGESIZE64K) { /* 64KB mappings */
229 		align_amount = MMU_PAGESIZE64K;
230 	} else  {
231 		/*
232 		 * Align virtual addresses on a 64K boundary to ensure
233 		 * that ELF shared libraries are mapped with the appropriate
234 		 * alignment constraints by the run-time linker.
235 		 */
236 		align_amount = ELF_SPARC_MAXPGSZ;
237 		if ((flags & MAP_ALIGN) && ((uintptr_t)*addrp != 0) &&
238 			((uintptr_t)*addrp < align_amount))
239 			align_amount = (uintptr_t)*addrp;
240 	}
241 
242 	/*
243 	 * 64-bit processes require 1024K alignment of ELF shared libraries.
244 	 */
245 	if (p->p_model == DATAMODEL_LP64)
246 		align_amount = MAX(align_amount, ELF_SPARCV9_MAXPGSZ);
247 #ifdef VAC
248 	if (vac && vacalign && (align_amount < shm_alignment))
249 		align_amount = shm_alignment;
250 #endif
251 
252 	if ((flags & MAP_ALIGN) && ((uintptr_t)*addrp > align_amount)) {
253 		align_amount = (uintptr_t)*addrp;
254 	}
255 	len += align_amount;
256 
257 	/*
258 	 * Look for a large enough hole starting below the stack limit.
259 	 * After finding it, use the upper part.  Addition of PAGESIZE is
260 	 * for the redzone as described above.
261 	 */
262 	as_purge(as);
263 	if (as_gap(as, len, &base, &slen, AH_HI, NULL) == 0) {
264 		caddr_t as_addr;
265 
266 		addr = base + slen - len + PAGESIZE;
267 		as_addr = addr;
268 		/*
269 		 * Round address DOWN to the alignment amount,
270 		 * add the offset, and if this address is less
271 		 * than the original address, add alignment amount.
272 		 */
273 		addr = (caddr_t)((uintptr_t)addr & (~(align_amount - 1l)));
274 		addr += (long)(off & (align_amount - 1l));
275 		if (addr < as_addr) {
276 			addr += align_amount;
277 		}
278 
279 		ASSERT(addr <= (as_addr + align_amount));
280 		ASSERT(((uintptr_t)addr & (align_amount - 1l)) ==
281 		    ((uintptr_t)(off & (align_amount - 1l))));
282 		*addrp = addr;
283 
284 	} else {
285 		*addrp = NULL;	/* no more virtual space */
286 	}
287 }
288 
289 /* Auto large page tunables. */
290 int auto_lpg_tlb_threshold = 32;
291 int auto_lpg_minszc = TTE64K;
292 int auto_lpg_maxszc = TTE256M;
293 size_t auto_lpg_heap_default = MMU_PAGESIZE64K;
294 size_t auto_lpg_stack_default = MMU_PAGESIZE64K;
295 size_t auto_lpg_va_default = MMU_PAGESIZE64K;
296 size_t auto_lpg_remap_threshold = 0; /* always remap */
297 
298 size_t
299 map_pgsz(int maptype, struct proc *p, caddr_t addr, size_t len, int *remap)
300 {
301 	uint_t	n;
302 	size_t	pgsz = 0;
303 
304 	if (remap)
305 		*remap = (len > auto_lpg_remap_threshold);
306 
307 	switch (maptype) {
308 	case MAPPGSZ_ISM:
309 		n = hat_preferred_pgsz(p->p_as->a_hat, addr, len, maptype);
310 		pgsz = hw_page_array[n].hp_size;
311 		break;
312 
313 	case MAPPGSZ_VA:
314 		n = hat_preferred_pgsz(p->p_as->a_hat, addr, len, maptype);
315 		pgsz = hw_page_array[n].hp_size;
316 		if ((pgsz <= MMU_PAGESIZE) ||
317 		    !IS_P2ALIGNED(addr, pgsz) || !IS_P2ALIGNED(len, pgsz))
318 			pgsz = map_pgszva(p, addr, len);
319 		break;
320 
321 	case MAPPGSZ_STK:
322 		pgsz = map_pgszstk(p, addr, len);
323 		break;
324 
325 	case MAPPGSZ_HEAP:
326 		pgsz = map_pgszheap(p, addr, len);
327 		break;
328 	}
329 	return (pgsz);
330 }
331 
332 /*
333  * Platform-dependent page scrub call.
334  * We call hypervisor to scrub the page.
335  */
336 void
337 pagescrub(page_t *pp, uint_t off, uint_t len)
338 {
339 	uint64_t pa, length;
340 
341 	pa = (uint64_t)(pp->p_pagenum << MMU_PAGESHIFT + off);
342 	length = (uint64_t)len;
343 
344 	(void) mem_scrub(pa, length);
345 }
346 
347 void
348 sync_data_memory(caddr_t va, size_t len)
349 {
350 	/* Call memory sync function */
351 	mem_sync(va, len);
352 }
353 
354 size_t
355 mmu_get_kernel_lpsize(size_t lpsize)
356 {
357 	extern int mmu_exported_pagesize_mask;
358 	uint_t tte;
359 
360 	if (lpsize == 0) {
361 		/* no setting for segkmem_lpsize in /etc/system: use default */
362 		if (mmu_exported_pagesize_mask & (1 << TTE256M)) {
363 			lpsize = MMU_PAGESIZE256M;
364 		} else if (mmu_exported_pagesize_mask & (1 << TTE4M)) {
365 			lpsize = MMU_PAGESIZE4M;
366 		} else if (mmu_exported_pagesize_mask & (1 << TTE64K)) {
367 			lpsize = MMU_PAGESIZE64K;
368 		} else {
369 			lpsize = MMU_PAGESIZE;
370 		}
371 
372 		return (lpsize);
373 	}
374 
375 	for (tte = TTE8K; tte <= TTE256M; tte++) {
376 
377 		if ((mmu_exported_pagesize_mask & (1 << tte)) == 0)
378 			continue;
379 
380 		if (lpsize == TTEBYTES(tte))
381 			return (lpsize);
382 	}
383 
384 	lpsize = TTEBYTES(TTE8K);
385 	return (lpsize);
386 }
387 
388 void
389 mmu_init_kcontext()
390 {
391 }
392 
393 /*ARGSUSED*/
394 void
395 mmu_init_kernel_pgsz(struct hat *hat)
396 {
397 }
398 
399 #define	QUANTUM_SIZE	64
400 
401 static	vmem_t	*contig_mem_slab_arena;
402 static	vmem_t	*contig_mem_arena;
403 
404 uint_t contig_mem_slab_size = MMU_PAGESIZE4M;
405 
406 static void *
407 contig_mem_span_alloc(vmem_t *vmp, size_t size, int vmflag)
408 {
409 	page_t *ppl;
410 	page_t *rootpp;
411 	caddr_t addr = NULL;
412 	pgcnt_t npages = btopr(size);
413 	page_t **ppa;
414 	int pgflags;
415 	int i = 0;
416 
417 
418 	if ((addr = vmem_xalloc(vmp, size, size, 0, 0,
419 	    NULL, NULL, vmflag)) == NULL) {
420 		return (NULL);
421 	}
422 
423 	/* If we ever don't want slab-sized pages, this will panic */
424 	ASSERT(((uintptr_t)addr & (contig_mem_slab_size - 1)) == 0);
425 
426 	if (page_resv(npages, vmflag & VM_KMFLAGS) == 0) {
427 		vmem_xfree(vmp, addr, size);
428 		return (NULL);
429 	}
430 
431 	pgflags = PG_EXCL;
432 	if ((vmflag & VM_NOSLEEP) == 0)
433 		pgflags |= PG_WAIT;
434 	if (vmflag & VM_PANIC)
435 		pgflags |= PG_PANIC;
436 	if (vmflag & VM_PUSHPAGE)
437 		pgflags |= PG_PUSHPAGE;
438 
439 	ppl = page_create_va_large(&kvp, (u_offset_t)(uintptr_t)addr, size,
440 	    pgflags, &kvseg, addr, NULL);
441 
442 	if (ppl == NULL) {
443 		vmem_xfree(vmp, addr, size);
444 		page_unresv(npages);
445 		return (NULL);
446 	}
447 
448 	rootpp = ppl;
449 	ppa = kmem_zalloc(npages * sizeof (page_t *), KM_SLEEP);
450 	while (ppl != NULL) {
451 		page_t *pp = ppl;
452 		ppa[i++] = pp;
453 		page_sub(&ppl, pp);
454 		ASSERT(page_iolock_assert(pp));
455 		page_io_unlock(pp);
456 	}
457 
458 	/*
459 	 * Load the locked entry.  It's OK to preload the entry into
460 	 * the TSB since we now support large mappings in the kernel TSB.
461 	 */
462 	hat_memload_array(kas.a_hat, (caddr_t)rootpp->p_offset, size,
463 	    ppa, (PROT_ALL & ~PROT_USER) | HAT_NOSYNC, HAT_LOAD_LOCK);
464 
465 	for (--i; i >= 0; --i) {
466 		(void) page_pp_lock(ppa[i], 0, 1);
467 		page_unlock(ppa[i]);
468 	}
469 
470 	kmem_free(ppa, npages * sizeof (page_t *));
471 	return (addr);
472 }
473 
474 void
475 contig_mem_span_free(vmem_t *vmp, void *inaddr, size_t size)
476 {
477 	page_t *pp;
478 	caddr_t addr = inaddr;
479 	caddr_t eaddr;
480 	pgcnt_t npages = btopr(size);
481 	pgcnt_t pgs_left = npages;
482 	page_t *rootpp = NULL;
483 
484 	ASSERT(((uintptr_t)addr & (contig_mem_slab_size - 1)) == 0);
485 
486 	hat_unload(kas.a_hat, addr, size, HAT_UNLOAD_UNLOCK);
487 
488 	for (eaddr = addr + size; addr < eaddr; addr += PAGESIZE) {
489 		pp = page_lookup(&kvp, (u_offset_t)(uintptr_t)addr, SE_EXCL);
490 		if (pp == NULL)
491 			panic("contig_mem_span_free: page not found");
492 
493 		ASSERT(PAGE_EXCL(pp));
494 		page_pp_unlock(pp, 0, 1);
495 
496 		if (rootpp == NULL)
497 			rootpp = pp;
498 		if (--pgs_left == 0) {
499 			/*
500 			 * similar logic to segspt_free_pages, but we know we
501 			 * have one large page.
502 			 */
503 			page_destroy_pages(rootpp);
504 		}
505 	}
506 	page_unresv(npages);
507 
508 	if (vmp != NULL)
509 		vmem_xfree(vmp, inaddr, size);
510 }
511 
512 static void *
513 contig_vmem_xalloc_aligned_wrapper(vmem_t *vmp, size_t size, int vmflag)
514 {
515 	return (vmem_xalloc(vmp, size, size, 0, 0, NULL, NULL, vmflag));
516 }
517 
518 void *
519 contig_mem_alloc(size_t size)
520 {
521 	return (vmem_xalloc(contig_mem_arena, size, size, 0, 0,
522 	    NULL, NULL, VM_NOSLEEP));
523 }
524 
525 void
526 contig_mem_free(void *vaddr, size_t size)
527 {
528 	vmem_xfree(contig_mem_arena, vaddr, size);
529 }
530 
531 /*
532  * We create a set of stacked vmem arenas to enable us to
533  * allocate large >PAGESIZE chucks of contiguous Real Address space
534  * This is  what the Dynamics TSB support does for TSBs.
535  * The contig_mem_arena import functions are exactly the same as the
536  * TSB kmem_default arena import functions.
537  */
538 void
539 contig_mem_init(void)
540 {
541 
542 	contig_mem_slab_arena = vmem_create("contig_mem_slab_arena", NULL, 0,
543 	    contig_mem_slab_size, contig_vmem_xalloc_aligned_wrapper,
544 	    vmem_xfree, heap_arena, 0, VM_SLEEP);
545 
546 	contig_mem_arena = vmem_create("contig_mem_arena", NULL, 0,
547 	    QUANTUM_SIZE, contig_mem_span_alloc, contig_mem_span_free,
548 	    contig_mem_slab_arena, 0, VM_SLEEP | VM_BESTFIT);
549 
550 }
551