2009-12-07 209 views
3

我想将用户空间内存的指针传递给内核模块中的函数。我不想用copy_from_user。我读过我应该使用get_user_pages函数。从内核空间访问用户空间 - get_user_pages

例如一页。

struct page **pages; 
pages = kmalloc(1 * sizeof(*pages), GFP_KERNEL); 

down_read(&current->mm->mmap_sem); 
get_user_pages(current,current->mm,uaddr, 1, 1, 0,pages,NULL); 
up_read(&current->mm->mmap_sem); 

uaddr是用户空间中的地址。

  1. 这样做后,我可以投入并通过uaddr到我的内核模块功能?或者,也许我必须以某种方式使用这些struct pages
  2. 为什么我必须使用down/up读取?
  3. 之后,我必须使用SetPageDirty()page_cache_release()函数?

回答

2

这不是get_user_pages的用途(也不是 - 你不能然后只是将uaddr投到你的内核模块函数中)。

如果您不想打电话copy_from_user调用函数,那么就只是传递一个void __user *你的模块功能,并有copy_from_user

2

您只能使用页面类型活动的用户页面,例如将Scatter/Gather DMA设置到用户空间内存中。您不能使用它从内核模式代码直接访问用户空间。因此,出于这个原因的copy_to/from函数。除非你移动大量的数据,为什么不使用这些功能?

2
  1. 不,您不能通过uaddr直接访问用户空间页面。结构页面被填充以允许内核访问与用户空间页面对应的物理页面。还要注意,它们最不可能是连续的,因此从uaddr的开始就必须小心地将正确的页索引用于数组。
  2. 您正在更改此进程的页面映射结构,因此需要在内核中的页面映射设置时保护它们。
  3. 当您完成get_user_pages()设置的映射时,您必须通过引用的函数“释放”它们。
0

一旦你得到有效的用户空间地址,使用get_user_pages来获取结构页面指针。一旦收到struct page指针,要在内核模式下访问它,必须使用kmap将其映射到内核虚拟地址。希望可以帮到