aboutsummaryrefslogtreecommitdiff
path: root/linux-user/aarch64
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-02-12 10:48:59 -0800
committerPeter Maydell <peter.maydell@linaro.org>2021-02-16 13:17:10 +0000
commit5d70c3510b2cb5664430d25da5d9bcbb7443f63f (patch)
treeafcc0d115b5f44d21632a0a3c253c6c6dc858e6a /linux-user/aarch64
parent61dbe03787f2f8bdd61da99ea19fd80b0d5c2bfa (diff)
downloadqemu-5d70c3510b2cb5664430d25da5d9bcbb7443f63f.zip
qemu-5d70c3510b2cb5664430d25da5d9bcbb7443f63f.tar.gz
qemu-5d70c3510b2cb5664430d25da5d9bcbb7443f63f.tar.bz2
linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error
The real kernel collects _TIF_MTE_ASYNC_FAULT into the current thread's state on any kernel entry (interrupt, exception etc), and then delivers the signal in advance of resuming the thread. This means that while the signal won't be delivered immediately, it will not be delayed forever -- at minimum it will be delivered after the next clock interrupt. We don't have a clock interrupt in linux-user, so we issue a cpu_kick to signal a return to the main loop at the end of the current TB. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210212184902.1251044-29-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/aarch64')
-rw-r--r--linux-user/aarch64/cpu_loop.c11
-rw-r--r--linux-user/aarch64/target_signal.h1
2 files changed, 12 insertions, 0 deletions
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index b6a2e65..7c42f65 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -164,6 +164,17 @@ void cpu_loop(CPUARMState *env)
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
+
+ /* 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);
+ }
+
process_pending_signals(env);
/* Exception return on AArch64 always clears the exclusive monitor,
* so any return to running guest code implies this.
diff --git a/linux-user/aarch64/target_signal.h b/linux-user/aarch64/target_signal.h
index 777fb66..18013e1 100644
--- a/linux-user/aarch64/target_signal.h
+++ b/linux-user/aarch64/target_signal.h
@@ -21,6 +21,7 @@ typedef struct target_sigaltstack {
#include "../generic/signal.h"
+#define TARGET_SEGV_MTEAERR 8 /* Asynchronous ARM MTE error */
#define TARGET_SEGV_MTESERR 9 /* Synchronous ARM MTE exception */
#define TARGET_ARCH_HAS_SETUP_FRAME