Apple Silicon M1 crashing with IOPCIFamily based custom KEXT

We have developed an IOPCIFamily based custom KEXT to communicate with Thunderbolt interface storage device.
This KEXT is working fine with Apple machines with Intel CPUs in all types of machines (iMac, iMac Pro and MacBooks).

We tested this KEXT with Apple Silicon M1 machine where we are observing crash for the very first command we send to the Thunderbolt device.

We observed that there is difference in number of bits in Physical Address we use for preparing command PRPs.
In Intel machines we get 28-Bit Physical Address whereas in M1 we are getting 36-Bit address used for PRPs.

We use inTaskWithPhysicalMask api to allocate memory buffer we use for preparing command PRPs.
Below are the options we have used for this:

options: kIOMemoryPhysicallyContiguous | kIODirectionInOut
capacity: 16kb
physicalMask: 0xFFFFF000UL (We want 4kb aligned memory)


According to below documentation, we have to use inTaskWithPhysicalMask api to get memory below 4gb.

https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/64bitPorting/KernelExtensionsandDrivers/KernelExtensionsandDrivers.html#//apple_ref/doc/uid/TP40001064-CH227-SW1

Some devices can only handle physical addresses that fit into 32 bits. To the extent that it is possible to use 64-bit addresses you should do so, but for these devices, you can either use IODMACommand or the initWithPhysicalMask method of IOBufferMemoryDescriptor to allocate a bounce buffer within the bottom 4 GB of physical memory.

So just want to know what's the difference between Intel and ARM64 architecture with respect to physical memory access.
Is there any difference between byte order for physical memory address..??

Crash log is given below:

panic(cpu 0 caller 0xfffffe0016e08cd8): "apciec[0:pcic0-bridge]::handleInterrupt: Request address is greater than 32 bits linksts=0x99000001 pcielint=0x00020000 linkcdmsts=0x00000800 (ltssm 0x11=L0)\n"
Debugger message: panic
Memory ID: 0x6
OS release type: User
OS version: 20C69
Kernel version: Darwin Kernel Version 20.2.0: Wed Dec 2 20:40:21 PST 2020; root:xnu-7195.60.75~1/RELEASEARM64T8101
Fileset Kernelcache UUID: 3E6AA74DF723BCB886499A5AAB34FA34
Kernel UUID: 48F71DB3-6C91-3E62-9576-3A1DCEF2B536
iBoot version: iBoot-6723.61.3
secure boot?: YES
Paniclog version: 13
KernelCache slide: 0x000000000dbfc000
KernelCache base: 0xfffffe0014c00000
Kernel slide: 0x000000000e73c000
Kernel text base: 0xfffffe0015740000
Kernel text exec base: 0xfffffe0015808000
machabsolutetime: 0x12643a9c5
Epoch Time: sec usec
Boot : 0x5fe06736 0x0009afbc
Sleep : 0x00000000 0x00000000
Wake : 0x00000000 0x00000000
Calendar: 0x5fe067fd 0x0006569d

CORE 0 recently retired instr at 0xfffffe0015971798
CORE 1 recently retired instr at 0xfffffe0015972c5c
CORE 2 recently retired instr at 0xfffffe0015972c5c
CORE 3 recently retired instr at 0xfffffe0015972c5c
CORE 4 recently retired instr at 0xfffffe0015972c60
CORE 5 recently retired instr at 0xfffffe0015972c60
CORE 6 recently retired instr at 0xfffffe0015972c60
CORE 7 recently retired instr at 0xfffffe0015972c60
Panicked task 0xfffffe166ce9e550: 75145 pages, 462 threads: pid 0: kernel_task
Panicked thread: 0xfffffe166d053918, backtrace: 0xfffffe306cb4b6d0, tid: 141
lr: 0xfffffe0015855f8c fp: 0xfffffe306cb4b740
lr: 0xfffffe0015855d58 fp: 0xfffffe306cb4b7b0
lr: 0xfffffe0015977f5c fp: 0xfffffe306cb4b7d0
lr: 0xfffffe0015969914 fp: 0xfffffe306cb4b880
lr: 0xfffffe001580f7e8 fp: 0xfffffe306cb4b890
lr: 0xfffffe00158559e8 fp: 0xfffffe306cb4bc20
lr: 0xfffffe00158559e8 fp: 0xfffffe306cb4bc90
lr: 0xfffffe0015ff03f8 fp: 0xfffffe306cb4bcb0
lr: 0xfffffe0016e08cd8 fp: 0xfffffe306cb4bd60
lr: 0xfffffe00166bc778 fp: 0xfffffe306cb4be30
lr: 0xfffffe0015f2226c fp: 0xfffffe306cb4be80
lr: 0xfffffe0015f1e2f4 fp: 0xfffffe306cb4bec0
lr: 0xfffffe0015f1f050 fp: 0xfffffe306cb4bf00
lr: 0xfffffe0015818c14 fp: 0x0000000000000000
Kernel Extensions in backtrace:
com.apple.driver.AppleEmbeddedPCIE(1.0)[4F37F34B-EE1B-3282-BD8B-00009B954483]@0xfffffe00166b4000->0xfffffe00166c7fff
dependency: com.apple.driver.AppleARMPlatform(1.0.2)[5CBA9CD0-E248-38E3-94E5-4CC5EAB96DE1]@0xfffffe0016148000->0xfffffe0016193fff
dependency: com.apple.driver.IODARTFamily(1)[88B19766-4B19-3106-8ACE-EC29201F00A3]@0xfffffe0017890000->0xfffffe00178a3fff
dependency: com.apple.iokit.IOPCIFamily(2.9)[5187699D-1DDC-3763-934C-1C4896310225]@0xfffffe0017c48000->0xfffffe0017c63fff
dependency: com.apple.iokit.IOReportFamily(47)[93EC9828-1413-3458-A6B2-DBB3E24540AE]@0xfffffe0017c64000->0xfffffe0017c67fff
com.apple.driver.AppleT8103PCIeC(1.0)[35AEB73B-D51E-3339-AB5B-50AC78740FB8]@0xfffffe0016e04000->0xfffffe0016e13fff
dependency: com.apple.driver.AppleARMPlatform(1.0.2)[5CBA9CD0-E248-38E3-94E5-4CC5EAB96DE1]@0xfffffe0016148000->0xfffffe0016193fff
dependency: com.apple.driver.AppleEmbeddedPCIE(1)[4F37F34B-EE1B-3282-BD8B-00009B954483]@0xfffffe00166b4000->0xfffffe00166c7fff
dependency: com.apple.driver.ApplePIODMA(1)[A8EFA5BD-B11D-3A84-ACBD-6DB25DBCD817]@0xfffffe0016b0c000->0xfffffe0016b13fff
dependency: com.apple.iokit.IOPCIFamily(2.9)[5187699D-1DDC-3763-934C-1C4896310225]@0xfffffe0017c48000->0xfffffe0017c63fff
dependency: com.apple.iokit.IOReportFamily(47)[93EC9828-1413-3458-A6B2-DBB3E24540AE]@0xfffffe0017c64000->0xfffffe0017c67fff
dependency: com.apple.iokit.IOThunderboltFamily(9.3.2)[11617399-2987-322D-85B6-EF2F1AD4A794]@0xfffffe0017d80000->0xfffffe0017e93fff

Stackshot Succeeded Bytes Traced 277390 (Uncompressed 703968) **

System Information:
Apple Silicon M1
BigSur 11.1
Model: Macmini9,1

Any help or suggestion is really appreciated.
Thanks
Did you try setPreparationID to your memory descriptor?
I am having a similar issue with IOBufferMemoryDescriptor::inTaskWithPhysicalMask.

It seems like inTaskWithPhysicalMask does not allow the physicalMask to restrict the output address to only 32-bits on an M1 based mac. If I change the physicalMask to be 0xFFFFFF000 (>32 bits) then the inTaskWithPhysicalMask succeeds but now the hardware has an issue with the 64-bit addressing.

Also, it would seem that setPreparationID is for user mode code, not Kernel.

Have you found a way round this?
Yes..
I have found the solution. Use IODMACommand .
Care to share some example source on how you were able to do that?

I am also using IODMACommand. However if the IOBufferMemoryDescriptor::inTaskWithPhysicalMask has the physicalMask set to 0xFFFFF000 (32 bits) then inTaskWithPhysicalMask fails and it wouldn't matter what IODMACommand does since you can't get there.
Apple Silicon M1 crashing with IOPCIFamily based custom KEXT
 
 
Q