lib: Don't return any invalid error from SBI ecall
authorAnup Patel <anup.patel@wdc.com>
Wed, 10 Jun 2020 13:09:53 +0000 (18:39 +0530)
committerAnup Patel <anup@brainfault.org>
Sat, 20 Jun 2020 05:06:13 +0000 (10:36 +0530)
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 <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
include/sbi/sbi_ecall_interface.h
include/sbi/sbi_error.h
lib/sbi/sbi_ecall.c
lib/sbi/sbi_hart.c
lib/sbi/sbi_hsm.c

index 0cdde39..af30500 100644 (file)
@@ -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
 #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
index 574a84d..3655d12 100644 (file)
 #ifndef __SBI_ERROR_H__
 #define __SBI_ERROR_H__
 
+#include <sbi/sbi_ecall_interface.h>
+
 /* 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 */
 
index 1a54c6e..64c9933 100644 (file)
@@ -7,6 +7,7 @@
  *   Anup Patel <anup.patel@wdc.com>
  */
 
+#include <sbi/sbi_console.h>
 #include <sbi/sbi_ecall.h>
 #include <sbi/sbi_ecall_interface.h>
 #include <sbi/sbi_error.h>
@@ -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
index 1d1c6d6..fa20bd2 100644 (file)
@@ -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;
index 4330a22..013647a 100644 (file)
@@ -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)