Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert reserved immediate word shifts with imm[5]!=0 #105

Merged
merged 3 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions rvgo/fast/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,16 @@ func (inst *InstrumentedState) riscvStep() (outErr error) {
case 0: // 000 = ADDIW
rdValue = mask32Signed64(add64(rs1Value, imm))
case 1: // 001 = SLLIW
// SLLIW where imm[5] != 0 is reserved
if and64(imm, toU64(0x20)) != 0 {
refcell marked this conversation as resolved.
Show resolved Hide resolved
revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr))
}
rdValue = mask32Signed64(shl64(and64(imm, toU64(0x1F)), rs1Value))
case 5: // 101 = SR~
// SRLIW and SRAIW where imm[5] != 0 is reserved
if and64(imm, toU64(0x20)) != 0 {
revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr))
}
shamt := and64(imm, toU64(0x1F))
switch shr64(toU64(5), imm) { // top 7 bits select the shift type
case 0x00: // 0000000 = SRLIW
Expand Down
8 changes: 8 additions & 0 deletions rvgo/slow/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,8 +843,16 @@ func Step(calldata []byte, po PreimageOracle) (stateHash common.Hash, outErr err
case 0: // 000 = ADDIW
rdValue = mask32Signed64(add64(rs1Value, imm))
case 1: // 001 = SLLIW
// SLLIW where imm[5] != 0 is reserved
if and64(imm, toU64(0x20)) != (U64{}) {
revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr))
}
rdValue = mask32Signed64(shl64(and64(imm, toU64(0x1F)), rs1Value))
case 5: // 101 = SR~
// SRLIW and SRAIW imm[5] != 0 is reserved
if and64(imm, toU64(0x20)) != (U64{}) {
revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr))
}
shamt := and64(imm, toU64(0x1F))
switch shr64(toU64(5), imm).val() { // top 7 bits select the shift type
case 0x00: // 0000000 = SRLIW
Expand Down
6 changes: 6 additions & 0 deletions rvsol/src/RISCV.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1271,9 +1271,15 @@ contract RISCV is IBigStepper {
}
case 1 {
// 001 = SLLIW

// SLLIW where imm[5] != 0 is reserved
if and64(imm, toU64(0x20)) { revertWithCode(0xf001ca11) }
rdValue := mask32Signed64(shl64(and64(imm, toU64(0x1F)), rs1Value))
}
case 5 {
// SRLIW and SRAIW where imm[5] != 0 is reserved
if and64(imm, toU64(0x20)) { revertWithCode(0xf001ca11) }

// 101 = SR~
let shamt := and64(imm, toU64(0x1F))
switch shr64(toU64(5), imm)
Expand Down
12 changes: 12 additions & 0 deletions rvsol/test/RISCV.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2460,6 +2460,18 @@ contract RISCV_Test is CommonTest {
riscv.step(encodedState, proof, 0);
}

function test_revert_reserved_slliw_instruction() public {
uint16 shamt = 0x15;
uint16 imm = (0 << 7) | shamt | 0x20; // set 0x20 to make imm[5] != 0
uint32 insn = encodeIType(0x1b, 17, 1, 25, imm); // slliw x17, x25, 0x15
(State memory state, bytes memory proof) = constructRISCVState(0, insn);
state.registers[25] = 0xf956;
bytes memory encodedState = encodeState(state);

vm.expectRevert(hex"00000000000000000000000000000000000000000000000000000000f001ca11");
riscv.step(encodedState, proof, 0);
}

/* Helper methods */

function encodeState(State memory state) internal pure returns (bytes memory) {
Expand Down
Loading