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;
}
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;
}
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
So why the process can't complete correcly the `ioctl' call? Maybe i have to lock something before navigating the page tables?
I'm working with kernel 2.6.35-22 and three levels page tables.
Thank you all!
main
beforereturn
. If i commentioctl
the process doesn't segfault. – Clorisstruct page
? Are you sure your segfaults does not come from here? Have you tried debugging this on qemu? – Mendicantwalk-page_table
i only do aprintk
ifpage
isNULL
. I tried also to keep only the call towalk_page_table
but the process still segfaults. Maybe yes, the fastest way to discover the problem is debugging. Thank you Quentin. – Clorisunlocked_ioctl
: kernel 2.6.35 still hasioctl
function pointer instruct file_operations
. Thanks sessyargc.jp! – Cloris