qemu - 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。任何帮助将不胜感激。
解决方案
问题原来是 RISC-V 的物理内存保护(PMP)。如果没有定义 PMP 规则,QEMU 将在执行指令时引发非法指令异常。MRET
添加 PMP 条目解决了该问题。
这令人困惑,因为特权架构手册的mret
.
推荐阅读
- node.js - 有什么方法可以识别 NodeJS 中的 SQL Server 存储过程返回的错误
- flutter - Flutter:谷歌创始之选
- django - 如何在 django 3.1 中执行允许 DELETE 方法的基于类的删除视图?
- c# - dotnet-trace 不解析 linux-arm 下的符号
- linux - 如何找到使用 _do_fork() 创建新进程的基本例程?
- javascript - 为什么在向上和向下缩放容器后将指针向下事件传递给错误的 PIXI.Container?附上测试用例
- javascript - 如何根据值使猫鼬模式动态化?
- python - 为什么 QTableView 有空白边距,我该如何删除它们?
- php - Wordpress 自定义小部件显示在错误的位置
- python - 使用机器人阅读 Discord 频道消息