/*
 *  Emulation of Linux signals
 *
 *  Copyright (c) 2003 Fabrice Bellard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#include "qemu/osdep.h"
#include "qemu.h"
#include "user-internals.h"
#include "signal-common.h"
#include "linux-user/trace.h"
#include "vdso-asmoffset.h"

#define __NUM_GPRS 16
#define __NUM_FPRS 16
#define __NUM_ACRS 16

#define _SIGCONTEXT_NSIG        64
#define _SIGCONTEXT_NSIG_BPW    64 /* FIXME: 31-bit mode -> 32 */
#define _SIGCONTEXT_NSIG_WORDS  (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
#define _SIGMASK_COPY_SIZE    (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)

typedef struct {
    target_psw_t psw;
    abi_ulong gprs[__NUM_GPRS];
    abi_uint acrs[__NUM_ACRS];
} target_s390_regs_common;

typedef struct {
    uint32_t fpc;
    uint32_t pad;
    uint64_t fprs[__NUM_FPRS];
} target_s390_fp_regs;

typedef struct {
    target_s390_regs_common regs;
    target_s390_fp_regs     fpregs;
} target_sigregs;

typedef struct {
    uint64_t vxrs_low[16];
    uint64_t vxrs_high[16][2];
    uint8_t reserved[128];
} target_sigregs_ext;

typedef struct {
    abi_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
    abi_ulong sregs;
} target_sigcontext;

typedef struct {
    uint8_t callee_used_stack[STACK_FRAME_OVERHEAD];
    target_sigcontext sc;
    target_sigregs sregs;
    int signo;
    target_sigregs_ext sregs_ext;
} sigframe;

#define TARGET_UC_VXRS 2

struct target_ucontext {
    abi_ulong tuc_flags;
    abi_ulong tuc_link;
    target_stack_t tuc_stack;
    target_sigregs tuc_mcontext;
    target_sigset_t tuc_sigmask;
    uint8_t reserved[128 - sizeof(target_sigset_t)];
    target_sigregs_ext tuc_mcontext_ext;
};

typedef struct {
    uint8_t callee_used_stack[STACK_FRAME_OVERHEAD];
    /*
     * This field is no longer initialized by the kernel, but it's still a part
     * of the ABI.
     */
    uint16_t svc_insn;
    struct target_siginfo info;
    struct target_ucontext uc;
} rt_sigframe;

static inline abi_ulong
get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
{
    abi_ulong sp;

    /* Default to using normal stack */
    sp = get_sp_from_cpustate(env);

    /* This is the X/Open sanctioned signal stack switching.  */
    if (ka->sa_flags & TARGET_SA_ONSTACK) {
        sp = target_sigsp(sp, ka);
    }

    /* This is the legacy signal stack switching. */
    else if (/* FIXME !user_mode(regs) */ 0 &&
             !(ka->sa_flags & TARGET_SA_RESTORER) &&
             ka->sa_restorer) {
        sp = (abi_ulong) ka->sa_restorer;
    }

    return (sp - frame_size) & -8ul;
}

#define PSW_USER_BITS   (PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | \
                         PSW_MASK_MCHECK | PSW_MASK_PSTATE | PSW_ASC_PRIMARY)
#define PSW_MASK_USER   (PSW_MASK_ASC | PSW_MASK_CC | PSW_MASK_PM | \
                         PSW_MASK_64 | PSW_MASK_32)

static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
{
    uint64_t psw_mask = s390_cpu_get_psw_mask(env);
    int i;

    /*
     * Copy a 'clean' PSW mask to the user to avoid leaking
     * information about whether PER is currently on.
     * TODO: qemu does not support PSW_MASK_RI; it will never be set.
     */
    psw_mask = PSW_USER_BITS | (psw_mask & PSW_MASK_USER);
    __put_user(psw_mask, &sregs->regs.psw.mask);
    __put_user(env->psw.addr, &sregs->regs.psw.addr);

    for (i = 0; i < 16; i++) {
        __put_user(env->regs[i], &sregs->regs.gprs[i]);
    }
    for (i = 0; i < 16; i++) {
        __put_user(env->aregs[i], &sregs->regs.acrs[i]);
    }

    /*
     * We have to store the fp registers to current->thread.fp_regs
     * to merge them with the emulated registers.
     */
    __put_user(env->fpc, &sregs->fpregs.fpc);
    for (i = 0; i < 16; i++) {
        __put_user(*get_freg(env, i), &sregs->fpregs.fprs[i]);
    }
}

static void save_sigregs_ext(CPUS390XState *env, target_sigregs_ext *ext)
{
    int i;

    /*
     * if (MACHINE_HAS_VX) ...
     * That said, we always allocate the stack storage and the
     * space is always available in env.
     */
    for (i = 0; i < 16; ++i) {
        __put_user(env->vregs[i][1], &ext->vxrs_low[i]);
    }
    for (i = 0; i < 16; ++i) {
        __put_user(env->vregs[i + 16][0], &ext->vxrs_high[i][0]);
        __put_user(env->vregs[i + 16][1], &ext->vxrs_high[i][1]);
    }
}

void setup_frame(int sig, struct target_sigaction *ka,
                 target_sigset_t *set, CPUS390XState *env)
{
    sigframe *frame;
    abi_ulong frame_addr;
    abi_ulong restorer;

    frame_addr = get_sigframe(ka, env, sizeof(*frame));
    trace_user_setup_frame(env, frame_addr);
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
        force_sigsegv(sig);
        return;
    }

    /* Set up backchain. */
    __put_user(env->regs[15], (abi_ulong *) frame);

    /* Create struct sigcontext on the signal stack. */
    /* Make sure that we're initializing all of oldmask. */
    QEMU_BUILD_BUG_ON(ARRAY_SIZE(frame->sc.oldmask) != 1);
    __put_user(set->sig[0], &frame->sc.oldmask[0]);
    __put_user(frame_addr + offsetof(sigframe, sregs), &frame->sc.sregs);

    /* Create _sigregs on the signal stack */
    save_sigregs(env, &frame->sregs);

    /*
     * ??? The kernel uses regs->gprs[2] here, which is not yet the signo.
     * Moreover the comment talks about allowing backtrace, which is really
     * done by the r15 copy above.
     */
    __put_user(sig, &frame->signo);

    /* Create sigregs_ext on the signal stack. */
    save_sigregs_ext(env, &frame->sregs_ext);

    /*
     * Set up to return from userspace.
     * If provided, use a stub already in userspace.
     */
    if (ka->sa_flags & TARGET_SA_RESTORER) {
        restorer = ka->sa_restorer;
    } else {
        restorer = default_sigreturn;
    }

    /* Set up registers for signal handler */
    env->regs[14] = restorer;
    env->regs[15] = frame_addr;
    /* Force default amode and default user address space control. */
    env->psw.mask = PSW_MASK_64 | PSW_MASK_32 | PSW_ASC_PRIMARY
                  | (env->psw.mask & ~PSW_MASK_ASC);
    env->psw.addr = ka->_sa_handler;

    env->regs[2] = sig;
    env->regs[3] = frame_addr + offsetof(typeof(*frame), sc);

    /*
     * We forgot to include these in the sigcontext.
     * To avoid breaking binary compatibility, they are passed as args.
     */
    env->regs[4] = 0; /* FIXME: regs->int_code & 127 */
    env->regs[5] = 0; /* FIXME: regs->int_parm_long */
    env->regs[6] = 0; /* FIXME: current->thread.last_break */

    unlock_user_struct(frame, frame_addr, 1);
}

void setup_rt_frame(int sig, struct target_sigaction *ka,
                    target_siginfo_t *info,
                    target_sigset_t *set, CPUS390XState *env)
{
    rt_sigframe *frame;
    abi_ulong frame_addr;
    abi_ulong restorer;
    abi_ulong uc_flags;

    frame_addr = get_sigframe(ka, env, sizeof *frame);
    trace_user_setup_rt_frame(env, frame_addr);
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
        force_sigsegv(sig);
        return;
    }

    /* Set up backchain. */
    __put_user(env->regs[15], (abi_ulong *) frame);

    /*
     * Set up to return from userspace.
     * If provided, use a stub already in userspace.
     */
    if (ka->sa_flags & TARGET_SA_RESTORER) {
        restorer = ka->sa_restorer;
    } else {
        restorer = default_rt_sigreturn;
    }

    /* Create siginfo on the signal stack. */
    frame->info = *info;

    /* Create ucontext on the signal stack. */
    uc_flags = 0;
    if (s390_has_feat(S390_FEAT_VECTOR)) {
        uc_flags |= TARGET_UC_VXRS;
    }
    __put_user(uc_flags, &frame->uc.tuc_flags);
    __put_user(0, &frame->uc.tuc_link);
    target_save_altstack(&frame->uc.tuc_stack, env);
    save_sigregs(env, &frame->uc.tuc_mcontext);
    save_sigregs_ext(env, &frame->uc.tuc_mcontext_ext);
    tswap_sigset(&frame->uc.tuc_sigmask, set);

    /* Set up registers for signal handler */
    env->regs[14] = restorer;
    env->regs[15] = frame_addr;
    /* Force default amode and default user address space control. */
    env->psw.mask = PSW_MASK_64 | PSW_MASK_32 | PSW_ASC_PRIMARY
                  | (env->psw.mask & ~PSW_MASK_ASC);
    env->psw.addr = ka->_sa_handler;

    env->regs[2] = sig;
    env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
    env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
    env->regs[5] = 0; /* FIXME: current->thread.last_break */
}

static void restore_sigregs(CPUS390XState *env, target_sigregs *sc)
{
    uint64_t prev_addr, prev_mask, mask, addr;
    int i;

    for (i = 0; i < 16; i++) {
        __get_user(env->regs[i], &sc->regs.gprs[i]);
    }

    prev_addr = env->psw.addr;
    __get_user(mask, &sc->regs.psw.mask);
    __get_user(addr, &sc->regs.psw.addr);
    trace_user_s390x_restore_sigregs(env, addr, prev_addr);

    /*
     * Use current psw.mask to preserve PER bit.
     * TODO:
     *  if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW_MASK_RI))
     *          return -EINVAL;
     * Simply do not allow it to be set in mask.
     */
    prev_mask = s390_cpu_get_psw_mask(env);
    mask = (prev_mask & ~PSW_MASK_USER) | (mask & PSW_MASK_USER);
    /* Check for invalid user address space control. */
    if ((mask & PSW_MASK_ASC) == PSW_ASC_HOME) {
        mask = (mask & ~PSW_MASK_ASC) | PSW_ASC_PRIMARY;
    }
    /* Check for invalid amode. */
    if (mask & PSW_MASK_64) {
        mask |= PSW_MASK_32;
    }
    s390_cpu_set_psw(env, mask, addr);

    for (i = 0; i < 16; i++) {
        __get_user(env->aregs[i], &sc->regs.acrs[i]);
    }
    __get_user(env->fpc, &sc->fpregs.fpc);
    for (i = 0; i < 16; i++) {
        __get_user(*get_freg(env, i), &sc->fpregs.fprs[i]);
    }
}

static void restore_sigregs_ext(CPUS390XState *env, target_sigregs_ext *ext)
{
    int i;

    /*
     * if (MACHINE_HAS_VX) ...
     * That said, we always allocate the stack storage and the
     * space is always available in env.
     */
    for (i = 0; i < 16; ++i) {
        __get_user(env->vregs[i][1], &ext->vxrs_low[i]);
    }
    for (i = 0; i < 16; ++i) {
        __get_user(env->vregs[i + 16][0], &ext->vxrs_high[i][0]);
        __get_user(env->vregs[i + 16][1], &ext->vxrs_high[i][1]);
    }
}

long do_sigreturn(CPUS390XState *env)
{
    sigframe *frame;
    abi_ulong frame_addr = env->regs[15];
    target_sigset_t target_set;
    sigset_t set;

    trace_user_do_sigreturn(env, frame_addr);
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
        force_sig(TARGET_SIGSEGV);
        return -QEMU_ESIGRETURN;
    }

    /* Make sure that we're initializing all of target_set. */
    QEMU_BUILD_BUG_ON(ARRAY_SIZE(target_set.sig) != 1);
    __get_user(target_set.sig[0], &frame->sc.oldmask[0]);

    target_to_host_sigset_internal(&set, &target_set);
    set_sigmask(&set); /* ~_BLOCKABLE? */

    restore_sigregs(env, &frame->sregs);
    restore_sigregs_ext(env, &frame->sregs_ext);

    unlock_user_struct(frame, frame_addr, 0);
    return -QEMU_ESIGRETURN;
}

long do_rt_sigreturn(CPUS390XState *env)
{
    rt_sigframe *frame;
    abi_ulong frame_addr = env->regs[15];
    sigset_t set;

    trace_user_do_rt_sigreturn(env, frame_addr);
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
        force_sig(TARGET_SIGSEGV);
        return -QEMU_ESIGRETURN;
    }
    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);

    set_sigmask(&set); /* ~_BLOCKABLE? */

    restore_sigregs(env, &frame->uc.tuc_mcontext);
    restore_sigregs_ext(env, &frame->uc.tuc_mcontext_ext);

    target_restore_altstack(&frame->uc.tuc_stack, env);

    unlock_user_struct(frame, frame_addr, 0);
    return -QEMU_ESIGRETURN;
}

void setup_sigtramp(abi_ulong sigtramp_page)
{
    uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 + 2, 0);
    assert(tramp != NULL);

    default_sigreturn = sigtramp_page;
    __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, &tramp[0]);

    default_rt_sigreturn = sigtramp_page + 2;
    __put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, &tramp[1]);

    unlock_user(tramp, sigtramp_page, 2 + 2);
}
