Skip to content

Commit 956d705

Browse files
damien-lemoalpalmer-dabbelt
authored andcommitted
riscv: Unaligned load/store handling for M_MODE
Add handlers for unaligned load and store traps that may be generated by applications. Code heavily inspired from the OpenSBI project. Handling of the unaligned access traps is suitable for applications compiled with or without compressed instructions and is independent of the kernel CONFIG_RISCV_ISA_C option value. Signed-off-by: Damien Le Moal <[email protected]> Signed-off-by: Anup Patel <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent f1e5858 commit 956d705

File tree

3 files changed

+395
-4
lines changed

3 files changed

+395
-4
lines changed

arch/riscv/kernel/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ obj-y += cacheinfo.o
3030
obj-y += patch.o
3131
obj-$(CONFIG_MMU) += vdso.o vdso/
3232

33-
obj-$(CONFIG_RISCV_M_MODE) += clint.o
33+
obj-$(CONFIG_RISCV_M_MODE) += clint.o traps_misaligned.o
3434
obj-$(CONFIG_FPU) += fpu.o
3535
obj-$(CONFIG_SMP) += smpboot.o
3636
obj-$(CONFIG_SMP) += smp.o

arch/riscv/kernel/traps.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,33 @@ DO_ERROR_INFO(do_trap_insn_fault,
9797
SIGSEGV, SEGV_ACCERR, "instruction access fault");
9898
DO_ERROR_INFO(do_trap_insn_illegal,
9999
SIGILL, ILL_ILLOPC, "illegal instruction");
100-
DO_ERROR_INFO(do_trap_load_misaligned,
101-
SIGBUS, BUS_ADRALN, "load address misaligned");
102100
DO_ERROR_INFO(do_trap_load_fault,
103101
SIGSEGV, SEGV_ACCERR, "load access fault");
102+
#ifndef CONFIG_RISCV_M_MODE
103+
DO_ERROR_INFO(do_trap_load_misaligned,
104+
SIGBUS, BUS_ADRALN, "Oops - load address misaligned");
104105
DO_ERROR_INFO(do_trap_store_misaligned,
105-
SIGBUS, BUS_ADRALN, "store (or AMO) address misaligned");
106+
SIGBUS, BUS_ADRALN, "Oops - store (or AMO) address misaligned");
107+
#else
108+
int handle_misaligned_load(struct pt_regs *regs);
109+
int handle_misaligned_store(struct pt_regs *regs);
110+
111+
asmlinkage void do_trap_load_misaligned(struct pt_regs *regs)
112+
{
113+
if (!handle_misaligned_load(regs))
114+
return;
115+
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
116+
"Oops - load address misaligned");
117+
}
118+
119+
asmlinkage void do_trap_store_misaligned(struct pt_regs *regs)
120+
{
121+
if (!handle_misaligned_store(regs))
122+
return;
123+
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
124+
"Oops - store (or AMO) address misaligned");
125+
}
126+
#endif
106127
DO_ERROR_INFO(do_trap_store_fault,
107128
SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
108129
DO_ERROR_INFO(do_trap_ecall_u,

0 commit comments

Comments
 (0)