> ------------------------------ > > 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 _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies