diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2022-01-06 11:22:42 -0800 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2022-01-06 11:22:42 -0800 |
| commit | 41fb4c14ee500125dc0ce6fb573cf84b8db29ed0 (patch) | |
| tree | 2c3da77c3ae2b5ba60b91c2b1a829f3a98e4327e /linux-user/nios2/cpu_loop.c | |
| parent | 7d4ae4d4978079d564d3b6354c90a949130409fe (diff) | |
| parent | f0effdbc2a5b43422bc4c9c22641ef9dafa0c7ae (diff) | |
| download | focaccia-qemu-41fb4c14ee500125dc0ce6fb573cf84b8db29ed0.tar.gz focaccia-qemu-41fb4c14ee500125dc0ce6fb573cf84b8db29ed0.zip | |
Merge tag 'linux-user-for-7.0-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging
linux-user pull request 20220106 update netlink entries nios2 fixes /proc/self/maps fixes set/getscheduler update prctl cleanup and fixes target_signal.h cleanup and some trivial fixes # gpg: Signature made Thu 06 Jan 2022 02:41:07 AM PST # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "laurent@vivier.eu" # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [undefined] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [undefined] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * tag 'linux-user-for-7.0-pull-request' of https://gitlab.com/laurent_vivier/qemu: (27 commits) linux-user: netlink: update IFLA_BRPORT entries linux-user: netlink: Add IFLA_VFINFO_LIST linux-user: netlink: update IFLA entries linux-user/syscall.c: malloc to g_try_malloc linux-user/nios2: Use set_sigmask in do_rt_sigreturn linux-user/nios2: Fix sigmask in setup_rt_frame linux-user/nios2: Fix EA vs PC confusion linux-user/nios2: Map a real kuser page linux-user/elfload: Rename ARM_COMMPAGE to HI_COMMPAGE linux-user/nios2: Fixes for signal frame setup linux-user/nios2: Properly emulate EXCP_TRAP linux-user/syscall.c: fix missed flag for shared memory in open_self_maps linux-user: call set/getscheduler set/getparam directly linux-user: add sched_getattr support linux-user/signal: Map exit signals in SIGCHLD siginfo_t target/sh4: Implement prctl_unalign_sigbus target/hppa: Implement prctl_unalign_sigbus target/alpha: Implement prctl_unalign_sigbus linux-user: Add code for PR_GET/SET_UNALIGN linux-user: Disable more prctl subcodes ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/nios2/cpu_loop.c')
| -rw-r--r-- | linux-user/nios2/cpu_loop.c | 93 |
1 files changed, 49 insertions, 44 deletions
diff --git a/linux-user/nios2/cpu_loop.c b/linux-user/nios2/cpu_loop.c index 34290fb3b5..1e93ef34e6 100644 --- a/linux-user/nios2/cpu_loop.c +++ b/linux-user/nios2/cpu_loop.c @@ -26,7 +26,6 @@ void cpu_loop(CPUNios2State *env) { CPUState *cs = env_cpu(env); - Nios2CPU *cpu = NIOS2_CPU(cs); target_siginfo_t info; int trapnr, ret; @@ -39,9 +38,10 @@ void cpu_loop(CPUNios2State *env) case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; + case EXCP_TRAP: - if (env->regs[R_AT] == 0) { - abi_long ret; + switch (env->error_code) { + case 0: qemu_log_mask(CPU_LOG_INT, "\nSyscall\n"); ret = do_syscall(env, env->regs[2], @@ -55,26 +55,56 @@ void cpu_loop(CPUNios2State *env) env->regs[2] = abs(ret); /* Return value is 0..4096 */ - env->regs[7] = (ret > 0xfffffffffffff000ULL); - env->regs[CR_ESTATUS] = env->regs[CR_STATUS]; - env->regs[CR_STATUS] &= ~0x3; - env->regs[R_EA] = env->regs[R_PC] + 4; + env->regs[7] = ret > 0xfffff000u; env->regs[R_PC] += 4; break; - } else { - qemu_log_mask(CPU_LOG_INT, "\nTrap\n"); - env->regs[CR_ESTATUS] = env->regs[CR_STATUS]; - env->regs[CR_STATUS] &= ~0x3; - env->regs[R_EA] = env->regs[R_PC] + 4; - env->regs[R_PC] = cpu->exception_addr; + case 1: + qemu_log_mask(CPU_LOG_INT, "\nTrap 1\n"); + force_sig_fault(TARGET_SIGUSR1, 0, env->regs[R_PC]); + break; + case 2: + qemu_log_mask(CPU_LOG_INT, "\nTrap 2\n"); + force_sig_fault(TARGET_SIGUSR2, 0, env->regs[R_PC]); + break; + case 31: + qemu_log_mask(CPU_LOG_INT, "\nTrap 31\n"); + force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->regs[R_PC]); + break; + default: + qemu_log_mask(CPU_LOG_INT, "\nTrap %d\n", env->error_code); + force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLTRP, + env->regs[R_PC]); + break; + + case 16: /* QEMU specific, for __kuser_cmpxchg */ + { + abi_ptr g = env->regs[4]; + uint32_t *h, n, o; - info.si_signo = TARGET_SIGTRAP; - info.si_errno = 0; - info.si_code = TARGET_TRAP_BRKPT; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + if (g & 0x3) { + force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, g); + break; + } + ret = page_get_flags(g); + if (!(ret & PAGE_VALID)) { + force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, g); + break; + } + if (!(ret & PAGE_READ) || !(ret & PAGE_WRITE)) { + force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_ACCERR, g); + break; + } + h = g2h(cs, g); + o = env->regs[5]; + n = env->regs[6]; + env->regs[2] = qatomic_cmpxchg(h, o, n) - o; + env->regs[R_PC] += 4; + } break; } + break; + case EXCP_DEBUG: info.si_signo = TARGET_SIGTRAP; info.si_errno = 0; @@ -82,29 +112,7 @@ void cpu_loop(CPUNios2State *env) queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; case 0xaa: - switch (env->regs[R_PC]) { - /*case 0x1000:*/ /* TODO:__kuser_helper_version */ - case 0x1004: /* __kuser_cmpxchg */ - start_exclusive(); - if (env->regs[4] & 0x3) { - goto kuser_fail; - } - ret = get_user_u32(env->regs[2], env->regs[4]); - if (ret) { - end_exclusive(); - goto kuser_fail; - } - env->regs[2] -= env->regs[5]; - if (env->regs[2] == 0) { - put_user_u32(env->regs[6], env->regs[4]); - } - end_exclusive(); - env->regs[R_PC] = env->regs[R_RA]; - break; - /*case 0x1040:*/ /* TODO:__kuser_sigtramp */ - default: - ; -kuser_fail: + { info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; /* TODO: check env->error_code */ @@ -147,9 +155,6 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) env->regs[R_SP] = regs->sp; env->regs[R_GP] = regs->gp; env->regs[CR_ESTATUS] = regs->estatus; - env->regs[R_EA] = regs->ea; - /* TODO: unsigned long orig_r7; */ - - /* Emulate eret when starting thread. */ env->regs[R_PC] = regs->ea; + /* TODO: unsigned long orig_r7; */ } |