首页 > 解决方案 > RISC-V:切换到管理员模式时出现非法指令异常

问题描述

mstatus.mpp字段设置为切换到主管模式时,我在调用时遇到非法指令异常mret。我正在qemu-system-riscv64使用系统在 6.1 版中对此进行测试riscv64-softmmu。我最近从 QEMU 5.0 升级到了 6.1。在此升级之前,我的代码有效。我在更改日志中看不到任何相关内容。我假设我的代码中存在新版本根本无法容忍的问题。

这是显示正在发生的事情的程序集片段(删除了不相关的引导代码):

.setup_hart:
    csrw satp, zero                                # Disable address translation.

    li   t0, (1 << 11)                             # Supervisor mode.
    csrw mstatus, t0

    csrw mie, zero                                 # Disable interrupts.

    la  sp, __stack_top                            # Setup stack pointer.

    la   t0, asm_trap_vector
    csrw mtvec, t0

    la   t0, kernel_main                           # Jump to kernel_main on trap return.
    csrw mepc, t0

    la   ra, cpu_halt                              # If we return from main, halt.
    mret

如果我将该mstatus.mpp字段设置0b11为机器模式,我可以kernel_main毫无问题地进入。

这是 QEMU 的输出,显示了异常信息:

riscv_cpu_do_interrupt: hart:0, async:0, cause:0000000000000002, epc:0x000000008000006c, tval:0x0000000000000000, desc=illegal_instruction

mepc指向mret发生异常的指令的地址。我已经通过mstatus.mpp成功写入和检索值来测试机器是否支持主管模式。

我有什么明显的遗漏吗?我的代码似乎与我可以在网上找到的几个示例非常相似,例如https://osblog.stephenmarz.com/ch3.2.html。任何帮助将不胜感激。

标签: qemuriscvlow-level

解决方案


问题原来是 RISC-V 的物理内存保护(PMP)。如果没有定义 PMP 规则,QEMU 将在执行指令时引发非法指令异常。MRET添加 PMP 条目解决了该问题。

这令人困惑,因为特权架构手册的mret.


推荐阅读