在编译用于页表遍历的内核时出现错误 [英] Getting error when compiling kernel for page table walk

查看:695
本文介绍了在编译用于页表遍历的内核时出现错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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)
                      ^

这是使用代码的地方:

....
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;
            ...
}

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

已更新*

解决方案

我最近遇到了同样的问题,我发现就像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;

...

以下是有关附加级别的一些信息:五级页表./p>

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

I am doing a page table walk. When I am getting ready to update the kernel I get an error:

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)
                      ^

This is where the code is being used:

....
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;
            ...
}

I looked up the errors and notes but didn't find anything about resolving this problem. Is this a well known problem or am I doing something wrong?

updated*

解决方案

I recently got the same problem and I found that just like pgd_offset and pud_offset, there is a p4d_offset. Put it between pgd and 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;

...

Edit: Here is some information about the additional level: Five-level page tables.

It has been implemented in kernel version 4.11.

这篇关于在编译用于页表遍历的内核时出现错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆