summaryrefslogtreecommitdiff
path: root/lib/sbi/sbi_trap_ldst.c
AgeCommit message (Collapse)Author
2026-06-17lib: sbi: Add variable-length unprivilege access functionsBo Gan
sbi_load/store_loop read/write variable-length buffer unprivileged. Both function use the widest aligned 8/4/2/1 byte load/stores in each loop to reduce the total number of iterations. Also switch the scalar/vector misaligned handlers to make use of such functions to simplify code. Miscellaneous: remove the unnecessary [taddr] in inline assembly Signed-off-by: Bo Gan <[email protected]> Tested-by: Anirudh Srinivasan <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2026-06-17lib: sbi: Rework and split sbi_misaligned(_v)_tinst_fixupBo Gan
The load/store address offset between the uptrap and the orig_trap can be derived by orig_trap->tval - uptrap->tval, thus refactor the function prototype for simplicity. For vector load, sbi_misaligned_v_tinst_fixup is introduced. There's no transformed instruction for vector load/store, so null out tinst if the fault is not a guest-page fault. Signed-off-by: Bo Gan <[email protected]> Tested-by: Anirudh Srinivasan <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2026-06-16lib: sbi: Rework load/store emulator instruction decodingBo Gan
Rehaul instruction decoding to fix the following issues: - We assume the XLEN of previous mode is the same as MXLEN. However, RVC instructions decodes differently in RV32 and RV64, so shouldn't have assumed that. - We assume it's a misaligned fault and the load/store offset is 0, i.e., base address == fault address, but access faults can have non-0 offset (on HW supporting misaligned accesses), so platform specific load/store fault handler gets the wrong base address. - No checking of [63:32] of tinst in RV64, which is explicitly required by Privileged ISA 19.6.3. Must reject tinst with non-0 high 32 bits. Thus, fix all the above. For misaligned load/store fault, the address offset should be 0, but we'll validate that on a DEBUG build. On an optmized build, we kill the use of base address, and use trap address instead (same as before), which lets the compiler optimize out imm parsing and other calculations. I also analyzed the behavior of misaligned fault handler before fix. With the following conditions met, it can trigger data corruption: - HW doesn't transform instruction into tinst. - HW doesn't support misaligned load/store, and OS doesn't enable misaligned delegation, thus OpenSBI handler is in effect - HW supports mixed XLEN, and M mode is running RV64, and the trapping mode (U/VS/VU) is running RV32. - The trapping instruction is c.f{l|s}w(sp). Due to the incorrect insn decoding, the trapping instruction would mistakenly be decoded as c.{l|s}d(sp). With this fix, c.f{l|s}w(sp) in RV32 is now emulated correctly. Validation: The patch is validated to have fixed the issue with test cases running on a modified version of QEMU that exposes misaligned faults [1], and a further modified version that removes tinst transformation [2]. The S-mode OS is a local build of Debian Trixie 6.12 kernel that enables COMPAT (RV32), and the U-mode test application exercises all integer and floating-point load/store (RVIFD64/32+RVC64/32) instructions with all possible imm values. The patch is also tested on real HW (Sifive P550/ESWIN EIC7700), which only supports RV64. On P550, the same test was validated both in U mode and VU mode, where the host runs a 6.12 ESWIN vendor kernel that has some ESWIN SoC device driver patches [3] applied, and the guest runs the exact same Debian Trixie 6.12 kernel mentioned above. [1] https://github.com/ganboing/qemu/tree/ganboing-misalign [2] https://github.com/ganboing/qemu/tree/ganboing-misalign-no-tinst [3] https://github.com/sifiveinc/riscv-linux/tree/rel/kernel-6.12/hifive-premier-p550 Fixes: 7219477f7b40 ("lib: Use MTINST CSR in misaligned load/store emulation") Fixes: b5ae8e8a650d ("lib: Add misaligned load/store trap handling") Fixes: 4c112650bbb0 ("lib: sbi: abstract out insn decoding to unify mem fault handlers") Signed-off-by: Bo Gan <[email protected]> Tested-by: Anirudh Srinivasan <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2026-06-16lib: sbi: Do not override emulator callback for vector load/storeBo Gan
It's wrong to override the emulator callback in sbi_trap_emulate_load/ store. The function must respect the callback function passed in the parameter. Hence, let the misaligned emulator callback decide when to use sbi_misaligned_v_ld/st_emulator. To clean up things, also make the following changes: - Add the `insn` parameter to the callback. The trapping insn has been fetched by the caller already, whether transformed or directly loaded, thus saving the trouble in the callback. Note that you must not rely on the length of the `insn`, as it can be a transformed one from tinst - Also the `tcntx` is added, providing the callback with register values to handle vector insn or other customized insns. - Clarify that the read/write length (rlen/wlen) can be 0, in which case it could be a vector load/store or some customized instruction. The callback is responsible to handle it accordingly. Also fixed issues in the sbi_misaligned_v_ld/st_emulator: a. Redirect the trap when OPENSBI_CC_SUPPORT_VECTOR is not available. b. Ensure the return code is >0 when no faults are redirected. Fixes: c2acc5e5b0d8 ("lib: sbi_misaligned_ldst: Add handling of vector load/store") Signed-off-by: Bo Gan <[email protected]> Reviewed-by: Anup Patel <[email protected]> Tested-by: Anirudh Srinivasan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2024-12-06lib: sbi_misaligned_ldst: Add handling of vector load/storeNylon Chen
Add misaligned load/store handling for the vector extension to the sbi_misaligned_ldst library. This implementation is inspired from the misaligned_vec_ldst implementation in the riscv-pk project. Co-developed-by: Zong Li <[email protected]> Signed-off-by: Zong Li <[email protected]> Signed-off-by: Nylon Chen <[email protected]> Reviewed-by: Andy Chiu <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-10-25lib: sbi: factorize previous mode computationClément Léger
Previous privilege mode retrieval from mstatus is done at different places, factorize it rather than copy/pasting it again. Signed-off-by: Clément Léger <[email protected]> Reviewed-by: Samuel Holland <[email protected]>
2024-03-19lib: sbi: Simplify parameters of misaligned and access fault handlersAnup Patel
The struct sbi_trap_context already has the information needed by misaligned load/store and access fault load/store handlers so directly pass struct sbi_trap_context pointer to these functions. Signed-off-by: Anup Patel <[email protected]> Reviewed-by: Samuel Holland <[email protected]> Tested-by: Samuel Holland <[email protected]> Reviewed-by: Clément Léger <[email protected]>
2024-03-19lib: sbi: Remove epc from struct sbi_trap_infoSamuel Holland
In the only places this value is used, it duplicates mepc from struct sbi_trap_regs. Signed-off-by: Samuel Holland <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-11lib: sbi: call platform load/store emulatorsBo Gan
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-11lib: sbi: abstract out insn decoding to unify mem fault handlersBo Gan
This patch abstracts out the instruction decoding part of misaligned ld/st fault handlers, so it can be reused by ld/st access fault handlers. Also Added lb/lbu/sb decoding. (previously unreachable by misaligned fault) sbi_trap_emulate_load/store is now the common handler which takes a `emu` parameter that is responsible for emulating the misaligned or access fault. The `emu` callback is expected to fixup the fault, and based on the return code of `emu`, sbi_trap_emulate_load/store will: r/wlen => the fixup is successful and regs/mepc needs to be updated. 0 => the fixup is successful, but regs/mepc should be left untouched (this is usually used if `emu` does `sbi_trap_redirect`) -err => failed, sbi_trap_error will be called For now, load/store access faults are blindly redirected. It will be enhanced in the following patches. Signed-off-by: Bo Gan <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-11lib: sbi: change prototype of sbi_misaligned_load/store_handlerBo Gan
This simplifies both handlers such that when the handler needs to redirect the original trap, it's readily available. Signed-off-by: Bo Gan <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-11include: sbi: rename sbi_misaligned_ldst.h to sbi_trap_ldst.hBo Gan
Signed-off-by: Bo Gan <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-11lib: sbi: rename sbi_misaligned_ldst.c to sbi_trap_ldst.cBo Gan
Signed-off-by: Bo Gan <[email protected]> Reviewed-by: Anup Patel <[email protected]>