On Page table walk.

mind entropy mindentropy at gmail.com
Mon Sep 29 13:35:44 EDT 2014


Hi,

  I am experimenting with page table walking. I run a user space
program and set the device attribute (of my sample device driver) in
the sysfs. (DEVICE_ATTR) which is the address of the variable in the
user space. I get the current->mm to get the current task memory
descriptor and use it to walk the pages. Once I get the pte address I
reboot and dump the memory at that point using u-boot. (md.b <addr> 1)
but I do not find the value present there.

Sample code: (This is just for illustration and experimenting and does
not contain error checks etc.).

--------------------------------------------------------------------------------------------
ssize_t process_mem_test_attr_store(struct device *dev,
                        struct device_attribute *attr,
                        const char *buf,
                        size_t count)
{

    struct task_struct *current_task;
    unsigned long addr_res;
    struct vm_area_struct *vmarea_struct_addr;
    pgd_t *pgd;
    pmd_t *pmd;
    pud_t *pud;
    pte_t *ptep, pte;
    struct page *page;
    int kval;
    int uval;

    DEFINE_SPINLOCK(test_lock);

    spin_lock_irq(&test_lock);

    current_task = current;

    if(current_task != NULL) {

        printk(KERN_ALERT "\nCurrent task pid: %d\n",
                                current_task->pid);

        printk(KERN_ALERT "mm: 0x%lx, active_mm 0x%lx\n",
                        current_task->mm,current_task->active_mm);
        printk(KERN_ALERT "Page global directory : 0x%lx\n",
                            current_task->mm->pgd);
        printk(KERN_ALERT "mmap base : 0x%lx",
                            current_task->mm->mmap_base);

        vmarea_struct_addr = current_task->mm->mmap;

        while(vmarea_struct_addr != NULL) {
            printk(KERN_ALERT "vm_start : 0x%lx, vm_end : 0x%lx\n",
                            vmarea_struct_addr->vm_start,
                            vmarea_struct_addr->vm_end);

            vmarea_struct_addr = vmarea_struct_addr->vm_next;
        }


    } else {
        printk(KERN_ALERT "Current task NULL\n");
    }

    if(kstrtol(buf,10,&addr_res) != 0) {
        printk(KERN_ALERT "Error converting to long\n");
        return count;
    }

    copy_from_user(&kval,(unsigned int *)addr_res,4);

    printk(KERN_ALERT "kval : %x\n",kval);
    printk(KERN_ALERT "addr: %lx\n",addr_res);

    pgd = pgd_offset(current_task->mm,addr_res);

    if(pgd_none(*pgd) || pgd_bad(*pgd)) {
        printk(KERN_ALERT "pgd bad\n");
        return count;
    } else {
        printk(KERN_ALERT "pgd 0x%lx\n",pgd);
    }

    pud = pud_offset(pgd,addr_res);

    if(pud_none(*pud) || pud_bad(*pud)) {
        printk(KERN_ALERT "pud bad\n");
        return count;
    } else {
        printk(KERN_ALERT "pud 0x%lx\n",pud);
    }

    pmd = pmd_offset(pud,addr_res);

    if(pmd_none(*pmd) || pmd_bad(*pmd)) {
        printk(KERN_ALERT "pmd bad\n");
        return count;
    } else {
        printk(KERN_ALERT "pmd 0x%lx\n",pmd);
    }


    ptep = pte_offset_map(pmd,addr_res);
    if(!ptep) {
        printk(KERN_ALERT "ptep bad\n");
    } else {
        printk(KERN_ALERT "ptep 0x%lx\n",ptep);
    }

    pte = *ptep;


    if(pte_present(pte)) {
        printk(KERN_ALERT "pte : 0x%lx\n",pte);
        page = pte_page(pte);

    } else {
        printk(KERN_ALERT "pte not present\n");
    }

    printk(KERN_ALERT "pte with offset 0x%lx offset : 0x%lx\n",
            pte+((addr_res) & ((1<<PAGE_SHIFT)-1)),
            addr_res & ((1<<PAGE_SHIFT)-1));


    while(1)
        ;

    printk(KERN_ALERT "After lock\n"); //Should not print this.


    return count;
}
--------------------------------------------------------------------------------------------

I use a spinlock to prevent the process from getting swapped. I
disable the irq and make it spin on while(1); after which I reboot.
After doing a memoy dump I find the value in the address but at an
offset from pte value printed. What seems to be wrong with my
approach?

Thanks in advance.



More information about the Kernelnewbies mailing list