Gil*_*il' 5 fork shared-memory virtual-memory linux-kernel
考虑使用get_user_pages
(或get_page
)映射来自调用进程的页面的 Linux 驱动程序。然后将页面的物理地址传递给硬件设备。进程和设备都可以读取和写入页面,直到双方决定结束通信。特别地,在调用get_user_pages
返回的系统调用之后,通信可以继续使用页面。系统调用实际上是在进程和硬件设备之间建立一个共享内存区域。
我担心如果进程调用会发生什么fork
(它可能来自另一个线程,并且可能在调用的系统调用get_user_pages
正在进行中或稍后发生)。特别是,如果父级在fork后写入共享内存区域,我对底层物理地址了解多少(可能是因为copy-on-write而改变)?我想明白:
进程需要遵守哪些限制,以便我们的驱动程序的功能正常工作(即物理内存保持映射到父进程中的相同地址)。
exec
几乎立即调用)来工作的常见情况。madvise
with MADV_DONTFORK
,并且可以让内存从子进程的空间中消失,但它不适用于堆栈分配的缓冲区。我愿意被指出文档或源代码。我特别查看了Linux Device Drivers,但没有发现这个问题得到解决。即使只是应用于内核源代码的相关部分的 RTFS 也有点让人不知所措。
内核版本不是完全固定的,而是最近的版本(比如 ??2.6.26)。如果重要的话,我们只针对 Arm 平台(目前是单处理器,但多核即将到来)。
Afork()
不会干涉get_user_pages()
:get_user_pages()
会给你一个struct page
。
您需要kmap()
它才能访问它,并且此映射是在内核空间而不是用户空间中完成的。
编辑:get_user_pages()
触摸页表,但您不应该担心这一点(它只是确保页面映射在用户空间中),如果这样做有任何问题,则返回 -EFAULT 。
如果您 fork(),直到执行写入时复制,子进程将能够看到该页面。一旦写时复制完成(因为子进程/驱动程序/父进程通过用户空间映射写入页面——而不是驱动程序具有的内核 kmap()),该页面将不再被共享。如果您仍然在页面上(在驱动程序代码中)持有 kmap(),您将无法知道您持有的是父页面还是子页面。
1)这不是一个安全漏洞,因为一旦你执行了 execve(),所有这些都消失了。
2)当您 fork() 时,您希望两个进程相同(这是一个分叉!!)。我认为你的设计应该允许父母和孩子都访问驱动程序。Execve() 将刷新所有内容。
在用户空间中添加一些功能怎么样:
f = open("/dev/your_thing")
mapping = mmap(f, ...)
Run Code Online (Sandbox Code Playgroud)
当在您的设备上调用 mmap() 时,您将安装带有特殊标志的内存映射: http://os1a.cs.columbia.edu/lxr/source/include/linux/mm.h#071
你有一些有趣的事情,例如:
#define VM_SHARED 0x00000008
#define VM_LOCKED 0x00002000
#define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
Run Code Online (Sandbox Code Playgroud)
VM_SHARED 将禁用写入时复制 VM_LOCKED 将禁用该页面上的交换 VM_DONTCOPY 将告诉内核不要在 fork 上复制 vma 区域,尽管我认为这不是一个好主意
归档时间: |
|
查看次数: |
2619 次 |
最近记录: |