xref: /illumos-gate/usr/src/uts/sun4v/vm/mach_vm_dep.c (revision 55381082)
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  * Number of pages in 1 GB.  Don't enable automatic large pages if we have
299  * fewer than this many pages.
300  */
301 pgcnt_t auto_lpg_min_physmem = 1 << (30 - MMU_PAGESHIFT);
302 
303 size_t
304 map_pgsz(int maptype, struct proc *p, caddr_t addr, size_t len, int *remap)
305 {
306 	uint_t	n;
307 	size_t	pgsz = 0;
308 
309 	if (remap)
310 		*remap = (len > auto_lpg_remap_threshold);
311 
312 	switch (maptype) {
313 	case MAPPGSZ_ISM:
314 		n = hat_preferred_pgsz(p->p_as->a_hat, addr, len, maptype);
315 		pgsz = hw_page_array[n].hp_size;
316 		break;
317 
318 	case MAPPGSZ_VA:
319 		n = hat_preferred_pgsz(p->p_as->a_hat, addr, len, maptype);
320 		pgsz = hw_page_array[n].hp_size;
321 		if ((pgsz <= MMU_PAGESIZE) ||
322 		    !IS_P2ALIGNED(addr, pgsz) || !IS_P2ALIGNED(len, pgsz))
323 			pgsz = map_pgszva(p, addr, len);
324 		break;
325 
326 	case MAPPGSZ_STK:
327 		pgsz = map_pgszstk(p, addr, len);
328 		break;
329 
330 	case MAPPGSZ_HEAP:
331 		pgsz = map_pgszheap(p, addr, len);
332 		break;
333 	}
334 	return (pgsz);
335 }
336 
337 /*
338  * Platform-dependent page scrub call.
339  * We call hypervisor to scrub the page.
340  */
341 void
342 pagescrub(page_t *pp, uint_t off, uint_t len)
343 {
344 	uint64_t pa, length;
345 
346 	pa = (uint64_t)(pp->p_pagenum << MMU_PAGESHIFT + off);
347 	length = (uint64_t)len;
348 
349 	(void) mem_scrub(pa, length);
350 }
351 
352 void
353 sync_data_memory(caddr_t va, size_t len)
354 {
355 	/* Call memory sync function */
356 	mem_sync(va, len);
357 }
358 
359 size_t
360 mmu_get_kernel_lpsize(size_t lpsize)
361 {
362 	extern int mmu_exported_pagesize_mask;
363 	uint_t tte;
364 
365 	if (lpsize == 0) {
366 		/* no setting for segkmem_lpsize in /etc/system: use default */
367 		if (mmu_exported_pagesize_mask & (1 << TTE256M)) {
368 			lpsize = MMU_PAGESIZE256M;
369 		} else if (mmu_exported_pagesize_mask & (1 << TTE4M)) {
370 			lpsize = MMU_PAGESIZE4M;
371 		} else if (mmu_exported_pagesize_mask & (1 << TTE64K)) {
372 			lpsize = MMU_PAGESIZE64K;
373 		} else {
374 			lpsize = MMU_PAGESIZE;
375 		}
376 
377 		return (lpsize);
378 	}
379 
380 	for (tte = TTE8K; tte <= TTE256M; tte++) {
381 
382 		if ((mmu_exported_pagesize_mask & (1 << tte)) == 0)
383 			continue;
384 
385 		if (lpsize == TTEBYTES(tte))
386 			return (lpsize);
387 	}
388 
389 	lpsize = TTEBYTES(TTE8K);
390 	return (lpsize);
391 }
392 
393 void
394 mmu_init_kcontext()
395 {
396 }
397 
398 /*ARGSUSED*/
399 void
400 mmu_init_kernel_pgsz(struct hat *hat)
401 {
402 }
403 
404 #define	QUANTUM_SIZE	64
405 
406 static	vmem_t	*contig_mem_slab_arena;
407 static	vmem_t	*contig_mem_arena;
408 
409 uint_t contig_mem_slab_size = MMU_PAGESIZE4M;
410 
411 static void *
412 contig_mem_span_alloc(vmem_t *vmp, size_t size, int vmflag)
413 {
414 	page_t *ppl;
415 	page_t *rootpp;
416 	caddr_t addr = NULL;
417 	pgcnt_t npages = btopr(size);
418 	page_t **ppa;
419 	int pgflags;
420 	int i = 0;
421 
422 
423 	if ((addr = vmem_xalloc(vmp, size, size, 0, 0,
424 	    NULL, NULL, vmflag)) == NULL) {
425 		return (NULL);
426 	}
427 
428 	/* If we ever don't want slab-sized pages, this will panic */
429 	ASSERT(((uintptr_t)addr & (contig_mem_slab_size - 1)) == 0);
430 
431 	if (page_resv(npages, vmflag & VM_KMFLAGS) == 0) {
432 		vmem_xfree(vmp, addr, size);
433 		return (NULL);
434 	}
435 
436 	pgflags = PG_EXCL;
437 	if ((vmflag & VM_NOSLEEP) == 0)
438 		pgflags |= PG_WAIT;
439 	if (vmflag & VM_PANIC)
440 		pgflags |= PG_PANIC;
441 	if (vmflag & VM_PUSHPAGE)
442 		pgflags |= PG_PUSHPAGE;
443 
444 	ppl = page_create_va_large(&kvp, (u_offset_t)(uintptr_t)addr, size,
445 	    pgflags, &kvseg, addr, NULL);
446 
447 	if (ppl == NULL) {
448 		vmem_xfree(vmp, addr, size);
449 		page_unresv(npages);
450 		return (NULL);
451 	}
452 
453 	rootpp = ppl;
454 	ppa = kmem_zalloc(npages * sizeof (page_t *), KM_SLEEP);
455 	while (ppl != NULL) {
456 		page_t *pp = ppl;
457 		ppa[i++] = pp;
458 		page_sub(&ppl, pp);
459 		ASSERT(page_iolock_assert(pp));
460 		page_io_unlock(pp);
461 	}
462 
463 	/*
464 	 * Load the locked entry.  It's OK to preload the entry into
465 	 * the TSB since we now support large mappings in the kernel TSB.
466 	 */
467 	hat_memload_array(kas.a_hat, (caddr_t)rootpp->p_offset, size,
468 	    ppa, (PROT_ALL & ~PROT_USER) | HAT_NOSYNC, HAT_LOAD_LOCK);
469 
470 	for (--i; i >= 0; --i) {
471 		(void) page_pp_lock(ppa[i], 0, 1);
472 		page_unlock(ppa[i]);
473 	}
474 
475 	kmem_free(ppa, npages * sizeof (page_t *));
476 	return (addr);
477 }
478 
479 void
480 contig_mem_span_free(vmem_t *vmp, void *inaddr, size_t size)
481 {
482 	page_t *pp;
483 	caddr_t addr = inaddr;
484 	caddr_t eaddr;
485 	pgcnt_t npages = btopr(size);
486 	pgcnt_t pgs_left = npages;
487 	page_t *rootpp = NULL;
488 
489 	ASSERT(((uintptr_t)addr & (contig_mem_slab_size - 1)) == 0);
490 
491 	hat_unload(kas.a_hat, addr, size, HAT_UNLOAD_UNLOCK);
492 
493 	for (eaddr = addr + size; addr < eaddr; addr += PAGESIZE) {
494 		pp = page_lookup(&kvp, (u_offset_t)(uintptr_t)addr, SE_EXCL);
495 		if (pp == NULL)
496 			panic("contig_mem_span_free: page not found");
497 
498 		ASSERT(PAGE_EXCL(pp));
499 		page_pp_unlock(pp, 0, 1);
500 
501 		if (rootpp == NULL)
502 			rootpp = pp;
503 		if (--pgs_left == 0) {
504 			/*
505 			 * similar logic to segspt_free_pages, but we know we
506 			 * have one large page.
507 			 */
508 			page_destroy_pages(rootpp);
509 		}
510 	}
511 	page_unresv(npages);
512 
513 	if (vmp != NULL)
514 		vmem_xfree(vmp, inaddr, size);
515 }
516 
517 static void *
518 contig_vmem_xalloc_aligned_wrapper(vmem_t *vmp, size_t size, int vmflag)
519 {
520 	return (vmem_xalloc(vmp, size, size, 0, 0, NULL, NULL, vmflag));
521 }
522 
523 /*
524  * conting_mem_alloc_align allocates real contiguous memory with the specified
525  * alignment upto contig_mem_slab_size. The alignment must be a power of 2.
526  */
527 void *
528 contig_mem_alloc_align(size_t size, size_t align)
529 {
530 	if ((align & (align - 1)) != 0)
531 		return (NULL);
532 
533 	return (vmem_xalloc(contig_mem_arena, size, align, 0, 0,
534 	    NULL, NULL, VM_NOSLEEP));
535 }
536 
537 /*
538  * Allocates size aligned contiguous memory upto contig_mem_slab_size.
539  * Size must be a power of 2.
540  */
541 void *
542 contig_mem_alloc(size_t size)
543 {
544 	ASSERT((size & (size - 1)) == 0);
545 	return (contig_mem_alloc_align(size, size));
546 }
547 
548 void
549 contig_mem_free(void *vaddr, size_t size)
550 {
551 	vmem_xfree(contig_mem_arena, vaddr, size);
552 }
553 
554 /*
555  * We create a set of stacked vmem arenas to enable us to
556  * allocate large >PAGESIZE chucks of contiguous Real Address space
557  * This is  what the Dynamics TSB support does for TSBs.
558  * The contig_mem_arena import functions are exactly the same as the
559  * TSB kmem_default arena import functions.
560  */
561 void
562 contig_mem_init(void)
563 {
564 
565 	contig_mem_slab_arena = vmem_create("contig_mem_slab_arena", NULL, 0,
566 	    contig_mem_slab_size, contig_vmem_xalloc_aligned_wrapper,
567 	    vmem_xfree, heap_arena, 0, VM_SLEEP);
568 
569 	contig_mem_arena = vmem_create("contig_mem_arena", NULL, 0,
570 	    QUANTUM_SIZE, contig_mem_span_alloc, contig_mem_span_free,
571 	    contig_mem_slab_arena, 0, VM_SLEEP | VM_BESTFIT);
572 
573 }
574