Skip to content

Commit 3fdb7d3

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 7c89063 commit 3fdb7d3

25 files changed

+283
-12
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());
@@ -2178,6 +2190,13 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
21782190
}
21792191

21802192
if (isa->extension_enabled(EXT_ZIMOP)) {
2193+
#define DISASM_MOP_R(name, rs1, rd) \
2194+
add_insn(new disasm_insn_t(#name, match_##name | (rs1 << 15) | (rd << 7), \
2195+
0xFFFFFFFF, {&xrd, &xrs1}));
2196+
2197+
#define DISASM_MOP_RR(name, rs1, rd, rs2) \
2198+
add_insn(new disasm_insn_t(#name, match_##name | (rs1 << 15) | (rd << 7) | (rs2 << 20), \
2199+
0xFFFFFFFF, {&xrd, &xrs1, &xrs2}));
21812200
DEFINE_R1TYPE(mop_r_0);
21822201
DEFINE_R1TYPE(mop_r_1);
21832202
DEFINE_R1TYPE(mop_r_2);
@@ -2206,7 +2225,15 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
22062225
DEFINE_R1TYPE(mop_r_25);
22072226
DEFINE_R1TYPE(mop_r_26);
22082227
DEFINE_R1TYPE(mop_r_27);
2209-
DEFINE_R1TYPE(mop_r_28);
2228+
if (!isa->extension_enabled(EXT_ZICFISS)) {
2229+
DEFINE_R1TYPE(mop_r_28);
2230+
} else {
2231+
// Add code points of mop_r_28 not used by Zicfiss
2232+
for (unsigned rd_val = 0; rd_val <= 31; ++rd_val)
2233+
for (unsigned rs1_val = 0; rs1_val <= 31; ++rs1_val)
2234+
if ((rd_val != 0 && rs1_val !=0) || (rd_val == 0 && !(rs1_val == 1 || rs1_val == 5)))
2235+
DISASM_MOP_R(mop_r_28, rs1_val, rd_val);
2236+
}
22102237
DEFINE_R1TYPE(mop_r_29);
22112238
DEFINE_R1TYPE(mop_r_30);
22122239
DEFINE_R1TYPE(mop_r_31);
@@ -2218,12 +2245,24 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
22182245
DEFINE_RTYPE(mop_rr_5);
22192246
DEFINE_RTYPE(mop_rr_6);
22202247
DEFINE_RTYPE(mop_rr_7);
2248+
if (!isa->extension_enabled(EXT_ZICFISS)) {
2249+
DEFINE_RTYPE(mop_rr_7);
2250+
} else {
2251+
// Add code points of mop_rr_7 not used by Zicfiss
2252+
for (unsigned rd_val = 0; rd_val <= 31; ++rd_val)
2253+
for (unsigned rs1_val = 0; rs1_val <= 31; ++rs1_val)
2254+
for (unsigned rs2_val = 0; rs2_val <= 31; ++rs2_val)
2255+
if ((rs2_val != 1 && rs2_val != 5) || rd_val != 0 || rs1_val != 0)
2256+
DISASM_MOP_RR(mop_rr_7, rs1_val, rd_val, rs2_val);
2257+
}
22212258
}
22222259

22232260
if (isa->extension_enabled(EXT_ZCMOP)) {
2224-
DISASM_INSN("c.mop.1", c_mop_1, 0, {});
2261+
if (!isa->extension_enabled(EXT_ZICFISS))
2262+
DISASM_INSN("c.mop.1", c_mop_1, 0, {});
22252263
DISASM_INSN("c.mop.3", c_mop_3, 0, {});
2226-
DISASM_INSN("c.mop.5", c_mop_5, 0, {});
2264+
if (!isa->extension_enabled(EXT_ZICFISS))
2265+
DISASM_INSN("c.mop.5", c_mop_5, 0, {});
22272266
DISASM_INSN("c.mop.7", c_mop_7, 0, {});
22282267
DISASM_INSN("c.mop.9", c_mop_9, 0, {});
22292268
DISASM_INSN("c.mop.11", c_mop_11, 0, {});
@@ -2386,6 +2425,23 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
23862425
DEFINE_XSTORE_BASE(sw_rl);
23872426
DEFINE_XSTORE_BASE(sd_rl);
23882427
}
2428+
2429+
if(isa->extension_enabled(EXT_ZICFISS)) {
2430+
DISASM_INSN("sspush", sspush_x1, 0, {&xrs2});
2431+
DISASM_INSN("sspush", sspush_x5, 0, {&xrs2});
2432+
DISASM_INSN("sspopchk", sspopchk_x1, 0, {&xrs1});
2433+
DISASM_INSN("sspopchk", sspopchk_x5, 0, {&xrs1});
2434+
DISASM_INSN("ssrdp", ssrdp, 0, {&xrd});
2435+
DEFINE_XAMO(ssamoswap_w);
2436+
2437+
if(isa->get_max_xlen() == 64)
2438+
DEFINE_XAMO(ssamoswap_d)
2439+
2440+
if (isa->extension_enabled(EXT_ZCA)) {
2441+
DISASM_INSN("c.sspush", c_sspush_x1, 0, {&rvc_ra});
2442+
DISASM_INSN("c.sspopchk", c_sspopchk_x5, 0, {&rvc_t0});
2443+
}
2444+
}
23892445
}
23902446

23912447
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
@@ -306,6 +306,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
306306
extension_table[EXT_ZALASR] = true;
307307
} else if (ext_str == "ssqosid") {
308308
extension_table[EXT_SSQOSID] = true;
309+
} else if (ext_str == "zicfiss") {
310+
extension_table[EXT_ZICFISS] = true;
309311
} else if (ext_str[0] == 'x') {
310312
extension_table['X'] = true;
311313
if (ext_str.size() == 1) {
@@ -391,6 +393,16 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
391393
(extension_table[EXT_ZVKG] || extension_table[EXT_ZVKNED] || extension_table[EXT_ZVKSH])) {
392394
bad_isa_string(str, "'Zvkg', 'Zvkned', and 'Zvksh' extensions are incompatible with 'Zpn' extension in rv64");
393395
}
396+
397+
// When SSE is 0, Zicfiss behavior is defined by Zicmop
398+
if (extension_table[EXT_ZICFISS] && !extension_table[EXT_ZIMOP]) {
399+
bad_isa_string(str, "'Zicfiss' extension requires 'Zimop' extension");
400+
}
401+
402+
if (extension_table[EXT_ZICFISS] && extension_table[EXT_ZCA] &&
403+
!extension_table[EXT_ZCMOP]) {
404+
bad_isa_string(str, "'Zicfiss' extension requires 'Zcmop' extension when `Zca` is supported");
405+
}
394406
#ifdef WORDS_BIGENDIAN
395407
// Access to the vector registers as element groups is unimplemented on big-endian setups.
396408
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
@@ -1717,3 +1717,13 @@ void srmcfg_csr_t::verify_permissions(insn_t insn, bool write) const {
17171717
if (state->v)
17181718
throw trap_virtual_instruction(insn.bits());
17191719
}
1720+
1721+
ssp_csr_t::ssp_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init):
1722+
masked_csr_t(proc, addr, mask, init) {
1723+
}
1724+
1725+
void ssp_csr_t::verify_permissions(insn_t insn, bool write) const {
1726+
masked_csr_t::verify_permissions(insn, write);
1727+
DECLARE_XENVCFG_VARS(SSE);
1728+
require_envcfg(SSE);
1729+
}

riscv/csrs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,4 +850,11 @@ class srmcfg_csr_t: public masked_csr_t {
850850
srmcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init);
851851
virtual void verify_permissions(insn_t insn, bool write) const override;
852852
};
853+
854+
// ssp CSR provided by CFI Zicfiss extension
855+
class ssp_csr_t final : public masked_csr_t {
856+
public:
857+
ssp_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init);
858+
virtual void verify_permissions(insn_t insn, bool write) const override;
859+
};
853860
#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/insn_macros.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66

77
#define require(x) (unlikely(!(x)) ? throw trap_illegal_instruction(insn.bits()) : (void) 0)
88

9+
#define software_check(x, tval) (unlikely(!(x)) ? throw trap_software_check(tval) : (void) 0)
10+
911
#endif

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() & 1) != 0) { // 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)