assembly - RISC-V 陷阱处理程序重入陷阱处理程序中的异常
问题描述
在系统初始化期间将 mscratch 设置为陷阱处理程序内存上下文然后执行似乎是一个常见的技巧:
csrrw tp, CSR_MSCRATCH, tp
在机器模式陷阱处理程序的开头交换 tp 和 mscratch。然后在机器模式陷阱处理程序中使用 tp 来访问陷阱处理程序本身所需的内存/状态。在陷阱处理程序结束时,再次执行以恢复指向 mscratch 的内存上下文指针和 tp 的原始值。
不过好像有问题。如果由于某种原因在陷阱处理程序本身中发生异常,您将交换 tp 的原始值,该值现在与机器模式陷阱处理程序上下文处于 mscratch 中,因此在处理陷阱时您将使用错误的内存上下文处理程序生成异常。
如果您想检测这种情况,您将需要一个免费寄存器来读取 MPP。
如何处理?
解决方案
我有一个支持嵌套异常的玩具处理程序。我总是1在那个 csr 中保留一个指向当前运行代码的上下文块的指针scratch
——这包括在异常处理程序本身的执行期间。
我的玩具处理程序开始这样的事情:
csrrw t0, scratch, t0 # swap interrupted t0 and its context block pointer
beqz t0, bootUp # or if it is null then put the base CBP in there...
sw t1, 12(t0) # save interrupted t1 to its context block
lw t1, 4(t0) # fetch context block pointer for me
csrrw t1, scratch, t1 # t1 has interrupted t0, CSR scratch points to my context block
sw t1, 8(t0) # save interrupted t0 to its context block
sw t2, 16(t0) # save t2
在这段代码之后,t0
是指向被中断代码的上下文块的指针,被中断的t0
, t1
&t2
被保存到被中断代码的上下文块中,因此t1
可以t2
自由使用,而scratch
csr 是指向本次运行的上下文块的指针异常处理程序。
用户代码的上下文块可以存储在任何地方,例如malloc
根据需要编辑。在每个用户上下文块中(例如4(t0)
上面的 at),我存储了一个指向特殊异常处理程序上下文块数组的指针。
在任何异常处理程序上下文块中(在特殊数组中),每个(在偏移量 4 处)都被预初始化以引用数组中的下一个条目,因此嵌套异常自然会在特殊数组中采用不同的上下文块,就像一个动态嵌套异常处理程序的堆栈;因此,对于该数组中的尽可能多的元素,它可以为许多嵌套异常提供服务。
如果需要,用于异常处理程序的上下文块可以包含其他数据,例如指向全局数据的指针。
处理快速中断可能会保存一些寄存器、运行一些代码、恢复这些寄存器并恢复中断的代码。对于其他一些中断,调度程序可能会选择切换上下文(例如 I/O 就绪),恢复与上次中断不同的线程。由于正确的上下文块已经具有中断线程的部分状态,因此对于完整的上下文切换,只需保存额外的寄存器状态(无需将任何寄存器状态从临时位置转移到正确的上下文块)。
1 除了处理程序开头的 ~4-5 指令窗口。
作为恢复的一部分,对于正在恢复的任何线程,将其 t0 及其上下文块指针恢复到scratch
csr 中。
如果遇到嵌套异常,要恢复的线程只是中断的异常处理程序,而如果用户线程被中断,则由调度程序决定是否恢复最近中断的用户线程(通常不需要完整的上下文切换)或恢复另一个先前挂起的用户线程,该线程可能已被时间片超时或 I/O 系统调用挂起。如果外部中断指示完成的 I/O 操作,则等待该 I/O 的线程可能适合恢复。(系统调用,我正在做 as csrrw zero, %arg, zero
,以便在捕获指令中编码系统调用号,并避免使用ecall
自 RARS 服务以来)。
在我的玩具系统中,我支持用户级别的多线程,因此一个线程可以通过系统调用请求“操作系统”创建另一个线程。因此,用户线程的上下文块可以“malloc”,而异常处理程序上下文块堆叠在该预初始化数组中。
我的玩具系统在 RARS 下运行,所以是的,它没有多个地址空间的复杂性。
推荐阅读
- android - 将地图存储在房间数据库中
- c# - 在 WPF 中,当我按下按钮时,会执行另一个事件按钮
- gcc - 显示编译过程的标志
- c - C中的Shell程序如何运行子目录中的已编译程序?
- debugging - 在没有警告/同意的情况下自动添加代码行
- haskell - 如何将重叠编译指示应用于派生实例
- python - 你好,我是learnign pyton,我得到一个错误响应400,我在谷歌上搜索解决方案,但我没有找到
- c# - 如何修复未显示的 Visual Studio C# 项目属性?
- xml - Angular 11文件上传formdata到asp.net核心api为空
- azure - Azure 自动化帐户中的 Runbook 和变量数是否有限制?