cpu 如何向内核发送有关硬件异常的信号?

Posted

技术标签:

【中文标题】cpu 如何向内核发送有关硬件异常的信号?【英文标题】:how cpu signal kernal about a hardware exception? 【发布时间】:2020-09-21 16:05:52 【问题描述】:

有一个这样的汇编用户空间程序:

_start:
data: db"DATA..........."
    mov eax, 5

导致 CPU 执行数据,这将导致硬件异常,该异常应该被 linux 内核捕获,这将导致分段错误并终止程序。我的问题是 CPU 如何告诉内核异常以及是否有一些细节(例如除以零或数据执行异常)以及当这样的异常发生处理异常时它如何知道要执行的下一条指令(类似于内核我猜是硬件异常处理程序)

【问题讨论】:

将导致硬件异常 - 如果该数据恰好是一系列有效的机器指令(没有 #UD 非法指令),并且不分页 -错误(没有无效的内存操作数)或其他异常。所以真的和问内核如何处理被零除、页面错误或其他异常(包括非法指令)没有什么不同 【参考方案1】:

我的问题是 CPU 如何告诉内核异常...

...以及它如何知道要执行的下一条指令...

在 x86 CPU 上,异常是中断(就像硬件中断或 int 指令调用的中断一样):

当某些异常发生时,CPU会将指令地址和其他一些信息压入内核堆栈,并跳转到中断向量表中指定的地址。

内核可能会读取压入堆栈的地址以获取有关哪个指令导致异常的信息。

...如果有一些细节...

不同类型的异常调用不同的中断向量:

“除以零”将导致跳转到中断向量表中第一个条目中指定的地址; “页面错误”将导致跳转到该表的第 15 个条目中指定的地址。

对于不同类型的异常,操作系统有不同的“异常处理程序”(在异常情况下由硬件调用的汇编程序)。这些处理程序的地址存储在中断向量表中。 CPU 将从该表中读取处理程序的地址。

对于某些异常类型(例如“一般保护故障”),CPU 会将附加信息写入堆栈。对于其他异常类型(例如“页面错误”),有包含附加信息的特殊寄存器。

【讨论】:

,所以 CPU 知道它的工作(使用哪个中断向量)以防发生特定异常并转到另一个异常。以及“其他信息”是什么样的 @KhaledGaber 对于与段相关的异常(使用段寄存器指定:csdsesssfsgs)段寄存器的值被压入堆栈。对于页面错误异常(当某些线性地址无法访问时),有一个寄存器包含无法访问的线性地址。【参考方案2】:

执行任意数据通常会导致未定义的指令异常#UD。 (但它也可能首先导致页面错误、GP 错误或其他一些异常。而且它有可能进入没有错误的循环。)

当 CPU 检测到故障时,它会转换到内核模式并从 IDT 中加载与故障号对应的描述符(#UD 的描述符 6)。它将当前的 SS、RSP、标志、CS 和 RIP 推入内核堆栈。它开始在 IDT 描述符中的地址处执行内核代码。内核可以通过开始执行的处理程序的地址来判断它是#UD 而不是其他异常。

【讨论】:

您查看了该数据并确认它是未定义的?请详细说明 或者它可以进行访问,这是一种不同的错误,如果你我们我可以制作一些“数据”,碰巧不是未定义的指令,而是运行一点点然后以其他方式出错或更糟糕的循环,那么其他人可能会很幸运。您的开场白非常明确,因此评论说明了原因...(如果问这个问题,我的赌注也将是未定义的指令,但是如果有一个但是,您可能会很幸运)

以上是关于cpu 如何向内核发送有关硬件异常的信号?的主要内容,如果未能解决你的问题,请参考以下文章

linux 信号处理

Linux进程信号

Linux进程信号

Linux---信号详解

Linux内核中的硬件时钟信号实现

进程信号(Linux)