Discussion:
pmap_extract question
(too old to reply)
Dr. Baud
2010-03-30 17:35:04 UTC
Permalink
Say I have a kernel module that allocates a contiguous chunk of kernel physical memory (note that a call to vtophys() reports a non-zero value):

memory_chunk = contigmalloc( memory_chunk_length,
NULL,
M_NOWAIT,
0UL,
~0UL,
PAGE_SIZE,
0);

The kernel virtual address returned from contigmalloc is passed to a user application which maps the chunk to the virtual address space of the application:

fd = open("/dev/mem", O_RDWR);
mapped_memory_chunk = mmap( NULL,
memory_chunk_length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
(off_t) memory_chunk);

Now consider that the mapped memory chunk address is then passed back to the kernel module. My question is; shouldn't pmap_extract(9) be able to determine the physical address?

struct thread *td = curthread;
pmap_t pmap = &td->td_proc->p_vmspace->vm_pmap;
physical_address = pmap_extract(pmap, mapped_memory_chunk);

In this example pmap_extract returns 0. Note also that /proc/<pid>/map indicates the page(s) associated with the virtual addresses are not resident, e.g.:

0x801731000 0x801732000 0 0 0xffffff01d1ecd360 rw- 10 0 0x1000 NCOW NNC device -

The first two values shown are the start (address returned from mmap above) and end addresses. The third, in this case zero, is intended to represent whether the pages are in resident. This value is simply the result of a call to pmap_extract.

Is this to be expected? Should mmap(2) serve up a virtual address which pmap_extract cannot determine the physical address? Or is there a flaw in this logic?

Thanks in advance......

Dr
Ryan Stone
2010-03-30 18:29:04 UTC
Permalink
Assuming that you're using the right pmap(it looks like you are, but it
depends on the thread context in which you're running), that will only work
if the userland application has touched the page and faulted it in. If it's
never tried to access the page it will never be mapped into the process's
page tables.
Dr. Baud
2010-03-30 18:28:31 UTC
Permalink
It was pointed out that you need to pass physical address to mmap. A step was missed in posted recipe. Consider that the return from vtophys(memory_chunk) was passed at the offset parameter. Sorry for the confusion.
Subject: pmap_extract question
Date: Tuesday, March 30, 2010, 12:35 PM
    Say I have a kernel module that allocates a
contiguous chunk of kernel physical memory (note that a call
memory_chunk = contigmalloc(   
memory_chunk_length,
               
               
NULL,
               
               
M_NOWAIT,
               
               
0UL,
               
               
~0UL,
               
               
PAGE_SIZE,
               
                0);
    The kernel virtual address returned from
contigmalloc is passed to a user application which maps the
fd = open("/dev/mem", O_RDWR);
mapped_memory_chunk = mmap( NULL,
               
           
memory_chunk_length,
               
            PROT_READ |
PROT_WRITE,
               
            MAP_SHARED,
               
            fd,
               
            (off_t)
memory_chunk);
    Now consider that the mapped memory chunk
address is then passed back to the kernel module. My
question is; shouldn't pmap_extract(9) be able to determine
the physical address?
struct thread *td = curthread;
pmap_t pmap =
&td->td_proc->p_vmspace->vm_pmap;
physical_address = pmap_extract(pmap,
mapped_memory_chunk);
    In this example pmap_extract returns 0. Note
also that /proc/<pid>/map indicates the page(s)
associated with the virtual addresses are not resident,
0x801731000 0x801732000 0 0 0xffffff01d1ecd360 rw- 10 0
0x1000 NCOW NNC device -
    The first two values shown are the st
addresses. The
third, in this case zero, is intended to represent whether
the pages are in resident. This value is simply the result
of a call to pmap_extract.
    Is this to be expected? Should mmap(2) serve
up a virtual address which pmap_extract cannot determine the
physical address? Or is there a flaw in this logic?
    Thanks in advance......
    Dr
     
Loading...