【问题标题】:Write to a cacheable physical address in linux kernel without using ioremap or mmap在不使用 ioremap 或 mmap 的情况下写入 linux 内核中的可缓存物理地址
【发布时间】:2012-02-29 21:47:49
【问题描述】:

我正在更改 linux 内核调度程序以在已知物理内存位置打印下一个进程的 pid。 mmap 用于用户空间程序,而我读到 ioremap 将页面标记为不可缓存,这会减慢程序的执行速度。我想要一种快速写入已知物理内存的方法。 phys_to_virt 是我认为可行的选项。任何关于不同技术的想法。

PS:我在 qemu 上运行这个 linux 内核。 qemu 将使用物理地址来读取客户内核发送的信息。写入已知 io-port 是不可行的,因为每次访问该设备时都会调用支持此 io-device 的设备代码。

编辑:我希望 pid 的物理地址位置是安全的。如何确保内核正在使用的物理地址没有分配给任何进程。据我所知,ioremap 会将页面标记为可缓存,因此没有什么用处。

【问题讨论】:

    标签: linux memory-management linux-kernel


    【解决方案1】:

    执行此操作的最简单方法是执行kmalloc() 以在内核中获取一些内存。然后您可以通过将其传递给virt_to_phys() 来获取返回的指针的物理地址。这完全是 hack,但对于您在 qemu 下调试/跟踪的情况,它应该可以正常工作。

    编辑:我误解了这个问题。如果你想使用一个特定的物理地址,你可以做几件事。也许最干净的做法是修改 qemu 传入的 e820 映射以将 RAM 页面标记为保留,然后内核不会使用它。 (即与传入 ACPI 表的方式相同)。

    如果你不想修改 qemu,你也可以修改早期内核启动(可能在arch/x86/kernel/setup.c 附近),在你想要保护不被使用的特定物理页面上做reserve_bootmem()

    要实际使用指定的物理地址,您可以使用ioremap_cache(),就像 ACPI 驱动程序访问它们的表一样。

    【讨论】:

    • 但是 kmalloc 并不总是给我相同的物理地址。在 qemu 中,我假设一个已知的物理地址。如果我可以使用模拟 io 设备以某种方式将 pid 的物理地址传达给 qemu,我仍然可以使用您的解决方案。你能建议我一种使用已知物理地址的方法吗?类似 kmalloc/reserve(物理地址) ??
    【解决方案2】:

    似乎我误解了 VM 和主机部分之间的缓存一致性,这是一个更新的答案。 您想要的是“VM 中的虚拟地址”“QEMU 地址空间中的虚拟或物理地址”。 然后你可以kmalloc它,但它可能因实例而异, 或者干脆在内核中声明一个全局变量。

    然后 virt_to_phys 会让你访问 VM 空间中的物理地址,我想你可以在 QEMU 地址空间中翻译它。 “内核正在使用的物理地址未分配给任何进程”是什么意思?您担心包含变量的页面可能会被交换? kmalloced memory is not swappable

    原始(和错误)答案

    如果你想写的地址在它自己的页面中,我看不到 ioremap 这个页面的 会减慢在不同页面中执行的代码。

    无论如何,您都需要缓存刷新,如果没有 SSE,我看不出如果 MMU 和缓存打开,您如何绕过缓存。我只能看到这两个选项:

    • ioremap 并声明特定页面不可缓存

    • 使用“正常”地址,并在每次写入时手动执行缓存刷新。

    【讨论】:

    • 对不起,我不明白这里缓存刷新的使用。我在 qemu-VMM 之上运行 linux 来宾。所以有没有flush都没关系。
    • 同意——为什么需要缓存刷新?如果你在 x86 上,一切都是缓存一致的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多