diff mbox series

[v1,RFC,Zisslpcfi,2/9] target/riscv: zisslpcfi CSR, bit positions and other definitions

Message ID 20230209062947.3585481-3-debug@rivosinc.com
State New
Headers show
Series zimops and zisslpcfi extension to riscv | expand

Commit Message

Deepak Gupta Feb. 9, 2023, 6:29 a.m. UTC
`zisslpcfi` extension adds two new CSRs. CSR_SSP and CSR_LPLR.
- CSR_SSP: This CSR holds shadow stack pointer for current privilege mode
           CSR_SSP is accessible in all modes. Each mode must establish
           it's own CSR_SSP.

- CSR_LPLR: This CSR holds label value set at the callsite by compiler.
            On call target label check instructions are emitted by
            compiler which check label value against value present in
            CSR_LPRL.

Enabling of `zisslpcfi` is controlled via menvcfg (for S/HS/VS/U/VU) and
henvcfg (for VS/VU) at bit position 60.

Each mode has enable/disable bits for forward cfi. Backward cfi doesn't
have separate enable/disable bits for S and M mode. User forward cfi and
user backward cfi enable/disable bits are in mstatus/sstatus CSR.
Supervisor forward cfi enable/disable bit are in menvcfg and henvcfg CSR.
Machine mode forward cfi enable/disable bit is in mseccfg CSR.

If forward cfi enabled, all indirect branches must land on a landing pad
instruction (`lpcll`, introduced in later commits). CPU/hart tracks this
internally using a landing pad tracker called `elp` short for `expecting
landing pad`. An interrupt can occur between an indirect branch and
target. If such an event occurs `elp` is saved away in mstatus/sstatus
CSR

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Signed-off-by: Kip Walker  <kip@rivosinc.com>
---
 target/riscv/cpu.h      |  5 +++++
 target/riscv/cpu_bits.h | 25 +++++++++++++++++++++++++
 target/riscv/pmp.h      |  3 ++-
 3 files changed, 32 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9a923760b2..18db61a06a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,11 @@  struct CPUArchState {
 
     uint32_t features;
 
+    /* CFI Extension user mode registers and state */
+    uint32_t     lplr;
+    target_ulong ssp;
+    cfi_elp      elp;
+
 #ifdef CONFIG_USER_ONLY
     uint32_t elf_flags;
 #endif
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..1663ba5775 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -39,6 +39,10 @@ 
 
 /* Control and Status Registers */
 
+/* CFI CSRs */
+#define CSR_LPLR            0x006
+#define CSR_SSP             0x020
+
 /* User Trap Setup */
 #define CSR_USTATUS         0x000
 #define CSR_UIE             0x004
@@ -542,6 +546,10 @@ 
 #define MSTATUS_TVM         0x00100000 /* since: priv-1.10 */
 #define MSTATUS_TW          0x00200000 /* since: priv-1.10 */
 #define MSTATUS_TSR         0x00400000 /* since: priv-1.10 */
+#define MSTATUS_UFCFIEN     0x00800000 /* Zisslpcfi-0.1 */
+#define MSTATUS_UBCFIEN     0x01000000 /* Zisslpcfi-0.1 */
+#define MSTATUS_SPELP       0x02000000 /* Zisslpcfi-0.1 */
+#define MSTATUS_MPELP       0x04000000 /* Zisslpcfi-0.1 */
 #define MSTATUS_GVA         0x4000000000ULL
 #define MSTATUS_MPV         0x8000000000ULL
 
@@ -572,12 +580,21 @@  typedef enum {
 #define SSTATUS_XS          0x00018000
 #define SSTATUS_SUM         0x00040000 /* since: priv-1.10 */
 #define SSTATUS_MXR         0x00080000
+#define SSTATUS_UFCFIEN     MSTATUS_UFCFIEN /* Zisslpcfi-0.1 */
+#define SSTATUS_UBCFIEN     MSTATUS_UBCFIEN /* Zisslpcfi-0.1 */
+#define SSTATUS_SPELP       MSTATUS_SPELP   /* Zisslpcfi-0.1 */
 
 #define SSTATUS64_UXL       0x0000000300000000ULL
 
 #define SSTATUS32_SD        0x80000000
 #define SSTATUS64_SD        0x8000000000000000ULL
 
+#define CFISTATUS_M_MASK    (MSTATUS_UFCFIEN | MSTATUS_UBCFIEN | \
+                             MSTATUS_MPELP | MSTATUS_SPELP)
+
+#define CFISTATUS_S_MASK    (SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \
+                             SSTATUS_SPELP)
+
 /* hstatus CSR bits */
 #define HSTATUS_VSBE         0x00000020
 #define HSTATUS_GVA          0x00000040
@@ -747,10 +764,14 @@  typedef enum RISCVException {
 #define MENVCFG_CBIE                       (3UL << 4)
 #define MENVCFG_CBCFE                      BIT(6)
 #define MENVCFG_CBZE                       BIT(7)
+#define MENVCFG_SFCFIEN                    BIT(59)
+#define MENVCFG_CFI                        BIT(60)
 #define MENVCFG_PBMTE                      (1ULL << 62)
 #define MENVCFG_STCE                       (1ULL << 63)
 
 /* For RV32 */
+#define MENVCFGH_SFCFIEN                   BIT(27)
+#define MENVCFGH_CFI                       BIT(28)
 #define MENVCFGH_PBMTE                     BIT(30)
 #define MENVCFGH_STCE                      BIT(31)
 
@@ -763,10 +784,14 @@  typedef enum RISCVException {
 #define HENVCFG_CBIE                       MENVCFG_CBIE
 #define HENVCFG_CBCFE                      MENVCFG_CBCFE
 #define HENVCFG_CBZE                       MENVCFG_CBZE
+#define HENVCFG_SFCFIEN                    MENVCFG_SFCFIEN
+#define HENVCFG_CFI                        MENVCFG_CFI
 #define HENVCFG_PBMTE                      MENVCFG_PBMTE
 #define HENVCFG_STCE                       MENVCFG_STCE
 
 /* For RV32 */
+#define HENVCFGH_SFCFIEN                    MENVCFGH_SFCFIEN
+#define HENVCFGH_CFI                        MENVCFGH_CFI
 #define HENVCFGH_PBMTE                      MENVCFGH_PBMTE
 #define HENVCFGH_STCE                       MENVCFGH_STCE
 
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index da32c61c85..f5bfc4955b 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -43,7 +43,8 @@  typedef enum {
     MSECCFG_MMWP  = 1 << 1,
     MSECCFG_RLB   = 1 << 2,
     MSECCFG_USEED = 1 << 8,
-    MSECCFG_SSEED = 1 << 9
+    MSECCFG_SSEED = 1 << 9,
+    MSECCFG_MFCFIEN =  1 << 10
 } mseccfg_field_t;
 
 typedef struct {