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>
This commit is contained in:
Richard Henderson 2021-07-23 12:20:55 -10:00
parent 12ed56407e
commit e7424abc20
4 changed files with 28 additions and 18 deletions

View File

@ -54,13 +54,6 @@ void cpu_loop(CPUAlphaState *env)
fprintf(stderr, "External interrupt. Exit\n");
exit(EXIT_FAILURE);
break;
case EXCP_UNALIGN:
info.si_signo = TARGET_SIGBUS;
info.si_errno = 0;
info.si_code = TARGET_BUS_ADRALN;
info._sifields._sigfault._addr = env->trap_arg0;
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_OPCDEC:
do_sigill:
info.si_signo = TARGET_SIGILL;

View File

@ -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,

View File

@ -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,

View File

@ -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);