LKML Archive on lore.kernel.org help / color / mirror / Atom feed
* Reversing a memory mapping? @ 2011-02-03 20:50 Nikolaus Rath 2011-02-05 21:04 ` virt_to_page for userspace pointers (was: Reversing a memory mapping?) Nikolaus Rath 0 siblings, 1 reply; 10+ messages in thread From: Nikolaus Rath @ 2011-02-03 20:50 UTC (permalink / raw) To: linux-kernel Hello, I am trying to outsmart the proprietary nvidia driver to get my own driver to access to a memory region set up by the nvidia driver. Strace tells me that the nividia userspace library is calling mmap2(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_SHARED, 5, 0x35375) to get a userspace pointer to the kernel memory that I'm interested in. 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? I know that the region is pinned and used as a DMA buffer for communication with the GPU. I want my own device to do DMA transfers to and from the same location. Thanks, -Nikolaus -- »Time flies like an arrow, fruit flies like a Banana.« PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C ^ permalink raw reply [flat|nested] 10+ messages in thread
* virt_to_page for userspace pointers (was: Reversing a memory mapping?) 2011-02-03 20:50 Reversing a memory mapping? Nikolaus Rath @ 2011-02-05 21:04 ` Nikolaus Rath 2011-02-05 21:36 ` virt_to_page for userspace pointers Brice Goglin 0 siblings, 1 reply; 10+ messages in thread From: Nikolaus Rath @ 2011-02-05 21:04 UTC (permalink / raw) To: linux-kernel Nikolaus Rath <Nikolaus@rath.org> 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: virt_to_page for userspace pointers 2011-02-05 21:04 ` virt_to_page for userspace pointers (was: Reversing a memory mapping?) Nikolaus Rath @ 2011-02-05 21:36 ` Brice Goglin 2011-02-13 20:24 ` Nikolaus Rath 0 siblings, 1 reply; 10+ messages in thread From: Brice Goglin @ 2011-02-05 21:36 UTC (permalink / raw) To: Nikolaus Rath; +Cc: LKML Le 05/02/2011 22:04, Nikolaus Rath a écrit : > Nikolaus Rath <Nikolaus@rath.org> 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: virt_to_page for userspace pointers 2011-02-05 21:36 ` virt_to_page for userspace pointers Brice Goglin @ 2011-02-13 20:24 ` Nikolaus Rath 2011-02-13 20:37 ` Brice Goglin 2011-02-14 22:46 ` Nikolaus Rath 0 siblings, 2 replies; 10+ messages in thread From: Nikolaus Rath @ 2011-02-13 20:24 UTC (permalink / raw) To: Brice Goglin; +Cc: LKML 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: virt_to_page for userspace pointers 2011-02-13 20:24 ` Nikolaus Rath @ 2011-02-13 20:37 ` Brice Goglin 2011-02-13 21:56 ` Nikolaus Rath 2011-02-14 22:46 ` Nikolaus Rath 1 sibling, 1 reply; 10+ messages in thread From: Brice Goglin @ 2011-02-13 20:37 UTC (permalink / raw) To: Nikolaus Rath; +Cc: LKML 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: virt_to_page for userspace pointers 2011-02-13 20:37 ` Brice Goglin @ 2011-02-13 21:56 ` Nikolaus Rath 2011-02-13 22:06 ` Alan Cox 0 siblings, 1 reply; 10+ messages in thread From: Nikolaus Rath @ 2011-02-13 21:56 UTC (permalink / raw) To: Brice Goglin; +Cc: LKML 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: virt_to_page for userspace pointers 2011-02-13 21:56 ` Nikolaus Rath @ 2011-02-13 22:06 ` Alan Cox 2011-02-13 22:11 ` Nikolaus Rath 0 siblings, 1 reply; 10+ messages in thread From: Alan Cox @ 2011-02-13 22:06 UTC (permalink / raw) To: Nikolaus Rath; +Cc: Brice Goglin, LKML > > 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: virt_to_page for userspace pointers 2011-02-13 22:06 ` Alan Cox @ 2011-02-13 22:11 ` Nikolaus Rath 0 siblings, 0 replies; 10+ messages in thread From: Nikolaus Rath @ 2011-02-13 22:11 UTC (permalink / raw) To: Alan Cox; +Cc: Brice Goglin, LKML 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: virt_to_page for userspace pointers 2011-02-13 20:24 ` Nikolaus Rath 2011-02-13 20:37 ` Brice Goglin @ 2011-02-14 22:46 ` Nikolaus Rath 2011-07-26 12:03 ` Alexey Skidanov 1 sibling, 1 reply; 10+ messages in thread From: Nikolaus Rath @ 2011-02-14 22:46 UTC (permalink / raw) To: linux-kernel Nikolaus Rath <Nikolaus@rath.org> writes: > 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? After studying the source for get_user_pages(), I believe the following should do what I want: vma = find_extend_vma(current->mm, (unsigned long) data.vi_buf); if(vma == NULL) { err("find_extend_vma failed for VI."); } acq_dev->vi_pg = follow_page(vma, (unsigned long) data.vi_buf, 0); if(acq_dev->vi_pg == NULL) { err("follow_page failed for VI."); } Unfortunately, I'm getting into trouble at link time when using these functions: MODPOST 1 modules WARNING: "follow_page" [/home/nikratio/control/acq196_hostdrv/acq200_hostdrv.ko] undefined! WARNING: "find_extend_vma" [/home/nikratio/control/acq196_hostdrv/acq200_hostdrv.ko] undefined! Can they only be used in the kernel itself, but not in kernel modules? Thanks, -Nikolaus -- »Time flies like an arrow, fruit flies like a Banana.« PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: virt_to_page for userspace pointers 2011-02-14 22:46 ` Nikolaus Rath @ 2011-07-26 12:03 ` Alexey Skidanov 0 siblings, 0 replies; 10+ messages in thread From: Alexey Skidanov @ 2011-07-26 12:03 UTC (permalink / raw) To: linux-kernel Nikolaus Rath <Nikolaus <at> rath.org> writes: > > Nikolaus Rath <Nikolaus <at> rath.org> writes: > > 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? > > After studying the source for get_user_pages(), I believe the following > should do what I want: > > vma = find_extend_vma(current->mm, (unsigned long) data.vi_buf); > if(vma == NULL) { > err("find_extend_vma failed for VI."); > } > acq_dev->vi_pg = follow_page(vma, (unsigned long) data.vi_buf, 0); > if(acq_dev->vi_pg == NULL) { > err("follow_page failed for VI."); > } > > Unfortunately, I'm getting into trouble at link time when using these > functions: > > MODPOST 1 modules > WARNING: "follow_page" [/home/nikratio/control/acq196_hostdrv/acq200_hostdrv.ko] undefined! > WARNING: "find_extend_vma" [/home/nikratio/control/acq196_hostdrv/acq200_hostdrv.ko] undefined! > > Can they only be used in the kernel itself, but not in kernel modules? > > Thanks, > > -Nikolaus > Hi, I had the same problem working with NVIDIA GPU driver. The NVIDIA driver mmap allocated memory using vm_insert_page() - allowing inserting single page into the vma. So you need to translate go over the whole vma and translate it page by page. I just implemented the function to translate the virtual address to pfn. It mostly the same as follow_page: /** * This function walks through page tables and get the PFN of virtual address */ long get_pfn_of_virtual_address(struct vm_area_struct *vma, unsigned long address, unsigned long& pfn) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *ptep; spinlock_t *ptl; struct mm_struct *mm = vma->vm_mm; pgd = pgd_offset(mm, address); if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) return -EFAULT; pud = pud_offset(pgd, address); if (pud_none(*pud) || unlikely(pud_bad(*pud))) return -EFAULT; pmd = pmd_offset(pud, address); if (pmd_none(*pmd)) return -EFAULT; ptep = pte_offset_map_lock(mm, pmd, address, &ptl); pfn = pte_pfn(*ptep); pte_unmap_unlock(ptep, ptl); return 0; } ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-07-26 12:05 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-02-03 20:50 Reversing a memory mapping? Nikolaus Rath 2011-02-05 21:04 ` virt_to_page for userspace pointers (was: Reversing a memory mapping?) Nikolaus Rath 2011-02-05 21:36 ` virt_to_page for userspace pointers Brice Goglin 2011-02-13 20:24 ` Nikolaus Rath 2011-02-13 20:37 ` Brice Goglin 2011-02-13 21:56 ` Nikolaus Rath 2011-02-13 22:06 ` Alan Cox 2011-02-13 22:11 ` Nikolaus Rath 2011-02-14 22:46 ` Nikolaus Rath 2011-07-26 12:03 ` Alexey Skidanov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).