diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2021-07-23 12:20:55 -1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-11-02 07:00:52 -0400 |
commit | e7424abc201ea06ff91a15fd86a533a22cd8dff4 (patch) | |
tree | d35abf7874f85105c7d7ae1d8bf6ab492ecf8498 /target/alpha | |
parent | 12ed56407e60371d45ffa3b7f2fd00c4d7efa580 (diff) |
target/alpha: Implement alpha_cpu_record_sigbus
Record trap_arg{0,1,2} for the linux-user signal frame.
Raise SIGBUS directly from cpu_loop_exit_sigbus, which means
we can remove the code for EXCP_UNALIGN in cpu_loop.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/alpha')
-rw-r--r-- | target/alpha/cpu.c | 1 | ||||
-rw-r--r-- | target/alpha/cpu.h | 8 | ||||
-rw-r--r-- | target/alpha/mem_helper.c | 30 |
3 files changed, 28 insertions, 11 deletions
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index 69f32c3078..a8990d401b 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -221,6 +221,7 @@ static const struct TCGCPUOps alpha_tcg_ops = { #ifdef CONFIG_USER_ONLY .record_sigsegv = alpha_cpu_record_sigsegv, + .record_sigbus = alpha_cpu_record_sigbus, #else .tlb_fill = alpha_cpu_tlb_fill, .cpu_exec_interrupt = alpha_cpu_exec_interrupt, diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index d49cc36d07..afd975c878 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -282,9 +282,6 @@ void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags); hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); -void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, - MMUAccessType access_type, int mmu_idx, - uintptr_t retaddr) QEMU_NORETURN; #define cpu_list alpha_cpu_list @@ -451,10 +448,15 @@ void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val); void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address, MMUAccessType access_type, bool maperr, uintptr_t retaddr); +void alpha_cpu_record_sigbus(CPUState *cs, vaddr address, + MMUAccessType access_type, uintptr_t retaddr); #else bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); +void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, + MMUAccessType access_type, int mmu_idx, + uintptr_t retaddr) QEMU_NORETURN; void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, unsigned size, MMUAccessType access_type, diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c index 75e72bc337..47283a0612 100644 --- a/target/alpha/mem_helper.c +++ b/target/alpha/mem_helper.c @@ -23,18 +23,12 @@ #include "exec/exec-all.h" #include "exec/cpu_ldst.h" -/* Softmmu support */ -#ifndef CONFIG_USER_ONLY -void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr, - MMUAccessType access_type, - int mmu_idx, uintptr_t retaddr) +static void do_unaligned_access(CPUAlphaState *env, vaddr addr, uintptr_t retaddr) { - AlphaCPU *cpu = ALPHA_CPU(cs); - CPUAlphaState *env = &cpu->env; uint64_t pc; uint32_t insn; - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(env_cpu(env), retaddr, true); pc = env->pc; insn = cpu_ldl_code(env, pc); @@ -42,6 +36,26 @@ void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr, env->trap_arg0 = addr; env->trap_arg1 = insn >> 26; /* opcode */ env->trap_arg2 = (insn >> 21) & 31; /* dest regno */ +} + +#ifdef CONFIG_USER_ONLY +void alpha_cpu_record_sigbus(CPUState *cs, vaddr addr, + MMUAccessType access_type, uintptr_t retaddr) +{ + AlphaCPU *cpu = ALPHA_CPU(cs); + CPUAlphaState *env = &cpu->env; + + do_unaligned_access(env, addr, retaddr); +} +#else +void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr, + MMUAccessType access_type, + int mmu_idx, uintptr_t retaddr) +{ + AlphaCPU *cpu = ALPHA_CPU(cs); + CPUAlphaState *env = &cpu->env; + + do_unaligned_access(env, addr, retaddr); cs->exception_index = EXCP_UNALIGN; env->error_code = 0; cpu_loop_exit(cs); |