summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/fw_base.S32
-rw-r--r--lib/sbi/sbi_init.c31
2 files changed, 31 insertions, 32 deletions
diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index 043de7d7..5d6540d7 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -107,30 +107,6 @@ _bss_zero:
add s4, s4, __SIZEOF_POINTER__
blt s4, s5, _bss_zero
- /* Trying to initialize the stack guard via the Zkr extension */
- lla t0, __stack_chk_guard_done
- csrw CSR_MTVEC, t0
- li t0, 0
- li t3, SEED_OPTS_ES16
- li t4, SEED_ENTROPY_MASK
- li t5, __SIZEOF_POINTER__
-__stack_chk_guard_loop:
- csrrw t1, CSR_SEED, x0
- li t2, SEED_OPTS_MASK
- and t2, t2, t1
- bgtu t2, t3, __stack_chk_guard_done
- bltu t2, t3, __stack_chk_guard_loop
- and t1, t1, t4
- slli t0, t0, 16
- or t0, t0, t1
- addi t5, t5, -2
- bgtz t5, __stack_chk_guard_loop
- lla t1, __stack_chk_guard
- REG_S t0, 0(t1)
- j __stack_chk_guard_done
- .align 3
-__stack_chk_guard_done:
-
/* Setup temporary trap handler */
lla s4, _start_hang
csrw CSR_MTVEC, s4
@@ -895,14 +871,6 @@ __stack_chk_fail:
la a0, .Lstack_corrupt_msg
call sbi_panic
- /* Initial value of the stack guard variable */
- .section .data
- .align 3
- .globl __stack_chk_guard
- .type __stack_chk_guard, %object
-__stack_chk_guard:
- RISCV_PTR 0x95B5FF5A
-
#ifdef FW_FDT_PATH
.section .rodata
.align 4
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index aae035e1..b248e73f 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -218,6 +218,8 @@ static void wake_coldboot_harts(struct sbi_scratch *scratch)
__smp_store_release(&coldboot_done, 1);
}
+unsigned long __stack_chk_guard = 0x95B5FF5A;
+
static unsigned long entry_count_offset;
static unsigned long init_count_offset;
@@ -269,6 +271,35 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
if (rc)
sbi_hart_hang();
+ /*
+ * Initialize stack guard via Zkr entropy source if Zkr is
+ * implemented according to device tree. Writing new seed value
+ * to __stack_chk_guard is safe here because function doesn't
+ * return and no check against value on entry will be done.
+ */
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_ZKR)) {
+ unsigned long guard_val = 0;
+ int chunks = sizeof(unsigned long) / sizeof(uint16_t);
+ bool res = true;
+
+ while (chunks) {
+ unsigned long seed = csr_swap(CSR_SEED, 0);
+ unsigned long opst = seed & SEED_OPTS_MASK;
+
+ if (opst == SEED_OPTS_DEAD) {
+ res = false;
+ break;
+ }
+ if (opst == SEED_OPTS_ES16) {
+ guard_val = (guard_val << 16) | (seed & SEED_ENTROPY_MASK);
+ chunks--;
+ }
+ continue;
+ }
+ if (res)
+ __stack_chk_guard = guard_val;
+ }
+
rc = sbi_timer_init(scratch, true);
if (rc)
sbi_hart_hang();