【问题标题】:RISC-V return from exception handler with compressed instructionsRISC-V 从带有压缩指令的异常处理程序返回
【发布时间】:2020-06-03 02:16:42
【问题描述】:

我看到退出 RISC-V 异常处理程序的标准方法是在 mret 之前将 mepc 更新为 mepc+4

但是如果下一条指令在压缩指令模式下只有2字节长,这不会引起问题吗?

在压缩指令模式下,混合了 4 字节和 2 字节指令。如果您不更新mepc 而只是更新mret,那么您将继续遇到相同的异常。但是总是在被困的mepc 上加 4 似乎是混合压缩指令的错误。

我错过了什么吗?

【问题讨论】:

  • @Dave2e,您以“需要详细信息”的形式结束了此问题,但并未暗示缺少哪些详细信息。这个问题对我来说非常清楚,而且,我在它关闭之前回答了它。给出一个合理的答案,关闭是没有意义的。

标签: exception assembly riscv


【解决方案1】:

我看到退出 risc-v 异常处理程序的标准方法是在 mret 之前将 mepc 更新为 mepc+4。

这些不是严重的异常处理程序;它们只是说明性的——显示异常的捕获,并在没有完成给定情况所需的实际异常处理的情况下返回到被中断的代码。因此,防止无限循环最简单的方法就是跳过有问题的指令。

我们推进 pc 以返回导致异常的代码的少数几个地方之一是处理 ecall。据我所知,没有压缩(16 位)ecall 指令。

许多可恢复的异常需要重新运行导致异常的指令——例如,导致页面错误的加载和存储(在 32 位和 16 位形式中都可用),例如,需要在页表完成后重新执行已修复(从磁盘读取并映射到用户地址空间的页面)。

许多其他异常通常不可恢复。

但是,模拟指令需要知道它的大小,ecall 就是这种情况。如果您选择模拟,例如,未对齐的内存访问,您确实必须决定指令的大小,因为模拟它意味着恢复过去。另请注意,RISC V 支持 16 位、32 位、48 位、64 位和更长的指令,因此要模拟指令的异常处理程序将需要能够解码它们的长度(仅选择用于不过是模拟)。

要补充的另一件事是,您可能正在查看的示例异常处理程序设计为在没有压缩指令集的情况下工作,并且由于 RVC 是可选的,这是一个合理的设计选择(尽管理想情况下,当然,显然声明)。

【讨论】:

  • 大多数页面错误不是hard(需要从磁盘获取页面),至少在大多数系统中是这样。更常见的是来自内核延迟分配和/或 CoW 的软页面错误。但可以肯定的是,硬页面错误可以作为示例。
  • 感谢 Erik 清楚地列出了所有异常以及如何处理它们。因此,对于我的自定义陷阱处理程序,解决方案是在 mret 恢复之前解码指令大小并相应地调整 mepc 要获得指令大小,我只需查看指令的低两位。 xxxxaa != xxxx11 是 16 位指令。
  • 是的,那个测试应该告诉你是增加2还是4。对于外部中断,不要调整pc,因为我们只想恢复被中断的线程而不修改;仅当您正在模拟/模拟异常指令(如 ecall 的情况)或者您只是想跳过异常指令时才调整 pc。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 2018-11-22
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 2020-01-12
相关资源
最近更新 更多