C 为页表遍历编译内核时出错
我正在做一个书桌散步。当我准备更新内核时,出现了一个错误:C 为页表遍历编译内核时出错,c,linux-kernel,virtual-memory,page-tables,C,Linux Kernel,Virtual Memory,Page Tables,我正在做一个书桌散步。当我准备更新内核时,出现了一个错误: kernel/sys.c: In function ‘__do_sys_get_page_info’: kernel/sys.c:2745:23: error: passing argument 1 of ‘pud_offset’ from incompatible pointer type [-Werror=incompatible-pointer-types] pud = pud_offset(pgd, vmpage);
kernel/sys.c: In function ‘__do_sys_get_page_info’:
kernel/sys.c:2745:23: error: passing argument 1 of ‘pud_offset’ from incompatible pointer type [-Werror=incompatible-pointer-types]
pud = pud_offset(pgd, vmpage);
^
In file included from ./include/linux/mm.h:99:0,
from kernel/sys.c:19:
./arch/x86/include/asm/pgtable.h:905:22: note: expected ‘p4d_t * {aka struct <anonymous> *}’ but argument is of type ‘pgd_t * {aka struct <anonymous> *}’
static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
^
kernel/sys.c:在函数“\u do\u sys\u get\u page\u info”中:
kernel/sys.c:2745:23:错误:从不兼容的指针类型传递'pud_offset'的参数1[-Werror=不兼容的指针类型]
pud=pud_偏移量(pgd,vmpage);
^
在包含自./include/linux/mm.h:99:0的文件中,
从kernel/sys.c:19:
/arch/x86/include/asm/pgtable.h:905:22:注意:应为“p4d_t*{aka struct*}”,但参数的类型为“pgd_t*{aka struct*}”
静态内联pud_t*pud_偏移量(p4d_t*p4d,无符号长地址)
^
这是使用代码的地方:
....
int loc, ref, dirty;
struct vm_area_struct *vma;
unsigned long vmpage;
struct mm_struct *task_mm = task->mm;
if ((task_mm && task_mm->mmap))
{
int i;
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *ptep, pte;
vma = task_mm->mmap;
while (vma)
{
for (vmpage = vma->vm_start, i = 1; vmpage < vma->vm_end; vmpage += PAGE_SIZE, i++)
{
pgd = pgd_offset(task_mm, vmpage);
if (pgd_none(*pgd) || pgd_bad(*pgd))
return 0;
pud = pud_offset(pgd, vmpage);
if (pud_none(*pud) || pud_bad(*pud))
return 0;
pmd = pmd_offset(pud, vmpage);
if (pmd_none(*pmd) || pmd_bad(*pmd))
return 0;
ptep = pte_offset_kernel(pmd, vmpage);
if (!ptep)
return 0;
pte = *ptep;
...
}
。。。。
int loc,ref,dirty;
结构vm_区域_结构*vma;
无符号长页;
结构mm_结构*task_mm=task->mm;
如果((任务-&任务->mmap))
{
int i;
pgd_t*pgd;
布丁;
pmd_t*pmd;
私人有限公司,私人有限公司;
vma=任务\u mm->mmap;
while(vma)
{
对于(vmpage=vma->vmu开始,i=1;vmpagevmu结束;vmpage+=页面大小,i++)
{
pgd=pgd_偏移量(任务毫米,vmpage);
如果(pgd_无(*pgd)| pgd_坏(*pgd))
返回0;
pud=pud_偏移量(pgd,vmpage);
如果(pud_none(*pud)| pud_bad(*pud))
返回0;
pmd=pmd_偏移量(pud,vmpage);
if(pmd_无(*pmd)| pmd_坏(*pmd))
返回0;
ptep=pte_偏移量_内核(pmd,vmpage);
如果(!ptep)
返回0;
pte=*ptep;
...
}
我查找了错误和注释,但没有找到任何关于解决此问题的方法。这是一个众所周知的问题还是我做错了什么
更新*我最近遇到了同样的问题,我发现就像pgd_偏移和pud_偏移一样,也有一个p4d_偏移。将其放在pgd和pud之间:
pgd_t *pgd;
p4d_t* p4d;
pud_t *pud;
pmd_t *pmd;
pte_t *ptep, pte;
...
pgd = pgd_offset(task_mm, vmpage);
if (pgd_none(*pgd) || pgd_bad(*pgd))
return 0;
p4d = p4d_offset(pgd, vmpage);
if (p4d_none(*p4d) || p4d_bad(*p4d))
return 0;
pud = pud_offset(p4d, vmpage);
if (pud_none(*pud) || pud_bad(*pud))
return 0;
...
编辑:以下是有关附加级别的一些信息:
它已经在内核版本4.11中实现。vmpage变量的类型是什么?看起来这种类型的宽度小于地址类型的宽度。我更新了代码,还添加了我得到的其他警告。关于
vmpage
未使用的警告。但我不知道我怎么没有使用它。明白了。Expressionint I=1,vmpage=vma->vmu start;
实际上定义了两个类型为int
的变量:i
和vmpage
。此声明隐藏了vmpage
for循环的之前的声明。这就是为什么您会收到警告未使用的变量“vmpage”
和关于“移位计数”的警告.我编辑了代码。由于pud\u offset
功能,它显示错误。