Instruction access fault reports mtval = pc+2 when the first half of an unaligned instruction fails its bus access and the second half fails PMP
维护者通常 2 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 1-2 天
- 新手友好度
- 55/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
调研方向
Start with the if_instr_err_plus2 assignment in rtl/ibex_if_stage.sv (lines 435–436) and trace how first-half bus and PMP errors affect the reported fault address. Reproduce with the attached bench and compare the f1_errplus2 and control runs. Done when the PMP case reports mtval = pc while the second-half-only fault behavior remains correct.
由索引模型根据 Issue 内容生成。
描述
Observed Behavior
A 32-bit instruction at a halfword address pc (pc[1] = 1) spans two fetch words. If the fetch of the first word gets a bus error (instr_err_i) and the second half (pc + 2) is in a PMP region without execute permission, Ibex takes an instruction access fault with mepc = pc but mtval = pc + 2, as if the first half had been fetched without fault.
| run | mcause | mepc | mtval |
|---|---|---|---|
f1_errplus2 (first half: bus error; second half: bus error + PMP no-X) |
1 | 0xd6cbfffe |
0xd6cc0000 |
f1_errplus2_ctl (same, no PMP region; both halves: bus error only) |
1 | 0xd6cbfffe |
0xd6cbfffe |
if_instr_err_plus2 is set by a PMP error on the second half and cleared only by a PMP error on the first half (& ~pmp_err_if_i), not by a bus error on the first half: rtl/ibex_if_stage.sv:435-436. When the second half has only a bus error, the prefetch buffer reports it only if the first half had no error, so that case is correct (control run above). mcause and mepc are correct in both runs; only mtval is wrong.
Attached: simulation logs of both runs (evidence/*.log) and a formal counterexample on the same RTL (evidence/formal_ibex_top_u_bp_u_spec_BP5_CAUSE.vcd, 14 cycles from a NOP start state).
Expected Behavior
mtval = pc = 0xd6cbfffe, as in the control run and as Ibex already reports when the first half fails PMP. RISC-V Privileged Specification, "Machine Trap Value Register (mtval)":
If mtval is written with a nonzero value when an instruction access-fault or page-fault exception occurs on a system with variable-length instructions, then mtval will contain the virtual address of the portion of the instruction that caused the fault, while mepc will point to the beginning of the instruction.
The pc + 2 reporting was added for the case where only the second half faults (#709, #713). A possible fix is to clear if_instr_err_plus2 on any first-half fault, not only a PMP one:
assign if_instr_err_plus2 = ((if_instr_addr[1] & ~instr_is_compressed & pmp_err_if_plus2_i) |
fetch_err_plus2) & ~(pmp_err_if_i | fetch_err);
Steps to reproduce the issue
The attached bench tb_ibex_bp.sv instantiates ibex_top with PMPEnable = 1, PMPNumRegions = 4, PMPGranularity = 0, plus the experimental-branch-predictor settings of ibex_configs.yaml (RV32M = RV32MSingleCycle, RV32ZC = RV32ZcaZcbZcmp, BranchTargetALU = 1, WritebackStage = 1, BranchPredictor = 1). Only PMPEnable = 1 and an instruction-bus error are needed; the branch predictor plays no part. The bench answers every fetch from 0xD0000000-0xDFFFFFFF with an error and returns 0xffffffff as data (OBI leaves error-response data undefined).
f1_errplus2.Slocks PMP region 2 as NAPOT 4 KiB at0xd6cc0000with R/W and no X, then jumps to0xd6cbfffe.f1_errplus2_ctl.Sis the same without the PMP region.
git clone https://github.com/lowRISC/ibex && cd ibex && git checkout 626034d7- Run the attached script, which builds the bench with Verilator (defines
+define+AB_PMP +define+SYNTHESIS), assembles both programs and runs them:sh run.sh <ibex checkout> # per program: riscv32-unknown-elf-gcc -march=rv32imc_zicsr_zifencei_zca_zcb_zcmp -mabi=ilp32 -nostdlib -nostartfiles -T link.ld crt.S f1_errplus2.S # simv +hex=f1_errplus2.hex +ierrdata=ffffffff - Each run prints three
SIGlines: mcause, mepc, mtval. Output:== f1_errplus2 SIG 00000001 SIG d6cbfffe SIG d6cc0000 == f1_errplus2_ctl SIG 00000001 SIG d6cbfffe SIG d6cbfffe
No changes to the Ibex source code.
My Environment
EDA tool and version:
Verilator 5.044 (simulation); riscv32-unknown-elf-gcc 16.1.0.
Operating system:
Red Hat Enterprise Linux 8.10
Version of the Ibex source code:
626034d7557ab85a6d989b13011b44296bad26fa (master, 2026-11-06), unmodified.
All of the relevant materials pertaining to the bug:
- 主要语言
- SystemVerilog
- 星标
- 2.2k
- 派生
- 836
- 平均合并
- 5 天 8 小时
- 30 天内合并 PR
- 22
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
lowRISC/ibex 的其他 Issue
-
[Bug Report] rvfi_intr is not set on the first instruction of an exception handler可能已有人在做 @h-filali 于 6 天前认领。 未关闭Type:Bug
难度 2/5 半天 新手友好度 68/100
维护者通常 2 天内回复
-
Type:Bug
难度 2/5 1-3 小时 新手友好度 83/100
维护者通常 2 天内回复
-
Type:Bug
难度 1/5 1 小时以内 新手友好度 88/100
维护者通常 2 天内回复
-
[doc] Document basic commands for running/checking Ibex可能已有人在做 @shrutikbalwan 于 46 天前认领。 未关闭Component:Doc Good First Issue Type:Task
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 2 天内回复
-
难度 4/5 3-5 天 新手友好度 42/100
维护者通常 2 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 67/100
FinanceFlash/unvibecode#699 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
coder/openstorage#807 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
libnoname/noname#4626 · 1 条评论 ·
维护者通常 1 天内回复
-
`epoch.Integer` raises a raw OverflowError for integers too large to convert to a float可能已有人在做 @arindam77 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
pydantic/pydantic-extra-types#479 ·
维护者通常 1 天内回复