Index: trunk/include/iprt/memobj.h
===================================================================
--- trunk/include/iprt/memobj.h	(revision 14823)
+++ trunk/include/iprt/memobj.h	(revision 14824)
@@ -188,4 +188,5 @@
  *          physical memory on this platform. The caller should expect
  *          this error and have a fallback strategy for it.
+ *
  * @param   pMemObj         Where to store the ring-0 memory object handle.
  * @param   cb              Number of bytes to allocate. This is rounded up to nearest page.
@@ -240,4 +241,7 @@
  * Maps a memory object into kernel virtual address space.
  *
+ * This is the same as calling RTR0MemObjMapKernelEx with cbSub and offSub set
+ * to zero.
+ *
  * @returns IPRT status code.
  * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
@@ -251,4 +255,31 @@
 
 /**
+ * Maps a memory object into kernel virtual address space.
+ *
+ * The ability to map subsections of the object into kernel space is currently
+ * not implemented on all platforms. All/Most of platforms supports mapping the
+ * whole object into  kernel space.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if it's not possible to map a subsection of a
+ *          memory object on this platform. When you hit this, try implement it.
+ *
+ * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
+ * @param   MemObjToMap     The object to be map.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   offSub          Where in the object to start mapping. If non-zero
+ *                          the value must be page aligned and cbSub must be
+ *                          non-zero as well.
+ * @param   cbSub           The size of the part of the object to be mapped. If
+ *                          zero the entire object is mapped. The value must be
+ *                          page aligned.
+ */
+RTR0DECL(int) RTR0MemObjMapKernelEx(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment,
+                                    unsigned fProt, size_t offSub, size_t cbSub);
+
+/**
  * Maps a memory object into user virtual address space in the current process.
  *
Index: trunk/src/VBox/Runtime/include/internal/memobj.h
===================================================================
--- trunk/src/VBox/Runtime/include/internal/memobj.h	(revision 14823)
+++ trunk/src/VBox/Runtime/include/internal/memobj.h	(revision 14824)
@@ -380,4 +380,6 @@
  *
  * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED see RTR0MemObjMapKernelEx.
+ *
  * @param   ppMem           Where to store the ring-0 memory object handle of the mapping object.
  * @param   pMemToMap       The object to be map.
@@ -385,6 +387,13 @@
  * @param   uAlignment      The alignment of the reserved memory; PAGE_SIZE, _2M or _4M.
  * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
- */
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt);
+ * @param   offSub          Where in the object to start mapping. If non-zero
+ *                          the value must be page aligned and cbSub must be
+ *                          non-zero as well.
+ * @param   cbSub           The size of the part of the object to be mapped. If
+ *                          zero the entire object is mapped. The value must be
+ *                          page aligned.
+ */
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub);
 
 /**
Index: trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
===================================================================
--- trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp	(revision 14823)
+++ trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp	(revision 14824)
@@ -44,5 +44,5 @@
 #include "internal/memobj.h"
 
-#define USE_VM_MAP_WIRE
+/*#define USE_VM_MAP_WIRE - may re-enable later when non-mapped allocations are added. */
 
 
@@ -542,5 +542,6 @@
 
 
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub)
 {
     /*
@@ -549,8 +550,10 @@
     int rc = VERR_INVALID_PARAMETER;
     PRTR0MEMOBJDARWIN pMemToMapDarwin = (PRTR0MEMOBJDARWIN)pMemToMap;
+printf("rtR0MemObjNativeMapKernel: pMemDesc=%p\n", pMemToMapDarwin->pMemDesc);
     if (pMemToMapDarwin->pMemDesc)
     {
         IOMemoryMap *pMemMap = pMemToMapDarwin->pMemDesc->map(kernel_task, kIOMapAnywhere,
-                                                              kIOMapAnywhere | kIOMapDefaultCache);
+                                                              kIOMapAnywhere | kIOMapDefaultCache,
+                                                              offSub, cbSub);
         if (pMemMap)
         {
Index: trunk/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c	(revision 14823)
+++ trunk/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c	(revision 14824)
@@ -468,6 +468,8 @@
 
 
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
-{
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub)
+{
+    AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
     AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
 
Index: trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c	(revision 14823)
+++ trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c	(revision 14824)
@@ -940,5 +940,6 @@
 
 
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub)
 {
     int rc = VERR_NO_MEMORY;
@@ -947,4 +948,5 @@
 
     /* Fail if requested to do something we can't. */
+    AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
     AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
     AssertMsgReturn(uAlignment <= PAGE_SIZE, ("%#x\n", uAlignment), VERR_NOT_SUPPORTED);
Index: trunk/src/VBox/Runtime/r0drv/memobj-r0drv.cpp
===================================================================
--- trunk/src/VBox/Runtime/r0drv/memobj-r0drv.cpp	(revision 14823)
+++ trunk/src/VBox/Runtime/r0drv/memobj-r0drv.cpp	(revision 14824)
@@ -670,4 +670,35 @@
 RTR0DECL(int) RTR0MemObjMapKernel(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
 {
+    return RTR0MemObjMapKernelEx(pMemObj, MemObjToMap, pvFixed, uAlignment, fProt, 0, 0);
+}
+
+
+/**
+ * Maps a memory object into kernel virtual address space.
+ *
+ * The ability to map subsections of the object into kernel space is currently
+ * not implemented on all platforms. All/Most of platforms supports mapping the
+ * whole object into  kernel space.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_NOT_SUPPORTED if it's not possible to map a subsection of a
+ *          memory object on this platform. When you hit this, try implement it.
+ *
+ * @param   pMemObj         Where to store the ring-0 memory object handle of the mapping object.
+ * @param   MemObjToMap     The object to be map.
+ * @param   pvFixed         Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param   uAlignment      The alignment of the reserved memory.
+ *                          Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param   fProt           Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param   offSub          Where in the object to start mapping. If non-zero
+ *                          the value must be page aligned and cbSub must be
+ *                          non-zero as well.
+ * @param   cbSub           The size of the part of the object to be mapped. If
+ *                          zero the entire object is mapped. The value must be
+ *                          page aligned.
+ */
+RTR0DECL(int) RTR0MemObjMapKernelEx(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment,
+                                    unsigned fProt, size_t offSub, size_t cbSub)
+{
     PRTR0MEMOBJINTERNAL pMemToMap;
     PRTR0MEMOBJINTERNAL pNew;
@@ -690,8 +721,16 @@
     AssertReturn(fProt != RTMEM_PROT_NONE, VERR_INVALID_PARAMETER);
     AssertReturn(!(fProt & ~(RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC)), VERR_INVALID_PARAMETER);
-
+    AssertReturn(!(offSub & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
+    AssertReturn(offSub < pMemToMap->cb, VERR_INVALID_PARAMETER);
+    AssertReturn(!(cbSub & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);
+    AssertReturn(cbSub <= pMemToMap->cb, VERR_INVALID_PARAMETER);
+    AssertReturn((!offSub && !cbSub) || (offSub + cbSub) <= pMemToMap->cb, VERR_INVALID_PARAMETER);
+
+    /* adjust the request to simplify the native code. */
+    if (offSub == 0 && cbSub == pMemToMap->cb)
+        cbSub = 0;
 
     /* do the mapping. */
-    rc = rtR0MemObjNativeMapKernel(&pNew, pMemToMap, pvFixed, uAlignment, fProt);
+    rc = rtR0MemObjNativeMapKernel(&pNew, pMemToMap, pvFixed, uAlignment, fProt, offSub, cbSub);
     if (RT_SUCCESS(rc))
     {
Index: trunk/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
===================================================================
--- trunk/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp	(revision 14823)
+++ trunk/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp	(revision 14824)
@@ -746,6 +746,8 @@
 
 
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
-{
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub)
+{
+    AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
     return rtR0MemObjNtMap(ppMem, pMemToMap, pvFixed, uAlignment, fProt, NIL_RTR0PROCESS);
 }
Index: trunk/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp
===================================================================
--- trunk/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp	(revision 14823)
+++ trunk/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp	(revision 14824)
@@ -304,6 +304,8 @@
 
 
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
-{
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub)
+{
+    AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
     AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
 
Index: trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c	(revision 14823)
+++ trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c	(revision 14824)
@@ -320,5 +320,6 @@
 }
 
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub)
 {
     /* @todo rtR0MemObjNativeMapKernel / Solaris - Should be fairly simple alloc kernel memory and memload it. */
Index: trunk/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c	(revision 14823)
+++ trunk/src/VBox/Runtime/r0drv/solaris/vbi/memobj-r0drv-solaris.c	(revision 14824)
@@ -254,5 +254,6 @@
 }
 
-int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub)
 {
     /* @todo rtR0MemObjNativeMapKernel / Solaris - Should be fairly simple alloc kernel memory and memload it. */
