Linux kernel 从内核空间访问用户空间-获取用户页面

Linux kernel 从内核空间访问用户空间-获取用户页面,linux-kernel,kernel,kernel-module,Linux Kernel,Kernel,Kernel Module,我希望将指针从用户空间内存传递到内核模块中的函数中。我不想使用copy\u from\u user。我读到应该使用get\u user\u 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,

我希望将指针从用户空间内存传递到内核模块中的函数中。我不想使用
copy\u from\u user
。我读到应该使用
get\u user\u 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
是用户空间中的地址

  • 完成此操作后,是否允许我将
    uaddr
    强制转换并传递到内核模块函数中?或者我必须以某种方式使用这些
    struct页面
  • 为什么我必须使用向下/向上读取
  • 毕竟我必须使用
    SetPageDirty()
    page\u cache\u release()
    函数吗

  • 这不是
    get\u user\u pages
    的目的(不-您不能将
    uaddr
    强制转换并传递到内核模块函数中)


    如果您不想在调用函数中调用
    copy\u from\u user
    ,则只需将
    void\u user*
    传递给模块函数,并让它执行
    copy\u from\u user

    您只能将用户页面用于页面类型活动,例如将分散/聚集DMA设置到用户空间内存中。您不能使用它直接从内核模式代码访问用户空间。因此,出于该原因存在的复制到/从函数。除非移动大量数据,否则为什么不使用这些功能

  • 不,您不能通过uaddr直接访问用户空间页面。结构页面被填充以允许内核访问与用户空间页面相对应的物理页面。还请注意,它们不太可能是连续的,因此必须小心从uaddr的开始就在数组中使用正确的页面索引
  • 您正在为此进程更改页面映射结构,因此需要在设置内核中的页面映射时保护它们
  • 完成由get_user_pages()设置的映射后,必须通过引用的函数“释放”它们
    获取有效的用户空间地址后,使用get_user_pages获取结构页指针。一旦收到结构页指针,要在内核模式下访问它,必须使用kmap将其映射到内核虚拟地址。希望有帮助