lib: sbi: Add variable-length unprivilege access functions

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 <ganboing@gmail.com>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260609060024.706-4-ganboing@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Bo Gan
2026-06-08 23:00:23 -07:00
committed by Anup Patel
parent 1475f147f6
commit 914aeddaf1
4 changed files with 122 additions and 42 deletions
+16 -20
View File
@@ -229,20 +229,17 @@ int sbi_misaligned_v_ld_emulator(ulong insn, struct sbi_trap_context *tcntx)
/* obtain load data from memory */
for (ulong seg = 0; seg < nf; seg++) {
for (ulong i = 0; i < len; i++) {
bytes[seg * len + i] =
sbi_load_u8((void *)(addr + seg * len + i),
&uptrap);
sbi_load_loop(bytes + seg * len,
addr + seg * len, len, &uptrap);
if (uptrap.cause) {
if (IS_FAULT_ONLY_FIRST_LOAD(insn) && vstart != 0) {
vl = vstart;
break;
}
vsetvl(vl, vtype);
sbi_misaligned_v_tinst_fixup(&uptrap);
return sbi_trap_redirect(regs, &uptrap);
if (uptrap.cause) {
if (IS_FAULT_ONLY_FIRST_LOAD(insn) && vstart != 0) {
vl = vstart;
break;
}
vsetvl(vl, vtype);
sbi_misaligned_v_tinst_fixup(&uptrap);
return sbi_trap_redirect(regs, &uptrap);
}
}
@@ -332,14 +329,13 @@ int sbi_misaligned_v_st_emulator(ulong insn, struct sbi_trap_context *tcntx)
/* write store data to memory */
for (ulong seg = 0; seg < nf; seg++) {
for (ulong i = 0; i < len; i++) {
sbi_store_u8((void *)(addr + seg * len + i),
bytes[seg * len + i], &uptrap);
if (uptrap.cause) {
vsetvl(vl, vtype);
sbi_misaligned_v_tinst_fixup(&uptrap);
return sbi_trap_redirect(regs, &uptrap);
}
sbi_store_loop(bytes + seg * len,
addr + seg * len, len, &uptrap);
if (uptrap.cause) {
vsetvl(vl, vtype);
sbi_misaligned_v_tinst_fixup(&uptrap);
return sbi_trap_redirect(regs, &uptrap);
}
}
} while (++vstart < vl);