Commit bbf6ea3b authored by David Hildenbrand's avatar David Hildenbrand Committed by Cornelia Huck
Browse files

s390x/tcg: factor out and fix DATA exception injection



The DXC is to be stored in the low core, and only in the FPC in case AFP
is enabled in CR0. Stub is not required in current code, but this way
we never run into problems.

Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Reviewed-by: default avatarThomas Huth <thuth@redhat.com>
Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Message-Id: <20180927130303.12236-3-david@redhat.com>
Signed-off-by: default avatarCornelia Huck <cohuck@redhat.com>
parent 52341ed6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -322,6 +322,7 @@ extern const struct VMStateDescription vmstate_s390_cpu;
#define CR0_LOWPROT             0x0000000010000000ULL
#define CR0_SECONDARY           0x0000000004000000ULL
#define CR0_EDAT                0x0000000000800000ULL
#define CR0_AFP                 0x0000000000040000ULL
#define CR0_EMERGENCY_SIGNAL_SC 0x0000000000004000ULL
#define CR0_EXTERNAL_CALL_SC    0x0000000000002000ULL
#define CR0_CKC_SC              0x0000000000000800ULL
+23 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "internal.h"
#include "exec/helper-proto.h"
#include "qemu/timer.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
@@ -61,6 +62,28 @@ void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,
    cpu_loop_exit(cs);
}

void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc,
                                           uintptr_t ra)
{
    g_assert(dxc <= 0xff);
#if !defined(CONFIG_USER_ONLY)
    /* Store the DXC into the lowcore */
    stl_phys(CPU(s390_env_get_cpu(env))->as,
             env->psa + offsetof(LowCore, data_exc_code), dxc);
#endif

    /* Store the DXC into the FPC if AFP is enabled */
    if (env->cregs[0] & CR0_AFP) {
        env->fpc = deposit32(env->fpc, 8, 8, dxc);
    }
    tcg_s390_program_interrupt(env, PGM_DATA, ILEN_AUTO, ra);
}

void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
{
    tcg_s390_data_exception(env, dxc, GETPC());
}

#if defined(CONFIG_USER_ONLY)

void s390_cpu_do_interrupt(CPUState *cs)
+3 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "internal.h"
#include "tcg_s390x.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#include "exec/helper-proto.h"
@@ -40,14 +41,6 @@
     ? (mask / (from / to)) & to    \
     : (mask & from) * (to / from))

static void ieee_exception(CPUS390XState *env, uint32_t dxc, uintptr_t retaddr)
{
    /* Install the DXC code.  */
    env->fpc = (env->fpc & ~0xff00) | (dxc << 8);
    /* Trap.  */
    s390_program_interrupt(env, PGM_DATA, ILEN_AUTO, retaddr);
}

/* Should be called after any operation that may raise IEEE exceptions.  */
static void handle_exceptions(CPUS390XState *env, uintptr_t retaddr)
{
@@ -75,7 +68,7 @@ static void handle_exceptions(CPUS390XState *env, uintptr_t retaddr)
    /* Send signals for enabled exceptions.  */
    s390_exc &= env->fpc >> 24;
    if (s390_exc) {
        ieee_exception(env, s390_exc, retaddr);
        tcg_s390_data_exception(env, s390_exc, retaddr);
    }
}

@@ -773,6 +766,6 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t val)
       is also 1, a simulated-iee-exception trap occurs.  */
    s390_exc = (signalling >> 16) & (source >> 24);
    if (s390_exc) {
        ieee_exception(env, s390_exc | 3, GETPC());
        tcg_s390_data_exception(env, s390_exc | 3, GETPC());
    }
}
+1 −0
Original line number Diff line number Diff line
DEF_HELPER_2(exception, noreturn, env, i32)
DEF_HELPER_2(data_exception, noreturn, env, i32)
DEF_HELPER_FLAGS_4(nc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(oc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(xc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
+5 −0
Original line number Diff line number Diff line
@@ -23,3 +23,8 @@ void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,
{
    g_assert_not_reached();
}
void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc,
                                           uintptr_t ra)
{
    g_assert_not_reached();
}
Loading