diff --git a/rvgo/fast/vm.go b/rvgo/fast/vm.go index 3e1755d6..bf9e60bc 100644 --- a/rvgo/fast/vm.go +++ b/rvgo/fast/vm.go @@ -587,6 +587,12 @@ func (inst *InstrumentedState) riscvStep() (outErr error) { switch opcode { case 0x03: // 000_0011: memory loading // LB, LH, LW, LD, LBU, LHU, LWU + + // bits[14:12] set to 111 are reserved + if eq64(funct3, toU64(0x7)) != 0 { + revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr)) + } + imm := parseImmTypeI(instr) signed := iszero64(and64(funct3, toU64(4))) // 4 = 100 -> bitflag size := shl64(and64(funct3, toU64(3)), toU64(1)) // 3 = 11 -> 1, 2, 4, 8 bytes size diff --git a/rvgo/slow/vm.go b/rvgo/slow/vm.go index 458f00c6..935e1357 100644 --- a/rvgo/slow/vm.go +++ b/rvgo/slow/vm.go @@ -760,6 +760,12 @@ func Step(calldata []byte, po PreimageOracle) (stateHash common.Hash, outErr err switch opcode.val() { case 0x03: // 000_0011: memory loading // LB, LH, LW, LD, LBU, LHU, LWU + + // bits[14:12] set to 111 are reserved + if eq64(funct3, toU64(0x7)) != (U64{}) { + revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr)) + } + imm := parseImmTypeI(instr) signed := iszero64(and64(funct3, toU64(4))) // 4 = 100 -> bitflag size := shl64(and64(funct3, toU64(3)), toU64(1)) // 3 = 11 -> 1, 2, 4, 8 bytes size diff --git a/rvsol/src/RISCV.sol b/rvsol/src/RISCV.sol index 1bbb681e..a5c76090 100644 --- a/rvsol/src/RISCV.sol +++ b/rvsol/src/RISCV.sol @@ -1147,6 +1147,10 @@ contract RISCV is IBigStepper { let pc_ := _pc // 000_0011: memory loading // LB, LH, LW, LD, LBU, LHU, LWU + + // bits[14:12] set to 111 are reserved + if eq64(funct3, toU64(0x7)) { revertWithCode(0xf001ca11) } + let imm := parseImmTypeI(instr) let signed := iszero64(and64(funct3, toU64(4))) // 4 = 100 -> bitflag let size := shl64(and64(funct3, toU64(3)), toU64(1)) // 3 = 11 -> 1, 2, 4, 8 bytes size