On Wed, Oct 1, 2014 at 7:17 PM, mind entropy <mindentropy@xxxxxxxxx> wrote: >> ------------------------------ >> >> Message: 5 >> Date: Mon, 29 Sep 2014 23:05:44 +0530 >> From: mind entropy <mindentropy@xxxxxxxxx> >> Subject: On Page table walk. >> To: kernelnewbies <kernelnewbies@xxxxxxxxxxxxxxxxx> >> Message-ID: >> <CAM2a4uyLDgFztL+xpos3GG76K3i71vp+63PpZKyVErrVUPU8XA@xxxxxxxxxxxxxx> >> Content-Type: text/plain; charset=UTF-8 >> >> 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. >> >> >> >> ------------------------------ > > > Hope somebody can give me some clue. My PHYS_OFFSET starts at 0x30000000. > > A sample output in the dmesg is as follows: > > ------------------------------ > > > Sample session: > > [ 92.086535] Current task pid: 2382 > [ 92.086632] mm: 0xc2d79480, active_mm 0xc2d79480 > [ 92.090522] Page global directory : 0xc2cb4000 > [ 92.094783] mmap base : 0xb6fe0000 > [ 92.097896] vm_start : 0x8000, vm_end : 0x9000 > [ 92.102454] vm_start : 0x10000, vm_end : 0x11000 > [ 92.106942] vm_start : 0xb6e7c000, vm_end : 0xb6fa5000 > [ 92.111983] vm_start : 0xb6fa5000, vm_end : 0xb6fac000 > [ 92.116995] vm_start : 0xb6fac000, vm_end : 0xb6fae000 > [ 92.122054] vm_start : 0xb6fae000, vm_end : 0xb6faf000 > [ 92.127062] vm_start : 0xb6faf000, vm_end : 0xb6fb2000 > [ 92.132121] vm_start : 0xb6fba000, vm_end : 0xb6fd7000 > [ 92.137177] vm_start : 0xb6fda000, vm_end : 0xb6fdd000 > [ 92.142223] vm_start : 0xb6fdd000, vm_end : 0xb6fde000 > [ 92.147203] vm_start : 0xb6fde000, vm_end : 0xb6fdf000 > [ 92.152275] vm_start : 0xb6fdf000, vm_end : 0xb6fe0000 > [ 92.157291] vm_start : 0xbe852000, vm_end : 0xbe874000 > [ 92.162345] kval : 1234 > [ 92.164670] addr: 10830 > [ 92.167145] pgd 0xc2cb4000 > [ 92.169705] pud 0xc2cb4000 > [ 92.172407] pmd 0xc2cb4000 > [ 92.174995] ptep 0xc3b78040 > [ 92.177774] pte : 0x326dc14f > [ 92.180545] pte with offset 0x326dc97f offset : 0x830 [Solved]. If anybody is interested I had some help in the "mm" list. Cross post here http://marc.info/?l=linux-mm&m=141261100710499&w=2 _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies