layout | title | category | description | tags |
---|---|---|---|---|
post |
从中断和异常返回 |
中断和异常 |
从中断和异常返回... |
中断 异常 |
在恢复中断和异常之后,通常直接恢复某个程序的执行即可,但是在这样做之前,还必须要考虑几个问题:
- 内核控制路径并发的执行数量,如果仅仅只有一个,那么CPU必须切换到用户态。
- 挂起进程的切换请求,如果有任何请求,内核就必须执行进程调度,否则,把控制权还给当前进程。
- 挂起的信号,如果一个信号发送到当前进程,就必须处理它。
- 单步执行模式,如果调试程序正在跟着当前的进程的执行,就必须在进程切换回到用户态之前恢复单步执行。
- Virtual-8086模式,如果CPU处以该模式,则当前进程正在执行原来实模式程序,因而必须以特殊的方式处理这种情况。
需要使用一些标志来记录挂起进程切换的请求、挂起信号和单步执行,这些标志被存放在thread_info描述符的flags字段中,这个字段也存放其他与中断和异常返回无关的标志,这些标志包含:
标志 | 说明 |
---|---|
TIF_SYSCALL_TRACE | 正在跟踪系统调用 |
TIF_NOTIFY_RESUME | 在80x86平台上不使用 |
TIF_SIGPENDING | 进程有挂起信号 |
TIF_NEED_RESCHED | 必须执行调度程序 |
TIF_SINGLESTEP | 临返回用户态前恢复单步执行 |
TIF_IRET | 通过iret而不是sysexit从系统调用强行返回 |
TIF_SYSCALL_AUDIT | 系统调用正在被审计 |
TIF_POLLING_NRFLAG | 空闲进程正在轮询TIF_NEED_RESCHED标志 |
TIF_MEMDIE | 正在撤销进程以回收内容 |
从技术上来说,完成所有这些事情的内核汇编语言代码并不是一个函数,因为控制权从不返回到调用它的函数,它只是一个代码片段,有两个不同的入口点,分别叫做ret_from_intr()和ret_from_exception()。
中断处理程序结束时,内核进入ret_from_intr(),而当异常处理程序结束时,它进入ret_from_exception。这两个入口点并不是两个函数,只是因为方便而如此使用。具体的实现是晦涩的汇编语言,也许在今后的笔记中会更详细的记录。