Linux kernel 为什么需要向用户/从用户复制?

Linux kernel 为什么需要向用户/从用户复制?,linux-kernel,Linux Kernel,按照x86和ppc上的linux设计,4g虚拟地址空间划分为3:1。 用户虚拟地址在3g之前都是可用的 现在,如果用户应用程序执行ioctl,将指针传递到缓冲区,内核模块可以直接执行memcpy,我尝试了,它成功了。 =>为什么我们需要向用户复制/从用户复制 注意:如果页面被调出,那么内核pagefault处理程序将把它带回来,并且内核模块看不到它 需要你的想法。。。评论你很幸运它成功了 用户空间和内核空间在完全不同的地址空间中运行。当您将_复制到_用户时,内核将用户空间的虚拟地址转换为真实的物

按照x86和ppc上的linux设计,4g虚拟地址空间划分为3:1。 用户虚拟地址在3g之前都是可用的

现在,如果用户应用程序执行ioctl,将指针传递到缓冲区,内核模块可以直接执行memcpy,我尝试了,它成功了。 =>为什么我们需要向用户复制/从用户复制

注意:如果页面被调出,那么内核pagefault处理程序将把它带回来,并且内核模块看不到它


需要你的想法。。。评论

你很幸运它成功了

用户空间和内核空间在完全不同的地址空间中运行。当您将_复制到_用户时,内核将用户空间的虚拟地址转换为真实的物理地址,并将数据复制到那里。类似的过程反过来发生


如果硬件支持分散/聚集DMA,则可以直接跳过复制到/从步骤。在这里,您将一个连续的虚拟内存块映射到一系列物理页面中,然后使用该信息将DMA直接映射到用户空间中。当然,如果任何虚拟地址空间当前未映射到物理内存(请考虑交换或文件备份的MMAP),这会带来复杂问题。

有几个很好的理由说明
copy_to_user
/
copy_from_user
是正确使用的功能:

  • 在某些体系结构上,简单的
    memcpy()
    不起作用,因此使用这些函数可以让代码在那里工作。我相信即使选择了
    HIGHMEM
    config选项的x86也在这条船上

  • 这些函数执行
    access\u ok()
    检查,以确保引用的用户空间地址确实是真实的用户空间地址。如果只执行
    memcpy()
    ,则
    ioctl()
    的调用方可以提供与内核地址重叠的地址范围,这是一个安全漏洞

  • 然而,主要原因是正确处理错误的用户地址。如果只使用裸的
    memcpy()
    ,未经处理的故障将导致内核oops。用户访问功能使用,允许处理故障(读取或写入时间短,在这种情况下,
    EFAULT
    通常返回到用户空间)


如果地址是有效的(比如说,最好的情况下,没有人在捣乱),memcpy应该可以工作。@Manish:它不一定是“捣乱”,它可能只是用户空间中的一个普通的老错误-这样的错误应该由内核优雅地处理。而
memcpy()
只能在某些架构上工作。是否可以将\u复制到\u用户/从\u用户睡眠复制\u?@nirvanaswap:是的,因为您点击的用户地址可能会导致页面错误,这可能需要睡眠来处理(例如可能需要从文件中读取页面)。3g:1g拆分应该解决这个问题。AFAIK内核不需要将va转换为pa进行复制。