This patch adds support for detecting zisslpcfi. zisslpcfi stands for
unprivleged integer spec extension to support shadow stack and landing
pad instruction for indirect branch.
This patch looks for "zisslpcfi" in device tree and accordinlgy lights up
bit in cpu feature bitmap. Furthermore this patch adds detection utility
functions to return whether shadow stack or landing pads are supported by
cpu.
Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
arch/riscv/include/asm/hwcap.h | 6 +++++-
arch/riscv/include/asm/processor.h | 12 ++++++++++++
arch/riscv/kernel/cpu.c | 1 +
arch/riscv/kernel/cpufeature.c | 1 +
4 files changed, 19 insertions(+), 1 deletion(-)
@@ -59,7 +59,8 @@ enum riscv_isa_ext_id {
RISCV_ISA_EXT_ZIHINTPAUSE,
RISCV_ISA_EXT_SSTC,
RISCV_ISA_EXT_SVINVAL,
- RISCV_ISA_EXT_ID_MAX
+ RISCV_ISA_EXT_ZCFI,
+ RISCV_ISA_EXT_ID_MAX,
};
static_assert(RISCV_ISA_EXT_ID_MAX <= RISCV_ISA_EXT_MAX);
@@ -72,6 +73,7 @@ enum riscv_isa_ext_key {
RISCV_ISA_EXT_KEY_FPU, /* For 'F' and 'D' */
RISCV_ISA_EXT_KEY_ZIHINTPAUSE,
RISCV_ISA_EXT_KEY_SVINVAL,
+ RISCV_ISA_EXT_KEY_ZCFI,
RISCV_ISA_EXT_KEY_MAX,
};
@@ -95,6 +97,8 @@ static __always_inline int riscv_isa_ext2key(int num)
return RISCV_ISA_EXT_KEY_ZIHINTPAUSE;
case RISCV_ISA_EXT_SVINVAL:
return RISCV_ISA_EXT_KEY_SVINVAL;
+ case RISCV_ISA_EXT_ZCFI:
+ return RISCV_ISA_EXT_KEY_ZCFI;
default:
return -EINVAL;
}
@@ -80,6 +80,18 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid);
extern void riscv_fill_hwcap(void);
extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
+#ifdef CONFIG_USER_SHADOW_STACK
+static inline bool arch_supports_shadow_stack(void)
+{
+ return __riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ZCFI);
+}
+#endif
+#ifdef CONFIG_USER_INDIRECT_BR_LP
+static inline bool arch_supports_indirect_br_lp_instr(void)
+{
+ return __riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ZCFI);
+}
+#endif
#endif /* __ASSEMBLY__ */
#endif /* _ASM_RISCV_PROCESSOR_H */
@@ -168,6 +168,7 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
+ __RISCV_ISA_EXT_DATA(zisslpcfi, RISCV_ISA_EXT_ZCFI),
__RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
};
@@ -228,6 +228,7 @@ void __init riscv_fill_hwcap(void)
SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE);
SET_ISA_EXT_MAP("sstc", RISCV_ISA_EXT_SSTC);
SET_ISA_EXT_MAP("svinval", RISCV_ISA_EXT_SVINVAL);
+ SET_ISA_EXT_MAP("zisslpcfi", RISCV_ISA_EXT_ZCFI);
}
#undef SET_ISA_EXT_MAP
}