Loading...
iokit/Kernel/IOBufferMemoryDescriptor.cpp xnu-3248.50.21 xnu-2422.1.72
--- xnu/xnu-3248.50.21/iokit/Kernel/IOBufferMemoryDescriptor.cpp
+++ xnu/xnu-2422.1.72/iokit/Kernel/IOBufferMemoryDescriptor.cpp
@@ -84,7 +84,7 @@
     int           options = 0; // KMA_LOMEM;
 
     kr = kernel_memory_allocate(kernel_map, &vmaddr,
-				page_size, 0, options, VM_KERN_MEMORY_IOKIT);
+				page_size, 0, options);
 
     if (KERN_SUCCESS != kr) vmaddr = 0;
     else 		    bzero((void *) vmaddr, page_size);
@@ -113,6 +113,7 @@
 				mach_vm_address_t alignment,
 				mach_vm_address_t physicalMask)
 {
+    kern_return_t 	  kr;
     task_t		  mapTask = NULL;
     vm_map_t 		  vmmap = NULL;
     mach_vm_address_t     highestMask = 0;
@@ -121,7 +122,8 @@
     bool                  mapped = false;
     bool                  needZero;
 
-    if (!capacity) return false;
+    if (!capacity)
+        return false;
 
     _options   	      = options;
     _capacity         = capacity;
@@ -145,7 +147,7 @@
 	IOMapper::checkForSystemMapper();
 	mapped = (0 != IOMapper::gSystem);
     }
-    needZero = (mapped || (0 != (kIOMemorySharingTypeMask & options)));
+    needZero = mapped;
 
     if (physicalMask && (alignment <= 1))
     {
@@ -167,8 +169,6 @@
 
     _alignment = alignment;
 
-    if ((capacity + alignment) < _capacity) return (false);
-
     if ((inTask != kernel_task) && !(options & kIOMemoryPageable))
 	return false;
 
@@ -184,15 +184,53 @@
 	highestMask = 0;
     }
 
-    // set memory entry cache mode, pageable, purgeable
-    iomdOptions |= ((options & kIOMapCacheMask) >> kIOMapCacheShift) << kIOMemoryBufferCacheShift;
+    // set flags for entry + object create
+    vm_prot_t memEntryCacheMode = VM_PROT_READ | VM_PROT_WRITE;
+
+    // set memory entry cache mode
+    switch (options & kIOMapCacheMask)
+    {
+	case kIOMapInhibitCache:
+	    SET_MAP_MEM(MAP_MEM_IO, memEntryCacheMode);
+	    break;
+
+	case kIOMapWriteThruCache:
+	    SET_MAP_MEM(MAP_MEM_WTHRU, memEntryCacheMode);
+	    break;
+
+	case kIOMapWriteCombineCache:
+	    SET_MAP_MEM(MAP_MEM_WCOMB, memEntryCacheMode);
+	    break;
+
+	case kIOMapCopybackCache:
+	    SET_MAP_MEM(MAP_MEM_COPYBACK, memEntryCacheMode);
+	    break;
+
+	case kIOMapCopybackInnerCache:
+	    SET_MAP_MEM(MAP_MEM_INNERWBACK, memEntryCacheMode);
+	    break;
+
+	case kIOMapDefaultCache:
+	default:
+	    SET_MAP_MEM(MAP_MEM_NOOP, memEntryCacheMode);
+	    break;
+    }
+
     if (options & kIOMemoryPageable)
     {
 	iomdOptions |= kIOMemoryBufferPageable;
-	if (options & kIOMemoryPurgeable) iomdOptions |= kIOMemoryBufferPurgeable;
+
+	// must create the entry before any pages are allocated
+
+	// set flags for entry + object create
+	memEntryCacheMode |= MAP_MEM_NAMED_CREATE;
+
+	if (options & kIOMemoryPurgeable)
+	    memEntryCacheMode |= MAP_MEM_PURGABLE;
     }
     else
     {
+	memEntryCacheMode |= MAP_MEM_NAMED_REUSE;
 	vmmap = kernel_map;
 
 	// Buffer shouldn't auto prepare they should be prepared explicitly
@@ -225,7 +263,7 @@
             				capacity, highestMask, alignment, contig);
 	}
 	else if (needZero
-		  && ((capacity + alignment) <= (page_size - gIOPageAllocChunkBytes)))
+		  && ((capacity + alignment) <= (page_size - kIOPageAllocChunkBytes)))
 	{
             _internalFlags |= kInternalFlagPageAllocated;
             needZero        = false;
@@ -234,7 +272,7 @@
 	    {
 		IOStatisticsAlloc(kIOStatisticsMallocAligned, capacity);
 #if IOALLOCDEBUG
-		OSAddAtomic(capacity, &debug_iomalloc_size);
+		debug_iomalloc_size += capacity;
 #endif
 	    }
 	}
@@ -254,14 +292,26 @@
     }
 
     if( (options & (kIOMemoryPageable | kIOMapCacheMask))) {
+	ipc_port_t	sharedMem;
 	vm_size_t	size = round_page(capacity);
 
-	// initWithOptions will create memory entry
-	iomdOptions |= kIOMemoryPersistent;
+	kr = mach_make_memory_entry(vmmap,
+				    &size, (vm_offset_t)_buffer,
+				    memEntryCacheMode, &sharedMem,
+				    NULL );
+
+	if( (KERN_SUCCESS == kr) && (size != round_page(capacity))) {
+	    ipc_port_release_send( sharedMem );
+	    kr = kIOReturnVMError;
+	}
+	if( KERN_SUCCESS != kr)
+	    return( false );
+
+	_memEntry = (void *) sharedMem;
 
 	if( options & kIOMemoryPageable) {
 #if IOALLOCDEBUG
-	    OSAddAtomicLong(size, &debug_iomallocpageable_size);
+	    debug_iomallocpageable_size += size;
 #endif
 	    mapTask = inTask;
 	    if (NULL == inTask)
@@ -302,7 +352,7 @@
 		return( false );
 	}
 	reserved->map = createMappingInTask(mapTask, 0, 
-			    kIOMapAnywhere | (options & kIOMapPrefault) | (options & kIOMapCacheMask), 0, 0);
+			    kIOMapAnywhere | (options & kIOMapCacheMask), 0, 0);
 	if (!reserved->map)
 	{
 	    _buffer = 0;
@@ -494,7 +544,7 @@
     if (options & kIOMemoryPageable)
     {
 #if IOALLOCDEBUG
-	OSAddAtomicLong(-(round_page(size)), &debug_iomallocpageable_size);
+	debug_iomallocpageable_size -= round_page(size);
 #endif
     }
     else if (buffer)
@@ -514,7 +564,7 @@
 		kmem_free(kernel_map, page, page_size);
 	    }
 #if IOALLOCDEBUG
-		OSAddAtomic(-size, &debug_iomalloc_size);
+	    debug_iomalloc_size -= size;
 #endif
 	    IOStatisticsAlloc(kIOStatisticsFreeAligned, size);
 	}
@@ -554,7 +604,6 @@
 void IOBufferMemoryDescriptor::setLength(vm_size_t length)
 {
     assert(length <= _capacity);
-    if (length > _capacity) return;
 
     _length = length;
     _ranges.v64->length = length;