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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/systm.h> 30 #include <vm/page.h> 31 #include <sys/errno.h> 32 33 /* 34 * Return supported page sizes. 35 */ 36 int 37 getpagesizes(int legacy, size_t *buf, int nelem) 38 { 39 int i, pagesizes = page_num_user_pagesizes(legacy); 40 size_t *pgsza; 41 42 if (nelem < 0) { 43 return (set_errno(EINVAL)); 44 } 45 if (nelem == 0 && buf != NULL) { 46 return (set_errno(EINVAL)); 47 } 48 if (nelem == 0 && buf == NULL) { 49 return (pagesizes); 50 } 51 if (buf == NULL) { 52 return (set_errno(EINVAL)); 53 } 54 if (nelem > pagesizes) { 55 nelem = pagesizes; 56 } 57 pgsza = kmem_alloc(sizeof (*pgsza) * nelem, KM_SLEEP); 58 for (i = 0; i < nelem; i++) { 59 pgsza[i] = page_get_user_pagesize(i); 60 } 61 if (copyout(pgsza, buf, nelem * sizeof (*pgsza)) != 0) { 62 kmem_free(pgsza, sizeof (*pgsza) * nelem); 63 return (set_errno(EFAULT)); 64 } 65 kmem_free(pgsza, sizeof (*pgsza) * nelem); 66 return (nelem); 67 } 68 69 #if defined(_SYSCALL32_IMPL) 70 71 /* 72 * Some future platforms will support page sizes larger than 73 * a 32-bit address space. 74 */ 75 int 76 getpagesizes32(int legacy, size32_t *buf, int nelem) 77 { 78 int i, pagesizes = page_num_user_pagesizes(legacy); 79 size32_t *pgsza32; 80 size_t pgsz; 81 int rc; 82 83 if (nelem < 0) { 84 return (set_errno(EINVAL)); 85 } 86 if (nelem == 0 && buf != NULL) { 87 return (set_errno(EINVAL)); 88 } 89 90 pgsza32 = kmem_alloc(sizeof (*pgsza32) * pagesizes, KM_SLEEP); 91 for (i = 0; i < pagesizes; i++) { 92 pgsz = page_get_user_pagesize(i); 93 pgsza32[i] = (size32_t)pgsz; 94 if (pgsz > (size32_t)-1) { 95 pagesizes = i - 1; 96 break; 97 } 98 } 99 ASSERT(pagesizes > 0); 100 ASSERT(page_get_user_pagesize(pagesizes - 1) <= (size32_t)-1); 101 if (nelem > pagesizes) { 102 nelem = pagesizes; 103 } 104 if (nelem == 0 && buf == NULL) { 105 rc = pagesizes; 106 goto done; 107 } 108 if (buf == NULL) { 109 rc = set_errno(EINVAL); 110 goto done; 111 } 112 if (copyout(pgsza32, buf, nelem * sizeof (*pgsza32)) != 0) { 113 rc = set_errno(EFAULT); 114 goto done; 115 } 116 rc = nelem; 117 done: 118 kmem_free(pgsza32, sizeof (*pgsza32) * 119 page_num_user_pagesizes(legacy)); 120 return (rc); 121 } 122 #endif 123