我正在ARM Linux上编写一个JIT,它执行一个包含自修改代码的指令集。指令集没有任何缓存刷新指令(在这方面类似于x86)。
如果我向页面写出一些代码,然后在该页面上调用mprotect
,那是否足以使指令缓存无效?或者我还需要在这些页面上使用cacheflush
系统调用吗?
答案 0 :(得分:3)
您希望mmap / mprotect系统调用会建立立即更新的映射,并且无需进一步交互即可使用指定的内存范围。我看到内核确实在mprotect上刷新了缓存。在这种情况下,不需要缓存刷新。
但是,我也看到某些版本的libc在cacheflush
之后调用mprotect
,这意味着某些环境需要刷新缓存(或以前) 。我猜想这是一个bug的解决方法。
您可以随时将调用添加到cacheflush;虽然它是额外的代码,但它不应该是有害的 - 最坏的情况下,缓存已经被刷新了。你总是可以写一个快速测试,看看会发生什么......
答案 1 :(得分:1)
特别是在 Linux 中,mprotect 会缓存刷新所有缓存,至少从 2.6.39 版开始(甚至更早)。你可以在代码中看到: https://elixir.bootlin.com/linux/v2.6.39.4/source/mm/mprotect.c#L122 .
如果您正在编写 POSIX 可移植代码,我会调用 cacheflush,因为标准 C 库不要求内核或实现执行此类行为。
编辑:您还应该小心检查 flush_cache_range
在您实现的特定架构中的作用,因为在某些架构(如 ARM64)中,此函数什么都不做...
答案 2 :(得分:0)
我相信你不必显式刷新缓存。
这是哪个处理器? ARMv5中?的ARMv7?