Print this page
OS-3602 lxbrand LTP recv* tests failing on MSG_ERRQUEUE flag
OS-3600 lxbrand 32bit cannot boot with OS-3594 fix
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>
OS-3594 lx brand: need support for MAP_32BIT

@@ -17,11 +17,14 @@
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
  */
 
-/* Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved. */
+/*
+ * Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved.
+ * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ */
 
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */

@@ -50,10 +53,11 @@
 #include <sys/mman.h>
 #include <sys/vmparam.h>
 #include <sys/fcntl.h>
 #include <sys/lwpchan_impl.h>
 #include <sys/nbmlock.h>
+#include <sys/brand.h>
 
 #include <vm/hat.h>
 #include <vm/as.h>
 #include <vm/seg.h>
 #include <vm/seg_dev.h>

@@ -540,11 +544,25 @@
         if (*addrp == NULL)
                 return (ENOMEM);
         return (0);
 }
 
+caddr_t
+map_userlimit(proc_t *pp, struct as *as, int flags)
+{
+        if (flags & _MAP_LOW32) {
+                if (PROC_IS_BRANDED(pp) && BROP(pp)->b_map32limit != NULL) {
+                        return ((caddr_t)(uintptr_t)BROP(pp)->b_map32limit(pp));
+                } else {
+                        return ((caddr_t)_userlimit32);
+                }
+        }
 
+        return (as->a_userlimit);
+}
+
+
 /*
  * Used for MAP_ANON - fast way to get anonymous pages
  */
 static int
 zmap(struct as *as, caddr_t *addrp, size_t len, uint_t uprot, int flags,

@@ -555,23 +573,20 @@
 
         if (((PROT_ALL & uprot) != uprot))
                 return (EACCES);
 
         if ((flags & MAP_FIXED) != 0) {
-                caddr_t userlimit;
-
                 /*
                  * Use the user address.  First verify that
                  * the address to be used is page aligned.
                  * Then make some simple bounds checks.
                  */
                 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
                         return (EINVAL);
 
-                userlimit = flags & _MAP_LOW32 ?
-                    (caddr_t)USERLIMIT32 : as->a_userlimit;
-                switch (valid_usr_range(*addrp, len, uprot, as, userlimit)) {
+                switch (valid_usr_range(*addrp, len, uprot, as,
+                    map_userlimit(as->a_proc, as, flags))) {
                 case RANGE_OKAY:
                         break;
                 case RANGE_BADPROT:
                         return (ENOTSUP);
                 case RANGE_BADADDR:

@@ -735,23 +750,19 @@
 
         /*
          * If the user specified an address, do some simple checks here
          */
         if ((flags & MAP_FIXED) != 0) {
-                caddr_t userlimit;
-
                 /*
                  * Use the user address.  First verify that
                  * the address to be used is page aligned.
                  * Then make some simple bounds checks.
                  */
                 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
                         return (EINVAL);
-
-                userlimit = flags & _MAP_LOW32 ?
-                    (caddr_t)USERLIMIT32 : as->a_userlimit;
-                switch (valid_usr_range(*addrp, len, uprot, as, userlimit)) {
+                switch (valid_usr_range(*addrp, len, uprot, as,
+                    map_userlimit(curproc, as, flags))) {
                 case RANGE_OKAY:
                         break;
                 case RANGE_BADPROT:
                         return (ENOTSUP);
                 case RANGE_BADADDR: