Post

Replies

Boosts

Views

Activity

PCI dext: scatter-gather DMA to application buffer
Hello, I am porting a PCI driver written with IOKit to the new PCIDriverKit framework. I am able to perform DMA with a contiguous buffer allocated inside the dext (with IOBufferMemoryDescriptor::Create). But I would also like to perform DMA to and from a buffer allocated by an application. What I exactly want to do is: Allocate an aligned buffer in the app (with e.g. posix_memalign) Send the pointer to this buffer to the dext In the dext, retrieve the list of pages descriptors to be able to perform DMA without copy into (or from) this buffer. In IOKit, we can use methods such IOMemoryDescriptor::withAddressRange and IODMACommand::gen64IOVMSegments to map and retrieve the scatter gather list but I cannot find any information on how to do this in a dext with the PCIDriverKit framework. Can anybody help me on how to do that?
4
0
2.2k
Dec ’21
IO virtual addresses are leaking
I am porting a PCIe driver to the new IODMACommand API (my previous post). I currently am able to perform DMA accesses, but I cannot seem to release the DART IO mapped addresses properly. After a few thousand requests, the address range is exhausted leading to Subsequent mapping requests fail (mapper-apciec0-3-0-0) IODARTVMAllocatorGeneric::vmAlloc: VM exhausted (mapper-apciec0-3-0-0) IODARTMapper::iovmMapMemory: Map request failed (0xe00002bd) ... setMemoryDescriptor() returned kIOReturnNoMemory The whole computer usually crashes a few seconds / minutes later with panic(cpu 1 caller 0xfffffe00283155d8): "pmap_mark_page_as_ppl_page_internal: page is not free, " "pa=0x80fb0c000" I do not understand what I'm doing wrong. I carefully call prepare and complete on my IODMACommand around DMA accesses. I check the return code of every call. I have tried creating and releasing a new IODMACommand for each request creating and releasing a new IOBufferMemoryDescriptor for each request unloading and reloading my kext between each request Whatever I do, the addresses returned by genIOVMSegments are increasing and never seem to be reused. Thanks for your help!
0
0
881
Jun ’21
IODMACommand::setMemoryDescriptor returns kIOReturnCannotLock
I am trying to port the DMA part of a PCIe driver from the old getPhysicalAddress() to the IODMACommand API. My problem is that IODMACommand::setMemoryDescriptor() returns kIOReturnCannotLock. I also have the following error in the system log: (mapper-apciec0-3-0-0) IODARTMapper::iovmMapMemory: Map request failed (0xe00002cc) iodc=<ptr>, iomd=<ptr>, length=0x10000 Here is how I allocate my memory descriptor : ULONGLONG PhysicalMask_LL = 0xffffffffffffffffULL << PAGE_SHIFT; mpCommonBuffers[BufId_UL].pBufferDescriptor = IOBufferMemoryDescriptor::inTaskWithPhysicalMask(kernel_task, kIOMemoryPhysicallyContiguous | kIODirectionIn, Size_UL, PhysicalMask_LL); And here is how I create the DMA command : IOMapper* pMapper_X = IOMapper::copyMapperForDevice(pProvider_O); mpDmaCommand_X = IODMACommand::withSpecification(kIODMACommandOutputHost64, 64, 0, (IODMACommand::MappingOptions)(IODMACommand::kMapped), 0, 1, pMapper_X, NULL); Any idea what could cause this error? Thanks.
2
0
1.2k
Jun ’21