RISC-V:切换到管理模式时出现非法指令异常
RISC-V: Illegal instruction exception when switching to supervisor mode
当设置 mstatus.mpp
字段切换到管理员模式时,调用 mret
时出现非法指令异常。我正在使用 riscv64-softmmu
系统在 qemu-system-riscv64
版本 6.1 中对此进行测试。
我最近从 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。任何帮助将不胜感激。
问题原来是 RISC-V 的 物理内存保护 (PMP)。如果没有定义 PMP 规则,QEMU 将在执行 MRET
指令时引发 illegal instruction 异常。添加 PMP 条目解决了问题。
这令人困惑,因为 Privileged Architecture 手册中关于 mret
的部分未指定此行为。
当设置 mstatus.mpp
字段切换到管理员模式时,调用 mret
时出现非法指令异常。我正在使用 riscv64-softmmu
系统在 qemu-system-riscv64
版本 6.1 中对此进行测试。
我最近从 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。任何帮助将不胜感激。
问题原来是 RISC-V 的 物理内存保护 (PMP)。如果没有定义 PMP 规则,QEMU 将在执行 MRET
指令时引发 illegal instruction 异常。添加 PMP 条目解决了问题。
这令人困惑,因为 Privileged Architecture 手册中关于 mret
的部分未指定此行为。