在 Linux 中遍历进程的页表 [英] Walking page tables of a process in Linux

查看:17
本文介绍了在 Linux 中遍历进程的页表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为 linux 中的进程导航页表.在内核模块中,我实现了以下功能:

i'm trying to navigate the page tables for a process in linux. In a kernel module i realized the following function:

static struct page *walk_page_table(unsigned long addr)
{
    pgd_t *pgd;
    pte_t *ptep, pte;
    pud_t *pud;
    pmd_t *pmd;

    struct page *page = NULL;
    struct mm_struct *mm = current->mm;

    pgd = pgd_offset(mm, addr);
    if (pgd_none(*pgd) || pgd_bad(*pgd))
        goto out;
    printk(KERN_NOTICE "Valid pgd");

    pud = pud_offset(pgd, addr);
    if (pud_none(*pud) || pud_bad(*pud))
        goto out;
    printk(KERN_NOTICE "Valid pud");

    pmd = pmd_offset(pud, addr);
    if (pmd_none(*pmd) || pmd_bad(*pmd))
        goto out;
    printk(KERN_NOTICE "Valid pmd");

    ptep = pte_offset_map(pmd, addr);
    if (!ptep)
        goto out;
    pte = *ptep;

    page = pte_page(pte);
    if (page)
        printk(KERN_INFO "page frame struct is @ %p", page);

 out:
    return page;
}

这个函数是从ioctl调用的,addr是进程地址空间中的一个虚拟地址:

This function is called from the ioctl and addr is a virtual address in process address space:

static int my_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long addr)
{
   struct page *page = walk_page_table(addr);
   ...
   return 0;
}

奇怪的是,在用户空间进程中调用ioctl,这个segfaults...但似乎我寻找页表条目的方式是正确的,因为使用dmesg 例如,我为每个 ioctl 调用获取:

The strange thing is that calling ioctl in a user space process, this segfaults...but it seems that the way i'm looking for the page table entry is correct because with dmesg i obtain for example for each ioctl call:

[ 1721.437104] Valid pgd
[ 1721.437108] Valid pud
[ 1721.437108] Valid pmd
[ 1721.437110] page frame struct is @ c17d9b80

那么为什么进程不能正确完成`ioctl'调用?也许我必须在导航页表之前锁定某些内容?

So why the process can't complete correcly the `ioctl' call? Maybe i have to lock something before navigating the page tables?

我正在使用内核 2.6.35-22 和三级页表.

I'm working with kernel 2.6.35-22 and three levels page tables.

谢谢大家!

推荐答案

pte_unmap(ptep); 

在标签出来之前丢失了.尝试以这种方式更改代码:

is missing just before the label out. Try to change the code in this way:

    ...
    page = pte_page(pte);
    if (page)
        printk(KERN_INFO "page frame struct is @ %p", page);

    pte_unmap(ptep); 

out:

这篇关于在 Linux 中遍历进程的页表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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