qemu/linux-user/include/host/aarch64/host-signal.h
<<
>>
Prefs
   1/*
   2 * host-signal.h: signal info dependent on the host architecture
   3 *
   4 * Copyright (c) 2003-2005 Fabrice Bellard
   5 * Copyright (c) 2021 Linaro Limited
   6 *
   7 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
   8 * See the COPYING file in the top-level directory.
   9 */
  10
  11#ifndef AARCH64_HOST_SIGNAL_H
  12#define AARCH64_HOST_SIGNAL_H
  13
  14/* The third argument to a SA_SIGINFO handler is ucontext_t. */
  15typedef ucontext_t host_sigcontext;
  16
  17/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
  18#ifndef ESR_MAGIC
  19#define ESR_MAGIC 0x45535201
  20struct esr_context {
  21    struct _aarch64_ctx head;
  22    uint64_t esr;
  23};
  24#endif
  25
  26static inline struct _aarch64_ctx *first_ctx(host_sigcontext *uc)
  27{
  28    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
  29}
  30
  31static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
  32{
  33    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
  34}
  35
  36static inline uintptr_t host_signal_pc(host_sigcontext *uc)
  37{
  38    return uc->uc_mcontext.pc;
  39}
  40
  41static inline void host_signal_set_pc(host_sigcontext *uc, uintptr_t pc)
  42{
  43    uc->uc_mcontext.pc = pc;
  44}
  45
  46static inline void *host_signal_mask(host_sigcontext *uc)
  47{
  48    return &uc->uc_sigmask;
  49}
  50
  51static inline bool host_signal_write(siginfo_t *info, host_sigcontext *uc)
  52{
  53    struct _aarch64_ctx *hdr;
  54    uint32_t insn;
  55
  56    /* Find the esr_context, which has the WnR bit in it */
  57    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
  58        if (hdr->magic == ESR_MAGIC) {
  59            struct esr_context const *ec = (struct esr_context const *)hdr;
  60            uint64_t esr = ec->esr;
  61
  62            /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
  63            return extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
  64        }
  65    }
  66
  67    /*
  68     * Fall back to parsing instructions; will only be needed
  69     * for really ancient (pre-3.16) kernels.
  70     */
  71    insn = *(uint32_t *)host_signal_pc(uc);
  72
  73    return (insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */
  74        || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */
  75        || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */
  76        || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */
  77        || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */
  78        || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */
  79        || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */
  80        /* Ignore bits 10, 11 & 21, controlling indexing.  */
  81        || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */
  82        || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */
  83        /* Ignore bits 23 & 24, controlling indexing.  */
  84        || (insn & 0x3a400000) == 0x28000000; /* C3.3.7,14-16 */
  85}
  86
  87#endif
  88