Skip to content

Commit b5940e8

Browse files
nemecadppisa
authored andcommitted
Machine: add privilege flags and decode-time illegal instruction checks
Extend instruction metadata with privilege flags (IMF_PRIV_M/H/S) for privileged operations. In the decode stage, compare the current privilege level against these flags to detect and raise illegal-instruction exceptions early, preventing execution of instructions that require higher privilege.
1 parent 79b7531 commit b5940e8

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

src/machine/core.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,17 @@ DecodeState Core::decode(const FetchInterstage &dt) {
351351
ExceptionCause excause = dt.excause;
352352

353353
dt.inst.flags_alu_op_mem_ctl(flags, alu_op, mem_ctl);
354+
auto current_priv = state.current_privilege();
355+
if ((flags & IMF_PRIV_M) && current_priv < CSR::PrivilegeLevel::MACHINE) {
356+
excause = EXCAUSE_INSN_ILLEGAL;
357+
}
358+
if ((flags & IMF_PRIV_H) && current_priv < CSR::PrivilegeLevel::HYPERVISOR) {
359+
excause = EXCAUSE_INSN_ILLEGAL;
360+
}
361+
if ((flags & IMF_PRIV_S) && current_priv < CSR::PrivilegeLevel::SUPERVISOR) {
362+
excause = EXCAUSE_INSN_ILLEGAL;
363+
}
364+
354365
CSR::PrivilegeLevel inst_xret_priv = CSR::PrivilegeLevel::UNPRIVILEGED;
355366
if (flags & IMF_XRET) {
356367
inst_xret_priv = decode_xret_type_from_inst(dt.inst);

src/machine/instruction.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,27 @@ void Instruction::flags_alu_op_mem_ctl(
749749
flags = (enum InstructionFlags)im.flags;
750750
alu_op = im.alu;
751751
mem_ctl = im.mem_ctl;
752+
if (flags & IMF_CSR) {
753+
machine::CSR::Address csr = csr_address();
754+
uint32_t csr12 = csr.data & 0xfffu;
755+
uint32_t min_bits = (csr12 >> 8) & 0x3u; // csr[9:8]
756+
switch (min_bits) {
757+
case 0u:
758+
// User (no extra flag required)
759+
break;
760+
case 1u:
761+
flags = InstructionFlags(flags | IMF_PRIV_S);
762+
break;
763+
case 2u:
764+
flags = InstructionFlags(flags | IMF_PRIV_H);
765+
break;
766+
case 3u:
767+
flags = InstructionFlags(flags | IMF_PRIV_M);
768+
break;
769+
default:
770+
break;
771+
}
772+
}
752773
}
753774

754775
bool Instruction::operator==(const Instruction &c) const {

src/machine/instruction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ enum InstructionFlags : unsigned {
6060
// TODO do we want to add those signals to the visualization?
6161

6262
IMF_RV64 = 1L << 24, /**< Mark instructions which are available in 64-bit mode only. */
63+
64+
/* Privilege requirement flags */
65+
IMF_PRIV_S = 1L << 25, /**< Requires at least Supervisor privilege */
66+
IMF_PRIV_H = 1L << 26, /**< Requires at least Hypervisor privilege */
67+
IMF_PRIV_M = 1L << 27, /**< Requires Machine privilege */
6368
};
6469

6570
/**

0 commit comments

Comments
 (0)