2011-02-05 21:08:20

by Nikolaus Rath

[permalink] [raw]
Subject: virt_to_page for userspace pointers (was: Reversing a memory mapping?)

Nikolaus Rath <[email protected]> writes:
> Is there a way that my own kernel module can "reverse" this mmap call?
> I.e. given the userspace pointer, how do I get access to the physical
> location of the memory that has been mapped?

Ok, after some studying I think I can ask the question in a better way:

Is there an equivalent function to virt_to_page (and virt_to_phys) that
works with userspace pointers? Or do I have to manually walk through the
page tables? In the later case, are there any examples of this kind of
search that I could use as a basis?


Thanks,

-Nikolaus

--
»Time flies like an arrow, fruit flies like a Banana.«

PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C


2011-02-05 21:46:03

by Brice Goglin

[permalink] [raw]
Subject: Re: virt_to_page for userspace pointers

Le 05/02/2011 22:04, Nikolaus Rath a écrit :
> Nikolaus Rath <[email protected]> writes:
>
>> Is there a way that my own kernel module can "reverse" this mmap call?
>> I.e. given the userspace pointer, how do I get access to the physical
>> location of the memory that has been mapped?
>>
> Ok, after some studying I think I can ask the question in a better way:
>
> Is there an equivalent function to virt_to_page (and virt_to_phys) that
> works with userspace pointers? Or do I have to manually walk through the
> page tables? In the later case, are there any examples of this kind of
> search that I could use as a basis?
>

You probably want get_user_pages() (or get_user_pages_fast()).

Brice

2011-02-13 20:30:29

by Nikolaus Rath

[permalink] [raw]
Subject: Re: virt_to_page for userspace pointers

On 02/05/2011 04:36 PM, Brice Goglin wrote:
>> Is there an equivalent function to virt_to_page (and virt_to_phys) that
>> works with userspace pointers? Or do I have to manually walk through the
>> page tables? In the later case, are there any examples of this kind of
>> search that I could use as a basis?
>>
>
> You probably want get_user_pages() (or get_user_pages_fast()).

Thanks for the pointer, that already helped a lot!

I would, however, prefer a more primitive function that just gives me
the struct page without locking it. And if the page is swapped out, I'd
rather get a NULL pointer than having a page frame allocated. Is there
anything like that?

Thanks,

-Nikolaus

--
»Time flies like an arrow, fruit flies like a Banana.«

PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C

2011-02-13 20:37:20

by Brice Goglin

[permalink] [raw]
Subject: Re: virt_to_page for userspace pointers

Le 13/02/2011 21:24, Nikolaus Rath a écrit :
> On 02/05/2011 04:36 PM, Brice Goglin wrote:
>
>>> Is there an equivalent function to virt_to_page (and virt_to_phys) that
>>> works with userspace pointers? Or do I have to manually walk through the
>>> page tables? In the later case, are there any examples of this kind of
>>> search that I could use as a basis?
>>>
>>>
>> You probably want get_user_pages() (or get_user_pages_fast()).
>>
> Thanks for the pointer, that already helped a lot!
>
> I would, however, prefer a more primitive function that just gives me
> the struct page without locking it. And if the page is swapped out, I'd
> rather get a NULL pointer than having a page frame allocated. Is there
> anything like that?
>

If you don't lock the page, you have no guarantee that it won't get
swapped out or migrated while you look at the physical page.

Brice

2011-02-13 21:56:40

by Nikolaus Rath

[permalink] [raw]
Subject: Re: virt_to_page for userspace pointers

On 02/13/2011 03:37 PM, Brice Goglin wrote:
> Le 13/02/2011 21:24, Nikolaus Rath a écrit :
>> On 02/05/2011 04:36 PM, Brice Goglin wrote:
>>
>>>> Is there an equivalent function to virt_to_page (and virt_to_phys) that
>>>> works with userspace pointers? Or do I have to manually walk through the
>>>> page tables? In the later case, are there any examples of this kind of
>>>> search that I could use as a basis?
>>>>
>>>>
>>> You probably want get_user_pages() (or get_user_pages_fast()).
>>>
>> Thanks for the pointer, that already helped a lot!
>>
>> I would, however, prefer a more primitive function that just gives me
>> the struct page without locking it. And if the page is swapped out, I'd
>> rather get a NULL pointer than having a page frame allocated. Is there
>> anything like that?
>>
>
> If you don't lock the page, you have no guarantee that it won't get
> swapped out or migrated while you look at the physical page.

That's fine, I know that if the page is there at all then it has been
locked by a (different) kernel driver. Is there any way to find out what
I want?


Thanks,

-Nikolaus

--
»Time flies like an arrow, fruit flies like a Banana.«

PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C

2011-02-13 22:01:48

by Alan

[permalink] [raw]
Subject: Re: virt_to_page for userspace pointers

> > If you don't lock the page, you have no guarantee that it won't get
> > swapped out or migrated while you look at the physical page.
>
> That's fine, I know that if the page is there at all then it has been
> locked by a (different) kernel driver. Is there any way to find out what
> I want?

How do you know the other driver isn't in the middle of releasing the
page ? Doing that deep in mm code without locking inversions will be fun.

Alan

2011-02-13 22:12:27

by Nikolaus Rath

[permalink] [raw]
Subject: Re: virt_to_page for userspace pointers

On 02/13/2011 05:06 PM, Alan Cox wrote:
>>> If you don't lock the page, you have no guarantee that it won't get
>>> swapped out or migrated while you look at the physical page.
>>
>> That's fine, I know that if the page is there at all then it has been
>> locked by a (different) kernel driver. Is there any way to find out what
>> I want?
>
> How do you know the other driver isn't in the middle of releasing the
> page ? Doing that deep in mm code without locking inversions will be fun.

I have complete control over the environment, and I know that my code
will only be called after the other driver has set up the mapping and
the mapping will continue to exist until my code returns.

Please let me risk to shoot myself in the foot, just tell me if there is
a function to do so.. I take full responsibility.


Thanks,

-Nikolaus

--
?Time flies like an arrow, fruit flies like a Banana.?

PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C