summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sbi/Kconfig12
-rw-r--r--lib/sbi/sbi_init.c15
2 files changed, 24 insertions, 3 deletions
diff --git a/lib/sbi/Kconfig b/lib/sbi/Kconfig
index c6cc04bc..89245a25 100644
--- a/lib/sbi/Kconfig
+++ b/lib/sbi/Kconfig
@@ -6,6 +6,18 @@ config CONSOLE_EARLY_BUFFER_SIZE
int "Early console buffer size (bytes)"
default 256
+config ZKR_POLL_BUDGET
+ int "Zkr seed polling budget (iterations)"
+ default 1000
+ help
+ Maximum number of iterations to poll CSR_SEED when initializing
+ the stack guard variable. The Zkr specification doesn't define
+ a time limit on transitioning to ES16 between polls, which
+ makes it impossible to tell whether entropy is being
+ accumulated slowly or the entropy source is not functioning.
+ This also limits the wait time on systems with an event-driven
+ entropy source. A successful read doesn't consume a try.
+
config SBI_ECALL_TIME
bool "Timer extension"
default y
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 4e34bbc5..658fe37f 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -280,20 +280,29 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
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;
+#ifndef CONFIG_ZKR_POLL_BUDGET
+#define CONFIG_ZKR_POLL_BUDGET 1000
+#endif
+ unsigned int tries = CONFIG_ZKR_POLL_BUDGET;
+ bool res = false;
- while (chunks) {
+ while (chunks && tries) {
unsigned long seed = csr_swap(CSR_SEED, 0);
unsigned long opst = seed & SEED_OPTS_MASK;
+ res = false;
if (opst == SEED_OPTS_DEAD) {
- res = false;
break;
}
if (opst == SEED_OPTS_ES16) {
guard_val = (guard_val << 16) | (seed & SEED_ENTROPY_MASK);
chunks--;
+ res = true;
+ /* Successful read doesn't consume a try */
+ tries++;
}
+
+ tries--;
continue;
}
if (res)