Skip to content

Commit 6c37dd9

Browse files
nemecadjdupak
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 b8ee693 commit 6c37dd9

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
@@ -343,6 +343,17 @@ DecodeState Core::decode(const FetchInterstage &dt) {
343343
ExceptionCause excause = dt.excause;
344344

345345
dt.inst.flags_alu_op_mem_ctl(flags, alu_op, mem_ctl);
346+
auto current_priv = state.current_privilege();
347+
if ((flags & IMF_PRIV_M) && current_priv < CSR::PrivilegeLevel::MACHINE) {
348+
excause = EXCAUSE_INSN_ILLEGAL;
349+
}
350+
if ((flags & IMF_PRIV_H) && current_priv < CSR::PrivilegeLevel::HYPERVISOR) {
351+
excause = EXCAUSE_INSN_ILLEGAL;
352+
}
353+
if ((flags & IMF_PRIV_S) && current_priv < CSR::PrivilegeLevel::SUPERVISOR) {
354+
excause = EXCAUSE_INSN_ILLEGAL;
355+
}
356+
346357
CSR::PrivilegeLevel inst_xret_priv = CSR::PrivilegeLevel::UNPRIVILEGED;
347358
if (flags & IMF_XRET) {
348359
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
@@ -750,6 +750,27 @@ void Instruction::flags_alu_op_mem_ctl(
750750
flags = (enum InstructionFlags)im.flags;
751751
alu_op = im.alu;
752752
mem_ctl = im.mem_ctl;
753+
if (flags & IMF_CSR) {
754+
machine::CSR::Address csr = csr_address();
755+
uint32_t csr12 = csr.data & 0xfffu;
756+
uint32_t min_bits = (csr12 >> 8) & 0x3u; // csr[9:8]
757+
switch (min_bits) {
758+
case 0u:
759+
// User (no extra flag required)
760+
break;
761+
case 1u:
762+
flags = InstructionFlags(flags | IMF_PRIV_S);
763+
break;
764+
case 2u:
765+
flags = InstructionFlags(flags | IMF_PRIV_H);
766+
break;
767+
case 3u:
768+
flags = InstructionFlags(flags | IMF_PRIV_M);
769+
break;
770+
default:
771+
break;
772+
}
773+
}
753774
}
754775

755776
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)