问题现象
(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》