summaryrefslogtreecommitdiff
path: root/target/s390x/excp_helper.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2018-09-27 15:02:56 +0200
committerCornelia Huck <cohuck@redhat.com>2018-10-04 10:32:39 +0200
commitbbf6ea3bd961970785a583117ac1c0b84a8ee736 (patch)
tree8c00137c06cfbdbec9a51a6b0fe09e2d7d147052 /target/s390x/excp_helper.c
parent52341ed61d3a7b84602f6ee6b4234027ed5e6172 (diff)
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: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20180927130303.12236-3-david@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/excp_helper.c')
-rw-r--r--target/s390x/excp_helper.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 5dab3387c3..cd76c3163a 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -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)