mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
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>
This commit is contained in:
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,
|
DO_ERROR_INFO(do_trap_load_fault,
|
||||||
SIGSEGV, SEGV_ACCERR, "load access 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)
|
asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
if (user_mode(regs)) {
|
do_trap_misaligned(regs, MISALIGNED_LOAD);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs)
|
asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
if (user_mode(regs)) {
|
do_trap_misaligned(regs, MISALIGNED_STORE);
|
||||||
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_ERROR_INFO(do_trap_store_fault,
|
DO_ERROR_INFO(do_trap_store_fault,
|
||||||
SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
|
SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
|
||||||
DO_ERROR_INFO(do_trap_ecall_s,
|
DO_ERROR_INFO(do_trap_ecall_s,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user