On Page table walk.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies




[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux