lib: sbi: call platform load/store emulators

sbi_load/store_access_handler now tries to call platform emulators
if defined. Otherwise, redirects the fault. If the platform code
returns failure, this means the H/S/U has accessed the emulated
devices in an unexpected manner, which is very likely caused by
buggy code in H/S/U. We redirect the fault, so lower privileged
level can get notified, and act accordingly. (E.g., oops in Linux)

We let the handler truly fail if the trap was originated from M mode.
In this case, something must be very wrong and we should just fail.

Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Bo Gan
2024-03-05 18:35:40 -08:00
committed by Anup Patel
parent ddf3b649f1
commit 81e3ba77a6
2 changed files with 80 additions and 2 deletions

View File

@@ -48,6 +48,7 @@
#include <sbi/sbi_error.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_version.h>
#include <sbi/sbi_trap_ldst.h>
struct sbi_domain_memregion;
struct sbi_ecall_return;
@@ -683,6 +684,50 @@ static inline int sbi_platform_vendor_ext_provider(
return SBI_ENOTSUPP;
}
/**
* Ask platform to emulate the trapped load
*
* @param plat pointer to struct sbi_platform
* @param rlen length of the load: 1/2/4/8...
* @param addr virtual address of the load. Platform needs to page-walk and
* find the physical address if necessary
* @param out_val value loaded
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_emulate_load(const struct sbi_platform *plat,
int rlen, unsigned long addr,
union sbi_ldst_data *out_val)
{
if (plat && sbi_platform_ops(plat)->emulate_load) {
return sbi_platform_ops(plat)->emulate_load(rlen, addr,
out_val);
}
return SBI_ENOTSUPP;
}
/**
* Ask platform to emulate the trapped store
*
* @param plat pointer to struct sbi_platform
* @param wlen length of the store: 1/2/4/8...
* @param addr virtual address of the store. Platform needs to page-walk and
* find the physical address if necessary
* @param in_val value to store
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_emulate_store(const struct sbi_platform *plat,
int wlen, unsigned long addr,
union sbi_ldst_data in_val)
{
if (plat && sbi_platform_ops(plat)->emulate_store) {
return sbi_platform_ops(plat)->emulate_store(wlen, addr,
in_val);
}
return SBI_ENOTSUPP;
}
#endif
#endif