Commit Graph

11 Commits

Author SHA1 Message Date
Bo Gan 56c39d1f08 lib: sbi: Rework load/store emulator instruction decoding
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: 7219477f7b ("lib: Use MTINST CSR in misaligned load/store emulation")
Fixes: b5ae8e8a65 ("lib: Add misaligned load/store trap handling")
Fixes: 4c112650bb ("lib: sbi: abstract out insn decoding to unify mem fault handlers")
Signed-off-by: Bo Gan <ganboing@gmail.com>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260605113214.242-8-ganboing@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2026-06-16 13:42:47 +05:30
Bo Gan eba121b459 lib: sbi: Do not override emulator callback for vector load/store
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: c2acc5e5b0 ("lib: sbi_misaligned_ldst: Add handling of vector load/store")
Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Link: https://lore.kernel.org/r/20260605113214.242-6-ganboing@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2026-06-16 13:25:27 +05:30
Nylon Chen c2acc5e5b0 lib: sbi_misaligned_ldst: Add handling of vector load/store
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 <zong.li@sifive.com>
Signed-off-by: Zong Li <zong.li@sifive.com>
Signed-off-by: Nylon Chen <nylon.chen@sifive.com>
Reviewed-by: Andy Chiu <andy.chiu@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-06 17:43:06 +05:30
Clément Léger 80656bdb1d lib: sbi: factorize previous mode computation
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 <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:53:18 +05:30
Anup Patel fea33a9334 lib: sbi: Simplify parameters of misaligned and access fault handlers
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 <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Clément Léger <cleger@rivosinc.com>
2024-03-19 11:31:28 +05:30
Samuel Holland 2e8517865a lib: sbi: Remove epc from struct sbi_trap_info
In the only places this value is used, it duplicates mepc from
struct sbi_trap_regs.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-19 11:31:16 +05:30
Bo Gan 81e3ba77a6 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>
2024-03-11 10:56:02 +05:30
Bo Gan 4c112650bb lib: sbi: abstract out insn decoding to unify mem fault handlers
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 <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:50:39 +05:30
Bo Gan 9221fe58d1 lib: sbi: change prototype of sbi_misaligned_load/store_handler
This simplifies both handlers such that when the handler needs to
redirect the original trap, it's readily available.

Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:48:00 +05:30
Bo Gan 2471cf2e6c include: sbi: rename sbi_misaligned_ldst.h to sbi_trap_ldst.h
Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:36:35 +05:30
Bo Gan c0a63205f8 lib: sbi: rename sbi_misaligned_ldst.c to sbi_trap_ldst.c
Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:36:29 +05:30