Strange MemoryDescriptor behavior
Hi, everyone. I'm observing the following strange situation: 1) I need to get a physical address of a part of my kext's code. I do it with the following code: uint64_t ClassName::virtualAddressToPhysicalAddress(const void* address) { IOReturn ioresult = kIOReturnSuccess; uint64_t result; IOMemoryDescriptor* descriptor = IOMemoryDescriptor::withAddressRange((mach_vm_address_t)address, 1, kIODirectionOut, kernel_task); if (descriptor == NULL) return -1; if ((ioresult = descriptor->prepare()) == kIOReturnSuccess) { result = getPhysicalAddressForDescriptor(descriptor); descriptor->complete(); } else { return -1; } descriptor->release(); return result; } uint64_t ClassName::getPhysicalAddressForDescriptor(IOMemoryDescriptor* descriptor) { uint64_t address = -1; IODMACommand* dma = IODMACommand::withSpecification(kIODMACommandOutputHost64, 64, 0, IODMACommand::kMapped, 0, 1); if (!dma) return address; if (kIOReturnSuccess == dma->setMemoryDescriptor(descriptor)) { IODMACommand::Segment64 segments[1]; UInt32 numSegments = 1; UInt64 offset = 0; if (kIOReturnSuccess == dma->gen64IOVMSegments(&offset, segments, &numSegments)) address = segments[0].fIOVMAddr; dma->clearMemoryDescriptor(); } dma->release(); return address; } 2) I need to wire a page in kernel task. I do it with the following code: void* ClassName::allocatePage(uint64_t* physical_address, bool within4GB) { void* result = NULL; IOBufferMemoryDescriptor* descriptor = NULL; if (within4GB) descriptor = IOBufferMemoryDescriptor::inTaskWithPhysicalMask(kernel_task, kIODirectionInOut| kIOMemoryPhysicallyContiguous| kIOMemoryKernelUserShared, page_size, 0x00000000FFFFFFFFull); else descriptor = IOBufferMemoryDescriptor::withOptions( kIODirectionInOut|kIOMemoryPhysicallyContiguous, page_size, page_size); if (descriptor == NULL) return NULL; descriptor->prepare(); *physical_address = getPhysicalAddressForDescriptor(descriptor); result = descriptor->getBytesNoCopy(); if (result) bzero(result, page_size); return result; } 3) I need to call those two subsequently. It used to work and return different physical addresses. But starting OS X 10.8.2 they may return same physical address. I.e. allocatePage may return the same physical address as virtualAddressToPhysicalAddress called for my kext's code address. I can observe it on latest MacBooks (Mid 2012) with OS X 10.8.2. It does work on the same machines with OS X 10.8.1 and earlier. My question is, if I'm doing it wrong from start, or did something change in the way the latest OS X version work with aforementioned hardware? _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.... This email sent to site_archiver@lists.apple.com
participants (1)
-
Maxim Zhuravlev