首页 > 解决方案 > Linux内核显示“警告:在arch/x86/mm/pageattr.c:962 change_page_attr_set_clr”,没有解释

问题描述

我正在编写一个针对 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()then set_pages_rw()。然而,正如内核源代码所说,这是一个已弃用的 API,它建议set_memory_rw()改用

这些 API 应被视为已弃用,并且将来可能会被删除。[...] 具体来说,旧 API 的许多用户都有一个虚拟地址,在该地址上称为 virt_to_page() 或 vmalloc_to_page() 以获取旧 API 所需的 struct page*。要转换这些情况,请在原始虚拟地址上使用 set_memory_*(),不要使用这些函数。

谁能解释这里的问题是什么?
我想我正在触发这个检查,这表明我可以添加*addr &= PAGE_MASK;但我不想盲目地这样做。

标签: linuxlinux-kernelx86kernel-module

解决方案


我想我正在触发这个检查,这表明我可以添加 *addr &= PAGE_MASK; 但我不想盲目地去做。

对我来说听起来不错(这极有可能是“地址未与页面边界对齐”问题;并且极有可能不想盲目地这样做是个好主意)。

可能的情况是您有一系列您关心的地址(而不是一系列页面);这就是你解决这个问题的方式。这意味着:

a)计算时要小心numpages(例如,原始范围可能类似于“4 个字节,一页末尾有 2 个字节,下一页开始有 2 个字节”)。正确的方法是将“起始地址”向下取整(pg = start_address & PAGE_MASK;),将“结束地址”向上取整(end_page = ((start_address + size_in_bytes - 1) | ~PAGE_MASK) + 1;),然后计算页数(numpages = end_page - pg)。

b) 同一页面中可能还有其他您不希望使用新页面属性的内容。如果是这种情况,那么你就有了一个基本的设计问题。


推荐阅读