【发布时间】:2021-09-09 20:50:26
【问题描述】:
我正在编写一个针对 Linux v3-v4 的 x86_64 内核模块,它在内核符号的地址上使用 set_memory_rw()。虽然通话有效,但我收到警告但没有任何解释:
[ 596.183643] ------------[ cut here ]------------
[ 596.183667] WARNING: at arch/x86/mm/pageattr.c:962 change_page_attr_set_clr+0x2ca/0x450()
以前我使用了另一种方法,称为 virt_to_page(),然后是 set_pages_rw()。然而,正如内核源代码所说,这是一个已弃用的 API,它建议使用 set_memory_rw() 代替
这些 API 应被视为已弃用,并且可能会 将来会被删除。 [...] 具体来说,旧 API 的许多用户都有一个虚拟地址, 在该地址上调用 virt_to_page() 或 vmalloc_to_page() 获取旧 API 所需的 struct page*。 要转换这些情况,请在原始文件上使用 set_memory_*() 虚拟地址,不要使用这些函数。
谁能解释这里的问题是什么?
我想我绊倒了this check,这表明我可以添加*addr &= PAGE_MASK;,但我不想盲目地这样做。
【问题讨论】:
-
“我收到警告,但没有任何解释” - 解释可能在警告消息所指的代码中。在您的情况下,您需要检查的是
arch/x86/mm/pageattr.c:962行。即使没有解释,该行也应该包含一个失败的检查,这可以给你一个提示是哪里出了问题。请注意,一行代码特定于您的 Linux 内核版本和补丁。例如。 3.10.108 版在给定行不包含警告:elixir.bootlin.com/linux/v3.10.108/source/arch/x86/mm/… -
@Tsyvarev 在我的案例中,第 962 行等于标准 941:elixir.bootlin.com/linux/v3.10.108/source/arch/x86/mm/… - 虽然我看到了支票,但我不清楚问题出在哪里......它是否强制地址指向页面的开头?
-
"是否强制地址指向页面的开头?" - 是的,它需要地址是页面对齐的。无论您使用何种架构(x86、arm 等),它都无法将 特定 地址设置为可写或可读。内存可写性或可读性的最小单位是页。
标签: linux linux-kernel x86 kernel-module