在 Linux 中遍历进程的页表 [英] Walking page tables of a process in 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屋!