Index: trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c	(revision 20449)
+++ trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c	(revision 20471)
@@ -20,5 +20,5 @@
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
@@ -111,5 +111,5 @@
  */
 static struct modlmisc vbi_modlmisc = {
-	&mod_miscops, "VirtualBox Interfaces V4"
+	&mod_miscops, "VirtualBox Interfaces V5"
 };
 
@@ -199,20 +199,26 @@
 };
 
-void *
-vbi_contig_alloc(uint64_t *phys, size_t size)
+static void *
+vbi_internal_alloc(uint64_t *phys, size_t size, int contig)
 {
 	ddi_dma_attr_t attr;
 	pfn_t pfn;
 	void *ptr;
+	uint_t npages;
 
 	if ((size & PAGEOFFSET) != 0)
 		return (NULL);
+	npages = size >> PAGESHIFT;
+	if (npages == 0)
+		return (NULL);
 
 	attr = base_attr;
 	attr.dma_attr_addr_hi = *phys;
+	if (!contig)
+		attr.dma_attr_sgllen = npages;
 	ptr = contig_alloc(size, &attr, PAGESIZE, 1);
 
 	if (ptr == NULL) {
-		VBI_VERBOSE("vbi_contig_alloc() failure");
+		VBI_VERBOSE("vbi_internal_alloc() failure");
 		return (NULL);
 	}
@@ -223,4 +229,10 @@
 	*phys = (uint64_t)pfn << PAGESHIFT;
 	return (ptr);
+}
+
+void *
+vbi_contig_alloc(uint64_t *phys, size_t size)
+{
+	return (vbi_internal_alloc(phys, size, 1));
 }
 
@@ -1060,15 +1072,27 @@
 }
 
-/*
- * This is revision 4 of the interface. As more functions are added,
+void
+vbi_poke_cpu(int c)
+{
+	if (c < ncpus)
+		poke_cpu(c);
+}
+
+/*
+ * This is revision 5 of the interface. As more functions are added,
  * they should go after this point in the file and the revision level
  * increased. Also change vbi_modlmisc at the top of the file.
  */
-uint_t vbi_revision_level = 4;
-
-void
-vbi_poke_cpu(int c)
-{
-	if (c < ncpus)
-		poke_cpu(c);
-}
+uint_t vbi_revision_level = 5;
+
+void *
+vbi_lowmem_alloc(uint64_t phys, size_t size)
+{
+	return (vbi_internal_alloc(&phys, size, 0));
+}
+
+void
+vbi_lowmem_free(void *va, size_t size)
+{
+	p_contig_free(va, size);
+}
Index: trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h
===================================================================
--- trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h	(revision 20449)
+++ trunk/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/sys/vbi.h	(revision 20471)
@@ -310,4 +310,25 @@
 /* end of interfaces defined for version 4 */
 
+/* begin interfaces defined for version 5 */
+/*
+ * Allocate and free physically limited, page aligned memory. Note that
+ * the allocated pages are not physically contiguous.
+ *
+ * return value is a) NULL if memory below "phys" not available or
+ * b) virtual address of memory in kernel heap
+ *
+ * phys on input is set to the upper boundary of acceptable memory
+ *
+ * size is the amount to allocate and must be a multiple of PAGESIZE
+ */
+extern void *vbi_lowmem_alloc(uint64_t phys, size_t size);
+
+/*
+ * va is from vbi_lowmem_alloc() return value
+ * size must match from vbi_lowmem_alloc()
+ */
+extern void vbi_lowmem_free(void *va, size_t size);
+/* end of interfaces defined for version 5 */
+
 #ifdef	__cplusplus
 }
Index: trunk/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c	(revision 20449)
+++ trunk/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c	(revision 20471)
@@ -69,4 +69,8 @@
     switch (pMemSolaris->Core.enmType)
     {
+        case RTR0MEMOBJTYPE_LOW:
+            vbi_lowmem_free(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
+            break;
+
         case RTR0MEMOBJTYPE_CONT:
             vbi_contig_free(pMemSolaris->Core.pv, pMemSolaris->Core.cb);
@@ -86,5 +90,4 @@
 
         /* unused */
-        case RTR0MEMOBJTYPE_LOW:
         case RTR0MEMOBJTYPE_PHYS:
         case RTR0MEMOBJTYPE_RES_VIRT:
@@ -121,19 +124,25 @@
 int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
 {
-    /* Try page alloc first */
-    int rc = rtR0MemObjNativeAllocPage(ppMem, cb, fExecutable);
-    if (RT_SUCCESS(rc))
-    {
-        size_t iPage = cb >> PAGE_SHIFT;
-        while (iPage-- > 0)
-            if (rtR0MemObjNativeGetPagePhysAddr(*ppMem, iPage) > (_4G - PAGE_SIZE))
-            {
-                /* Failed! Fall back to physical contiguous alloc */
-                RTR0MemObjFree(*ppMem, false);
-                rc = rtR0MemObjNativeAllocCont(ppMem, cb, fExecutable);
-                break;
-            }
-    }
-    return rc;
+    NOREF(fExecutable);
+
+    /* Create the object */
+    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_LOW, NULL, cb);
+    if (!pMemSolaris)
+        return VERR_NO_MEMORY;
+
+    /* Allocate physically low page-aligned memory. */
+    caddr_t virtAddr;
+    uint64_t phys = (unsigned)0xffffffff;
+    virtAddr = vbi_lowmem_alloc(&phys, cb);
+    if (virtAddr == NULL)
+    {
+        rtR0MemObjDelete(&pMemSolaris->Core);
+        return VERR_NO_LOW_MEMORY;
+    }
+    Assert(phys < (uint64_t)1 << 32);
+    pMemSolaris->Core.pv = virtAddr;
+    pMemSolaris->handle = NULL;
+    *ppMem = &pMemSolaris->Core;
+    return VINF_SUCCESS;
 }
 
