問題現象
(1) 內核中通過ioremap映射一段大小0x8000的保留內存,在執行memset(addr, 0, 256)時出現非對齊異常:
1 Unhandled fault: alignment fault (0x96000061) at 0xffffff8009080000 2 Internal error: : 96000061 [#1] PREEMPT SMP 3 Modules linked in: my_kmod(O) [last unloaded: my_kmod]
(2) 將上述的memset(addr, 0, size)中的 size改小,如20個字節,上述問題消失。
問題解決方案
將ioremap()更換為ioremap_normal()或者ioremap_wc()可規避此問題。
問題原因
armv8架構為了性能方面的考慮使用了dczva指令對memset進行了改造;這條指令
1 ffffff80082b252c: d50b7428 dc zva, x8
觸發了異常。根據armv8寄存器手冊dc zva 指令如果操作的是device memory類型有可能觸發非對齊訪問異常;而通過ioremap()映射的內存類型就是device memory類型,因而會出現此問題。
參考《Arm® Architecture Registers Armv8, for Armv8-A architecture profile》