【问题标题】:Does mprotect flush the instruction cache on ARM Linux?mprotect 是否刷新 ARM Linux 上的指令缓存?
【发布时间】:2011-02-16 04:33:25
【问题描述】:

我正在 ARM Linux 上编写一个 JIT,它执行包含自修改代码的指令集。该指令集没有任何缓存刷新指令(在这方面类似于 x86)。

如果我将一些代码写入一个页面,然后在该页面上调用mprotect,这足以使指令缓存无效吗?还是我还需要在这些页面上使用 cacheflush 系统调用?

【问题讨论】:

    标签: linux arm jit self-modifying mprotect


    【解决方案1】:

    我相信您不必显式刷新缓存。

    这是哪个处理器? ARMv5? ARMv7?

    【讨论】:

    • 嗯,我名义上是针对 ARMv5。根据 ARM ARM,在自修改代码的情况下,您确实需要刷新指令缓存。我只是想知道 mprotect 是否会为我做这件事。
    【解决方案2】:

    您希望 mmap/mprotect 系统调用会建立立即更新的映射,并且无需进一步交互即可使用指定的内存范围。我看到内核确实刷新了 mprotect 上的缓存。在这种情况下,不需要缓存刷新。

    然而,我还看到某些版本的 libc 确实在 mprotect 之后调用了 cacheflush,这意味着某些环境需要刷新(或以前)缓存。我猜这是一个错误的解决方法。

    您可以随时添加对 cacheflush 的调用;虽然它是额外的代码,但它不应该是有害的——最坏的情况是,缓存已经被刷新了。你总是可以写一个快速测试,看看会发生什么......

    【讨论】:

      【解决方案3】:

      特别是在 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)中,此函数什么都不做......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-09
        • 2011-12-20
        • 2018-02-10
        • 2014-10-08
        相关资源
        最近更新 更多