Loading...
--- xnu/xnu-3248.50.21/iokit/Kernel/IOBufferMemoryDescriptor.cpp
+++ xnu/xnu-2422.115.4/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;