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

excp_helper.c (20599B)


      1/*
      2 * s390x exception / interrupt helpers
      3 *
      4 *  Copyright (c) 2009 Ulrich Hecht
      5 *  Copyright (c) 2011 Alexander Graf
      6 *
      7 * This library is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU Lesser General Public
      9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * This library is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     19 */
     20
     21#include "qemu/osdep.h"
     22#include "cpu.h"
     23#include "s390x-internal.h"
     24#include "exec/helper-proto.h"
     25#include "qemu/timer.h"
     26#include "exec/exec-all.h"
     27#include "exec/cpu_ldst.h"
     28#include "hw/s390x/ioinst.h"
     29#include "exec/address-spaces.h"
     30#include "tcg_s390x.h"
     31#ifndef CONFIG_USER_ONLY
     32#include "hw/s390x/s390_flic.h"
     33#include "hw/boards.h"
     34#endif
     35
     36void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
     37                                              uint32_t code, uintptr_t ra)
     38{
     39    CPUState *cs = env_cpu(env);
     40
     41    cpu_restore_state(cs, ra, true);
     42    qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
     43                  env->psw.addr);
     44    trigger_pgm_exception(env, code);
     45    cpu_loop_exit(cs);
     46}
     47
     48void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc,
     49                                           uintptr_t ra)
     50{
     51    g_assert(dxc <= 0xff);
     52#if !defined(CONFIG_USER_ONLY)
     53    /* Store the DXC into the lowcore */
     54    stl_phys(env_cpu(env)->as,
     55             env->psa + offsetof(LowCore, data_exc_code), dxc);
     56#endif
     57
     58    /* Store the DXC into the FPC if AFP is enabled */
     59    if (env->cregs[0] & CR0_AFP) {
     60        env->fpc = deposit32(env->fpc, 8, 8, dxc);
     61    }
     62    tcg_s390_program_interrupt(env, PGM_DATA, ra);
     63}
     64
     65void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
     66                                             uintptr_t ra)
     67{
     68    g_assert(vxc <= 0xff);
     69#if !defined(CONFIG_USER_ONLY)
     70    /* Always store the VXC into the lowcore, without AFP it is undefined */
     71    stl_phys(env_cpu(env)->as,
     72             env->psa + offsetof(LowCore, data_exc_code), vxc);
     73#endif
     74
     75    /* Always store the VXC into the FPC, without AFP it is undefined */
     76    env->fpc = deposit32(env->fpc, 8, 8, vxc);
     77    tcg_s390_program_interrupt(env, PGM_VECTOR_PROCESSING, ra);
     78}
     79
     80void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
     81{
     82    tcg_s390_data_exception(env, dxc, GETPC());
     83}
     84
     85#if defined(CONFIG_USER_ONLY)
     86
     87void s390_cpu_do_interrupt(CPUState *cs)
     88{
     89    cs->exception_index = -1;
     90}
     91
     92bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     93                       MMUAccessType access_type, int mmu_idx,
     94                       bool probe, uintptr_t retaddr)
     95{
     96    S390CPU *cpu = S390_CPU(cs);
     97
     98    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING);
     99    /* On real machines this value is dropped into LowMem.  Since this
    100       is userland, simply put this someplace that cpu_loop can find it.  */
    101    cpu->env.__excp_addr = address;
    102    cpu_loop_exit_restore(cs, retaddr);
    103}
    104
    105#else /* !CONFIG_USER_ONLY */
    106
    107static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
    108{
    109    switch (mmu_idx) {
    110    case MMU_PRIMARY_IDX:
    111        return PSW_ASC_PRIMARY;
    112    case MMU_SECONDARY_IDX:
    113        return PSW_ASC_SECONDARY;
    114    case MMU_HOME_IDX:
    115        return PSW_ASC_HOME;
    116    default:
    117        abort();
    118    }
    119}
    120
    121bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
    122                       MMUAccessType access_type, int mmu_idx,
    123                       bool probe, uintptr_t retaddr)
    124{
    125    S390CPU *cpu = S390_CPU(cs);
    126    CPUS390XState *env = &cpu->env;
    127    target_ulong vaddr, raddr;
    128    uint64_t asc, tec;
    129    int prot, excp;
    130
    131    qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
    132                  __func__, address, access_type, mmu_idx);
    133
    134    vaddr = address;
    135
    136    if (mmu_idx < MMU_REAL_IDX) {
    137        asc = cpu_mmu_idx_to_asc(mmu_idx);
    138        /* 31-Bit mode */
    139        if (!(env->psw.mask & PSW_MASK_64)) {
    140            vaddr &= 0x7fffffff;
    141        }
    142        excp = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, &tec);
    143    } else if (mmu_idx == MMU_REAL_IDX) {
    144        /* 31-Bit mode */
    145        if (!(env->psw.mask & PSW_MASK_64)) {
    146            vaddr &= 0x7fffffff;
    147        }
    148        excp = mmu_translate_real(env, vaddr, access_type, &raddr, &prot, &tec);
    149    } else {
    150        g_assert_not_reached();
    151    }
    152
    153    env->tlb_fill_exc = excp;
    154    env->tlb_fill_tec = tec;
    155
    156    if (!excp) {
    157        qemu_log_mask(CPU_LOG_MMU,
    158                      "%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n",
    159                      __func__, (uint64_t)vaddr, (uint64_t)raddr, prot);
    160        tlb_set_page(cs, address & TARGET_PAGE_MASK, raddr, prot,
    161                     mmu_idx, TARGET_PAGE_SIZE);
    162        return true;
    163    }
    164    if (probe) {
    165        return false;
    166    }
    167
    168    if (excp != PGM_ADDRESSING) {
    169        stq_phys(env_cpu(env)->as,
    170                 env->psa + offsetof(LowCore, trans_exc_code), tec);
    171    }
    172
    173    /*
    174     * For data accesses, ILEN will be filled in from the unwind info,
    175     * within cpu_loop_exit_restore.  For code accesses, retaddr == 0,
    176     * and so unwinding will not occur.  However, ILEN is also undefined
    177     * for that case -- we choose to set ILEN = 2.
    178     */
    179    env->int_pgm_ilen = 2;
    180    trigger_pgm_exception(env, excp);
    181    cpu_loop_exit_restore(cs, retaddr);
    182}
    183
    184static void do_program_interrupt(CPUS390XState *env)
    185{
    186    uint64_t mask, addr;
    187    LowCore *lowcore;
    188    int ilen = env->int_pgm_ilen;
    189
    190    assert(ilen == 2 || ilen == 4 || ilen == 6);
    191
    192    switch (env->int_pgm_code) {
    193    case PGM_PER:
    194        if (env->per_perc_atmid & PER_CODE_EVENT_NULLIFICATION) {
    195            break;
    196        }
    197        /* FALL THROUGH */
    198    case PGM_OPERATION:
    199    case PGM_PRIVILEGED:
    200    case PGM_EXECUTE:
    201    case PGM_PROTECTION:
    202    case PGM_ADDRESSING:
    203    case PGM_SPECIFICATION:
    204    case PGM_DATA:
    205    case PGM_FIXPT_OVERFLOW:
    206    case PGM_FIXPT_DIVIDE:
    207    case PGM_DEC_OVERFLOW:
    208    case PGM_DEC_DIVIDE:
    209    case PGM_HFP_EXP_OVERFLOW:
    210    case PGM_HFP_EXP_UNDERFLOW:
    211    case PGM_HFP_SIGNIFICANCE:
    212    case PGM_HFP_DIVIDE:
    213    case PGM_TRANS_SPEC:
    214    case PGM_SPECIAL_OP:
    215    case PGM_OPERAND:
    216    case PGM_HFP_SQRT:
    217    case PGM_PC_TRANS_SPEC:
    218    case PGM_ALET_SPEC:
    219    case PGM_MONITOR:
    220        /* advance the PSW if our exception is not nullifying */
    221        env->psw.addr += ilen;
    222        break;
    223    }
    224
    225    qemu_log_mask(CPU_LOG_INT,
    226                  "%s: code=0x%x ilen=%d psw: %" PRIx64 " %" PRIx64 "\n",
    227                  __func__, env->int_pgm_code, ilen, env->psw.mask,
    228                  env->psw.addr);
    229
    230    lowcore = cpu_map_lowcore(env);
    231
    232    /* Signal PER events with the exception.  */
    233    if (env->per_perc_atmid) {
    234        env->int_pgm_code |= PGM_PER;
    235        lowcore->per_address = cpu_to_be64(env->per_address);
    236        lowcore->per_perc_atmid = cpu_to_be16(env->per_perc_atmid);
    237        env->per_perc_atmid = 0;
    238    }
    239
    240    lowcore->pgm_ilen = cpu_to_be16(ilen);
    241    lowcore->pgm_code = cpu_to_be16(env->int_pgm_code);
    242    lowcore->program_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
    243    lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr);
    244    mask = be64_to_cpu(lowcore->program_new_psw.mask);
    245    addr = be64_to_cpu(lowcore->program_new_psw.addr);
    246    lowcore->per_breaking_event_addr = cpu_to_be64(env->gbea);
    247
    248    cpu_unmap_lowcore(lowcore);
    249
    250    s390_cpu_set_psw(env, mask, addr);
    251}
    252
    253static void do_svc_interrupt(CPUS390XState *env)
    254{
    255    uint64_t mask, addr;
    256    LowCore *lowcore;
    257
    258    lowcore = cpu_map_lowcore(env);
    259
    260    lowcore->svc_code = cpu_to_be16(env->int_svc_code);
    261    lowcore->svc_ilen = cpu_to_be16(env->int_svc_ilen);
    262    lowcore->svc_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
    263    lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + env->int_svc_ilen);
    264    mask = be64_to_cpu(lowcore->svc_new_psw.mask);
    265    addr = be64_to_cpu(lowcore->svc_new_psw.addr);
    266
    267    cpu_unmap_lowcore(lowcore);
    268
    269    s390_cpu_set_psw(env, mask, addr);
    270
    271    /* When a PER event is pending, the PER exception has to happen
    272       immediately after the SERVICE CALL one.  */
    273    if (env->per_perc_atmid) {
    274        env->int_pgm_code = PGM_PER;
    275        env->int_pgm_ilen = env->int_svc_ilen;
    276        do_program_interrupt(env);
    277    }
    278}
    279
    280#define VIRTIO_SUBCODE_64 0x0D00
    281
    282static void do_ext_interrupt(CPUS390XState *env)
    283{
    284    QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic());
    285    S390CPU *cpu = env_archcpu(env);
    286    uint64_t mask, addr;
    287    uint16_t cpu_addr;
    288    LowCore *lowcore;
    289
    290    if (!(env->psw.mask & PSW_MASK_EXT)) {
    291        cpu_abort(CPU(cpu), "Ext int w/o ext mask\n");
    292    }
    293
    294    lowcore = cpu_map_lowcore(env);
    295
    296    if ((env->pending_int & INTERRUPT_EMERGENCY_SIGNAL) &&
    297        (env->cregs[0] & CR0_EMERGENCY_SIGNAL_SC)) {
    298        MachineState *ms = MACHINE(qdev_get_machine());
    299        unsigned int max_cpus = ms->smp.max_cpus;
    300
    301        lowcore->ext_int_code = cpu_to_be16(EXT_EMERGENCY);
    302        cpu_addr = find_first_bit(env->emergency_signals, S390_MAX_CPUS);
    303        g_assert(cpu_addr < S390_MAX_CPUS);
    304        lowcore->cpu_addr = cpu_to_be16(cpu_addr);
    305        clear_bit(cpu_addr, env->emergency_signals);
    306        if (bitmap_empty(env->emergency_signals, max_cpus)) {
    307            env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL;
    308        }
    309    } else if ((env->pending_int & INTERRUPT_EXTERNAL_CALL) &&
    310               (env->cregs[0] & CR0_EXTERNAL_CALL_SC)) {
    311        lowcore->ext_int_code = cpu_to_be16(EXT_EXTERNAL_CALL);
    312        lowcore->cpu_addr = cpu_to_be16(env->external_call_addr);
    313        env->pending_int &= ~INTERRUPT_EXTERNAL_CALL;
    314    } else if ((env->pending_int & INTERRUPT_EXT_CLOCK_COMPARATOR) &&
    315               (env->cregs[0] & CR0_CKC_SC)) {
    316        lowcore->ext_int_code = cpu_to_be16(EXT_CLOCK_COMP);
    317        lowcore->cpu_addr = 0;
    318        env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR;
    319    } else if ((env->pending_int & INTERRUPT_EXT_CPU_TIMER) &&
    320               (env->cregs[0] & CR0_CPU_TIMER_SC)) {
    321        lowcore->ext_int_code = cpu_to_be16(EXT_CPU_TIMER);
    322        lowcore->cpu_addr = 0;
    323        env->pending_int &= ~INTERRUPT_EXT_CPU_TIMER;
    324    } else if (qemu_s390_flic_has_service(flic) &&
    325               (env->cregs[0] & CR0_SERVICE_SC)) {
    326        uint32_t param;
    327
    328        param = qemu_s390_flic_dequeue_service(flic);
    329        lowcore->ext_int_code = cpu_to_be16(EXT_SERVICE);
    330        lowcore->ext_params = cpu_to_be32(param);
    331        lowcore->cpu_addr = 0;
    332    } else {
    333        g_assert_not_reached();
    334    }
    335
    336    mask = be64_to_cpu(lowcore->external_new_psw.mask);
    337    addr = be64_to_cpu(lowcore->external_new_psw.addr);
    338    lowcore->external_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
    339    lowcore->external_old_psw.addr = cpu_to_be64(env->psw.addr);
    340
    341    cpu_unmap_lowcore(lowcore);
    342
    343    s390_cpu_set_psw(env, mask, addr);
    344}
    345
    346static void do_io_interrupt(CPUS390XState *env)
    347{
    348    QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic());
    349    uint64_t mask, addr;
    350    QEMUS390FlicIO *io;
    351    LowCore *lowcore;
    352
    353    g_assert(env->psw.mask & PSW_MASK_IO);
    354    io = qemu_s390_flic_dequeue_io(flic, env->cregs[6]);
    355    g_assert(io);
    356
    357    lowcore = cpu_map_lowcore(env);
    358
    359    lowcore->subchannel_id = cpu_to_be16(io->id);
    360    lowcore->subchannel_nr = cpu_to_be16(io->nr);
    361    lowcore->io_int_parm = cpu_to_be32(io->parm);
    362    lowcore->io_int_word = cpu_to_be32(io->word);
    363    lowcore->io_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
    364    lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
    365    mask = be64_to_cpu(lowcore->io_new_psw.mask);
    366    addr = be64_to_cpu(lowcore->io_new_psw.addr);
    367
    368    cpu_unmap_lowcore(lowcore);
    369    g_free(io);
    370
    371    s390_cpu_set_psw(env, mask, addr);
    372}
    373
    374typedef struct MchkExtSaveArea {
    375    uint64_t    vregs[32][2];                     /* 0x0000 */
    376    uint8_t     pad_0x0200[0x0400 - 0x0200];      /* 0x0200 */
    377} MchkExtSaveArea;
    378QEMU_BUILD_BUG_ON(sizeof(MchkExtSaveArea) != 1024);
    379
    380static int mchk_store_vregs(CPUS390XState *env, uint64_t mcesao)
    381{
    382    hwaddr len = sizeof(MchkExtSaveArea);
    383    MchkExtSaveArea *sa;
    384    int i;
    385
    386    sa = cpu_physical_memory_map(mcesao, &len, true);
    387    if (!sa) {
    388        return -EFAULT;
    389    }
    390    if (len != sizeof(MchkExtSaveArea)) {
    391        cpu_physical_memory_unmap(sa, len, 1, 0);
    392        return -EFAULT;
    393    }
    394
    395    for (i = 0; i < 32; i++) {
    396        sa->vregs[i][0] = cpu_to_be64(env->vregs[i][0]);
    397        sa->vregs[i][1] = cpu_to_be64(env->vregs[i][1]);
    398    }
    399
    400    cpu_physical_memory_unmap(sa, len, 1, len);
    401    return 0;
    402}
    403
    404static void do_mchk_interrupt(CPUS390XState *env)
    405{
    406    QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic());
    407    uint64_t mcic = s390_build_validity_mcic() | MCIC_SC_CP;
    408    uint64_t mask, addr, mcesao = 0;
    409    LowCore *lowcore;
    410    int i;
    411
    412    /* for now we only support channel report machine checks (floating) */
    413    g_assert(env->psw.mask & PSW_MASK_MCHECK);
    414    g_assert(env->cregs[14] & CR14_CHANNEL_REPORT_SC);
    415
    416    qemu_s390_flic_dequeue_crw_mchk(flic);
    417
    418    lowcore = cpu_map_lowcore(env);
    419
    420    /* extended save area */
    421    if (mcic & MCIC_VB_VR) {
    422        /* length and alignment is 1024 bytes */
    423        mcesao = be64_to_cpu(lowcore->mcesad) & ~0x3ffull;
    424    }
    425
    426    /* try to store vector registers */
    427    if (!mcesao || mchk_store_vregs(env, mcesao)) {
    428        mcic &= ~MCIC_VB_VR;
    429    }
    430
    431    /* we are always in z/Architecture mode */
    432    lowcore->ar_access_id = 1;
    433
    434    for (i = 0; i < 16; i++) {
    435        lowcore->floating_pt_save_area[i] = cpu_to_be64(*get_freg(env, i));
    436        lowcore->gpregs_save_area[i] = cpu_to_be64(env->regs[i]);
    437        lowcore->access_regs_save_area[i] = cpu_to_be32(env->aregs[i]);
    438        lowcore->cregs_save_area[i] = cpu_to_be64(env->cregs[i]);
    439    }
    440    lowcore->prefixreg_save_area = cpu_to_be32(env->psa);
    441    lowcore->fpt_creg_save_area = cpu_to_be32(env->fpc);
    442    lowcore->tod_progreg_save_area = cpu_to_be32(env->todpr);
    443    lowcore->cpu_timer_save_area = cpu_to_be64(env->cputm);
    444    lowcore->clock_comp_save_area = cpu_to_be64(env->ckc >> 8);
    445
    446    lowcore->mcic = cpu_to_be64(mcic);
    447    lowcore->mcck_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
    448    lowcore->mcck_old_psw.addr = cpu_to_be64(env->psw.addr);
    449    mask = be64_to_cpu(lowcore->mcck_new_psw.mask);
    450    addr = be64_to_cpu(lowcore->mcck_new_psw.addr);
    451
    452    cpu_unmap_lowcore(lowcore);
    453
    454    s390_cpu_set_psw(env, mask, addr);
    455}
    456
    457void s390_cpu_do_interrupt(CPUState *cs)
    458{
    459    QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic());
    460    S390CPU *cpu = S390_CPU(cs);
    461    CPUS390XState *env = &cpu->env;
    462    bool stopped = false;
    463
    464    qemu_log_mask(CPU_LOG_INT, "%s: %d at psw=%" PRIx64 ":%" PRIx64 "\n",
    465                  __func__, cs->exception_index, env->psw.mask, env->psw.addr);
    466
    467try_deliver:
    468    /* handle machine checks */
    469    if (cs->exception_index == -1 && s390_cpu_has_mcck_int(cpu)) {
    470        cs->exception_index = EXCP_MCHK;
    471    }
    472    /* handle external interrupts */
    473    if (cs->exception_index == -1 && s390_cpu_has_ext_int(cpu)) {
    474        cs->exception_index = EXCP_EXT;
    475    }
    476    /* handle I/O interrupts */
    477    if (cs->exception_index == -1 && s390_cpu_has_io_int(cpu)) {
    478        cs->exception_index = EXCP_IO;
    479    }
    480    /* RESTART interrupt */
    481    if (cs->exception_index == -1 && s390_cpu_has_restart_int(cpu)) {
    482        cs->exception_index = EXCP_RESTART;
    483    }
    484    /* STOP interrupt has least priority */
    485    if (cs->exception_index == -1 && s390_cpu_has_stop_int(cpu)) {
    486        cs->exception_index = EXCP_STOP;
    487    }
    488
    489    switch (cs->exception_index) {
    490    case EXCP_PGM:
    491        do_program_interrupt(env);
    492        break;
    493    case EXCP_SVC:
    494        do_svc_interrupt(env);
    495        break;
    496    case EXCP_EXT:
    497        do_ext_interrupt(env);
    498        break;
    499    case EXCP_IO:
    500        do_io_interrupt(env);
    501        break;
    502    case EXCP_MCHK:
    503        do_mchk_interrupt(env);
    504        break;
    505    case EXCP_RESTART:
    506        do_restart_interrupt(env);
    507        break;
    508    case EXCP_STOP:
    509        do_stop_interrupt(env);
    510        stopped = true;
    511        break;
    512    }
    513
    514    if (cs->exception_index != -1 && !stopped) {
    515        /* check if there are more pending interrupts to deliver */
    516        cs->exception_index = -1;
    517        goto try_deliver;
    518    }
    519    cs->exception_index = -1;
    520
    521    /* we might still have pending interrupts, but not deliverable */
    522    if (!env->pending_int && !qemu_s390_flic_has_any(flic)) {
    523        cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
    524    }
    525
    526    /* WAIT PSW during interrupt injection or STOP interrupt */
    527    if ((env->psw.mask & PSW_MASK_WAIT) || stopped) {
    528        /* don't trigger a cpu_loop_exit(), use an interrupt instead */
    529        cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT);
    530    } else if (cs->halted) {
    531        /* unhalt if we had a WAIT PSW somehwere in our injection chain */
    532        s390_cpu_unhalt(cpu);
    533    }
    534}
    535
    536bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
    537{
    538    if (interrupt_request & CPU_INTERRUPT_HARD) {
    539        S390CPU *cpu = S390_CPU(cs);
    540        CPUS390XState *env = &cpu->env;
    541
    542        if (env->ex_value) {
    543            /* Execution of the target insn is indivisible from
    544               the parent EXECUTE insn.  */
    545            return false;
    546        }
    547        if (s390_cpu_has_int(cpu)) {
    548            s390_cpu_do_interrupt(cs);
    549            return true;
    550        }
    551        if (env->psw.mask & PSW_MASK_WAIT) {
    552            /* Woken up because of a floating interrupt but it has already
    553             * been delivered. Go back to sleep. */
    554            cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT);
    555        }
    556    }
    557    return false;
    558}
    559
    560void s390x_cpu_debug_excp_handler(CPUState *cs)
    561{
    562    S390CPU *cpu = S390_CPU(cs);
    563    CPUS390XState *env = &cpu->env;
    564    CPUWatchpoint *wp_hit = cs->watchpoint_hit;
    565
    566    if (wp_hit && wp_hit->flags & BP_CPU) {
    567        /* FIXME: When the storage-alteration-space control bit is set,
    568           the exception should only be triggered if the memory access
    569           is done using an address space with the storage-alteration-event
    570           bit set.  We have no way to detect that with the current
    571           watchpoint code.  */
    572        cs->watchpoint_hit = NULL;
    573
    574        env->per_address = env->psw.addr;
    575        env->per_perc_atmid |= PER_CODE_EVENT_STORE | get_per_atmid(env);
    576        /* FIXME: We currently no way to detect the address space used
    577           to trigger the watchpoint.  For now just consider it is the
    578           current default ASC. This turn to be true except when MVCP
    579           and MVCS instrutions are not used.  */
    580        env->per_perc_atmid |= env->psw.mask & (PSW_MASK_ASC) >> 46;
    581
    582        /*
    583         * Remove all watchpoints to re-execute the code.  A PER exception
    584         * will be triggered, it will call s390_cpu_set_psw which will
    585         * recompute the watchpoints.
    586         */
    587        cpu_watchpoint_remove_all(cs, BP_CPU);
    588        cpu_loop_exit_noexc(cs);
    589    }
    590}
    591
    592/* Unaligned accesses are only diagnosed with MO_ALIGN.  At the moment,
    593   this is only for the atomic operations, for which we want to raise a
    594   specification exception.  */
    595void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
    596                                   MMUAccessType access_type,
    597                                   int mmu_idx, uintptr_t retaddr)
    598{
    599    S390CPU *cpu = S390_CPU(cs);
    600    CPUS390XState *env = &cpu->env;
    601
    602    tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
    603}
    604
    605static void QEMU_NORETURN monitor_event(CPUS390XState *env,
    606                                        uint64_t monitor_code,
    607                                        uint8_t monitor_class, uintptr_t ra)
    608{
    609    /* Store the Monitor Code and the Monitor Class Number into the lowcore */
    610    stq_phys(env_cpu(env)->as,
    611             env->psa + offsetof(LowCore, monitor_code), monitor_code);
    612    stw_phys(env_cpu(env)->as,
    613             env->psa + offsetof(LowCore, mon_class_num), monitor_class);
    614
    615    tcg_s390_program_interrupt(env, PGM_MONITOR, ra);
    616}
    617
    618void HELPER(monitor_call)(CPUS390XState *env, uint64_t monitor_code,
    619                          uint32_t monitor_class)
    620{
    621    g_assert(monitor_class <= 0xff);
    622
    623    if (env->cregs[8] & (0x8000 >> monitor_class)) {
    624        monitor_event(env, monitor_code, monitor_class, GETPC());
    625    }
    626}
    627
    628#endif /* !CONFIG_USER_ONLY */