All of lore.kernel.org
 help / color / mirror / Atom feed
* On page table walk.
@ 2014-10-02 19:34 mind entropy
  2014-10-06 15:56 ` mind entropy
  0 siblings, 1 reply; 5+ messages in thread
From: mind entropy @ 2014-10-02 19:34 UTC (permalink / raw)
  To: linux-mm

Hi,

  I am experimenting with page table walking. I run a user space
program and mmap a memory region and pass the address to the module.

  In the kernel module 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 values present there. ( I have filled the region
with incremental value starting from 0 to 255).

My processor is a Samsung S3C2440 ARM920T (mini2440 development
board). The physical address starts at 0x30000000.

-------------------------------------------------------------------
Sample code of the page walk: (This is just for illustration and
experimenting and does
not contain error checks etc.).

void my_follow_page(struct mm_struct *mm,
                    unsigned long addr_res)
{
    pgd_t *pgd;
    pmd_t *pmd;
    pud_t *pud;
    pte_t *ptep, pte;
    struct page *page;


    down_read(&(mm->mmap_sem));

    pgd = pgd_offset(mm,addr_res);

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

    pud = pud_offset(pgd,addr_res);

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

    pmd = pmd_offset(pud,addr_res);

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


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

    pte = *ptep;


    if(pte_present(pte)) {
        printk(KERN_ALERT "pte : 0x%lx\n",(unsigned long)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));

    up_read(&(mm->mmap_sem));
}

-------------------------------------------------------------------

Sample output:

[   86.447788] Current task pid: 2384
[   86.447885] mm: 0xc3b39a80, active_mm 0xc3b39a80
[   86.451594] Page global directory : 0xc3af4000
[   86.456127] mmap base : 0xb6f60000
[   86.459175] vm_start : 0x8000, vm_end : 0x9000
[   86.463684] vm_start : 0x10000, vm_end : 0x11000
[   86.468202] vm_start : 0x100000, vm_end : 0x101000
[   86.472884] vm_start : 0xb6dfc000, vm_end : 0xb6f25000
[   86.477975] vm_start : 0xb6f25000, vm_end : 0xb6f2c000
[   86.483000] vm_start : 0xb6f2c000, vm_end : 0xb6f2e000
[   86.488070] vm_start : 0xb6f2e000, vm_end : 0xb6f2f000
[   86.493080] vm_start : 0xb6f2f000, vm_end : 0xb6f32000
[   86.498089] vm_start : 0xb6f3a000, vm_end : 0xb6f57000
[   86.503120] vm_start : 0xb6f5a000, vm_end : 0xb6f5d000
[   86.508149] vm_start : 0xb6f5d000, vm_end : 0xb6f5e000
[   86.513187] vm_start : 0xb6f5e000, vm_end : 0xb6f5f000
[   86.518225] vm_start : 0xb6f5f000, vm_end : 0xb6f60000
[   86.523251] vm_start : 0xbe934000, vm_end : 0xbe956000
[   86.528299] kval : 3020100
[   86.530870] addr: 100000
[   86.533446] pgd 0xc3af4000
[   86.535992] pud 0xc3af4000
[   86.538720] pmd 0xc3af4000
[   86.541281] ptep 0xc3b0e400
[   86.544071] pte : 0x3278214f
[   86.546831] pte with offset 0x3278214f offset : 0x0


The problem is that when I do a md.b 0x3278214f 100 in u-boot to do a
memory dump I see the values in it but I don't see the exact value
filled in that memory location. What am I doing wrong?

Thanks,
Gautam.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: On page table walk.
  2014-10-02 19:34 On page table walk mind entropy
@ 2014-10-06 15:56 ` mind entropy
  0 siblings, 0 replies; 5+ messages in thread
From: mind entropy @ 2014-10-06 15:56 UTC (permalink / raw)
  To: linux-mm

On Fri, Oct 3, 2014 at 1:04 AM, mind entropy <mindentropy@gmail.com> wrote:
> Hi,
>
>   I am experimenting with page table walking. I run a user space
> program and mmap a memory region and pass the address to the module.
>
>   In the kernel module 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 values present there. ( I have filled the region
> with incremental value starting from 0 to 255).
>
> My processor is a Samsung S3C2440 ARM920T (mini2440 development
> board). The physical address starts at 0x30000000.
>
> -------------------------------------------------------------------
> Sample code of the page walk: (This is just for illustration and
> experimenting and does
> not contain error checks etc.).
>
> void my_follow_page(struct mm_struct *mm,
>                     unsigned long addr_res)
> {
>     pgd_t *pgd;
>     pmd_t *pmd;
>     pud_t *pud;
>     pte_t *ptep, pte;
>     struct page *page;
>
>
>     down_read(&(mm->mmap_sem));
>
>     pgd = pgd_offset(mm,addr_res);
>
>     if(pgd_none(*pgd) || pgd_bad(*pgd)) {
>         printk(KERN_ALERT "pgd bad\n");
>         return;
>     } else {
>         printk(KERN_ALERT "pgd 0x%lx\n",(unsigned long)pgd);
>     }
>
>     pud = pud_offset(pgd,addr_res);
>
>     if(pud_none(*pud) || pud_bad(*pud)) {
>         printk(KERN_ALERT "pud bad\n");
>         return;
>     } else {
>         printk(KERN_ALERT "pud 0x%lx\n",(unsigned long)pud);
>     }
>
>     pmd = pmd_offset(pud,addr_res);
>
>     if(pmd_none(*pmd) || pmd_bad(*pmd)) {
>         printk(KERN_ALERT "pmd bad\n");
>         return;
>     } else {
>         printk(KERN_ALERT "pmd 0x%lx\n",(unsigned long)pmd);
>     }
>
>
>     ptep = pte_offset_map(pmd,addr_res);
>     if(!ptep) {
>         printk(KERN_ALERT "ptep bad\n");
>     } else {
>         printk(KERN_ALERT "ptep 0x%lx\n",(unsigned long)ptep);
>     }
>
>     pte = *ptep;
>
>
>     if(pte_present(pte)) {
>         printk(KERN_ALERT "pte : 0x%lx\n",(unsigned long)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));
>
>     up_read(&(mm->mmap_sem));
> }
>
> -------------------------------------------------------------------
>
> Sample output:
>
> [   86.447788] Current task pid: 2384
> [   86.447885] mm: 0xc3b39a80, active_mm 0xc3b39a80
> [   86.451594] Page global directory : 0xc3af4000
> [   86.456127] mmap base : 0xb6f60000
> [   86.459175] vm_start : 0x8000, vm_end : 0x9000
> [   86.463684] vm_start : 0x10000, vm_end : 0x11000
> [   86.468202] vm_start : 0x100000, vm_end : 0x101000
> [   86.472884] vm_start : 0xb6dfc000, vm_end : 0xb6f25000
> [   86.477975] vm_start : 0xb6f25000, vm_end : 0xb6f2c000
> [   86.483000] vm_start : 0xb6f2c000, vm_end : 0xb6f2e000
> [   86.488070] vm_start : 0xb6f2e000, vm_end : 0xb6f2f000
> [   86.493080] vm_start : 0xb6f2f000, vm_end : 0xb6f32000
> [   86.498089] vm_start : 0xb6f3a000, vm_end : 0xb6f57000
> [   86.503120] vm_start : 0xb6f5a000, vm_end : 0xb6f5d000
> [   86.508149] vm_start : 0xb6f5d000, vm_end : 0xb6f5e000
> [   86.513187] vm_start : 0xb6f5e000, vm_end : 0xb6f5f000
> [   86.518225] vm_start : 0xb6f5f000, vm_end : 0xb6f60000
> [   86.523251] vm_start : 0xbe934000, vm_end : 0xbe956000
> [   86.528299] kval : 3020100
> [   86.530870] addr: 100000
> [   86.533446] pgd 0xc3af4000
> [   86.535992] pud 0xc3af4000
> [   86.538720] pmd 0xc3af4000
> [   86.541281] ptep 0xc3b0e400
> [   86.544071] pte : 0x3278214f
> [   86.546831] pte with offset 0x3278214f offset : 0x0
>
>
> The problem is that when I do a md.b 0x3278214f 100 in u-boot to do a
> memory dump I see the values in it but I don't see the exact value
> filled in that memory location. What am I doing wrong?
>
> Thanks,
> Gautam.


Got it working. Thanks to riel on #mm the pte which I am using
contains other bits not related to the physical address. I have to do
a pte_pfn(pte) to get the page frame number. The pfn to physical addr
can be got by (pfn<<PAGE_SHIFT) + (addr_res & ~PAGE_MASK). The
addr_res & ~PAGE_MASK gives the offset in the physical frame.

So the final code looks as


--------------------------------------------------------
    printk(KERN_ALERT "pfn from pte : 0x%lx\n",pfn = pte_pfn(pte));
    printk(KERN_ALERT "pfn to addr : 0x%lx, addr_res :
0x%lx\n",(pfn<<PAGE_SHIFT),
                    (unsigned long)PAGE_MASK);
    printk(KERN_ALERT "phys_addr : 0x%lx\n",(pfn<<PAGE_SHIFT) +
(addr_res & ~PAGE_MASK));
--------------------------------------------------------


Thanks,
Gautam.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* On Page table walk.
  2014-10-01 13:47 On Page " mind entropy
@ 2014-10-06 16:29 ` mind entropy
  0 siblings, 0 replies; 5+ messages in thread
From: mind entropy @ 2014-10-06 16:29 UTC (permalink / raw)
  To: kernelnewbies

On Wed, Oct 1, 2014 at 7:17 PM, mind entropy <mindentropy@gmail.com> wrote:
>> ------------------------------
>>
>> Message: 5
>> Date: Mon, 29 Sep 2014 23:05:44 +0530
>> From: mind entropy <mindentropy@gmail.com>
>> Subject: On Page table walk.
>> To: kernelnewbies <kernelnewbies@kernelnewbies.org>
>> Message-ID:
>>         <CAM2a4uyLDgFztL+xpos3GG76K3i71vp+63PpZKyVErrVUPU8XA@mail.gmail.com>
>> 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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* On Page table walk.
@ 2014-10-01 13:47 mind entropy
  2014-10-06 16:29 ` mind entropy
  0 siblings, 1 reply; 5+ messages in thread
From: mind entropy @ 2014-10-01 13:47 UTC (permalink / raw)
  To: kernelnewbies

> ------------------------------
>
> Message: 5
> Date: Mon, 29 Sep 2014 23:05:44 +0530
> From: mind entropy <mindentropy@gmail.com>
> Subject: On Page table walk.
> To: kernelnewbies <kernelnewbies@kernelnewbies.org>
> Message-ID:
>         <CAM2a4uyLDgFztL+xpos3GG76K3i71vp+63PpZKyVErrVUPU8XA@mail.gmail.com>
> 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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* On Page table walk.
@ 2014-09-29 17:35 mind entropy
  0 siblings, 0 replies; 5+ messages in thread
From: mind entropy @ 2014-09-29 17:35 UTC (permalink / raw)
  To: kernelnewbies

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@an
offset from pte value printed. What seems to be wrong with my
approach?

Thanks in advance.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-10-06 16:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-02 19:34 On page table walk mind entropy
2014-10-06 15:56 ` mind entropy
  -- strict thread matches above, loose matches on Subject: below --
2014-10-01 13:47 On Page " mind entropy
2014-10-06 16:29 ` mind entropy
2014-09-29 17:35 mind entropy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.