armv8 memset()引发alignment fault

问题现象

  (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》

原文地址:https://www.cnblogs.com/liuhailong0112/p/12917912.html