1 /* 2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 #define IOKIT_ENABLE_SHARED_PTR 29 #include <IOKit/IOGuardPageMemoryDescriptor.h> 30 #include <IOKit/IOMemoryDescriptor.h> 31 #include <IOKit/IOLib.h> 32 #include <vm/vm_kern_xnu.h> 33 #include <mach/mach_vm.h> 34 35 #define super IOGeneralMemoryDescriptor 36 37 OSDefineMetaClassAndStructorsWithZone(IOGuardPageMemoryDescriptor, IOGeneralMemoryDescriptor, ZC_ZFREE_CLEARMEM); 38 39 OSSharedPtr<IOGuardPageMemoryDescriptor> 40 IOGuardPageMemoryDescriptor::withSize(vm_size_t size) 41 { 42 OSSharedPtr<IOGuardPageMemoryDescriptor> me = OSMakeShared<IOGuardPageMemoryDescriptor>(); 43 44 if (me && !me->initWithSize(size)) { 45 me.reset(); 46 } 47 return me; 48 } 49 50 bool 51 IOGuardPageMemoryDescriptor::initWithSize(vm_size_t size) 52 { 53 mach_vm_address_t address; 54 kern_return_t kr; 55 IOOptionBits iomdOptions = kIOMemoryTypeVirtual64 | kIOMemoryAsReference | kIODirectionOutIn; 56 57 size = round_page(size); 58 59 _ranges.v64 = IOMallocType(IOAddressRange); 60 if (!_ranges.v64) { 61 return false; 62 } 63 64 kr = mach_vm_allocate_kernel(kernel_map, &address, size, 65 VM_MAP_KERNEL_FLAGS_ANYWHERE(.vm_tag = VM_KERN_MEMORY_IOKIT)); 66 if (kr != KERN_SUCCESS) { 67 return false; 68 } 69 70 71 _ranges.v64->address = address; 72 _ranges.v64->length = size; 73 74 if (!super::initWithOptions(_ranges.v64, 1, 0, kernel_task, iomdOptions, NULL)) { 75 return false; 76 } 77 78 _size = size; 79 _buffer = (vm_offset_t)address; 80 81 return true; 82 } 83 84 void 85 IOGuardPageMemoryDescriptor::free() 86 { 87 if (_buffer) { 88 vm_deallocate(kernel_map, _buffer, _size); 89 _buffer = 0; 90 } 91 92 if (_ranges.v64) { 93 IOFreeType(_ranges.v64, IOAddressRange); 94 } 95 96 super::free(); 97 } 98 99 IOReturn 100 IOGuardPageMemoryDescriptor::doMap(vm_map_t addressMap, 101 IOVirtualAddress * atAddress, 102 IOOptionBits options, 103 IOByteCount sourceOffset, 104 IOByteCount length) 105 { 106 IOReturn ret = super::doMap(addressMap, atAddress, options, sourceOffset, length); 107 if (ret == kIOReturnSuccess) { 108 IOMemoryMap * mapping = (IOMemoryMap *) *atAddress; 109 vm_map_t map = mapping->fAddressMap; 110 mach_vm_size_t length = mapping->fLength; 111 mach_vm_address_t address = mapping->fAddress; 112 kern_return_t kr = mach_vm_protect(map, address, length, true, VM_PROT_NONE); 113 if (kr != KERN_SUCCESS) { 114 doUnmap(map, (IOVirtualAddress) mapping, 0); 115 return kIOReturnError; 116 } 117 } 118 return ret; 119 } 120