riscv: misaligned: factorize trap handling
Since both load/store and user/kernel should use almost the same path and that we are going to add some code around that, factorize it. Signed-off-by: Clément Léger <cleger@rivosinc.com> Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com> Link: https://lore.kernel.org/r/20250422162324.956065-2-cleger@rivosinc.com Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>pull/899/merge
parent
eb16b3727c
commit
fd94de9f9e
|
|
@ -198,47 +198,53 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
|
|||
DO_ERROR_INFO(do_trap_load_fault,
|
||||
SIGSEGV, SEGV_ACCERR, "load access fault");
|
||||
|
||||
enum misaligned_access_type {
|
||||
MISALIGNED_STORE,
|
||||
MISALIGNED_LOAD,
|
||||
};
|
||||
static const struct {
|
||||
const char *type_str;
|
||||
int (*handler)(struct pt_regs *regs);
|
||||
} misaligned_handler[] = {
|
||||
[MISALIGNED_STORE] = {
|
||||
.type_str = "Oops - store (or AMO) address misaligned",
|
||||
.handler = handle_misaligned_store,
|
||||
},
|
||||
[MISALIGNED_LOAD] = {
|
||||
.type_str = "Oops - load address misaligned",
|
||||
.handler = handle_misaligned_load,
|
||||
},
|
||||
};
|
||||
|
||||
static void do_trap_misaligned(struct pt_regs *regs, enum misaligned_access_type type)
|
||||
{
|
||||
irqentry_state_t state;
|
||||
|
||||
if (user_mode(regs))
|
||||
irqentry_enter_from_user_mode(regs);
|
||||
else
|
||||
state = irqentry_nmi_enter(regs);
|
||||
|
||||
if (misaligned_handler[type].handler(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
misaligned_handler[type].type_str);
|
||||
|
||||
if (user_mode(regs))
|
||||
irqentry_exit_to_user_mode(regs);
|
||||
else
|
||||
irqentry_nmi_exit(regs, state);
|
||||
}
|
||||
|
||||
asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs)) {
|
||||
irqentry_enter_from_user_mode(regs);
|
||||
|
||||
if (handle_misaligned_load(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
"Oops - load address misaligned");
|
||||
|
||||
irqentry_exit_to_user_mode(regs);
|
||||
} else {
|
||||
irqentry_state_t state = irqentry_nmi_enter(regs);
|
||||
|
||||
if (handle_misaligned_load(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
"Oops - load address misaligned");
|
||||
|
||||
irqentry_nmi_exit(regs, state);
|
||||
}
|
||||
do_trap_misaligned(regs, MISALIGNED_LOAD);
|
||||
}
|
||||
|
||||
asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs)) {
|
||||
irqentry_enter_from_user_mode(regs);
|
||||
|
||||
if (handle_misaligned_store(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
"Oops - store (or AMO) address misaligned");
|
||||
|
||||
irqentry_exit_to_user_mode(regs);
|
||||
} else {
|
||||
irqentry_state_t state = irqentry_nmi_enter(regs);
|
||||
|
||||
if (handle_misaligned_store(regs))
|
||||
do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
|
||||
"Oops - store (or AMO) address misaligned");
|
||||
|
||||
irqentry_nmi_exit(regs, state);
|
||||
}
|
||||
do_trap_misaligned(regs, MISALIGNED_STORE);
|
||||
}
|
||||
|
||||
DO_ERROR_INFO(do_trap_store_fault,
|
||||
SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
|
||||
DO_ERROR_INFO(do_trap_ecall_s,
|
||||
|
|
|
|||
Loading…
Reference in New Issue