我正在尝试浏览Linux中的进程的页表。在一个内核模块我实现了以下功能:Linux中的进程的走页表
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称为是在进程的地址空间中的虚拟地址:
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在一个用户空间的过程,这段错误......但似乎我正在寻找页表条目的方式是正确的,因为我得到例如每个ioctl呼叫:
[ 1721.437104] Valid pgd
[ 1721.437108] Valid pud
[ 1721.437108] Valid pmd
[ 1721.437110] page frame struct is @ c17d9b80
那么为什么这个过程无法完成正确的`ioctl'调用呢?也许我必须在浏览页面表之前锁定某些内容?
我正在使用内核2.6.35-22和三个级别的页表。
谢谢大家!
+0
是否有可能ioctl系统调用成功返回并且代码在此之后进行了segfaulting? –
+0
否,因为ioctl系统调用是'return'前'main'中的最后一条指令。如果我评论'ioctl'这个过程不会出现段错误。 –
+0
你为什么隐藏你使用'struct page'地址的地方?你确定你的段错误不是来自这里吗?你有没有尝试在qemu上进行调试? –