来自内核空间的用户空间访问 - get_user_pages

时间:2009-12-07 19:53:23

标签: linux-kernel kernel kernel-module

我想将指针从用户空间内存传递到我的内核模块中的函数。我不想使用copy_from_user。我已经读过我应该使用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. 为什么我必须使用向下/向上阅读?
  3. 完成所有操作后,我必须使用SetPageDirty()page_cache_release()函数?

4 个答案:

答案 0 :(得分:2)

这不是get_user_pages的用途(并且没有 - 你不能只是将uaddr转换并传递给你的内核模块函数。)

如果您不想在调用函数中调用copy_from_user,那么只需将void __user *传递给您的模块函数并让执行copy_from_user }。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

答案 3 :(得分:0)

获得有效的用户空间地址后,使用get_user_pages获取struct page指针。一旦接收到struct page指针,要在内核模式下访问它,您必须使用kmap将其映射到内核虚拟地址。希望有所帮助