diff options
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r-- | usr/src/uts/common/os/sysent.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/mman.h | 8 | ||||
-rw-r--r-- | usr/src/uts/common/sys/syscall.h | 5 | ||||
-rw-r--r-- | usr/src/uts/common/syscall/getpagesizes.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/vm/page.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/vm/vm_pagelist.c | 29 |
6 files changed, 45 insertions, 21 deletions
diff --git a/usr/src/uts/common/os/sysent.c b/usr/src/uts/common/os/sysent.c index 38c3270f9b..b6d097b585 100644 --- a/usr/src/uts/common/os/sysent.c +++ b/usr/src/uts/common/os/sysent.c @@ -520,7 +520,7 @@ struct sysent sysent[NSYSCALL] = /* 70 */ SYSENT_CI("tasksys", tasksys, 5), /* 71 */ SYSENT_LOADABLE(), /* acctctl */ /* 72 */ SYSENT_LOADABLE(), /* exacct */ - /* 73 */ SYSENT_CI("getpagesizes", getpagesizes, 2), + /* 73 */ SYSENT_CI("getpagesizes", getpagesizes, 3), /* 74 */ SYSENT_CI("rctlsys", rctlsys, 6), /* 75 */ SYSENT_2CI("sidsys", sidsys, 4), /* 76 */ IF_LP64( @@ -921,7 +921,7 @@ struct sysent sysent32[NSYSCALL] = /* 70 */ SYSENT_CI("tasksys", tasksys, 5), /* 71 */ SYSENT_LOADABLE32(), /* acctctl */ /* 72 */ SYSENT_LOADABLE32(), /* exacct */ - /* 73 */ SYSENT_CI("getpagesizes", getpagesizes32, 2), + /* 73 */ SYSENT_CI("getpagesizes", getpagesizes32, 3), /* 74 */ SYSENT_CI("rctlsys", rctlsys, 6), /* 75 */ SYSENT_2CI("sidsys", sidsys, 4), /* 76 */ SYSENT_CI("fsat", fsat32, 6), diff --git a/usr/src/uts/common/sys/mman.h b/usr/src/uts/common/sys/mman.h index 5132833ed0..14b1f52efc 100644 --- a/usr/src/uts/common/sys/mman.h +++ b/usr/src/uts/common/sys/mman.h @@ -143,6 +143,12 @@ extern "C" { #endif #endif /* _LP64 && _LARGEFILE64_SOURCE */ +#ifdef __PRAGMA_REDEFINE_EXTNAME +#pragma redefine_extname getpagesizes getpagesizes2 +#else +#define getpagesizes getpagesizes2 +#endif + /* * Except for old binaries mmap() will return the resultant * address of mapping on success and (caddr_t)-1 on error. @@ -174,6 +180,7 @@ extern int memcntl(caddr_t, size_t, int, caddr_t, int, int); extern int madvise(caddr_t, size_t, int); #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) extern int getpagesizes(size_t *, int); +extern int getpagesizes2(size_t *, int); /* guard visibility of uint64_t */ #if defined(_INT64_TYPE) extern int meminfo(const uint64_t *, int, const uint_t *, int, uint64_t *, @@ -205,6 +212,7 @@ extern int memcntl(); extern int msync(); extern int madvise(); extern int getpagesizes(); +extern int getpagesizes2(); extern int mlock(); extern int mlockall(); extern int munlock(); diff --git a/usr/src/uts/common/sys/syscall.h b/usr/src/uts/common/sys/syscall.h index 9fbc05f054..b04d0cf876 100644 --- a/usr/src/uts/common/sys/syscall.h +++ b/usr/src/uts/common/sys/syscall.h @@ -195,6 +195,11 @@ extern "C" { * wracct(...) :: exacct(2, ...) */ #define SYS_getpagesizes 73 + /* + * subcodes: + * getpagesizes2(...) :: getpagesizes(0, ...) + * getpagesizes(...) :: getpagesizes(1, ...) legacy + */ #define SYS_rctlsys 74 /* * subcodes: diff --git a/usr/src/uts/common/syscall/getpagesizes.c b/usr/src/uts/common/syscall/getpagesizes.c index d53e9a9936..cfef91eb6c 100644 --- a/usr/src/uts/common/syscall/getpagesizes.c +++ b/usr/src/uts/common/syscall/getpagesizes.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,9 +34,9 @@ * Return supported page sizes. */ int -getpagesizes(size_t *buf, int nelem) +getpagesizes(int legacy, size_t *buf, int nelem) { - int i, pagesizes = page_num_user_pagesizes(); + int i, pagesizes = page_num_user_pagesizes(legacy); size_t *pgsza; if (nelem < 0) { @@ -74,9 +73,9 @@ getpagesizes(size_t *buf, int nelem) * a 32-bit address space. */ int -getpagesizes32(size32_t *buf, int nelem) +getpagesizes32(int legacy, size32_t *buf, int nelem) { - int i, pagesizes = page_num_user_pagesizes(); + int i, pagesizes = page_num_user_pagesizes(legacy); size32_t *pgsza32; size_t pgsz; int rc; @@ -116,7 +115,8 @@ getpagesizes32(size32_t *buf, int nelem) } rc = nelem; done: - kmem_free(pgsza32, sizeof (*pgsza32) * page_num_user_pagesizes()); + kmem_free(pgsza32, sizeof (*pgsza32) * + page_num_user_pagesizes(legacy)); return (rc); } #endif diff --git a/usr/src/uts/common/vm/page.h b/usr/src/uts/common/vm/page.h index 45a3811eaf..89525bd8f7 100644 --- a/usr/src/uts/common/vm/page.h +++ b/usr/src/uts/common/vm/page.h @@ -834,7 +834,7 @@ extern uint_t colorequiv; extern uchar_t colorequivszc[]; uint_t page_num_pagesizes(void); -uint_t page_num_user_pagesizes(void); +uint_t page_num_user_pagesizes(int); size_t page_get_pagesize(uint_t); size_t page_get_user_pagesize(uint_t n); pgcnt_t page_get_pagecnt(uint_t); diff --git a/usr/src/uts/common/vm/vm_pagelist.c b/usr/src/uts/common/vm/vm_pagelist.c index d45b8cd0fe..889b8ad690 100644 --- a/usr/src/uts/common/vm/vm_pagelist.c +++ b/usr/src/uts/common/vm/vm_pagelist.c @@ -419,10 +419,18 @@ page_szc_user_filtered(size_t pagesize) * Return how many page sizes are available for the user to use. This is * what the hardware supports and not based upon how the OS implements the * support of different page sizes. + * + * If legacy is non-zero, return the number of pagesizes available to legacy + * applications. The number of legacy page sizes might be less than the + * exported user page sizes. This is to prevent legacy applications that + * use the largest page size returned from getpagesizes(3c) from inadvertantly + * using the 'new' large pagesizes. */ uint_t -page_num_user_pagesizes(void) +page_num_user_pagesizes(int legacy) { + if (legacy) + return (mmu_legacy_page_sizes); return (mmu_exported_page_sizes); } @@ -3311,7 +3319,6 @@ trimkcage(struct memseg *mseg, pfn_t *lo, pfn_t *hi, pfn_t pfnlo, pfn_t pfnhi) * 'pfnflag' specifies the subset of the pfn range to search. */ - static page_t * page_geti_contig_pages(int mnode, uint_t bin, uchar_t szc, int flags, pfn_t pfnlo, pfn_t pfnhi, pgcnt_t pfnflag) @@ -3330,7 +3337,9 @@ page_geti_contig_pages(int mnode, uint_t bin, uchar_t szc, int flags, ASSERT(szc != 0 || (flags & PGI_PGCPSZC0)); - if ((pfnhi - pfnlo) + 1 < szcpgcnt) + pfnlo = P2ROUNDUP(pfnlo, szcpgcnt); + + if ((pfnhi - pfnlo) + 1 < szcpgcnt || pfnlo >= pfnhi) return (NULL); ASSERT(szc < mmu_page_sizes); @@ -3368,15 +3377,16 @@ page_geti_contig_pages(int mnode, uint_t bin, uchar_t szc, int flags, pgcnt_t szcpages; int slotlen; - pfnlo = P2ROUNDUP(pfnlo, szcpgcnt); - pfnhi = pfnhi & ~(szcpgcnt - 1); - + pfnhi = P2ALIGN((pfnhi + 1), szcpgcnt) - 1; szcpages = ((pfnhi - pfnlo) + 1) / szcpgcnt; slotlen = howmany(szcpages, slots); + /* skip if 'slotid' slot is empty */ + if (slotid * slotlen >= szcpages) + return (NULL); pfnlo = pfnlo + (((slotid * slotlen) % szcpages) * szcpgcnt); ASSERT(pfnlo < pfnhi); if (pfnhi > pfnlo + (slotlen * szcpgcnt)) - pfnhi = pfnlo + (slotlen * szcpgcnt); + pfnhi = pfnlo + (slotlen * szcpgcnt) - 1; } memsegs_lock(0); @@ -3406,8 +3416,9 @@ page_geti_contig_pages(int mnode, uint_t bin, uchar_t szc, int flags, /* round to szcpgcnt boundaries */ lo = P2ROUNDUP(lo, szcpgcnt); + MEM_NODE_ITERATOR_INIT(lo, mnode, &it); - hi = hi & ~(szcpgcnt - 1); + hi = P2ALIGN((hi + 1), szcpgcnt) - 1; if (hi <= lo) continue; @@ -3449,7 +3460,7 @@ page_geti_contig_pages(int mnode, uint_t bin, uchar_t szc, int flags, ASSERT(randpp->p_pagenum == randpfn); pp = randpp; - endpp = mseg->pages + (hi - mseg->pages_base); + endpp = mseg->pages + (hi - mseg->pages_base) + 1; ASSERT(randpp + szcpgcnt <= endpp); |