From 2314101989684585f942b50a827aac4886825ba1 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 10 Jun 2020 18:39:53 +0530 Subject: [PATCH] lib: Don't return any invalid error from SBI ecall We should only return valid error codes from SBI ecalls as defined by the RISC-V SBI spec. To achieve this: 1. We use SBI_Exxxx defines for OpenSBI internal errors with error values starting from -1000 2. We use SBI_ERR_xxxx defines for errors defined by SBI spec 3. We map some of the SBI_Exxxx defines to SBI_ERR_xxxx defines which are semantically same 4. We throw a error print and force return error code to SBI_ERR_FAILED in sbi_ecall_handler() if we see an invalid error code being returned to S-mode Signed-off-by: Anup Patel Reviewed-by: Atish Patra --- include/sbi/sbi_ecall_interface.h | 14 +++++++++++++- include/sbi/sbi_error.h | 35 +++++++++++++++++++---------------- lib/sbi/sbi_ecall.c | 8 ++++++++ lib/sbi/sbi_hart.c | 2 +- lib/sbi/sbi_hsm.c | 4 ++-- 5 files changed, 43 insertions(+), 20 deletions(-) diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h index 0cdde39..af30500 100644 --- a/include/sbi/sbi_ecall_interface.h +++ b/include/sbi/sbi_ecall_interface.h @@ -13,7 +13,7 @@ /* clang-format off */ /* SBI Extension IDs */ -#define SBI_EXT_0_1_SET_TIMER 0x0 +#define SBI_EXT_0_1_SET_TIMER 0x0 #define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 #define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2 #define SBI_EXT_0_1_CLEAR_IPI 0x3 @@ -69,6 +69,18 @@ #define SBI_EXT_VENDOR_END 0x09FFFFFF #define SBI_EXT_FIRMWARE_START 0x0A000000 #define SBI_EXT_FIRMWARE_END 0x0AFFFFFF + +/* SBI return error codes */ +#define SBI_SUCCESS 0 +#define SBI_ERR_FAILED -1 +#define SBI_ERR_NOT_SUPPORTED -2 +#define SBI_ERR_INVALID_PARAM -3 +#define SBI_ERR_DENIED -4 +#define SBI_ERR_INVALID_ADDRESS -5 +#define SBI_ERR_ALREADY_AVAILABLE -6 + +#define SBI_LAST_ERR SBI_ERR_ALREADY_AVAILABLE + /* clang-format on */ #endif diff --git a/include/sbi/sbi_error.h b/include/sbi/sbi_error.h index 574a84d..3655d12 100644 --- a/include/sbi/sbi_error.h +++ b/include/sbi/sbi_error.h @@ -10,25 +10,28 @@ #ifndef __SBI_ERROR_H__ #define __SBI_ERROR_H__ +#include + /* clang-format off */ #define SBI_OK 0 -#define SBI_EFAIL -1 -#define SBI_ENOTSUPP -2 -#define SBI_EINVAL -3 -#define SBI_DENIED -4 -#define SBI_INVALID_ADDR -5 -#define SBI_ENODEV -6 -#define SBI_ENOSYS -7 -#define SBI_ETIMEDOUT -8 -#define SBI_EIO -9 -#define SBI_EILL -10 -#define SBI_ENOSPC -11 -#define SBI_ENOMEM -12 -#define SBI_ETRAP -13 -#define SBI_EUNKNOWN -14 -#define SBI_ENOENT -15 -#define SBI_EALREADY_STARTED -16 +#define SBI_EFAIL SBI_ERR_FAILED +#define SBI_ENOTSUPP SBI_ERR_NOT_SUPPORTED +#define SBI_EINVAL SBI_ERR_INVALID_PARAM +#define SBI_EDENIED SBI_ERR_DENIED +#define SBI_EINVALID_ADDR SBI_ERR_INVALID_ADDRESS +#define SBI_EALREADY SBI_ERR_ALREADY_AVAILABLE + +#define SBI_ENODEV -1000 +#define SBI_ENOSYS -1001 +#define SBI_ETIMEDOUT -1002 +#define SBI_EIO -1003 +#define SBI_EILL -1004 +#define SBI_ENOSPC -1005 +#define SBI_ENOMEM -1006 +#define SBI_ETRAP -1007 +#define SBI_EUNKNOWN -1008 +#define SBI_ENOENT -1009 /* clang-format on */ diff --git a/lib/sbi/sbi_ecall.c b/lib/sbi/sbi_ecall.c index 1a54c6e..64c9933 100644 --- a/lib/sbi/sbi_ecall.c +++ b/lib/sbi/sbi_ecall.c @@ -7,6 +7,7 @@ * Anup Patel */ +#include #include #include #include @@ -124,6 +125,13 @@ int sbi_ecall_handler(struct sbi_trap_regs *regs) trap.epc = regs->mepc; sbi_trap_redirect(regs, &trap); } else { + if (ret < SBI_LAST_ERR) { + sbi_printf("%s: Invalid error %d for ext=0x%lx " + "func=0x%lx\n", __func__, ret, + extension_id, func_id); + ret = SBI_ERR_FAILED; + } + /* * This function should return non-zero value only in case of * fatal error. However, there is no good way to distinguish diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index 1d1c6d6..fa20bd2 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -200,7 +200,7 @@ int sbi_hart_pmp_check_addr(struct sbi_scratch *scratch, unsigned long addr, continue; if (tempaddr <= addr && addr <= tempaddr + size) if (!(prot & attr)) - return SBI_INVALID_ADDR; + return SBI_EINVALID_ADDR; } return SBI_OK; diff --git a/lib/sbi/sbi_hsm.c b/lib/sbi/sbi_hsm.c index 4330a22..013647a 100644 --- a/lib/sbi/sbi_hsm.c +++ b/lib/sbi/sbi_hsm.c @@ -219,7 +219,7 @@ int sbi_hsm_hart_start(struct sbi_scratch *scratch, u32 hartid, hstate = atomic_cmpxchg(&hdata->state, SBI_HART_STOPPED, SBI_HART_STARTING); if (hstate == SBI_HART_STARTED) - return SBI_EALREADY_STARTED; + return SBI_EALREADY; /** * if a hart is already transition to start or stop, another start call @@ -263,7 +263,7 @@ int sbi_hsm_hart_stop(struct sbi_scratch *scratch, bool exitnow) if (oldstate != SBI_HART_STARTED) { sbi_printf("%s: ERR: The hart is in invalid state [%u]\n", __func__, oldstate); - return SBI_DENIED; + return SBI_EDENIED; } if (exitnow) -- 2.7.4