diff mbox series

[v5,12/67] linux-user/host/aarch64: Populate host_signal.h

Message ID 20211015041053.2769193-13-richard.henderson@linaro.org
State Superseded
Headers show
Series user-only: Cleanup SIGSEGV and SIGBUS handling | expand

Commit Message

Richard Henderson Oct. 15, 2021, 4:09 a.m. UTC
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 linux-user/host/aarch64/host-signal.h | 74 ++++++++++++++++++++-
 accel/tcg/user-exec.c                 | 94 +--------------------------
 2 files changed, 74 insertions(+), 94 deletions(-)

-- 
2.25.1

Comments

Warner Losh Oct. 15, 2021, 6:30 p.m. UTC | #1
On Thu, Oct 14, 2021 at 10:11 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> Split host_signal_pc and host_signal_write out of user-exec.c.

> Drop the *BSD code, to be re-created under bsd-user/ later.

>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  linux-user/host/aarch64/host-signal.h | 74 ++++++++++++++++++++-

>  accel/tcg/user-exec.c                 | 94 +--------------------------

>  2 files changed, 74 insertions(+), 94 deletions(-)

>


Reviewed-by: Warner Losh <imp@bsdimp.com>




> diff --git a/linux-user/host/aarch64/host-signal.h

> b/linux-user/host/aarch64/host-signal.h

> index f4b4d65031..02a55c3372 100644

> --- a/linux-user/host/aarch64/host-signal.h

> +++ b/linux-user/host/aarch64/host-signal.h

> @@ -1 +1,73 @@

> -#define HOST_SIGNAL_PLACEHOLDER

> +/*

> + * host-signal.h: signal info dependent on the host architecture

> + *

> + * Copyright (C) 2021 Linaro Limited

> + *

> + * This work is licensed under the terms of the GNU GPL, version 2 or

> later.

> + * See the COPYING file in the top-level directory.

> + */

> +

> +#ifndef AARCH64_HOST_SIGNAL_H

> +#define AARCH64_HOST_SIGNAL_H

> +

> +/* Pre-3.16 kernel headers don't have these, so provide fallback

> definitions */

> +#ifndef ESR_MAGIC

> +#define ESR_MAGIC 0x45535201

> +struct esr_context {

> +    struct _aarch64_ctx head;

> +    uint64_t esr;

> +};

> +#endif

> +

> +static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)

> +{

> +    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;

> +}

> +

> +static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)

> +{

> +    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);

> +}

> +

> +static inline uintptr_t host_signal_pc(ucontext_t *uc)

> +{

> +    return uc->uc_mcontext.pc;

> +}

> +

> +static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)

> +{

> +    struct _aarch64_ctx *hdr;

> +    uint32_t insn;

> +

> +    /* Find the esr_context, which has the WnR bit in it */

> +    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {

> +        if (hdr->magic == ESR_MAGIC) {

> +            struct esr_context const *ec = (struct esr_context const

> *)hdr;

> +            uint64_t esr = ec->esr;

> +

> +            /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR

> bit */

> +            return extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1)

> == 1;

> +        }

> +    }

> +

> +    /*

> +     * Fall back to parsing instructions; will only be needed

> +     * for really ancient (pre-3.16) kernels.

> +     */

> +    insn = *(uint32_t *)host_signal_pc(uc);

> +

> +    return (insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */

> +        || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */

> +        || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */

> +        || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */

> +        || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */

> +        || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */

> +        || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */

> +        /* Ignore bits 10, 11 & 21, controlling indexing.  */

> +        || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */

> +        || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */

> +        /* Ignore bits 23 & 24, controlling indexing.  */

> +        || (insn & 0x3a400000) == 0x28000000; /* C3.3.7,14-16 */

> +}

> +

> +#endif

> diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c

> index 5656c654e1..0915eb7f95 100644

> --- a/accel/tcg/user-exec.c

> +++ b/accel/tcg/user-exec.c

> @@ -255,99 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong

> addr, int size,

>      return size ? g2h(env_cpu(env), addr) : NULL;

>  }

>

> -#if defined(__aarch64__)

> -

> -#if defined(__NetBSD__)

> -

> -#include <ucontext.h>

> -#include <sys/siginfo.h>

> -

> -int cpu_signal_handler(int host_signum, void *pinfo, void *puc)

> -{

> -    ucontext_t *uc = puc;

> -    siginfo_t *si = pinfo;

> -    unsigned long pc;

> -    int is_write;

> -    uint32_t esr;

> -

> -    pc = uc->uc_mcontext.__gregs[_REG_PC];

> -    esr = si->si_trap;

> -

> -    /*

> -     * siginfo_t::si_trap is the ESR value, for data aborts ESR.EC

> -     * is 0b10010x: then bit 6 is the WnR bit

> -     */

> -    is_write = extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;

> -    return handle_cpu_signal(pc, si, is_write, &uc->uc_sigmask);

> -}

> -

> -#else

> -

> -#ifndef ESR_MAGIC

> -/* Pre-3.16 kernel headers don't have these, so provide fallback

> definitions */

> -#define ESR_MAGIC 0x45535201

> -struct esr_context {

> -    struct _aarch64_ctx head;

> -    uint64_t esr;

> -};

> -#endif

> -

> -static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)

> -{

> -    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;

> -}

> -

> -static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)

> -{

> -    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);

> -}

> -

> -int cpu_signal_handler(int host_signum, void *pinfo, void *puc)

> -{

> -    siginfo_t *info = pinfo;

> -    ucontext_t *uc = puc;

> -    uintptr_t pc = uc->uc_mcontext.pc;

> -    bool is_write;

> -    struct _aarch64_ctx *hdr;

> -    struct esr_context const *esrctx = NULL;

> -

> -    /* Find the esr_context, which has the WnR bit in it */

> -    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {

> -        if (hdr->magic == ESR_MAGIC) {

> -            esrctx = (struct esr_context const *)hdr;

> -            break;

> -        }

> -    }

> -

> -    if (esrctx) {

> -        /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit

> */

> -        uint64_t esr = esrctx->esr;

> -        is_write = extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1)

> == 1;

> -    } else {

> -        /*

> -         * Fall back to parsing instructions; will only be needed

> -         * for really ancient (pre-3.16) kernels.

> -         */

> -        uint32_t insn = *(uint32_t *)pc;

> -

> -        is_write = ((insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */

> -                    || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */

> -                    || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */

> -                    || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */

> -                    || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */

> -                    || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */

> -                    || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit

> */

> -                    /* Ignore bits 10, 11 & 21, controlling indexing.  */

> -                    || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */

> -                    || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit

> */

> -                    /* Ignore bits 23 & 24, controlling indexing.  */

> -                    || (insn & 0x3a400000) == 0x28000000); /*

> C3.3.7,14-16 */

> -    }

> -    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);

> -}

> -#endif

> -

> -#elif defined(__s390__)

> +#if defined(__s390__)

>

>  int cpu_signal_handler(int host_signum, void *pinfo,

>                         void *puc)

> --

> 2.25.1

>

>
<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Oct 14, 2021 at 10:11 PM Richard Henderson &lt;<a href="mailto:richard.henderson@linaro.org">richard.henderson@linaro.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Split host_signal_pc and host_signal_write out of user-exec.c.<br>
Drop the *BSD code, to be re-created under bsd-user/ later.<br>
<br>
Signed-off-by: Richard Henderson &lt;<a href="mailto:richard.henderson@linaro.org" target="_blank">richard.henderson@linaro.org</a>&gt;<br>

---<br>
 linux-user/host/aarch64/host-signal.h | 74 ++++++++++++++++++++-<br>
 accel/tcg/user-exec.c                 | 94 +--------------------------<br>
 2 files changed, 74 insertions(+), 94 deletions(-)<br></blockquote><div><br></div><div><div>Reviewed-by: Warner Losh &lt;<a href="mailto:imp@bsdimp.com">imp@bsdimp.com</a>&gt;</div><br class="gmail-Apple-interchange-newline"></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch64/host-signal.h<br>
index f4b4d65031..02a55c3372 100644<br>
--- a/linux-user/host/aarch64/host-signal.h<br>
+++ b/linux-user/host/aarch64/host-signal.h<br>
@@ -1 +1,73 @@<br>
-#define HOST_SIGNAL_PLACEHOLDER<br>
+/*<br>
+ * host-signal.h: signal info dependent on the host architecture<br>
+ *<br>
+ * Copyright (C) 2021 Linaro Limited<br>
+ *<br>
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.<br>
+ * See the COPYING file in the top-level directory.<br>
+ */<br>
+<br>
+#ifndef AARCH64_HOST_SIGNAL_H<br>
+#define AARCH64_HOST_SIGNAL_H<br>
+<br>
+/* Pre-3.16 kernel headers don&#39;t have these, so provide fallback definitions */<br>
+#ifndef ESR_MAGIC<br>
+#define ESR_MAGIC 0x45535201<br>
+struct esr_context {<br>
+    struct _aarch64_ctx head;<br>
+    uint64_t esr;<br>
+};<br>
+#endif<br>
+<br>
+static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)<br>
+{<br>
+    return (struct _aarch64_ctx *)&amp;uc-&gt;uc_mcontext.__reserved;<br>
+}<br>
+<br>
+static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)<br>
+{<br>
+    return (struct _aarch64_ctx *)((char *)hdr + hdr-&gt;size);<br>
+}<br>
+<br>
+static inline uintptr_t host_signal_pc(ucontext_t *uc)<br>
+{<br>
+    return uc-&gt;uc_mcontext.pc;<br>
+}<br>
+<br>
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)<br>
+{<br>
+    struct _aarch64_ctx *hdr;<br>
+    uint32_t insn;<br>
+<br>
+    /* Find the esr_context, which has the WnR bit in it */<br>
+    for (hdr = first_ctx(uc); hdr-&gt;magic; hdr = next_ctx(hdr)) {<br>
+        if (hdr-&gt;magic == ESR_MAGIC) {<br>
+            struct esr_context const *ec = (struct esr_context const *)hdr;<br>
+            uint64_t esr = ec-&gt;esr;<br>
+<br>
+            /* For data aborts <a href="http://ESR.EC" rel="noreferrer" target="_blank">ESR.EC</a> is 0b10010x: then bit 6 is the WnR bit */<br>
+            return extract32(esr, 27, 5) == 0x12 &amp;&amp; extract32(esr, 6, 1) == 1;<br>
+        }<br>
+    }<br>
+<br>
+    /*<br>
+     * Fall back to parsing instructions; will only be needed<br>
+     * for really ancient (pre-3.16) kernels.<br>
+     */<br>
+    insn = *(uint32_t *)host_signal_pc(uc);<br>
+<br>
+    return (insn &amp; 0xbfff0000) == 0x0c000000   /* C3.3.1 */<br>
+        || (insn &amp; 0xbfe00000) == 0x0c800000   /* C3.3.2 */<br>
+        || (insn &amp; 0xbfdf0000) == 0x0d000000   /* C3.3.3 */<br>
+        || (insn &amp; 0xbfc00000) == 0x0d800000   /* C3.3.4 */<br>
+        || (insn &amp; 0x3f400000) == 0x08000000   /* C3.3.6 */<br>
+        || (insn &amp; 0x3bc00000) == 0x39000000   /* C3.3.13 */<br>
+        || (insn &amp; 0x3fc00000) == 0x3d800000   /* ... 128bit */<br>
+        /* Ignore bits 10, 11 &amp; 21, controlling indexing.  */<br>
+        || (insn &amp; 0x3bc00000) == 0x38000000   /* C3.3.8-12 */<br>
+        || (insn &amp; 0x3fe00000) == 0x3c800000   /* ... 128bit */<br>
+        /* Ignore bits 23 &amp; 24, controlling indexing.  */<br>
+        || (insn &amp; 0x3a400000) == 0x28000000; /* C3.3.7,14-16 */<br>
+}<br>
+<br>
+#endif<br>
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c<br>
index 5656c654e1..0915eb7f95 100644<br>
--- a/accel/tcg/user-exec.c<br>
+++ b/accel/tcg/user-exec.c<br>
@@ -255,99 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,<br>
     return size ? g2h(env_cpu(env), addr) : NULL;<br>
 }<br>
<br>
-#if defined(__aarch64__)<br>
-<br>
-#if defined(__NetBSD__)<br>
-<br>
-#include &lt;ucontext.h&gt;<br>
-#include &lt;sys/siginfo.h&gt;<br>
-<br>
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)<br>
-{<br>
-    ucontext_t *uc = puc;<br>
-    siginfo_t *si = pinfo;<br>
-    unsigned long pc;<br>
-    int is_write;<br>
-    uint32_t esr;<br>
-<br>
-    pc = uc-&gt;uc_mcontext.__gregs[_REG_PC];<br>
-    esr = si-&gt;si_trap;<br>
-<br>
-    /*<br>
-     * siginfo_t::si_trap is the ESR value, for data aborts <a href="http://ESR.EC" rel="noreferrer" target="_blank">ESR.EC</a><br>
-     * is 0b10010x: then bit 6 is the WnR bit<br>
-     */<br>
-    is_write = extract32(esr, 27, 5) == 0x12 &amp;&amp; extract32(esr, 6, 1) == 1;<br>
-    return handle_cpu_signal(pc, si, is_write, &amp;uc-&gt;uc_sigmask);<br>
-}<br>
-<br>
-#else<br>
-<br>
-#ifndef ESR_MAGIC<br>
-/* Pre-3.16 kernel headers don&#39;t have these, so provide fallback definitions */<br>
-#define ESR_MAGIC 0x45535201<br>
-struct esr_context {<br>
-    struct _aarch64_ctx head;<br>
-    uint64_t esr;<br>
-};<br>
-#endif<br>
-<br>
-static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)<br>
-{<br>
-    return (struct _aarch64_ctx *)&amp;uc-&gt;uc_mcontext.__reserved;<br>
-}<br>
-<br>
-static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)<br>
-{<br>
-    return (struct _aarch64_ctx *)((char *)hdr + hdr-&gt;size);<br>
-}<br>
-<br>
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)<br>
-{<br>
-    siginfo_t *info = pinfo;<br>
-    ucontext_t *uc = puc;<br>
-    uintptr_t pc = uc-&gt;uc_mcontext.pc;<br>
-    bool is_write;<br>
-    struct _aarch64_ctx *hdr;<br>
-    struct esr_context const *esrctx = NULL;<br>
-<br>
-    /* Find the esr_context, which has the WnR bit in it */<br>
-    for (hdr = first_ctx(uc); hdr-&gt;magic; hdr = next_ctx(hdr)) {<br>
-        if (hdr-&gt;magic == ESR_MAGIC) {<br>
-            esrctx = (struct esr_context const *)hdr;<br>
-            break;<br>
-        }<br>
-    }<br>
-<br>
-    if (esrctx) {<br>
-        /* For data aborts <a href="http://ESR.EC" rel="noreferrer" target="_blank">ESR.EC</a> is 0b10010x: then bit 6 is the WnR bit */<br>
-        uint64_t esr = esrctx-&gt;esr;<br>
-        is_write = extract32(esr, 27, 5) == 0x12 &amp;&amp; extract32(esr, 6, 1) == 1;<br>
-    } else {<br>
-        /*<br>
-         * Fall back to parsing instructions; will only be needed<br>
-         * for really ancient (pre-3.16) kernels.<br>
-         */<br>
-        uint32_t insn = *(uint32_t *)pc;<br>
-<br>
-        is_write = ((insn &amp; 0xbfff0000) == 0x0c000000   /* C3.3.1 */<br>
-                    || (insn &amp; 0xbfe00000) == 0x0c800000   /* C3.3.2 */<br>
-                    || (insn &amp; 0xbfdf0000) == 0x0d000000   /* C3.3.3 */<br>
-                    || (insn &amp; 0xbfc00000) == 0x0d800000   /* C3.3.4 */<br>
-                    || (insn &amp; 0x3f400000) == 0x08000000   /* C3.3.6 */<br>
-                    || (insn &amp; 0x3bc00000) == 0x39000000   /* C3.3.13 */<br>
-                    || (insn &amp; 0x3fc00000) == 0x3d800000   /* ... 128bit */<br>
-                    /* Ignore bits 10, 11 &amp; 21, controlling indexing.  */<br>
-                    || (insn &amp; 0x3bc00000) == 0x38000000   /* C3.3.8-12 */<br>
-                    || (insn &amp; 0x3fe00000) == 0x3c800000   /* ... 128bit */<br>
-                    /* Ignore bits 23 &amp; 24, controlling indexing.  */<br>
-                    || (insn &amp; 0x3a400000) == 0x28000000); /* C3.3.7,14-16 */<br>
-    }<br>
-    return handle_cpu_signal(pc, info, is_write, &amp;uc-&gt;uc_sigmask);<br>
-}<br>
-#endif<br>
-<br>
-#elif defined(__s390__)<br>
+#if defined(__s390__)<br>
<br>
 int cpu_signal_handler(int host_signum, void *pinfo,<br>
                        void *puc)<br>
-- <br>
2.25.1<br>
<br>
</blockquote></div></div>
Richard Henderson Oct. 15, 2021, 7:49 p.m. UTC | #2
On 10/15/21 11:30 AM, Warner Losh wrote:
>     +    /*

>     +     * Fall back to parsing instructions; will only be needed

>     +     * for really ancient (pre-3.16) kernels.

>     +     */

>     +    insn = *(uint32_t *)host_signal_pc(uc);

>     +

>     +    return (insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */

>     +        || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */

>     +        || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */

>     +        || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */

>     +        || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */

>     +        || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */

>     +        || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */

>     +        /* Ignore bits 10, 11 & 21, controlling indexing.  */

>     +        || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */

>     +        || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */

>     +        /* Ignore bits 23 & 24, controlling indexing.  */

>     +        || (insn & 0x3a400000) == 0x28000000; /* C3.3.7,14-16 */

>     +}


Oh, Warner, I was thinking about your query about sharing the instruction parsing code 
between *-user.

I was thinking that we should have, under e.g. user-only/, a library of stuff that could 
be referenced by *-user.  One of these would be a simpler interface like

bool host_is_write_insn_at(void *pc);

We can hammer out details on that as you discover what you need in bsd-user.


r~
diff mbox series

Patch

diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch64/host-signal.h
index f4b4d65031..02a55c3372 100644
--- a/linux-user/host/aarch64/host-signal.h
+++ b/linux-user/host/aarch64/host-signal.h
@@ -1 +1,73 @@ 
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef AARCH64_HOST_SIGNAL_H
+#define AARCH64_HOST_SIGNAL_H
+
+/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
+#ifndef ESR_MAGIC
+#define ESR_MAGIC 0x45535201
+struct esr_context {
+    struct _aarch64_ctx head;
+    uint64_t esr;
+};
+#endif
+
+static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
+{
+    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
+}
+
+static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
+{
+    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
+}
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    struct _aarch64_ctx *hdr;
+    uint32_t insn;
+
+    /* Find the esr_context, which has the WnR bit in it */
+    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
+        if (hdr->magic == ESR_MAGIC) {
+            struct esr_context const *ec = (struct esr_context const *)hdr;
+            uint64_t esr = ec->esr;
+
+            /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
+            return extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
+        }
+    }
+
+    /*
+     * Fall back to parsing instructions; will only be needed
+     * for really ancient (pre-3.16) kernels.
+     */
+    insn = *(uint32_t *)host_signal_pc(uc);
+
+    return (insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */
+        || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */
+        || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */
+        || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */
+        || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */
+        || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */
+        || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */
+        /* Ignore bits 10, 11 & 21, controlling indexing.  */
+        || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */
+        || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */
+        /* Ignore bits 23 & 24, controlling indexing.  */
+        || (insn & 0x3a400000) == 0x28000000; /* C3.3.7,14-16 */
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 5656c654e1..0915eb7f95 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,99 +255,7 @@  void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__aarch64__)
-
-#if defined(__NetBSD__)
-
-#include <ucontext.h>
-#include <sys/siginfo.h>
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-    ucontext_t *uc = puc;
-    siginfo_t *si = pinfo;
-    unsigned long pc;
-    int is_write;
-    uint32_t esr;
-
-    pc = uc->uc_mcontext.__gregs[_REG_PC];
-    esr = si->si_trap;
-
-    /*
-     * siginfo_t::si_trap is the ESR value, for data aborts ESR.EC
-     * is 0b10010x: then bit 6 is the WnR bit
-     */
-    is_write = extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
-    return handle_cpu_signal(pc, si, is_write, &uc->uc_sigmask);
-}
-
-#else
-
-#ifndef ESR_MAGIC
-/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
-#define ESR_MAGIC 0x45535201
-struct esr_context {
-    struct _aarch64_ctx head;
-    uint64_t esr;
-};
-#endif
-
-static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
-{
-    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
-}
-
-static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
-{
-    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
-}
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-    siginfo_t *info = pinfo;
-    ucontext_t *uc = puc;
-    uintptr_t pc = uc->uc_mcontext.pc;
-    bool is_write;
-    struct _aarch64_ctx *hdr;
-    struct esr_context const *esrctx = NULL;
-
-    /* Find the esr_context, which has the WnR bit in it */
-    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
-        if (hdr->magic == ESR_MAGIC) {
-            esrctx = (struct esr_context const *)hdr;
-            break;
-        }
-    }
-
-    if (esrctx) {
-        /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
-        uint64_t esr = esrctx->esr;
-        is_write = extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
-    } else {
-        /*
-         * Fall back to parsing instructions; will only be needed
-         * for really ancient (pre-3.16) kernels.
-         */
-        uint32_t insn = *(uint32_t *)pc;
-
-        is_write = ((insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */
-                    || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */
-                    || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */
-                    || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */
-                    || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */
-                    || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */
-                    || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */
-                    /* Ignore bits 10, 11 & 21, controlling indexing.  */
-                    || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */
-                    || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */
-                    /* Ignore bits 23 & 24, controlling indexing.  */
-                    || (insn & 0x3a400000) == 0x28000000); /* C3.3.7,14-16 */
-    }
-    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-#endif
-
-#elif defined(__s390__)
+#if defined(__s390__)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)