编译内核进行页表遍历时出现错误

Jin*_*nzu 2 c virtual-memory linux-kernel page-tables

我正在执行页表遍历。当我准备更新内核时出现错误:

\n\n
kernel/sys.c: In function \xe2\x80\x98__do_sys_get_page_info\xe2\x80\x99:\nkernel/sys.c:2745:23: error: passing argument 1 of \xe2\x80\x98pud_offset\xe2\x80\x99 from incompatible pointer type [-Werror=incompatible-pointer-types]\n      pud = pud_offset(pgd, vmpage);\n                       ^\nIn file included from ./include/linux/mm.h:99:0,\n                 from kernel/sys.c:19:\n./arch/x86/include/asm/pgtable.h:905:22: note: expected \xe2\x80\x98p4d_t * {aka struct <anonymous> *}\xe2\x80\x99 but argument is of type \xe2\x80\x98pgd_t * {aka struct <anonymous> *}\xe2\x80\x99\n static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)\n                      ^\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是使用代码的地方:

\n\n
....\nint loc, ref, dirty;\nstruct vm_area_struct *vma;\nunsigned long vmpage;\nstruct mm_struct *task_mm = task->mm;\nif ((task_mm && task_mm->mmap))\n{\n    int i;\n    pgd_t *pgd;\n    pud_t *pud;\n    pmd_t *pmd;\n    pte_t *ptep, pte;\n\n    vma = task_mm->mmap;\n\n    while (vma)\n    {\n        for (vmpage = vma->vm_start, i = 1; vmpage < vma->vm_end; vmpage += PAGE_SIZE, i++)\n        {\n            pgd = pgd_offset(task_mm, vmpage);\n            if (pgd_none(*pgd) || pgd_bad(*pgd))\n                return 0;\n\n            pud = pud_offset(pgd, vmpage);\n            if (pud_none(*pud) || pud_bad(*pud))\n                return 0;\n\n            pmd = pmd_offset(pud, vmpage);\n            if (pmd_none(*pmd) || pmd_bad(*pmd))\n                return 0;\n\n            ptep = pte_offset_kernel(pmd, vmpage);\n            if (!ptep)\n                return 0;\n\n            pte = *ptep;\n            ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我查找了错误和注释,但没有找到任何有关解决此问题的信息。这是一个众所周知的问题还是我做错了什么?

\n\n

更新*

\n

Jim*_*bei 5

我最近遇到了同样的问题,我发现就像pgd_offset和pud_offset一样,有一个p4d_offset。将其放在 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;

...
Run Code Online (Sandbox Code Playgroud)

编辑:以下是有关附加级别的一些信息:五级页表

它已在内核版本 4.11 中实现。