summaryrefslogtreecommitdiff
path: root/usr/src/uts/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r--usr/src/uts/common/os/sysent.c4
-rw-r--r--usr/src/uts/common/sys/mman.h8
-rw-r--r--usr/src/uts/common/sys/syscall.h5
-rw-r--r--usr/src/uts/common/syscall/getpagesizes.c18
-rw-r--r--usr/src/uts/common/vm/page.h2
-rw-r--r--usr/src/uts/common/vm/vm_pagelist.c29
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);