从内核空间访问用户空间 - get_user_pages

发布于 2024-08-13 08:01:34 字数 626 浏览 5 评论 0原文

我想将指针从用户空间内存传递到内核模块中的函数中。我不想使用 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 转换并传递到我的内核模块函数中?或者也许我必须以某种方式使用这些结构页面
  2. 为什么我必须使用向下/向上读取?
  3. 毕竟我必须使用 SetPageDirty()page_cache_release() 函数吗?

I'd like pass a pointer from a user space memory into a function in my kernel module. I don't want to use copy_from_user. I've read that I should use get_user_pages function.

For example one page.

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

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

uaddr is an address in User Space.

  1. After doing this, am I allowed to cast and pass uaddr into my kernel module function? Or maybe I have to use these struct pages in some way?
  2. Why do I have to use down/up read?
  3. After everything do I have to use SetPageDirty() and page_cache_release() functions ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

内心旳酸楚 2024-08-20 08:01:34
  1. 不,您不能通过 uaddr 直接访问用户空间页面。结构体页面被填充以允许内核访问与用户空间页面相对应的物理页面。另请注意,它们不太可能是连续的,因此必须小心地从 uaddr 开头开始在数组中使用正确的页索引。
  2. 您正在更改此进程的页面映射结构,因此需要在内核中设置页面映射时保护它们。
  3. 当您完成由 get_user_pages() 设置的映射后,您必须通过引用的函数“释放”它们。
  1. No, you cannot directly access the userspace pages via uaddr. The struct pages are filled out to allow the kernel to access the physical pages that correspond to the userspace pages. Note also that they are most unlikely to be contiguous, so one must be careful to use the correct page index into the array from the start of the uaddr.
  2. You are changing the page mapping structures for this process, so need to protect them while the page mapping in the kernel is set up.
  3. When you are done with the mappings that were setup by get_user_pages(), you must 'release' them by the referenced functions.
挽你眉间 2024-08-20 08:01:34

这不是 get_user_pages 的用途(而且不 - 你不能直接将 uaddr 强制转换并传递到内核模块函数中)。

如果您不想在调用函数中调用 copy_from_user,则只需将 void __user * 传递给您的模块函数并让它执行此操作copy_from_user

This is not what get_user_pages is for (and no - you can't then just cast and pass uaddr into your kernel module function).

If you don't want to call copy_from_user in the calling function, then just pass a void __user * to your module function and have it do the copy_from_user.

方圜几里 2024-08-20 08:01:34

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

You can only use the user pages for page type activity, for example setting up Scatter/Gather DMA into userspace memory. You cannot use it to directly access user space from kernel mode code. Hence the copy_to/from functions that are there for that reason. Unless your moving large amounts of data why not use these functions?

若无相欠,怎会相见 2024-08-20 08:01:34

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

Once you get the valid user space address, use get_user_pages to get the struct page pointer. once struct page pointer received , to access it in the kernel mode you have to map it to kernel virtual address by using kmap. hope that helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文