linux内核如何知道在syscall中作为参数传递的地址无效?

linux内核如何知道在syscall中作为参数传递的地址无效?,linux,linux-kernel,operating-system,system-calls,Linux,Linux Kernel,Operating System,System Calls,目前我正在阅读理解linux内核的一章中的系统调用,我无法理解linux内核如何知道通过syscall()传递的地址参数是无效的 这本书提到,地址检查会延迟到它被使用,当linux使用这个地址时,它会生成页面错误。 它进一步提到了在内核模式下有三种情况会发生故障 •内核试图寻址属于进程的页面 地址空间,但相应的页框不存在, 或者内核正在尝试编写只读页 •某些内核函数包含导致 执行该程序时引发的异常;或者, 异常可能是由瞬时硬件错误引起的 •系统调用服务例程尝试读取或写入 其地址已作为系统调用参数

目前我正在阅读理解linux内核的一章中的系统调用,我无法理解linux内核如何知道通过syscall()传递的地址参数是无效的

这本书提到,地址检查会延迟到它被使用,当linux使用这个地址时,它会生成页面错误。 它进一步提到了在内核模式下有三种情况会发生故障

•内核试图寻址属于进程的页面 地址空间,但相应的页框不存在, 或者内核正在尝试编写只读页

•某些内核函数包含导致 执行该程序时引发的异常;或者, 异常可能是由瞬时硬件错误引起的

•系统调用服务例程尝试读取或写入 其地址已作为系统调用参数传递的内存区域, 但该地址不属于进程地址空间

这些情况必须由页面错误处理程序区分,因为要采取的操作完全不同。页面错误处理程序可以通过确定错误的线性地址是否包含在进程拥有的某个内存区域中,轻松识别第一种情况


但内核如何区分其余两种情况。虽然课本上有解释,但我觉得它很陌生。请帮助并解释。

页面错误处理程序
\u do\u页面错误
包括以下代码:

if (!(error_code & X86_PF_USER) &&
            !search_exception_tables(regs->ip)) {
            bad_area_nosemaphore(regs, error_code, address, NULL);
            return;
        }
这种情况
!(error_code&X86_PF_USER)
在系统调用源自内核模式而非用户模式时为true。这种情况
!当执行使用传递给系统调用的线性函数的指令之一时,如果没有发生页面错误,则search_exception_tables(regs->ip)
为真。请注意,
regs->ip
保存导致页面错误的指令的指令指针。当这两个条件都为真时,这意味着要么某个内核函数中存在错误,要么存在某个硬件错误(第二种情况)

regs
包含页面出错时所有体系结构寄存器的快照。在x86上,这包括CS段寄存器。该寄存器中的RPL可用于确定系统调用源于用户模式还是内核模式

search\u exception\u tables
对编译内核时生成的指令地址排序数组执行二进制搜索。这些基本上是访问传递给系统调用的地址的指令


对于您列出的其他两种情况,条件
!(错误代码和X86用户)
将是错误的。

您的问题有问题。这三种情况似乎无法解决在内核模式下可能出现页面错误的问题。