/*
 *  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"

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

#define __SIGNAL_FRAMESIZE      160 /* FIXME: 31-bit mode -> 96 */

#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[__SIGNAL_FRAMESIZE];
    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[__SIGNAL_FRAMESIZE];
    /*
     * 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.
     */
    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. */
    tswap_siginfo(&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]);
    }
    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);
}
