驱动程序有什么方法可以检查给定的虚拟地址是否已映射并且可以取消引用吗?
谢谢。
最佳答案
我假设您在执行某些需要用户空间地址的系统调用时遇到问题。在这种情况下,我们实际上不需要检查地址是否有效 - 事实上,我们需要做相反的事情:防止失败机制参与。
来自Kernel System Calls by Alessandro Rubini
Like any other function that transfers data to/from user space using a user-provided pointer, the system call checks whether the provided buffer is a valid address or not. During normal operation, an address that lies in the user address range (0-3GB for standard kernel configuration) is considered valid, and an address that lies in kernel address space (3GB-4GB) is not.
您可以一起使用宏get_ds
、get_fs
和set_fs
来定义被视为有效的最高虚拟地址,从而允许您将内核空间地址传递给系统调用。
mm_segment_t fs = get_fs(); /* save previous value */
set_fs (get_ds()); /* use kernel limit */
/* system calls can be invoked */
set_fs(fs); /* restore before returning to user space */
- 首先,我们使用
get_fs
宏保存当前配置。 - 接下来,我们使用
set_fs
宏来设置新的上限。get_ds
宏为内核提供最大可能的虚拟地址。
- 所有内核地址现在都有效。
- 此配置将持续到下一个
set_fs
。 - 根据需要调用尽可能多的系统调用,而不必担心通常的用户空间地址检查失败。
- 此配置将持续到下一个
- 最后我们使用
set_fs
宏将限制返回到之前的配置。
重要:确保将限制返回到之前的配置(其中只有用户空间地址有效);否则,从用户空间传递的无效指针可能会对您的驱动程序造成严重破坏!
关于linux-kernel - 我如何判断虚拟内核地址是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16455787/