cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

signal.c (7372B)


      1/*
      2 *  Emulation of Linux signals
      3 *
      4 *  Copyright (c) 2003 Fabrice Bellard
      5 *
      6 *  This program is free software; you can redistribute it and/or modify
      7 *  it under the terms of the GNU General Public License as published by
      8 *  the Free Software Foundation; either version 2 of the License, or
      9 *  (at your option) any later version.
     10 *
     11 *  This program is distributed in the hope that it will be useful,
     12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 *  GNU General Public License for more details.
     15 *
     16 *  You should have received a copy of the GNU General Public License
     17 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
     18 */
     19#include "qemu/osdep.h"
     20#include "qemu.h"
     21#include "user-internals.h"
     22#include "signal-common.h"
     23#include "linux-user/trace.h"
     24
     25struct target_sigcontext {
     26    struct target_pt_regs regs;  /* needs to be first */
     27    uint32_t oldmask;
     28};
     29
     30struct target_stack_t {
     31    abi_ulong ss_sp;
     32    int ss_flags;
     33    unsigned int ss_size;
     34};
     35
     36struct target_ucontext {
     37    abi_ulong tuc_flags;
     38    abi_ulong tuc_link;
     39    target_stack_t tuc_stack;
     40    struct target_sigcontext tuc_mcontext;
     41    target_sigset_t tuc_sigmask;
     42};
     43
     44/* Signal frames. */
     45struct target_rt_sigframe {
     46    target_siginfo_t info;
     47    struct target_ucontext uc;
     48    uint32_t tramp[2];
     49};
     50
     51static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
     52{
     53    __put_user(env->regs[0], &sc->regs.r0);
     54    __put_user(env->regs[1], &sc->regs.r1);
     55    __put_user(env->regs[2], &sc->regs.r2);
     56    __put_user(env->regs[3], &sc->regs.r3);
     57    __put_user(env->regs[4], &sc->regs.r4);
     58    __put_user(env->regs[5], &sc->regs.r5);
     59    __put_user(env->regs[6], &sc->regs.r6);
     60    __put_user(env->regs[7], &sc->regs.r7);
     61    __put_user(env->regs[8], &sc->regs.r8);
     62    __put_user(env->regs[9], &sc->regs.r9);
     63    __put_user(env->regs[10], &sc->regs.r10);
     64    __put_user(env->regs[11], &sc->regs.r11);
     65    __put_user(env->regs[12], &sc->regs.r12);
     66    __put_user(env->regs[13], &sc->regs.r13);
     67    __put_user(env->regs[14], &sc->regs.r14);
     68    __put_user(env->regs[15], &sc->regs.r15);
     69    __put_user(env->regs[16], &sc->regs.r16);
     70    __put_user(env->regs[17], &sc->regs.r17);
     71    __put_user(env->regs[18], &sc->regs.r18);
     72    __put_user(env->regs[19], &sc->regs.r19);
     73    __put_user(env->regs[20], &sc->regs.r20);
     74    __put_user(env->regs[21], &sc->regs.r21);
     75    __put_user(env->regs[22], &sc->regs.r22);
     76    __put_user(env->regs[23], &sc->regs.r23);
     77    __put_user(env->regs[24], &sc->regs.r24);
     78    __put_user(env->regs[25], &sc->regs.r25);
     79    __put_user(env->regs[26], &sc->regs.r26);
     80    __put_user(env->regs[27], &sc->regs.r27);
     81    __put_user(env->regs[28], &sc->regs.r28);
     82    __put_user(env->regs[29], &sc->regs.r29);
     83    __put_user(env->regs[30], &sc->regs.r30);
     84    __put_user(env->regs[31], &sc->regs.r31);
     85    __put_user(env->pc, &sc->regs.pc);
     86}
     87
     88static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
     89{
     90    __get_user(env->regs[0], &sc->regs.r0);
     91    __get_user(env->regs[1], &sc->regs.r1);
     92    __get_user(env->regs[2], &sc->regs.r2);
     93    __get_user(env->regs[3], &sc->regs.r3);
     94    __get_user(env->regs[4], &sc->regs.r4);
     95    __get_user(env->regs[5], &sc->regs.r5);
     96    __get_user(env->regs[6], &sc->regs.r6);
     97    __get_user(env->regs[7], &sc->regs.r7);
     98    __get_user(env->regs[8], &sc->regs.r8);
     99    __get_user(env->regs[9], &sc->regs.r9);
    100    __get_user(env->regs[10], &sc->regs.r10);
    101    __get_user(env->regs[11], &sc->regs.r11);
    102    __get_user(env->regs[12], &sc->regs.r12);
    103    __get_user(env->regs[13], &sc->regs.r13);
    104    __get_user(env->regs[14], &sc->regs.r14);
    105    __get_user(env->regs[15], &sc->regs.r15);
    106    __get_user(env->regs[16], &sc->regs.r16);
    107    __get_user(env->regs[17], &sc->regs.r17);
    108    __get_user(env->regs[18], &sc->regs.r18);
    109    __get_user(env->regs[19], &sc->regs.r19);
    110    __get_user(env->regs[20], &sc->regs.r20);
    111    __get_user(env->regs[21], &sc->regs.r21);
    112    __get_user(env->regs[22], &sc->regs.r22);
    113    __get_user(env->regs[23], &sc->regs.r23);
    114    __get_user(env->regs[24], &sc->regs.r24);
    115    __get_user(env->regs[25], &sc->regs.r25);
    116    __get_user(env->regs[26], &sc->regs.r26);
    117    __get_user(env->regs[27], &sc->regs.r27);
    118    __get_user(env->regs[28], &sc->regs.r28);
    119    __get_user(env->regs[29], &sc->regs.r29);
    120    __get_user(env->regs[30], &sc->regs.r30);
    121    __get_user(env->regs[31], &sc->regs.r31);
    122    __get_user(env->pc, &sc->regs.pc);
    123}
    124
    125static abi_ulong get_sigframe(struct target_sigaction *ka,
    126                              CPUMBState *env, int frame_size)
    127{
    128    abi_ulong sp = env->regs[1];
    129
    130    sp = target_sigsp(sp, ka);
    131
    132    return ((sp - frame_size) & -8UL);
    133}
    134
    135void setup_rt_frame(int sig, struct target_sigaction *ka,
    136                    target_siginfo_t *info,
    137                    target_sigset_t *set, CPUMBState *env)
    138{
    139    struct target_rt_sigframe *frame;
    140    abi_ulong frame_addr;
    141
    142    frame_addr = get_sigframe(ka, env, sizeof *frame);
    143    trace_user_setup_rt_frame(env, frame_addr);
    144
    145    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
    146        force_sigsegv(sig);
    147        return;
    148    }
    149
    150    tswap_siginfo(&frame->info, info);
    151
    152    __put_user(0, &frame->uc.tuc_flags);
    153    __put_user(0, &frame->uc.tuc_link);
    154
    155    target_save_altstack(&frame->uc.tuc_stack, env);
    156    setup_sigcontext(&frame->uc.tuc_mcontext, env);
    157
    158    for (int i = 0; i < TARGET_NSIG_WORDS; i++) {
    159        __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
    160    }
    161
    162    /* Kernel does not use SA_RESTORER. */
    163
    164    /*
    165     * Return from sighandler will jump to the tramp.
    166     * Negative 8 offset because return is rtsd r15, 8
    167     */
    168    env->regs[15] = default_rt_sigreturn - 8;
    169
    170    /* Set up registers for signal handler */
    171    env->regs[1] = frame_addr;
    172
    173    /* Signal handler args: */
    174    env->regs[5] = sig;
    175    env->regs[6] = frame_addr + offsetof(struct target_rt_sigframe, info);
    176    env->regs[7] = frame_addr + offsetof(struct target_rt_sigframe, uc);
    177
    178    /* Offset to handle microblaze rtid r14, 0 */
    179    env->pc = (unsigned long)ka->_sa_handler;
    180
    181    unlock_user_struct(frame, frame_addr, 1);
    182}
    183
    184
    185long do_sigreturn(CPUMBState *env)
    186{
    187    return -TARGET_ENOSYS;
    188}
    189
    190long do_rt_sigreturn(CPUMBState *env)
    191{
    192    struct target_rt_sigframe *frame = NULL;
    193    abi_ulong frame_addr = env->regs[1];
    194    sigset_t set;
    195
    196    trace_user_do_rt_sigreturn(env, frame_addr);
    197
    198    if  (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
    199        goto badframe;
    200    }
    201
    202    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
    203    set_sigmask(&set);
    204
    205    restore_sigcontext(&frame->uc.tuc_mcontext, env);
    206
    207    target_restore_altstack(&frame->uc.tuc_stack, env);
    208
    209    unlock_user_struct(frame, frame_addr, 0);
    210    return -TARGET_QEMU_ESIGRETURN;
    211
    212 badframe:
    213    unlock_user_struct(frame, frame_addr, 0);
    214    force_sig(TARGET_SIGSEGV);
    215    return -TARGET_QEMU_ESIGRETURN;
    216}
    217
    218void setup_sigtramp(abi_ulong sigtramp_page)
    219{
    220    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
    221    assert(tramp != NULL);
    222
    223    /*
    224     * addi r12, r0, __NR_rt_sigreturn
    225     * brki r14, 0x8
    226     */
    227    __put_user(0x31800000U | TARGET_NR_rt_sigreturn, tramp);
    228    __put_user(0xb9cc0008U, tramp + 1);
    229
    230    default_rt_sigreturn = sigtramp_page;
    231    unlock_user(tramp, sigtramp_page, 8);
    232}