* [PATCH v3 01/25] linux-user/arm: Use force_sig_fault()
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
@ 2021-09-19 1:56 ` Richard Henderson
2021-09-19 1:56 ` [PATCH v3 02/25] linux-user/aarch64: " Richard Henderson
` (24 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, laurent
From: Peter Maydell <peter.maydell@linaro.org>
Use the new force_sig_fault() function instead of setting up
a target_siginfo_t and calling queue_signal().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20210813131809.28655-7-peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/arm/cpu_loop.c | 53 +++++++++++----------------------------
1 file changed, 15 insertions(+), 38 deletions(-)
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index b8ece169f9..d4b4f0c71f 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -93,7 +93,6 @@ static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
{
uint64_t oldval, newval, val;
uint32_t addr, cpsr;
- target_siginfo_t info;
/* Based on the 32 bit code in do_kernel_trap */
@@ -142,12 +141,9 @@ segv:
end_exclusive();
/* We get the PC of the entry address - which is as good as anything,
on a real kernel what you get depends on which mode it uses. */
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
/* XXX: check env->error_code */
- info.si_code = TARGET_SEGV_MAPERR;
- info._sifields._sigfault._addr = env->exception.vaddress;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
+ env->exception.vaddress);
}
/* Handle a jump to the kernel code page. */
@@ -285,8 +281,6 @@ void cpu_loop(CPUARMState *env)
CPUState *cs = env_cpu(env);
int trapnr;
unsigned int n, insn;
- target_siginfo_t info;
- uint32_t addr;
abi_ulong ret;
for(;;) {
@@ -321,11 +315,8 @@ void cpu_loop(CPUARMState *env)
break;
}
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPN;
- info._sifields._sigfault._addr = env->regs[15];
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN,
+ env->regs[15]);
}
break;
case EXCP_SWI:
@@ -393,18 +384,14 @@ void cpu_loop(CPUARMState *env)
* Otherwise SIGILL. This includes any SWI with
* immediate not originally 0x9fxxxx, because
* of the earlier XOR.
+ * Like the real kernel, we report the addr of the
+ * SWI in the siginfo si_addr but leave the PC
+ * pointing at the insn after the SWI.
*/
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLTRP;
- info._sifields._sigfault._addr = env->regs[15];
- if (env->thumb) {
- info._sifields._sigfault._addr -= 2;
- } else {
- info._sifields._sigfault._addr -= 4;
- }
- queue_signal(env, info.si_signo,
- QEMU_SI_FAULT, &info);
+ abi_ulong faultaddr = env->regs[15];
+ faultaddr -= env->thumb ? 2 : 4;
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLTRP,
+ faultaddr);
}
break;
}
@@ -435,24 +422,14 @@ void cpu_loop(CPUARMState *env)
break;
case EXCP_PREFETCH_ABORT:
case EXCP_DATA_ABORT:
- addr = env->exception.vaddress;
- {
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- /* XXX: check env->error_code */
- info.si_code = TARGET_SEGV_MAPERR;
- info._sifields._sigfault._addr = addr;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- }
+ /* XXX: check env->error_code */
+ force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
+ env->exception.vaddress);
break;
case EXCP_DEBUG:
case EXCP_BKPT:
excp_debug:
- info.si_signo = TARGET_SIGTRAP;
- info.si_errno = 0;
- info.si_code = TARGET_TRAP_BRKPT;
- info._sifields._sigfault._addr = env->regs[15];
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->regs[15]);
break;
case EXCP_KERNEL_TRAP:
if (do_kernel_trap(env))
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 02/25] linux-user/aarch64: Use force_sig_fault()
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
2021-09-19 1:56 ` [PATCH v3 01/25] linux-user/arm: Use force_sig_fault() Richard Henderson
@ 2021-09-19 1:56 ` Richard Henderson
2021-09-19 1:56 ` [PATCH v3 03/25] linux-user/alpha: Set TRAP_UNK for bugchk and unknown gentrap Richard Henderson
` (23 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, laurent
From: Peter Maydell <peter.maydell@linaro.org>
Use the new force_sig_fault() function instead of setting up
a target_siginfo_t and calling queue_signal().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20210813131809.28655-8-peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/cpu_loop.c | 34 +++++++++-------------------------
1 file changed, 9 insertions(+), 25 deletions(-)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 5d8675944d..11e34cb100 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
#include "qemu/guest-random.h"
#include "semihosting/common-semi.h"
#include "target/arm/syndrome.h"
@@ -77,9 +78,8 @@
void cpu_loop(CPUARMState *env)
{
CPUState *cs = env_cpu(env);
- int trapnr, ec, fsc;
+ int trapnr, ec, fsc, si_code;
abi_long ret;
- target_siginfo_t info;
for (;;) {
cpu_exec_start(cs);
@@ -108,18 +108,10 @@ void cpu_loop(CPUARMState *env)
/* just indicate that signals should be handled asap */
break;
case EXCP_UDEF:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPN;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->pc);
break;
case EXCP_PREFETCH_ABORT:
case EXCP_DATA_ABORT:
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info._sifields._sigfault._addr = env->exception.vaddress;
-
/* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
ec = syn_get_ec(env->exception.syndrome);
assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
@@ -128,28 +120,24 @@ void cpu_loop(CPUARMState *env)
fsc = extract32(env->exception.syndrome, 0, 6);
switch (fsc) {
case 0x04 ... 0x07: /* Translation fault, level {0-3} */
- info.si_code = TARGET_SEGV_MAPERR;
+ si_code = TARGET_SEGV_MAPERR;
break;
case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
- info.si_code = TARGET_SEGV_ACCERR;
+ si_code = TARGET_SEGV_ACCERR;
break;
case 0x11: /* Synchronous Tag Check Fault */
- info.si_code = TARGET_SEGV_MTESERR;
+ si_code = TARGET_SEGV_MTESERR;
break;
default:
g_assert_not_reached();
}
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGSEGV, si_code, env->exception.vaddress);
break;
case EXCP_DEBUG:
case EXCP_BKPT:
- info.si_signo = TARGET_SIGTRAP;
- info.si_errno = 0;
- info.si_code = TARGET_TRAP_BRKPT;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCP_SEMIHOST:
env->xregs[0] = do_common_semihosting(cs);
@@ -169,11 +157,7 @@ void cpu_loop(CPUARMState *env)
/* Check for MTE asynchronous faults */
if (unlikely(env->cp15.tfsr_el[0])) {
env->cp15.tfsr_el[0] = 0;
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info._sifields._sigfault._addr = 0;
- info.si_code = TARGET_SEGV_MTEAERR;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MTEAERR, 0);
}
process_pending_signals(env);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 03/25] linux-user/alpha: Set TRAP_UNK for bugchk and unknown gentrap
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
2021-09-19 1:56 ` [PATCH v3 01/25] linux-user/arm: Use force_sig_fault() Richard Henderson
2021-09-19 1:56 ` [PATCH v3 02/25] linux-user/aarch64: " Richard Henderson
@ 2021-09-19 1:56 ` Richard Henderson
2021-09-19 1:56 ` [PATCH v3 04/25] linux-user/alpha: Set FPE_FLTUNK for gentrap ROPRAND Richard Henderson
` (22 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:56 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
These si_codes were changed in 535906c684fca, for linux 4.17.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/syscall_defs.h | 1 +
linux-user/alpha/cpu_loop.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index a5ce487dcc..55ccc6ae03 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -715,6 +715,7 @@ typedef struct target_siginfo {
#define TARGET_TRAP_TRACE (2) /* process trace trap */
#define TARGET_TRAP_BRANCH (3) /* process taken branch trap */
#define TARGET_TRAP_HWBKPT (4) /* hardware breakpoint/watchpoint */
+#define TARGET_TRAP_UNK (5) /* undiagnosed trap */
struct target_rlimit {
abi_ulong rlim_cur;
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 60b650a827..13ba9bc1d4 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -91,7 +91,7 @@ void cpu_loop(CPUAlphaState *env)
/* BUGCHK */
info.si_signo = TARGET_SIGTRAP;
info.si_errno = 0;
- info.si_code = 0;
+ info.si_code = TARGET_TRAP_UNK;
info._sifields._sigfault._addr = env->pc;
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
@@ -160,7 +160,7 @@ void cpu_loop(CPUAlphaState *env)
break;
default:
info.si_signo = TARGET_SIGTRAP;
- info.si_code = 0;
+ info.si_code = TARGET_TRAP_UNK;
break;
}
info.si_errno = 0;
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 04/25] linux-user/alpha: Set FPE_FLTUNK for gentrap ROPRAND
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (2 preceding siblings ...)
2021-09-19 1:56 ` [PATCH v3 03/25] linux-user/alpha: Set TRAP_UNK for bugchk and unknown gentrap Richard Henderson
@ 2021-09-19 1:56 ` Richard Henderson
2021-09-19 1:56 ` [PATCH v3 05/25] linux-user/alpha: Use force_sig_fault Richard Henderson
` (21 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:56 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
This si_code was changed in 4cc13e4f6d441, for linux 4.17.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/alpha/cpu_loop.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 13ba9bc1d4..18698d9515 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -156,7 +156,7 @@ void cpu_loop(CPUAlphaState *env)
info.si_code = TARGET_FPE_FLTRES;
break;
case TARGET_GEN_ROPRAND:
- info.si_code = 0;
+ info.si_code = TARGET_FPE_FLTUNK;
break;
default:
info.si_signo = TARGET_SIGTRAP;
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 05/25] linux-user/alpha: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (3 preceding siblings ...)
2021-09-19 1:56 ` [PATCH v3 04/25] linux-user/alpha: Set FPE_FLTUNK for gentrap ROPRAND Richard Henderson
@ 2021-09-19 1:56 ` Richard Henderson
2021-09-19 1:56 ` [PATCH v3 06/25] linux-user/cris: " Richard Henderson
` (20 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:56 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/alpha/cpu_loop.c | 69 ++++++++++++-------------------------
1 file changed, 22 insertions(+), 47 deletions(-)
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 18698d9515..09455eff2e 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -21,12 +21,13 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
+
void cpu_loop(CPUAlphaState *env)
{
CPUState *cs = env_cpu(env);
- int trapnr;
- target_siginfo_t info;
+ int trapnr, si_code;
abi_long sysret;
while (1) {
@@ -53,26 +54,14 @@ void cpu_loop(CPUAlphaState *env)
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);
+ force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->trap_arg0);
break;
case EXCP_OPCDEC:
do_sigill:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPC;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc);
break;
case EXCP_ARITH:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- info.si_code = TARGET_FPE_FLTINV;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_FLTINV, env->pc);
break;
case EXCP_FEN:
/* No-op. Linux simply re-enables the FPU. */
@@ -81,20 +70,10 @@ void cpu_loop(CPUAlphaState *env)
switch (env->error_code) {
case 0x80:
/* BPT */
- info.si_signo = TARGET_SIGTRAP;
- info.si_errno = 0;
- info.si_code = TARGET_TRAP_BRKPT;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- break;
+ goto do_sigtrap_brkpt;
case 0x81:
/* BUGCHK */
- info.si_signo = TARGET_SIGTRAP;
- info.si_errno = 0;
- info.si_code = TARGET_TRAP_UNK;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- break;
+ goto do_sigtrap_unk;
case 0x83:
/* CALLSYS */
trapnr = env->ir[IR_V0];
@@ -135,47 +114,43 @@ void cpu_loop(CPUAlphaState *env)
abort();
case 0xAA:
/* GENTRAP */
- info.si_signo = TARGET_SIGFPE;
switch (env->ir[IR_A0]) {
case TARGET_GEN_INTOVF:
- info.si_code = TARGET_FPE_INTOVF;
+ si_code = TARGET_FPE_INTOVF;
break;
case TARGET_GEN_INTDIV:
- info.si_code = TARGET_FPE_INTDIV;
+ si_code = TARGET_FPE_INTDIV;
break;
case TARGET_GEN_FLTOVF:
- info.si_code = TARGET_FPE_FLTOVF;
+ si_code = TARGET_FPE_FLTOVF;
break;
case TARGET_GEN_FLTUND:
- info.si_code = TARGET_FPE_FLTUND;
+ si_code = TARGET_FPE_FLTUND;
break;
case TARGET_GEN_FLTINV:
- info.si_code = TARGET_FPE_FLTINV;
+ si_code = TARGET_FPE_FLTINV;
break;
case TARGET_GEN_FLTINE:
- info.si_code = TARGET_FPE_FLTRES;
+ si_code = TARGET_FPE_FLTRES;
break;
case TARGET_GEN_ROPRAND:
- info.si_code = TARGET_FPE_FLTUNK;
+ si_code = TARGET_FPE_FLTUNK;
break;
default:
- info.si_signo = TARGET_SIGTRAP;
- info.si_code = TARGET_TRAP_UNK;
- break;
+ goto do_sigtrap_unk;
}
- info.si_errno = 0;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
break;
default:
goto do_sigill;
}
break;
case EXCP_DEBUG:
- 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);
+ do_sigtrap_brkpt:
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
+ break;
+ do_sigtrap_unk:
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_UNK, env->pc);
break;
case EXCP_INTERRUPT:
/* Just indicate that signals should be handled asap. */
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 06/25] linux-user/cris: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (4 preceding siblings ...)
2021-09-19 1:56 ` [PATCH v3 05/25] linux-user/alpha: Use force_sig_fault Richard Henderson
@ 2021-09-19 1:56 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 07/25] linux-user/hppa: " Richard Henderson
` (19 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:56 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/cris/cpu_loop.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/linux-user/cris/cpu_loop.c b/linux-user/cris/cpu_loop.c
index 0de941c0b4..2637c19a46 100644
--- a/linux-user/cris/cpu_loop.c
+++ b/linux-user/cris/cpu_loop.c
@@ -21,13 +21,13 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
void cpu_loop(CPUCRISState *env)
{
CPUState *cs = env_cpu(env);
int trapnr, ret;
- target_siginfo_t info;
-
+
while (1) {
cpu_exec_start(cs);
trapnr = cpu_exec(cs);
@@ -36,8 +36,8 @@ void cpu_loop(CPUCRISState *env)
switch (trapnr) {
case EXCP_INTERRUPT:
- /* just indicate that signals should be handled asap */
- break;
+ /* just indicate that signals should be handled asap */
+ break;
case EXCP_BREAK:
ret = do_syscall(env,
env->regs[9],
@@ -55,10 +55,7 @@ void cpu_loop(CPUCRISState *env)
}
break;
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 07/25] linux-user/hppa: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (5 preceding siblings ...)
2021-09-19 1:56 ` [PATCH v3 06/25] linux-user/cris: " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 08/25] linux-user/hppa: Use the proper si_code for PRIV_OPR, PRIV_REG, OVERFLOW Richard Henderson
` (18 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/hppa/cpu_loop.c | 26 ++++++--------------------
1 file changed, 6 insertions(+), 20 deletions(-)
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index a6122b3594..c01ccbbdc0 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -20,6 +20,8 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
+
static abi_ulong hppa_lws(CPUHPPAState *env)
{
@@ -108,7 +110,6 @@ static abi_ulong hppa_lws(CPUHPPAState *env)
void cpu_loop(CPUHPPAState *env)
{
CPUState *cs = env_cpu(env);
- target_siginfo_t info;
abi_ulong ret;
int trapnr;
@@ -143,35 +144,20 @@ void cpu_loop(CPUHPPAState *env)
env->iaoq_b = env->gr[31] + 4;
break;
case EXCP_UNALIGN:
- info.si_signo = TARGET_SIGBUS;
- info.si_errno = 0;
- info.si_code = 0;
- info._sifields._sigfault._addr = env->cr[CR_IOR];
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->cr[CR_IOR]);
break;
case EXCP_ILL:
case EXCP_PRIV_OPR:
case EXCP_PRIV_REG:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPN;
- info._sifields._sigfault._addr = env->iaoq_f;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->iaoq_f);
break;
case EXCP_OVERFLOW:
case EXCP_COND:
case EXCP_ASSIST:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- info.si_code = 0;
- info._sifields._sigfault._addr = env->iaoq_f;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f);
break;
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f);
break;
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 08/25] linux-user/hppa: Use the proper si_code for PRIV_OPR, PRIV_REG, OVERFLOW
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (6 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 07/25] linux-user/hppa: " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 09/25] linux-user/hppa: Set FPE_CONDTRAP for COND Richard Henderson
` (17 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
These si_codes have been properly set by the kernel since the beginning.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/hppa/cpu_loop.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index c01ccbbdc0..10487df88c 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -147,11 +147,17 @@ void cpu_loop(CPUHPPAState *env)
force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->cr[CR_IOR]);
break;
case EXCP_ILL:
- case EXCP_PRIV_OPR:
- case EXCP_PRIV_REG:
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->iaoq_f);
break;
+ case EXCP_PRIV_OPR:
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->iaoq_f);
+ break;
+ case EXCP_PRIV_REG:
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVREG, env->iaoq_f);
+ break;
case EXCP_OVERFLOW:
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, env->iaoq_f);
+ break;
case EXCP_COND:
case EXCP_ASSIST:
force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 09/25] linux-user/hppa: Set FPE_CONDTRAP for COND
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (7 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 08/25] linux-user/hppa: Use the proper si_code for PRIV_OPR, PRIV_REG, OVERFLOW Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 10/25] linux-user/i386: Split out maybe_handle_vm86_trap Richard Henderson
` (16 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
This si_code was changed in 75abf64287cab, for linux 4.17.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/syscall_defs.h | 1 +
linux-user/hppa/cpu_loop.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 55ccc6ae03..f9efbffe0c 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -688,6 +688,7 @@ typedef struct target_siginfo {
#define TARGET_FPE_FLTINV (7) /* floating point invalid operation */
#define TARGET_FPE_FLTSUB (8) /* subscript out of range */
#define TARGET_FPE_FLTUNK (14) /* undiagnosed fp exception */
+#define TARGET_FPE_CONDTRAP (15) /* trap on condition */
#define TARGET_NSIGFPE 15
/*
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index 10487df88c..a7177ab54e 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -159,6 +159,8 @@ void cpu_loop(CPUHPPAState *env)
force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, env->iaoq_f);
break;
case EXCP_COND:
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_CONDTRAP, env->iaoq_f);
+ break;
case EXCP_ASSIST:
force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f);
break;
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 10/25] linux-user/i386: Split out maybe_handle_vm86_trap
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (8 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 09/25] linux-user/hppa: Set FPE_CONDTRAP for COND Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 11/25] linux-user/i386: Use force_sig, force_sig_fault Richard Henderson
` (15 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Reduce the number of ifdefs within cpu_loop().
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/i386/cpu_loop.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index f813e87294..5866e98441 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -195,6 +195,17 @@ static void emulate_vsyscall(CPUX86State *env)
}
#endif
+static bool maybe_handle_vm86_trap(CPUX86State *env, int trapnr)
+{
+#ifndef TARGET_X86_64
+ if (env->eflags & VM_MASK) {
+ handle_vm86_trap(env, trapnr);
+ return true;
+ }
+#endif
+ return false;
+}
+
void cpu_loop(CPUX86State *env)
{
CPUState *cs = env_cpu(env);
@@ -256,12 +267,9 @@ void cpu_loop(CPUX86State *env)
break;
case EXCP0D_GPF:
/* XXX: potential problem if ABI32 */
-#ifndef TARGET_X86_64
- if (env->eflags & VM_MASK) {
- handle_vm86_fault(env);
+ if (maybe_handle_vm86_trap(env, trapnr)) {
break;
}
-#endif
gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
break;
case EXCP0E_PAGE:
@@ -271,22 +279,16 @@ void cpu_loop(CPUX86State *env)
env->cr[2]);
break;
case EXCP00_DIVZ:
-#ifndef TARGET_X86_64
- if (env->eflags & VM_MASK) {
- handle_vm86_trap(env, trapnr);
+ if (maybe_handle_vm86_trap(env, trapnr)) {
break;
}
-#endif
gen_signal(env, TARGET_SIGFPE, TARGET_FPE_INTDIV, env->eip);
break;
case EXCP01_DB:
case EXCP03_INT3:
-#ifndef TARGET_X86_64
- if (env->eflags & VM_MASK) {
- handle_vm86_trap(env, trapnr);
+ if (maybe_handle_vm86_trap(env, trapnr)) {
break;
}
-#endif
if (trapnr == EXCP01_DB) {
gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
} else {
@@ -295,12 +297,9 @@ void cpu_loop(CPUX86State *env)
break;
case EXCP04_INTO:
case EXCP05_BOUND:
-#ifndef TARGET_X86_64
- if (env->eflags & VM_MASK) {
- handle_vm86_trap(env, trapnr);
+ if (maybe_handle_vm86_trap(env, trapnr)) {
break;
}
-#endif
gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
break;
case EXCP06_ILLOP:
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 11/25] linux-user/i386: Use force_sig, force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (9 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 10/25] linux-user/i386: Split out maybe_handle_vm86_trap Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 12/25] linux-user/m68k: Use force_sig_fault Richard Henderson
` (14 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Replace the local gen_signal with the generic functions that match
how the kernel raises signals. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/i386/cpu_loop.c | 48 +++++++++++++++-----------------------
1 file changed, 19 insertions(+), 29 deletions(-)
diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index 5866e98441..cd6c2b032d 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
/***********************************************************/
/* CPUX86 core interface */
@@ -81,17 +82,6 @@ static void set_idt(int n, unsigned int dpl)
}
#endif
-static void gen_signal(CPUX86State *env, int sig, int code, abi_ptr addr)
-{
- target_siginfo_t info = {
- .si_signo = sig,
- .si_code = code,
- ._sifields._sigfault._addr = addr
- };
-
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-}
-
#ifdef TARGET_X86_64
static bool write_ok_or_segv(CPUX86State *env, abi_ptr addr, size_t len)
{
@@ -104,7 +94,7 @@ static bool write_ok_or_segv(CPUX86State *env, abi_ptr addr, size_t len)
}
env->error_code = PG_ERROR_W_MASK | PG_ERROR_U_MASK;
- gen_signal(env, TARGET_SIGSEGV, TARGET_SEGV_MAPERR, addr);
+ force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, addr);
return false;
}
@@ -190,8 +180,7 @@ static void emulate_vsyscall(CPUX86State *env)
return;
sigsegv:
- /* Like force_sig(SIGSEGV). */
- gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
+ force_sig(TARGET_SIGSEGV);
}
#endif
@@ -263,53 +252,54 @@ void cpu_loop(CPUX86State *env)
#endif
case EXCP0B_NOSEG:
case EXCP0C_STACK:
- gen_signal(env, TARGET_SIGBUS, TARGET_SI_KERNEL, 0);
+ force_sig(TARGET_SIGBUS);
break;
case EXCP0D_GPF:
/* XXX: potential problem if ABI32 */
if (maybe_handle_vm86_trap(env, trapnr)) {
break;
}
- gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
+ force_sig(TARGET_SIGSEGV);
break;
case EXCP0E_PAGE:
- gen_signal(env, TARGET_SIGSEGV,
- (env->error_code & 1 ?
- TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR),
- env->cr[2]);
+ force_sig_fault(TARGET_SIGSEGV,
+ (env->error_code & PG_ERROR_P_MASK ?
+ TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR),
+ env->cr[2]);
break;
case EXCP00_DIVZ:
if (maybe_handle_vm86_trap(env, trapnr)) {
break;
}
- gen_signal(env, TARGET_SIGFPE, TARGET_FPE_INTDIV, env->eip);
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->eip);
break;
case EXCP01_DB:
+ if (maybe_handle_vm86_trap(env, trapnr)) {
+ break;
+ }
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
+ break;
case EXCP03_INT3:
if (maybe_handle_vm86_trap(env, trapnr)) {
break;
}
- if (trapnr == EXCP01_DB) {
- gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
- } else {
- gen_signal(env, TARGET_SIGTRAP, TARGET_SI_KERNEL, 0);
- }
+ force_sig(TARGET_SIGTRAP);
break;
case EXCP04_INTO:
case EXCP05_BOUND:
if (maybe_handle_vm86_trap(env, trapnr)) {
break;
}
- gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
+ force_sig(TARGET_SIGSEGV);
break;
case EXCP06_ILLOP:
- gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPN, env->eip);
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->eip);
break;
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
break;
case EXCP_DEBUG:
- gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, 0);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 12/25] linux-user/m68k: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (10 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 11/25] linux-user/i386: Use force_sig, force_sig_fault Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 13/25] linux-user/microblaze: " Richard Henderson
` (13 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/m68k/cpu_loop.c | 26 ++++++--------------------
1 file changed, 6 insertions(+), 20 deletions(-)
diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index 7d106aa86e..cf79a17f93 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -21,13 +21,14 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
+
void cpu_loop(CPUM68KState *env)
{
CPUState *cs = env_cpu(env);
int trapnr;
unsigned int n;
- target_siginfo_t info;
for(;;) {
cpu_exec_start(cs);
@@ -44,25 +45,13 @@ void cpu_loop(CPUM68KState *env)
case EXCP_ILLEGAL:
case EXCP_LINEA:
case EXCP_LINEF:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPN;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->pc);
break;
case EXCP_CHK:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- info.si_code = TARGET_FPE_INTOVF;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, env->pc);
break;
case EXCP_DIV0:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- info.si_code = TARGET_FPE_INTDIV;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->pc);
break;
case EXCP_TRAP0:
{
@@ -89,10 +78,7 @@ void cpu_loop(CPUM68KState *env)
/* just indicate that signals should be handled asap */
break;
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 13/25] linux-user/microblaze: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (11 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 12/25] linux-user/m68k: Use force_sig_fault Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 14/25] linux-user/microblaze: Fix SIGFPE si_codes Richard Henderson
` (12 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/microblaze/cpu_loop.c | 63 ++++++++++++++------------------
1 file changed, 27 insertions(+), 36 deletions(-)
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index 0b889a04a7..c527d21889 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -21,13 +21,14 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
+
void cpu_loop(CPUMBState *env)
{
CPUState *cs = env_cpu(env);
- int trapnr, ret;
- target_siginfo_t info;
-
+ int trapnr, ret, si_code;
+
while (1) {
cpu_exec_start(cs);
trapnr = cpu_exec(cs);
@@ -36,8 +37,8 @@ void cpu_loop(CPUMBState *env)
switch (trapnr) {
case EXCP_INTERRUPT:
- /* just indicate that signals should be handled asap */
- break;
+ /* just indicate that signals should be handled asap */
+ break;
case EXCP_SYSCALL:
/* Return address is 4 bytes after the call. */
env->regs[14] += 4;
@@ -65,6 +66,7 @@ void cpu_loop(CPUMBState *env)
*/
env->regs[14] = env->pc;
break;
+
case EXCP_HW_EXCP:
env->regs[17] = env->pc + 4;
if (env->iflags & D_FLAG) {
@@ -72,42 +74,31 @@ void cpu_loop(CPUMBState *env)
env->pc -= 4;
/* FIXME: if branch was immed, replay the imm as well. */
}
-
env->iflags &= ~(IMM_FLAG | D_FLAG);
-
switch (env->esr & 31) {
- case ESR_EC_DIVZERO:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- info.si_code = TARGET_FPE_FLTDIV;
- info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- break;
- case ESR_EC_FPU:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- if (env->fsr & FSR_IO) {
- info.si_code = TARGET_FPE_FLTINV;
- }
- if (env->fsr & FSR_DZ) {
- info.si_code = TARGET_FPE_FLTDIV;
- }
- info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- break;
- default:
- fprintf(stderr, "Unhandled hw-exception: 0x%x\n",
- env->esr & ESR_EC_MASK);
- cpu_dump_state(cs, stderr, 0);
- exit(EXIT_FAILURE);
- break;
+ case ESR_EC_DIVZERO:
+ si_code = TARGET_FPE_FLTDIV;
+ break;
+ case ESR_EC_FPU:
+ si_code = 0;
+ if (env->fsr & FSR_IO) {
+ si_code = TARGET_FPE_FLTINV;
+ }
+ if (env->fsr & FSR_DZ) {
+ si_code = TARGET_FPE_FLTDIV;
+ }
+ break;
+ default:
+ fprintf(stderr, "Unhandled hw-exception: 0x%x\n",
+ env->esr & ESR_EC_MASK);
+ cpu_dump_state(cs, stderr, 0);
+ exit(EXIT_FAILURE);
}
+ force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
break;
+
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 14/25] linux-user/microblaze: Fix SIGFPE si_codes
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (12 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 13/25] linux-user/microblaze: " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 15/25] linux-user/mips: Improve do_break Richard Henderson
` (11 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Fix a typo for ESR_EC_DIVZERO, which is integral not floating-point.
Fix the if ladder for decoding floating-point exceptions.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/microblaze/cpu_loop.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index c527d21889..74b2a9fc43 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -77,15 +77,25 @@ void cpu_loop(CPUMBState *env)
env->iflags &= ~(IMM_FLAG | D_FLAG);
switch (env->esr & 31) {
case ESR_EC_DIVZERO:
- si_code = TARGET_FPE_FLTDIV;
+ si_code = TARGET_FPE_INTDIV;
break;
case ESR_EC_FPU:
- si_code = 0;
- if (env->fsr & FSR_IO) {
+ /*
+ * Note that the kernel passes along fsr as si_code
+ * if there's no recognized bit set. Possibly this
+ * implies that si_code is 0, but follow the structure.
+ */
+ si_code = env->fsr;
+ if (si_code & FSR_IO) {
si_code = TARGET_FPE_FLTINV;
- }
- if (env->fsr & FSR_DZ) {
+ } else if (si_code & FSR_OF) {
+ si_code = TARGET_FPE_FLTOVF;
+ } else if (si_code & FSR_UF) {
+ si_code = TARGET_FPE_FLTUND;
+ } else if (si_code & FSR_DZ) {
si_code = TARGET_FPE_FLTDIV;
+ } else if (si_code & FSR_DO) {
+ si_code = TARGET_FPE_FLTRES;
}
break;
default:
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 15/25] linux-user/mips: Improve do_break
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (13 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 14/25] linux-user/microblaze: Fix SIGFPE si_codes Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 16/25] linux-user/mips: Use force_sig_fault Richard Henderson
` (10 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Rename to do_tr_or_bp, as per the kernel function.
Add a 'trap' argument, akin to the kernel's si_code, but clearer.
The return value is always 0, so change the return value to void.
Use force_sig and force_sig_fault.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/mips/cpu_loop.c | 47 ++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index 40825ca566..a330dc03db 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
#include "elf.h"
#include "internal.h"
#include "fpu_helper.h"
@@ -38,29 +39,25 @@ enum {
BRK_DIVZERO = 7
};
-static int do_break(CPUMIPSState *env, target_siginfo_t *info,
- unsigned int code)
+static void do_tr_or_bp(CPUMIPSState *env, unsigned int code, bool trap)
{
- int ret = -1;
+ target_ulong pc = env->active_tc.PC;
switch (code) {
case BRK_OVERFLOW:
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, pc);
+ break;
case BRK_DIVZERO:
- info->si_signo = TARGET_SIGFPE;
- info->si_errno = 0;
- info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
- queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
- ret = 0;
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, pc);
break;
default:
- info->si_signo = TARGET_SIGTRAP;
- info->si_errno = 0;
- queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
- ret = 0;
+ if (trap) {
+ force_sig(TARGET_SIGTRAP);
+ } else {
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, pc);
+ }
break;
}
-
- return ret;
}
void cpu_loop(CPUMIPSState *env)
@@ -203,6 +200,13 @@ done_syscall:
abi_ulong trap_instr;
unsigned int code;
+ /*
+ * FIXME: It would be better to decode the trap number
+ * during translate, and store it in error_code while
+ * raising the exception. We should not be re-reading
+ * the opcode here.
+ */
+
if (env->hflags & MIPS_HFLAG_M16) {
if (env->insn_flags & ASE_MICROMIPS) {
/* microMIPS mode */
@@ -255,9 +259,7 @@ done_syscall:
}
}
- if (do_break(env, &info, code) != 0) {
- goto error;
- }
+ do_tr_or_bp(env, code, false);
}
break;
case EXCP_TRAP:
@@ -265,6 +267,13 @@ done_syscall:
abi_ulong trap_instr;
unsigned int code = 0;
+ /*
+ * FIXME: It would be better to decode the trap number
+ * during translate, and store it in error_code while
+ * raising the exception. We should not be re-reading
+ * the opcode here.
+ */
+
if (env->hflags & MIPS_HFLAG_M16) {
/* microMIPS mode */
abi_ulong instr[2];
@@ -291,9 +300,7 @@ done_syscall:
}
}
- if (do_break(env, &info, code) != 0) {
- goto error;
- }
+ do_tr_or_bp(env, code, true);
}
break;
case EXCP_ATOMIC:
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 16/25] linux-user/mips: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (14 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 15/25] linux-user/mips: Improve do_break Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 17/25] target/mips: Extract break code into env->error_code Richard Henderson
` (9 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/mips/cpu_loop.c | 38 +++++++++++++-------------------------
1 file changed, 13 insertions(+), 25 deletions(-)
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index a330dc03db..e9d9208e83 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -63,8 +63,7 @@ static void do_tr_or_bp(CPUMIPSState *env, unsigned int code, bool trap)
void cpu_loop(CPUMIPSState *env)
{
CPUState *cs = env_cpu(env);
- target_siginfo_t info;
- int trapnr;
+ int trapnr, si_code;
abi_long ret;
# ifdef TARGET_ABI_MIPSO32
unsigned int syscall_num;
@@ -155,43 +154,32 @@ done_syscall:
break;
case EXCP_CpU:
case EXCP_RI:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = 0;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ case EXCP_DSPDIS:
+ force_sig(TARGET_SIGILL);
break;
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
break;
case EXCP_DEBUG:
- 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);
- break;
- case EXCP_DSPDIS:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPC;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT,
+ env->active_tc.PC);
break;
case EXCP_FPE:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- info.si_code = TARGET_FPE_FLTUNK;
+ si_code = TARGET_FPE_FLTUNK;
if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID) {
- info.si_code = TARGET_FPE_FLTINV;
+ si_code = TARGET_FPE_FLTINV;
} else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_DIV0) {
- info.si_code = TARGET_FPE_FLTDIV;
+ si_code = TARGET_FPE_FLTDIV;
} else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_OVERFLOW) {
- info.si_code = TARGET_FPE_FLTOVF;
+ si_code = TARGET_FPE_FLTOVF;
} else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_UNDERFLOW) {
- info.si_code = TARGET_FPE_FLTUND;
+ si_code = TARGET_FPE_FLTUND;
} else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INEXACT) {
- info.si_code = TARGET_FPE_FLTRES;
+ si_code = TARGET_FPE_FLTRES;
}
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGFPE, si_code, env->active_tc.PC);
break;
+
/* The code below was inspired by the MIPS Linux kernel trap
* handling code in arch/mips/kernel/traps.c.
*/
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 17/25] target/mips: Extract break code into env->error_code
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (15 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 16/25] linux-user/mips: Use force_sig_fault Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 18/25] target/mips: Extract trap " Richard Henderson
` (8 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Simplify cpu_loop by doing all of the decode in translate.
This fixes a bug in that cpu_loop was not handling the
different layout of the R6 version of break16. This fixes
a bug in that cpu_loop extracted the wrong bits for the
mips16e break16 instruction.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/mips/tcg/translate.h | 1 +
linux-user/mips/cpu_loop.c | 73 +++--------------------
target/mips/tcg/translate.c | 12 +++-
target/mips/tcg/micromips_translate.c.inc | 6 +-
target/mips/tcg/mips16e_translate.c.inc | 2 +-
5 files changed, 25 insertions(+), 69 deletions(-)
diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
index 6111493651..ae01515efe 100644
--- a/target/mips/tcg/translate.h
+++ b/target/mips/tcg/translate.h
@@ -129,6 +129,7 @@ enum {
void generate_exception(DisasContext *ctx, int excp);
void generate_exception_err(DisasContext *ctx, int excp, int err);
void generate_exception_end(DisasContext *ctx, int excp);
+void generate_exception_break(DisasContext *ctx, int code);
void gen_reserved_instruction(DisasContext *ctx);
void check_insn(DisasContext *ctx, uint64_t flags);
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index e9d9208e83..c105b00eac 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -64,6 +64,7 @@ void cpu_loop(CPUMIPSState *env)
{
CPUState *cs = env_cpu(env);
int trapnr, si_code;
+ unsigned int code;
abi_long ret;
# ifdef TARGET_ABI_MIPSO32
unsigned int syscall_num;
@@ -184,71 +185,15 @@ done_syscall:
* handling code in arch/mips/kernel/traps.c.
*/
case EXCP_BREAK:
- {
- abi_ulong trap_instr;
- unsigned int code;
-
- /*
- * FIXME: It would be better to decode the trap number
- * during translate, and store it in error_code while
- * raising the exception. We should not be re-reading
- * the opcode here.
- */
-
- if (env->hflags & MIPS_HFLAG_M16) {
- if (env->insn_flags & ASE_MICROMIPS) {
- /* microMIPS mode */
- ret = get_user_u16(trap_instr, env->active_tc.PC);
- if (ret != 0) {
- goto error;
- }
-
- if ((trap_instr >> 10) == 0x11) {
- /* 16-bit instruction */
- code = trap_instr & 0xf;
- } else {
- /* 32-bit instruction */
- abi_ulong instr_lo;
-
- ret = get_user_u16(instr_lo,
- env->active_tc.PC + 2);
- if (ret != 0) {
- goto error;
- }
- trap_instr = (trap_instr << 16) | instr_lo;
- code = ((trap_instr >> 6) & ((1 << 20) - 1));
- /* Unfortunately, microMIPS also suffers from
- the old assembler bug... */
- if (code >= (1 << 10)) {
- code >>= 10;
- }
- }
- } else {
- /* MIPS16e mode */
- ret = get_user_u16(trap_instr, env->active_tc.PC);
- if (ret != 0) {
- goto error;
- }
- code = (trap_instr >> 6) & 0x3f;
- }
- } else {
- ret = get_user_u32(trap_instr, env->active_tc.PC);
- if (ret != 0) {
- goto error;
- }
-
- /* As described in the original Linux kernel code, the
- * below checks on 'code' are to work around an old
- * assembly bug.
- */
- code = ((trap_instr >> 6) & ((1 << 20) - 1));
- if (code >= (1 << 10)) {
- code >>= 10;
- }
- }
-
- do_tr_or_bp(env, code, false);
+ /*
+ * As described in the original Linux kernel code, the below
+ * checks on 'code' are to work around an old assembly bug.
+ */
+ code = env->error_code;
+ if (code >= (1 << 10)) {
+ code >>= 10;
}
+ do_tr_or_bp(env, code, false);
break;
case EXCP_TRAP:
{
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 148afec9dc..e17bcd24db 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1367,6 +1367,16 @@ void generate_exception_end(DisasContext *ctx, int excp)
generate_exception_err(ctx, excp, 0);
}
+void generate_exception_break(DisasContext *ctx, int code)
+{
+#ifdef CONFIG_USER_ONLY
+ /* Pass the break code along to cpu_loop. */
+ tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
+ offsetof(CPUMIPSState, error_code));
+#endif
+ generate_exception_end(ctx, EXCP_BREAK);
+}
+
void gen_reserved_instruction(DisasContext *ctx)
{
generate_exception_end(ctx, EXCP_RI);
@@ -14176,7 +14186,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
generate_exception_end(ctx, EXCP_SYSCALL);
break;
case OPC_BREAK:
- generate_exception_end(ctx, EXCP_BREAK);
+ generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
break;
case OPC_SYNC:
check_insn(ctx, ISA_MIPS2);
diff --git a/target/mips/tcg/micromips_translate.c.inc b/target/mips/tcg/micromips_translate.c.inc
index 0da4c802a3..f91f7a96cd 100644
--- a/target/mips/tcg/micromips_translate.c.inc
+++ b/target/mips/tcg/micromips_translate.c.inc
@@ -822,7 +822,7 @@ static void gen_pool16c_insn(DisasContext *ctx)
gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
break;
case BREAK16:
- generate_exception_end(ctx, EXCP_BREAK);
+ generate_exception_break(ctx, extract32(ctx->opcode, 0, 4));
break;
case SDBBP16:
if (is_uhi(extract32(ctx->opcode, 0, 4))) {
@@ -937,7 +937,7 @@ static void gen_pool16c_r6_insn(DisasContext *ctx)
break;
case R6_BREAK16:
/* BREAK16 */
- generate_exception(ctx, EXCP_BREAK);
+ generate_exception_break(ctx, extract32(ctx->opcode, 6, 4));
break;
case R6_SDBBP16:
/* SDBBP16 */
@@ -1812,7 +1812,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
gen_pool32axf(env, ctx, rt, rs);
break;
case BREAK32:
- generate_exception_end(ctx, EXCP_BREAK);
+ generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
break;
case SIGRIE:
check_insn(ctx, ISA_MIPS_R6);
diff --git a/target/mips/tcg/mips16e_translate.c.inc b/target/mips/tcg/mips16e_translate.c.inc
index 84d816603a..f57e0a5f2a 100644
--- a/target/mips/tcg/mips16e_translate.c.inc
+++ b/target/mips/tcg/mips16e_translate.c.inc
@@ -969,7 +969,7 @@ static int decode_ase_mips16e(CPUMIPSState *env, DisasContext *ctx)
gen_slt(ctx, OPC_SLTU, 24, rx, ry);
break;
case RR_BREAK:
- generate_exception_end(ctx, EXCP_BREAK);
+ generate_exception_break(ctx, extract32(ctx->opcode, 5, 6));
break;
case RR_SLLV:
gen_shift(ctx, OPC_SLLV, ry, rx, ry);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 18/25] target/mips: Extract trap code into env->error_code
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (16 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 17/25] target/mips: Extract break code into env->error_code Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 19/25] linux-user/openrisc: Use force_sig_fault Richard Henderson
` (7 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Simplify cpu_loop by doing all of the decode in translate.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/mips/cpu_loop.c | 41 +----------------------
target/mips/tcg/translate.c | 24 ++++++++++---
target/mips/tcg/micromips_translate.c.inc | 4 +--
target/mips/tcg/nanomips_translate.c.inc | 4 +--
4 files changed, 25 insertions(+), 48 deletions(-)
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index c105b00eac..c02403d8f6 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -196,51 +196,12 @@ done_syscall:
do_tr_or_bp(env, code, false);
break;
case EXCP_TRAP:
- {
- abi_ulong trap_instr;
- unsigned int code = 0;
-
- /*
- * FIXME: It would be better to decode the trap number
- * during translate, and store it in error_code while
- * raising the exception. We should not be re-reading
- * the opcode here.
- */
-
- if (env->hflags & MIPS_HFLAG_M16) {
- /* microMIPS mode */
- abi_ulong instr[2];
-
- ret = get_user_u16(instr[0], env->active_tc.PC) ||
- get_user_u16(instr[1], env->active_tc.PC + 2);
-
- trap_instr = (instr[0] << 16) | instr[1];
- } else {
- ret = get_user_u32(trap_instr, env->active_tc.PC);
- }
-
- if (ret != 0) {
- goto error;
- }
-
- /* The immediate versions don't provide a code. */
- if (!(trap_instr & 0xFC000000)) {
- if (env->hflags & MIPS_HFLAG_M16) {
- /* microMIPS mode */
- code = ((trap_instr >> 12) & ((1 << 4) - 1));
- } else {
- code = ((trap_instr >> 6) & ((1 << 10) - 1));
- }
- }
-
- do_tr_or_bp(env, code, true);
- }
+ do_tr_or_bp(env, env->error_code, true);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
break;
default:
-error:
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index e17bcd24db..6bb631e74a 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -4733,7 +4733,7 @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
/* Traps */
static void gen_trap(DisasContext *ctx, uint32_t opc,
- int rs, int rt, int16_t imm)
+ int rs, int rt, int16_t imm, int code)
{
int cond;
TCGv t0 = tcg_temp_new();
@@ -4778,6 +4778,11 @@ static void gen_trap(DisasContext *ctx, uint32_t opc,
case OPC_TGEU: /* rs >= rs unsigned */
case OPC_TGEIU: /* r0 >= 0 unsigned */
/* Always trap */
+#ifdef CONFIG_USER_ONLY
+ /* Pass the break code along to cpu_loop. */
+ tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
+ offsetof(CPUMIPSState, error_code));
+#endif
generate_exception_end(ctx, EXCP_TRAP);
break;
case OPC_TLT: /* rs < rs */
@@ -4818,6 +4823,18 @@ static void gen_trap(DisasContext *ctx, uint32_t opc,
tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
break;
}
+#ifdef CONFIG_USER_ONLY
+ /* Pass the break code along to cpu_loop. */
+ tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
+ offsetof(CPUMIPSState, error_code));
+#endif
+ /* Like save_cpu_state, only don't update saved values. */
+ if (ctx->base.pc_next != ctx->saved_pc) {
+ gen_save_pc(ctx->base.pc_next);
+ }
+ if (ctx->hflags != ctx->saved_hflags) {
+ tcg_gen_movi_i32(hflags, ctx->hflags);
+ }
generate_exception(ctx, EXCP_TRAP);
gen_set_label(l1);
}
@@ -14171,7 +14188,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
case OPC_TEQ:
case OPC_TNE:
check_insn(ctx, ISA_MIPS2);
- gen_trap(ctx, op1, rs, rt, -1);
+ gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
break;
case OPC_PMON:
/* Pmon entry point, also R4010 selsl */
@@ -15305,11 +15322,10 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
case OPC_TLTI:
case OPC_TLTIU:
case OPC_TEQI:
-
case OPC_TNEI:
check_insn(ctx, ISA_MIPS2);
check_insn_opc_removed(ctx, ISA_MIPS_R6);
- gen_trap(ctx, op1, rs, -1, imm);
+ gen_trap(ctx, op1, rs, -1, imm, 0);
break;
case OPC_SIGRIE:
check_insn(ctx, ISA_MIPS_R6);
diff --git a/target/mips/tcg/micromips_translate.c.inc b/target/mips/tcg/micromips_translate.c.inc
index f91f7a96cd..7e7d26a91b 100644
--- a/target/mips/tcg/micromips_translate.c.inc
+++ b/target/mips/tcg/micromips_translate.c.inc
@@ -1047,7 +1047,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
case TNE:
mips32_op = OPC_TNE;
do_trap:
- gen_trap(ctx, mips32_op, rs, rt, -1);
+ gen_trap(ctx, mips32_op, rs, rt, -1, extract32(ctx->opcode, 12, 4));
break;
#ifndef CONFIG_USER_ONLY
case MFC0:
@@ -2439,7 +2439,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
check_insn_opc_removed(ctx, ISA_MIPS_R6);
mips32_op = OPC_TEQI;
do_trapi:
- gen_trap(ctx, mips32_op, rs, -1, imm);
+ gen_trap(ctx, mips32_op, rs, -1, imm, 0);
break;
case BNEZC:
diff --git a/target/mips/tcg/nanomips_translate.c.inc b/target/mips/tcg/nanomips_translate.c.inc
index ccbcecad09..2432c747df 100644
--- a/target/mips/tcg/nanomips_translate.c.inc
+++ b/target/mips/tcg/nanomips_translate.c.inc
@@ -1268,11 +1268,11 @@ static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
switch (extract32(ctx->opcode, 10, 1)) {
case NM_TEQ:
check_nms(ctx);
- gen_trap(ctx, OPC_TEQ, rs, rt, -1);
+ gen_trap(ctx, OPC_TEQ, rs, rt, -1, rd);
break;
case NM_TNE:
check_nms(ctx);
- gen_trap(ctx, OPC_TNE, rs, rt, -1);
+ gen_trap(ctx, OPC_TNE, rs, rt, -1, rd);
break;
}
break;
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 19/25] linux-user/openrisc: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (17 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 18/25] target/mips: Extract trap " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 20/25] linux-user/ppc: " Richard Henderson
` (6 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/openrisc/cpu_loop.c | 18 +++---------------
1 file changed, 3 insertions(+), 15 deletions(-)
diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index 5e50c0d743..9f8dd0afd6 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -28,7 +28,6 @@ void cpu_loop(CPUOpenRISCState *env)
CPUState *cs = env_cpu(env);
int trapnr;
abi_long ret;
- target_siginfo_t info;
for (;;) {
cpu_exec_start(cs);
@@ -59,27 +58,16 @@ void cpu_loop(CPUOpenRISCState *env)
force_sig(TARGET_SIGSEGV);
break;
case EXCP_ALIGN:
- info.si_signo = TARGET_SIGBUS;
- info.si_errno = 0;
- info.si_code = TARGET_BUS_ADRALN;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->eear);
break;
case EXCP_ILLEGAL:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPC;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc);
break;
case EXCP_INTERRUPT:
/* We processed the pending cpu work above. */
break;
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 20/25] linux-user/ppc: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (18 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 19/25] linux-user/openrisc: Use force_sig_fault Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 21/25] linux-user/riscv: " Richard Henderson
` (5 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
The fault address for POWERPC_EXCP_ISI is nip exactly, not nip - 4.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/ppc/cpu_loop.c | 146 +++++++++-----------------------------
1 file changed, 34 insertions(+), 112 deletions(-)
diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index fa91ea0eed..2b006317ba 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -21,6 +21,8 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
+
static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
{
@@ -74,8 +76,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
void cpu_loop(CPUPPCState *env)
{
CPUState *cs = env_cpu(env);
- target_siginfo_t info;
- int trapnr;
+ int trapnr, si_signo, si_code;
target_ulong ret;
for(;;) {
@@ -100,61 +101,14 @@ void cpu_loop(CPUPPCState *env)
"Aborting\n");
break;
case POWERPC_EXCP_DSI: /* Data storage exception */
- /* XXX: check this. Seems bugged */
- switch (env->error_code & 0xFF000000) {
- case 0x40000000:
- case 0x42000000:
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SEGV_MAPERR;
- break;
- case 0x04000000:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLADR;
- break;
- case 0x08000000:
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SEGV_ACCERR;
- break;
- default:
- /* Let's send a regular segfault... */
- EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
- env->error_code);
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SEGV_MAPERR;
- break;
- }
- info._sifields._sigfault._addr = env->spr[SPR_DAR];
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ /* FIXME: handle maperr in ppc_cpu_record_sigsegv. */
+ force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
+ env->spr[SPR_DAR]);
break;
case POWERPC_EXCP_ISI: /* Instruction storage exception */
- /* XXX: check this */
- switch (env->error_code & 0xFF000000) {
- case 0x40000000:
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SEGV_MAPERR;
- break;
- case 0x10000000:
- case 0x08000000:
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SEGV_ACCERR;
- break;
- default:
- /* Let's send a regular segfault... */
- EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
- env->error_code);
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SEGV_MAPERR;
- break;
- }
- info._sifields._sigfault._addr = env->nip - 4;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ /* FIXME: handle maperr in ppc_cpu_record_sigsegv. */
+ force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
+ env->spr[SPR_DAR]);
break;
case POWERPC_EXCP_EXTERNAL: /* External input */
cpu_abort(cs, "External interrupt while in user mode. "
@@ -162,35 +116,30 @@ void cpu_loop(CPUPPCState *env)
break;
case POWERPC_EXCP_ALIGN: /* Alignment exception */
/* XXX: check this */
- info.si_signo = TARGET_SIGBUS;
- info.si_errno = 0;
- info.si_code = TARGET_BUS_ADRALN;
- info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->nip);
break;
case POWERPC_EXCP_PROGRAM: /* Program exception */
case POWERPC_EXCP_HV_EMU: /* HV emulation */
/* XXX: check this */
switch (env->error_code & ~0xF) {
case POWERPC_EXCP_FP:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
+ si_signo = TARGET_SIGFPE;
switch (env->error_code & 0xF) {
case POWERPC_EXCP_FP_OX:
- info.si_code = TARGET_FPE_FLTOVF;
+ si_code = TARGET_FPE_FLTOVF;
break;
case POWERPC_EXCP_FP_UX:
- info.si_code = TARGET_FPE_FLTUND;
+ si_code = TARGET_FPE_FLTUND;
break;
case POWERPC_EXCP_FP_ZX:
case POWERPC_EXCP_FP_VXZDZ:
- info.si_code = TARGET_FPE_FLTDIV;
+ si_code = TARGET_FPE_FLTDIV;
break;
case POWERPC_EXCP_FP_XX:
- info.si_code = TARGET_FPE_FLTRES;
+ si_code = TARGET_FPE_FLTRES;
break;
case POWERPC_EXCP_FP_VXSOFT:
- info.si_code = TARGET_FPE_FLTINV;
+ si_code = TARGET_FPE_FLTINV;
break;
case POWERPC_EXCP_FP_VXSNAN:
case POWERPC_EXCP_FP_VXISI:
@@ -199,51 +148,50 @@ void cpu_loop(CPUPPCState *env)
case POWERPC_EXCP_FP_VXVC:
case POWERPC_EXCP_FP_VXSQRT:
case POWERPC_EXCP_FP_VXCVI:
- info.si_code = TARGET_FPE_FLTSUB;
+ si_code = TARGET_FPE_FLTSUB;
break;
default:
EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
env->error_code);
+ si_code = 0;
break;
}
break;
case POWERPC_EXCP_INVAL:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
+ si_signo = TARGET_SIGILL;
switch (env->error_code & 0xF) {
case POWERPC_EXCP_INVAL_INVAL:
- info.si_code = TARGET_ILL_ILLOPC;
+ si_code = TARGET_ILL_ILLOPC;
break;
case POWERPC_EXCP_INVAL_LSWX:
- info.si_code = TARGET_ILL_ILLOPN;
+ si_code = TARGET_ILL_ILLOPN;
break;
case POWERPC_EXCP_INVAL_SPR:
- info.si_code = TARGET_ILL_PRVREG;
+ si_code = TARGET_ILL_PRVREG;
break;
case POWERPC_EXCP_INVAL_FP:
- info.si_code = TARGET_ILL_COPROC;
+ si_code = TARGET_ILL_COPROC;
break;
default:
EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
env->error_code & 0xF);
- info.si_code = TARGET_ILL_ILLADR;
+ si_code = TARGET_ILL_ILLADR;
break;
}
break;
case POWERPC_EXCP_PRIV:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
+ si_signo = TARGET_SIGILL;
switch (env->error_code & 0xF) {
case POWERPC_EXCP_PRIV_OPC:
- info.si_code = TARGET_ILL_PRVOPC;
+ si_code = TARGET_ILL_PRVOPC;
break;
case POWERPC_EXCP_PRIV_REG:
- info.si_code = TARGET_ILL_PRVREG;
+ si_code = TARGET_ILL_PRVREG;
break;
default:
EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
env->error_code & 0xF);
- info.si_code = TARGET_ILL_PRVOPC;
+ si_code = TARGET_ILL_PRVOPC;
break;
}
break;
@@ -256,28 +204,19 @@ void cpu_loop(CPUPPCState *env)
env->error_code);
break;
}
- info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(si_signo, si_code, env->nip);
break;
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_COPROC;
- info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
+ case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
+ case POWERPC_EXCP_VPU: /* Vector unavailable exception */
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_COPROC, env->nip);
break;
case POWERPC_EXCP_SYSCALL: /* System call exception */
case POWERPC_EXCP_SYSCALL_VECTORED:
cpu_abort(cs, "Syscall exception while in user mode. "
"Aborting\n");
break;
- case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_COPROC;
- info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- break;
case POWERPC_EXCP_DECR: /* Decrementer exception */
cpu_abort(cs, "Decrementer interrupt while in user mode. "
"Aborting\n");
@@ -298,13 +237,6 @@ void cpu_loop(CPUPPCState *env)
cpu_abort(cs, "Instruction TLB exception while in user mode. "
"Aborting\n");
break;
- case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_COPROC;
- info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- break;
case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
break;
@@ -361,13 +293,6 @@ void cpu_loop(CPUPPCState *env)
cpu_abort(cs, "Hypervisor instruction segment exception "
"while in user mode. Aborting\n");
break;
- case POWERPC_EXCP_VPU: /* Vector unavailable exception */
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_COPROC;
- info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- break;
case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
cpu_abort(cs, "Programmable interval timer interrupt "
"while in user mode. Aborting\n");
@@ -450,10 +375,7 @@ void cpu_loop(CPUPPCState *env)
env->gpr[3] = ret;
break;
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->nip);
break;
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 21/25] linux-user/riscv: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (19 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 20/25] linux-user/ppc: " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 22/25] linux-user/s390x: " Richard Henderson
` (4 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/riscv/cpu_loop.c | 32 ++++++--------------------------
1 file changed, 6 insertions(+), 26 deletions(-)
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 49fa2209a7..9912796ebf 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -22,14 +22,14 @@
#include "qemu/error-report.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
#include "elf.h"
#include "semihosting/common-semi.h"
void cpu_loop(CPURISCVState *env)
{
CPUState *cs = env_cpu(env);
- int trapnr, signum, sigcode;
- target_ulong sigaddr;
+ int trapnr;
target_ulong ret;
for (;;) {
@@ -38,10 +38,6 @@ void cpu_loop(CPURISCVState *env)
cpu_exec_end(cs);
process_queued_cpu_work(cs);
- signum = 0;
- sigcode = 0;
- sigaddr = 0;
-
switch (trapnr) {
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
@@ -77,39 +73,23 @@ void cpu_loop(CPURISCVState *env)
}
break;
case RISCV_EXCP_ILLEGAL_INST:
- signum = TARGET_SIGILL;
- sigcode = TARGET_ILL_ILLOPC;
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc);
break;
case RISCV_EXCP_BREAKPOINT:
- signum = TARGET_SIGTRAP;
- sigcode = TARGET_TRAP_BRKPT;
- sigaddr = env->pc;
+ case EXCP_DEBUG:
+ gdbstep:
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case RISCV_EXCP_SEMIHOST:
env->gpr[xA0] = do_common_semihosting(cs);
env->pc += 4;
break;
- case EXCP_DEBUG:
- gdbstep:
- signum = TARGET_SIGTRAP;
- sigcode = TARGET_TRAP_BRKPT;
- break;
default:
EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
trapnr);
exit(EXIT_FAILURE);
}
- if (signum) {
- target_siginfo_t info = {
- .si_signo = signum,
- .si_errno = 0,
- .si_code = sigcode,
- ._sifields._sigfault._addr = sigaddr
- };
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- }
-
process_pending_signals(env);
}
}
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 22/25] linux-user/s390x: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (20 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 21/25] linux-user/riscv: " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 23/25] linux-user/sh4: " Richard Henderson
` (3 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/s390x/cpu_loop.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c
index 7a1d032227..cc034b860e 100644
--- a/linux-user/s390x/cpu_loop.c
+++ b/linux-user/s390x/cpu_loop.c
@@ -57,7 +57,6 @@ void cpu_loop(CPUS390XState *env)
{
CPUState *cs = env_cpu(env);
int trapnr, n, sig;
- target_siginfo_t info;
target_ulong addr;
abi_long ret;
@@ -157,11 +156,7 @@ void cpu_loop(CPUS390XState *env)
*/
env->psw.addr += env->int_pgm_ilen;
do_signal:
- info.si_signo = sig;
- info.si_errno = 0;
- info.si_code = n;
- info._sifields._sigfault._addr = addr;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(sig, n, addr);
break;
case EXCP_ATOMIC:
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 23/25] linux-user/sh4: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (21 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 22/25] linux-user/s390x: " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 24/25] linux-user/sparc: " Richard Henderson
` (2 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/sh4/cpu_loop.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c
index 8408d0c42d..3d0dd6d34e 100644
--- a/linux-user/sh4/cpu_loop.c
+++ b/linux-user/sh4/cpu_loop.c
@@ -21,12 +21,13 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
+
void cpu_loop(CPUSH4State *env)
{
CPUState *cs = env_cpu(env);
int trapnr, ret;
- target_siginfo_t info;
while (1) {
bool arch_interrupt = true;
@@ -58,10 +59,7 @@ void cpu_loop(CPUSH4State *env)
/* just indicate that signals should be handled asap */
break;
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 24/25] linux-user/sparc: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (22 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 23/25] linux-user/sh4: " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 1:57 ` [PATCH v3 25/25] linux-user/xtensa: " Richard Henderson
2021-09-19 16:34 ` [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/sparc/cpu_loop.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index f5e0de7eaf..414cc95740 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
#define SPARC64_STACK_BIAS 2047
@@ -153,7 +154,6 @@ void cpu_loop (CPUSPARCState *env)
CPUState *cs = env_cpu(env);
int trapnr;
abi_long ret;
- target_siginfo_t info;
while (1) {
cpu_exec_start(cs);
@@ -239,19 +239,10 @@ void cpu_loop (CPUSPARCState *env)
/* just indicate that signals should be handled asap */
break;
case TT_ILL_INSN:
- {
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPC;
- info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- }
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->pc);
break;
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 25/25] linux-user/xtensa: Use force_sig_fault
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (23 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 24/25] linux-user/sparc: " Richard Henderson
@ 2021-09-19 1:57 ` Richard Henderson
2021-09-19 16:34 ` [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 1:57 UTC (permalink / raw)
To: qemu-devel; +Cc: laurent
Use the new function instead of setting up a target_siginfo_t
and calling queue_signal. Fill in the missing PC for SIGTRAP.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/xtensa/cpu_loop.c | 28 +++++++++++-----------------
1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/linux-user/xtensa/cpu_loop.c b/linux-user/xtensa/cpu_loop.c
index b48781c6e8..7392e83c9b 100644
--- a/linux-user/xtensa/cpu_loop.c
+++ b/linux-user/xtensa/cpu_loop.c
@@ -20,6 +20,8 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "signal-common.h"
+
static void xtensa_rfw(CPUXtensaState *env)
{
@@ -124,7 +126,6 @@ static void xtensa_underflow12(CPUXtensaState *env)
void cpu_loop(CPUXtensaState *env)
{
CPUState *cs = env_cpu(env);
- target_siginfo_t info;
abi_ulong ret;
int trapnr;
@@ -161,14 +162,12 @@ void cpu_loop(CPUXtensaState *env)
case EXC_USER:
switch (env->sregs[EXCCAUSE]) {
case ILLEGAL_INSTRUCTION_CAUSE:
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC,
+ env->sregs[EPC1]);
+ break;
case PRIVILEGED_CAUSE:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code =
- env->sregs[EXCCAUSE] == ILLEGAL_INSTRUCTION_CAUSE ?
- TARGET_ILL_ILLOPC : TARGET_ILL_PRVOPC;
- info._sifields._sigfault._addr = env->sregs[EPC1];
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC,
+ env->sregs[EPC1]);
break;
case SYSCALL_CAUSE:
@@ -217,11 +216,8 @@ void cpu_loop(CPUXtensaState *env)
break;
case INTEGER_DIVIDE_BY_ZERO_CAUSE:
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- info.si_code = TARGET_FPE_INTDIV;
- info._sifields._sigfault._addr = env->sregs[EPC1];
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV,
+ env->sregs[EPC1]);
break;
default:
@@ -230,10 +226,8 @@ void cpu_loop(CPUXtensaState *env)
}
break;
case EXCP_DEBUG:
- 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);
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT,
+ env->sregs[EPC1]);
break;
case EXC_DEBUG:
default:
--
2.25.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH v3 00/25] linux-user: Clean up siginfo_t handling
2021-09-19 1:56 [PATCH v3 00/25] linux-user: Clean up siginfo_t handling Richard Henderson
` (24 preceding siblings ...)
2021-09-19 1:57 ` [PATCH v3 25/25] linux-user/xtensa: " Richard Henderson
@ 2021-09-19 16:34 ` Richard Henderson
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2021-09-19 16:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, laurent, Philippe Mathieu-Daudé
On 9/18/21 6:56 PM, Richard Henderson wrote:
> Based-on: 20210918184527.408540-1-richard.henderson@linaro.org
> ("linux-user: Streamline handling of SIGSEGV")
>
> which is in turn based on at least 3 other patch sets, so:
>
> https://gitlab.com/rth7680/qemu/-/commits/tcg-siginfo
>
> Changes since v2:
> * Rebase on top of sigsegv cleanup, which eliminates about
> half of the places that needed updating to force_sig_fault.
> * target/mips cleanups+fixes for EXCP_BREAK and EXCP_TRAP.
Apologies to Phil and Peter, who gave me r-b on v2, which I failed to pick into this patch
set. I'll remedy that for v4.
r~
^ permalink raw reply [flat|nested] 27+ messages in thread