Skip to content

Commit ee1d0f4

Browse files
committed
Add Zicfiss extension from CFI extension, v0.4.0
1. Add EXT_ZICFISS for enable Zicfiss with zicfiss extension name. 2. Add new software exception with tval 3 for shadow stack. 3. Implement sspush_x1/sspush_x5/sspopchk_x1/sspopchk_x5/ssrdp/ssamoswap_w/ssamoswap_d. 4. Implement c_sspush_x1/c_sspopchk_x5 in c_lui.h which has same encoding. 5. Add new special access type ss_access in xlate_flags_t for checking special read/write permission in SS(Shadow Stack) page. 6. Add new ss_load/ss_store/ssamoswap to enable ss_access flag. 7. Check special pte(xwr=010) of SS page.
1 parent 3192ee4 commit ee1d0f4

24 files changed

+265
-11
lines changed

disasm/disasm.cc

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,18 @@ struct : public arg_t {
266266
}
267267
} rvc_sp;
268268

269+
struct : public arg_t {
270+
std::string to_string(insn_t UNUSED insn) const {
271+
return xpr_name[X_RA];
272+
}
273+
} rvc_ra;
274+
275+
struct : public arg_t {
276+
std::string to_string(insn_t UNUSED insn) const {
277+
return xpr_name[X_T0];
278+
}
279+
} rvc_t0;
280+
269281
struct : public arg_t {
270282
std::string to_string(insn_t insn) const {
271283
return std::to_string((int)insn.rvc_imm());
@@ -2184,6 +2196,13 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
21842196
}
21852197

21862198
if (isa->extension_enabled(EXT_ZIMOP)) {
2199+
#define DISASM_MOP_R(name, rs1, rd) \
2200+
add_insn(new disasm_insn_t(#name, match_##name | (rs1 << 15) | (rd << 7), \
2201+
0xFFFFFFFF, {&xrd, &xrs1}));
2202+
2203+
#define DISASM_MOP_RR(name, rs1, rd, rs2) \
2204+
add_insn(new disasm_insn_t(#name, match_##name | (rs1 << 15) | (rd << 7) | (rs2 << 20), \
2205+
0xFFFFFFFF, {&xrd, &xrs1, &xrs2}));
21872206
DEFINE_R1TYPE(mop_r_0);
21882207
DEFINE_R1TYPE(mop_r_1);
21892208
DEFINE_R1TYPE(mop_r_2);
@@ -2212,7 +2231,15 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
22122231
DEFINE_R1TYPE(mop_r_25);
22132232
DEFINE_R1TYPE(mop_r_26);
22142233
DEFINE_R1TYPE(mop_r_27);
2215-
DEFINE_R1TYPE(mop_r_28);
2234+
if (!isa->extension_enabled(EXT_ZICFISS)) {
2235+
DEFINE_R1TYPE(mop_r_28);
2236+
} else {
2237+
// Add code points of mop_r_28 not used by Zicfiss
2238+
for (unsigned rd_val = 0; rd_val <= 31; ++rd_val)
2239+
for (unsigned rs1_val = 0; rs1_val <= 31; ++rs1_val)
2240+
if ((rd_val != 0 && rs1_val !=0) || (rd_val == 0 && !(rs1_val == 1 || rs1_val == 5)))
2241+
DISASM_MOP_R(mop_r_28, rs1_val, rd_val);
2242+
}
22162243
DEFINE_R1TYPE(mop_r_29);
22172244
DEFINE_R1TYPE(mop_r_30);
22182245
DEFINE_R1TYPE(mop_r_31);
@@ -2224,12 +2251,24 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
22242251
DEFINE_RTYPE(mop_rr_5);
22252252
DEFINE_RTYPE(mop_rr_6);
22262253
DEFINE_RTYPE(mop_rr_7);
2254+
if (!isa->extension_enabled(EXT_ZICFISS)) {
2255+
DEFINE_RTYPE(mop_rr_7);
2256+
} else {
2257+
// Add code points of mop_rr_7 not used by Zicfiss
2258+
for (unsigned rd_val = 0; rd_val <= 31; ++rd_val)
2259+
for (unsigned rs1_val = 0; rs1_val <= 31; ++rs1_val)
2260+
for (unsigned rs2_val = 0; rs2_val <= 31; ++rs2_val)
2261+
if ((rs2_val != 1 && rs2_val != 5) || rd_val != 0 || rs1_val != 0)
2262+
DISASM_MOP_RR(mop_rr_7, rs1_val, rd_val, rs2_val);
2263+
}
22272264
}
22282265

22292266
if (isa->extension_enabled(EXT_ZCMOP)) {
2230-
DISASM_INSN("c.mop.1", c_mop_1, 0, {});
2267+
if (!isa->extension_enabled(EXT_ZICFISS))
2268+
DISASM_INSN("c.mop.1", c_mop_1, 0, {});
22312269
DISASM_INSN("c.mop.3", c_mop_3, 0, {});
2232-
DISASM_INSN("c.mop.5", c_mop_5, 0, {});
2270+
if (!isa->extension_enabled(EXT_ZICFISS))
2271+
DISASM_INSN("c.mop.5", c_mop_5, 0, {});
22332272
DISASM_INSN("c.mop.7", c_mop_7, 0, {});
22342273
DISASM_INSN("c.mop.9", c_mop_9, 0, {});
22352274
DISASM_INSN("c.mop.11", c_mop_11, 0, {});
@@ -2392,6 +2431,23 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
23922431
DEFINE_XSTORE_BASE(sw_rl);
23932432
DEFINE_XSTORE_BASE(sd_rl);
23942433
}
2434+
2435+
if(isa->extension_enabled(EXT_ZICFISS)) {
2436+
DISASM_INSN("sspush", sspush_x1, 0, {&xrs2});
2437+
DISASM_INSN("sspush", sspush_x5, 0, {&xrs2});
2438+
DISASM_INSN("sspopchk", sspopchk_x1, 0, {&xrs1});
2439+
DISASM_INSN("sspopchk", sspopchk_x5, 0, {&xrs1});
2440+
DISASM_INSN("ssrdp", ssrdp, 0, {&xrd});
2441+
DEFINE_XAMO(ssamoswap_w);
2442+
2443+
if(isa->get_max_xlen() == 64)
2444+
DEFINE_XAMO(ssamoswap_d)
2445+
2446+
if (isa->extension_enabled(EXT_ZCA)) {
2447+
DISASM_INSN("c.sspush", c_sspush_x1, 0, {&rvc_ra});
2448+
DISASM_INSN("c.sspopchk", c_sspopchk_x5, 0, {&rvc_t0});
2449+
}
2450+
}
23952451
}
23962452

23972453
disassembler_t::disassembler_t(const isa_parser_t *isa)

disasm/isa_parser.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
308308
extension_table[EXT_SSQOSID] = true;
309309
} else if (ext_str == "zicfilp") {
310310
extension_table[EXT_ZICFILP] = true;
311+
} else if (ext_str == "zicfiss") {
312+
extension_table[EXT_ZICFISS] = true;
311313
} else if (ext_str[0] == 'x') {
312314
extension_table['X'] = true;
313315
if (ext_str.size() == 1) {
@@ -393,6 +395,16 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
393395
(extension_table[EXT_ZVKG] || extension_table[EXT_ZVKNED] || extension_table[EXT_ZVKSH])) {
394396
bad_isa_string(str, "'Zvkg', 'Zvkned', and 'Zvksh' extensions are incompatible with 'Zpn' extension in rv64");
395397
}
398+
399+
// When SSE is 0, Zicfiss behavior is defined by Zicmop
400+
if (extension_table[EXT_ZICFISS] && !extension_table[EXT_ZIMOP]) {
401+
bad_isa_string(str, "'Zicfiss' extension requires 'Zimop' extension");
402+
}
403+
404+
if (extension_table[EXT_ZICFISS] && extension_table[EXT_ZCA] &&
405+
!extension_table[EXT_ZCMOP]) {
406+
bad_isa_string(str, "'Zicfiss' extension requires 'Zcmop' extension when `Zca` is supported");
407+
}
396408
#ifdef WORDS_BIGENDIAN
397409
// Access to the vector registers as element groups is unimplemented on big-endian setups.
398410
if (extension_table[EXT_ZVKG] || extension_table[EXT_ZVKNHA] || extension_table[EXT_ZVKNHB] ||

riscv/csrs.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,3 +1757,13 @@ bool hvip_csr_t::unlogged_write(const reg_t val) noexcept {
17571757
state->mip->write_with_mask(MIP_VSSIP, val); // hvip.VSSIP is an alias of mip.VSSIP
17581758
return basic_csr_t::unlogged_write(val & (MIP_VSEIP | MIP_VSTIP));
17591759
}
1760+
1761+
ssp_csr_t::ssp_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init):
1762+
masked_csr_t(proc, addr, mask, init) {
1763+
}
1764+
1765+
void ssp_csr_t::verify_permissions(insn_t insn, bool write) const {
1766+
masked_csr_t::verify_permissions(insn, write);
1767+
DECLARE_XENVCFG_VARS(SSE);
1768+
require_envcfg(SSE);
1769+
}

riscv/csrs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,4 +871,11 @@ class hvip_csr_t : public basic_csr_t {
871871
};
872872

873873
typedef std::shared_ptr<hvip_csr_t> hvip_csr_t_p;
874+
875+
// ssp CSR provided by CFI Zicfiss extension
876+
class ssp_csr_t final : public masked_csr_t {
877+
public:
878+
ssp_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init);
879+
virtual void verify_permissions(insn_t insn, bool write) const override;
880+
};
874881
#endif

riscv/decode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const int NCSR = 4096;
2626

2727
#define X_RA 1
2828
#define X_SP 2
29+
#define X_T0 5
2930
#define X_S0 8
3031
#define X_A0 10
3132
#define X_A1 11

riscv/encoding.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@
348348

349349
/* software check exception xtval codes */
350350
#define LANDING_PAD_FAULT 2
351+
#define SHADOW_STACK_FAULT 3
351352

352353
#ifdef __riscv
353354

riscv/insns/c_lui.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ if (insn.rvc_rd() == 2) { // c.addi16sp
55
} else if (insn.rvc_imm() != 0) { // c.lui
66
WRITE_RD(insn.rvc_imm() << 12);
77
} else if ((insn.rvc_rd() & 0x11) == 1) { // c.mop.N
8-
#include "c_mop_N.h"
8+
if (insn.rvc_rd() == 5 && p->extension_enabled(EXT_ZICFISS)) {
9+
#include "c_sspopchk_x5.h"
10+
} else if (insn.rvc_rd() == 1 && p->extension_enabled(EXT_ZICFISS)) {
11+
#include "c_sspush_x1.h"
12+
} else {
13+
#include "c_mop_N.h"
14+
}
915
} else {
1016
require(false);
1117
}

riscv/insns/c_sspopchk_x5.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "zicfiss.h"
2+
3+
if (xSSE()) {
4+
POP_VALUE_FROM_SS_AND_CHECK(READ_REG(X_T0));
5+
}

riscv/insns/c_sspush_x1.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "zicfiss.h"
2+
3+
if (xSSE()) {
4+
PUSH_VALUE_TO_SS(RA);
5+
}

riscv/insns/ssamoswap_d.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require_extension(EXT_ZICFISS);
2+
require_extension('A');
3+
require_rv64;
4+
5+
DECLARE_XENVCFG_VARS(SSE);
6+
require_envcfg(SSE);
7+
WRITE_RD(MMU.ssamoswap<uint64_t>(RS1, RS2));

0 commit comments

Comments
 (0)