Finding the phsical address for a virtual address

Finding the phsical address for a virtual address

Post by Urs Thuerman » Thu, 19 Sep 2002 18:00:51



For a talk I will give tomorrow I'd like to able to show the physical
address of the phyiscal page frame of a given virtual address in a
given process.  I.e. I would like a tool that can be called like

        $ show-phys <pid> <vma>

and that shows wether the process <pid> has mapped a page at address
<vma> and if so to which physical page frame it is mapped.

AFAIK, the standard kernel does not export that information, does it?
Is there a patch/module that implements that (via ioctl() or /proc FS
or whatever).  If not, how would the function

    unsigned long get_phys(pid_t pid, unsigned long vma)

in the kernel look like?

urs

 
 
 

Finding the phsical address for a virtual address

Post by Roberto Nibal » Thu, 19 Sep 2002 19:46:16


Hello,

Quote:> AFAIK, the standard kernel does not export that information, does it?

Maybe /proc/${pid}/maps or /proc/${pid}/stat{us}

Quote:> Is there a patch/module that implements that (via ioctl() or /proc FS
> or whatever).  If not, how would the function

>     unsigned long get_phys(pid_t pid, unsigned long vma)

> in the kernel look like?

You could glance at the __pa(unsigned long (x)-PAGE_OFFSET) or the
virt_to_phys(unsigned long a) makros until someone more knowledgable
gives you the correct answer. This makro will convert a logical address
to a physical one in the kernel.

Best regards,
Roberto Nibali, ratz
--
echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc

 
 
 

Finding the phsical address for a virtual address

Post by Ed Skinne » Thu, 19 Sep 2002 22:27:57


      I use (as root) "cat maps | sort -r" in lecture quite often. (The
"sort -r" puts the addresses in high-to-low sequence which I prefer when
drawing memory diagrams.)
      The "maps" are particularly informative with multi-threaded
applications as you will see each thread's stack allocation and,
depending on the version of Linux you have, you may also see "guard
pages" between the thread stacks.
       Best regards to you!

> For a talk I will give tomorrow I'd like to able to show the physical
> address of the phyiscal page frame of a given virtual address in a
> given process.  I.e. I would like a tool that can be called like

>         $ show-phys <pid> <vma>

> and that shows wether the process <pid> has mapped a page at address
> <vma> and if so to which physical page frame it is mapped.

> AFAIK, the standard kernel does not export that information, does it?
> Is there a patch/module that implements that (via ioctl() or /proc FS
> or whatever).  If not, how would the function

>     unsigned long get_phys(pid_t pid, unsigned long vma)

> in the kernel look like?

> urs

 
 
 

Finding the phsical address for a virtual address

Post by Pete Zaitc » Fri, 20 Sep 2002 01:13:09



Quote:> For a talk I will give tomorrow I'd like to able to show the physical
> address of the phyiscal page frame of a given virtual address in a
> given process.  I.e. I would like a tool that can be called like

>         $ show-phys <pid> <vma>

> and that shows wether the process <pid> has mapped a page at address
><vma> and if so to which physical page frame it is mapped.

Steal the page table walker from bttv.c and wrap it into
a trivial driver. You have to find current pointer by pid first.
I'm afraid you're past the deadline though.

I saw two other replies, both wrong. User addresses cannot be
fed to __pa or virt_to_phys as one guy suggested. The other one
did not understand the question.

-- Pete

 
 
 

Finding the phsical address for a virtual address

Post by Urs Thuerman » Fri, 20 Sep 2002 13:18:58



>       I use (as root) "cat maps | sort -r" in lecture quite
> often. (The "sort -r" puts the addresses in high-to-low sequence which
> I prefer when drawing memory diagrams.)

Yes, I know about /proc/<pid>/maps and I will use it for my talk,
too.  But that does not give me the physical addresses of the pages.

Quote:>       The "maps" are particularly informative with multi-threaded
> applications as you will see each thread's stack allocation and,
> depending on the version of Linux you have, you may also see "guard
> pages" between the thread stacks.

I have just tried it.  Interesting.  But why have different threads
their stack mapped at different addresses?  I would assume the stack
of each thread to start at 0xc0000000.

Do the threads of one process also share page directories and page
tables or only pages frames?  In the former case no thread could have
private memory and it's clear that the stacks have to be at different
addresses.  But I have thought that each thread has its own page dirs
and page tables and only most of their page frames shared.

But my questions remains, how can I get the physical address for a
virtual address of a given process?

urs

 
 
 

Finding the phsical address for a virtual address

Post by Kasper Dupon » Fri, 20 Sep 2002 15:25:02




> >       I use (as root) "cat maps | sort -r" in lecture quite
> > often. (The "sort -r" puts the addresses in high-to-low sequence which
> > I prefer when drawing memory diagrams.)

> Yes, I know about /proc/<pid>/maps and I will use it for my talk,
> too.  But that does not give me the physical addresses of the pages.

They might not even have any physical address.

Quote:

> >       The "maps" are particularly informative with multi-threaded
> > applications as you will see each thread's stack allocation and,
> > depending on the version of Linux you have, you may also see "guard
> > pages" between the thread stacks.

The guard pages does not depend on the Linux version,
it depends on the threading library.

Quote:

> I have just tried it.  Interesting.  But why have different threads
> their stack mapped at different addresses?

The threads share the same address space. So the only
way to have one stack for each thread is to place them
at different addresses. The threads can access each
others stacks by using the right addresses.

Quote:> I would assume the stack of each thread to start at 0xc0000000.

No. Only the initial thread will have the stack
starting at 0xc0000000. As soon as you start making
differences between the memory layout of the threads
they are no longer threads but processess.

Quote:

> Do the threads of one process also share page directories and page
> tables or only pages frames?

They share it all.

Quote:> In the former case no thread could have
> private memory and it's clear that the stacks have to be at different
> addresses.

That is exactly the case.

Quote:> But I have thought that each thread has its own page dirs
> and page tables and only most of their page frames shared.

In that case it is not threads but processes using
shared memory. You can do that if you want to by
using SysV shared memory or the like. But you will
not get as good performance as with threads.

Quote:

> But my questions remains, how can I get the physical address for a
> virtual address of a given process?

First we look at struct the task_struct:
http://lxr.linux.no/source/include/linux/sched.h#L287
and find the field named mm
http://lxr.linux.no/source/include/linux/sched.h#L312

This is a struct mm_struct
http://lxr.linux.no/source/include/linux/sched.h#L210
which has a mmap field of the type struct vm_area_struct
http://lxr.linux.no/source/include/linux/mm.h#L44
these are in a chained list.

But I don't see how to get from the vm_area_struct to
the actual pages, so I could be on the wrong track
here.

--
Kasper Dupont -- der bruger for meget tid p? usenet.


 
 
 

Finding the phsical address for a virtual address

Post by Natma » Sat, 21 Sep 2002 13:10:05




<snip>

> > But my questions remains, how can I get the physical address for a
> > virtual address of a given process?

> First we look at struct the task_struct:
> http://lxr.linux.no/source/include/linux/sched.h#L287
> and find the field named mm
> http://lxr.linux.no/source/include/linux/sched.h#L312

> This is a struct mm_struct
> http://lxr.linux.no/source/include/linux/sched.h#L210
> which has a mmap field of the type struct vm_area_struct
> http://lxr.linux.no/source/include/linux/mm.h#L44
> these are in a chained list.

> But I don't see how to get from the vm_area_struct to
> the actual pages, so I could be on the wrong track
> here.

While we're on the topic here, I've browsed through these
structures before in search of a way to find out which process
is using a particular physical page.  I know about looking through
mem_map (I think that's what it's called) to see the list of physical
pages, but given any page in the list, I'd like to know if a page is
allocated to user-land programs, or to the kernel.

Just by chance, would Kasper or anyone else have any ideas
on accomplishing this?

It seems like Urs and I are looking for the same things, but starting
on opposite ends of the rope.

Nathan

 
 
 

Finding the phsical address for a virtual address

Post by Kasper Dupon » Sat, 21 Sep 2002 15:21:02



> While we're on the topic here, I've browsed through these
> structures before in search of a way to find out which process
> is using a particular physical page.  I know about looking through
> mem_map (I think that's what it's called) to see the list of physical
> pages, but given any page in the list, I'd like to know if a page is
> allocated to user-land programs, or to the kernel.

What you have access to is a struct for every page:
http://lxr.linux.no/source/include/linux/mm.h#L137
The array is called mem_map:
http://lxr.linux.no/source/mm/memory.c#L73

From the comments:
   Note that we have no way to track which tasks
   are using a page.

This array currently uses 1.6% of the physical
memory, on computers with lots of physical memory,
this can be a significant amount of memory. Thus
the developers will try to keep this struct as
small as possible. You should find no information
in this array that the kernel doesn't absolutely
need.

--
Kasper Dupont -- der bruger for meget tid p? usenet.


 
 
 

Finding the phsical address for a virtual address

Post by Urs Thuerman » Sun, 22 Sep 2002 21:05:12




> > For a talk I will give tomorrow I'd like to able to show the physical
> > address of the phyiscal page frame of a given virtual address in a
> > given process.  I.e. I would like a tool that can be called like

> >         $ show-phys <pid> <vma>

> > and that shows wether the process <pid> has mapped a page at address
> ><vma> and if so to which physical page frame it is mapped.

> Steal the page table walker from bttv.c and wrap it into
> a trivial driver. You have to find current pointer by pid first.
> I'm afraid you're past the deadline though.

Thanks very much for that hint.  I did take a look at the bttv driver
and (also looking up those functions in Rubini) was able to modify it
for my purpose in time.

I wrote a small kernel module implementing one ioctl() that can be
given a PID and a virtual address and that returns the corresponding
address if any or 0 otherwise.  The main code is

    static unsigned long vtop(struct task_struct *p, unsigned long va)
    {
        unsigned long pa;
        pgd_t *pgd;
        pmd_t *pmd;
        pte_t *pte;

        pgd = pgd_offset(p->mm, va);
        if (pgd_none(*pgd))
                return 0;
        pmd = pmd_offset(pgd, va);
        if (pmd_none(*pmd))
                return 0;
        pte = pte_offset(pmd, va);
        if (!pte_present(*pte))
                return 0;
        pa = pte_val(*pte);
        return pa;
    }

Using this I wrote a small tool show-phys that can show the physical
address (more exactly the page table entry including the physical
address and some flags) for some virtual address of some process.  In
my talk on ELF, linker, demand paging, shared libs and PIC I could
show that shared libs are really shared even if loaded at different
addresses like this:

    isnogud:mm$ cat /proc/1/maps|grep libc
    4001c000-40135000 r-xp 00000000 3a:00 2130       /lib/libc-2.2.5.so
    40135000-4013b000 rw-p 00119000 3a:00 2130       /lib/libc-2.2.5.so
    isnogud:mm$ cat /proc/$$/maps|grep libc
    40090000-401a9000 r-xp 00000000 3a:00 2130       /lib/libc-2.2.5.so
    401a9000-401af000 rw-p 00119000 3a:00 2130       /lib/libc-2.2.5.so
    isnogud:mm$ ./show-phys 1 0x4001c000
    07e50005
    isnogud:mm$ ./show-phys $$ 0x40090000
    07e50025
    isnogud:mm$

However, experimenting with this, I found surprising behavior with the
last stack page of each process, which I don't understand:

    isnogud:mm$ cat /proc/$$/maps | tail -1
    bfffb000-c0000000 rwxp ffffc000 00:00 0
    isnogud:mm$ for i in 1 2 3 4 5; do ./show-phys $$ 0xbffff000; done
    0a27d067
    079a0067
    0f596067
    0213a067
    097a8067
    isnogud:mm$

Why does the mapping of the last stack page change continously?
AFAICS, this happens only with the last stack page, not with any other
page of the process, e.g. pages mapped from a file (exec or shlib) or
other stack pages like 0xbfffe000.

BTW, I forgot to define the MODULE_LICENSE("GPL") in my module so that
my kernel now says it is tainted (/proc/modules and lsmod).  Is there
a way to undo this?

urs

 
 
 

Finding the phsical address for a virtual address

Post by Pete Zaitc » Sun, 22 Sep 2002 22:11:08



Quote:>     static unsigned long vtop(struct task_struct *p, unsigned long va)

That's what I meant. How do you find p gived the pid?

Quote:> However, experimenting with this, I found surprising behavior with the
> last stack page of each process, which I don't understand:

>     isnogud:mm$ cat /proc/$$/maps | tail -1
>     bfffb000-c0000000 rwxp ffffc000 00:00 0
>     isnogud:mm$ for i in 1 2 3 4 5; do ./show-phys $$ 0xbffff000; done
>     0a27d067
>     079a0067
>     0f596067
>     0213a067
>     097a8067
>     isnogud:mm$
> Why does the mapping of the last stack page change continously?
> AFAICS, this happens only with the last stack page, not with any other
> page of the process, e.g. pages mapped from a file (exec or shlib) or
> other stack pages like 0xbfffe000.

They probably weren't COWed yet. I do not think stack can be
shared :)  Check protection bits in the PTE.

-- Pete

 
 
 

Finding the phsical address for a virtual address

Post by Urs Thuerman » Mon, 23 Sep 2002 02:19:11



> > Why does the mapping of the last stack page change continously?
> > AFAICS, this happens only with the last stack page, not with any other
> > page of the process, e.g. pages mapped from a file (exec or shlib) or
> > other stack pages like 0xbfffe000.

> They probably weren't COWed yet. I do not think stack can be
> shared :)  Check protection bits in the PTE.

Of course are stack pages not shared between processes.  But that does
not explain why the mapping of the stack page changes *continously*.
This has nothing to do with COW.

urs

 
 
 

Finding the phsical address for a virtual address

Post by James T. Denni » Thu, 28 Nov 2002 17:05:13


 ...

Quote:>> But my questions remains, how can I get the physical address for a
>> virtual address of a given process?
> First we look at struct the task_struct:
> http://lxr.linux.no/source/include/linux/sched.h#L287
> and find the field named mm
> http://lxr.linux.no/source/include/linux/sched.h#L312
> This is a struct mm_struct
> http://lxr.linux.no/source/include/linux/sched.h#L210
> which has a mmap field of the type struct vm_area_struct
> http://lxr.linux.no/source/include/linux/mm.h#L44
> these are in a chained list.
> But I don't see how to get from the vm_area_struct to
> the actual pages, so I could be on the wrong track
> here.

 Perhaps a gander at Rik van Riel's (?) rmap patches might help.
 
 
 

Finding the phsical address for a virtual address

Post by Joshua Jone » Fri, 29 Nov 2002 00:29:38


Quote:

>>> But my questions remains, how can I get the physical address for a
>>> virtual address of a given process?

Why do you need to get the physical address of the process memory?

--
 josh(at)intmain.net  |  http://intmain.net

 262471 local keystrokes since last reboot (38 days ago)

 
 
 

Finding the phsical address for a virtual address

Post by Kasper Dupon » Fri, 29 Nov 2002 04:50:27



> >>> But my questions remains, how can I get the physical address for a
> >>> virtual address of a given process?

> Why do you need to get the physical address of the process memory?

The start of this thread already expired from my server, but IIRC
it was for "educational" purposes. It was for some piece of code
demonstrating the inner workings of the memory management system.

--
Kasper Dupont -- der bruger for meget tid p? usenet.

char *mybuf[1==1]; (2==3)[mybuf]="Hello World!";

 
 
 

Finding the phsical address for a virtual address

Post by Chenghong0ya » Fri, 29 Nov 2002 04:56:08


Quote:>>> But my questions remains, how can I get the physical address for a
>>> virtual address of a given process?

I remember there some macro defined like
vir_to_phy, I can not remember the right form.
like into uaccess.h
 
 
 

1. YDL 1.2 Synergy VGM5 Virtual Address, Physical Address, Bus Address and remap_page_range (HELP!)

I am currently developing a kernel module to communicate with a PCI memory
device and I have run into a few problems.

1. How do I determine the physical address of my PCI device? I did examine
the IO-mapping.txt file in /usr/scr/linux and it states the following is
true for Power PC:

Physical Address: 0x0
Virtual Memory Address: 0xC0000000
Bus Address 0x80000000

Using lspci -v I find that the bus address of my device is as follows:
memory at 0xF0042100 non-prefectable
memory at 0xF1000000 prefetchable
memory at 0xF2000000 prefetchable

So how do I figure out the physical address for the bus address 0XF1000000
do I just subtract/add 0x80000000 to get the address?

2. I need the physical address because I am trying to obtain it to pass into
remap_page_range() (I need to map all of the memory from my PCI device into
kernel memory and then pass a pointer from the kernel to user space. I tried
using the value of 0x71000000 (which I obtained by subtracting 0x80000000
from 0xF1000000 and it doesn't work:
User mode application:

if( (fd = open( SCR_INT_DEV, O_RDWR )) == -1 )
             rvalue = DEVICE_ERROR;
        else
        {
            paddr = mmap( 0, 0x80000, prot, mmap_flags, fd, 0 );
            if( (int)paddr == -1 )
                rvalue = MAP_ERROR;

(mmap entry point in kernel module)

static int pci_mmap(struct file * file, struct vm_area_struct * vma)
 physical += vma->vm_offset;
  mapped_mem = vma->vm_end - vma->vm_start;

if (remap_page_range(vma->vm_start, 0x71000000, mapped_mem,
vma->vm_page_prot))

This works fine on a Linux 2.2.18 distribution running on an X86 (I
understand that on the Power PC that Phy addr and bus addr aren't the same)

I realize that this is a non-portable way of accessing memory, but our API
requires that it receive a user pointer to directly access memory from our
card. Can anyone please help me or point me to information that might help
me to solve the problem.

Thanks,

Chris Fought

2. Some Success with Cirrus 7548 Xfree86 3.3

3. How Can I get the phsical address?

4. Samba and Printers on Win95 question

5. Changing IP address on Solaris 9 with multiple virtual IP addresses

6. Parallel port ?

7. User virtual address to physical address translation -- how?

8. colors when doing ls

9. how to get virtual address from dma address

10. virtual address to physical address

11. Map physical address to virtual address

12. physical address from virtual address

13. virtual addressing, aliasing or dummy addresses