aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/mem_helper.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2018-02-15 11:38:22 +0100
committerCornelia Huck <cohuck@redhat.com>2018-02-26 12:55:26 +0100
commit21fc97c5fff10433d839047da44eee652f050041 (patch)
tree0d1afe20f6540901a542d7ded5cf2161a4cbf3f0 /target/s390x/mem_helper.c
parentf26852aa31d49bf83a8defd65538137a2f9da82c (diff)
s390x/tcg: add various alignment checks
Let's add proper alignment checks for a handful of instructions that require a SPECIFICATION exception in case alignment is violated. Introduce new wout/in functions. As we are right now only using them for privileged instructions, we have to add ugly ifdefs to silence compilers. Convert STORE CPU ID right away to make use of the wout function. Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20180215103822.15179-1-david@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/mem_helper.c')
-rw-r--r--target/s390x/mem_helper.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 427b795a78..d5291b246e 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -693,6 +693,11 @@ void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
uintptr_t ra = GETPC();
int i;
+ if (a2 & 0x3) {
+ /* we either came here by lam or lamy, which have different lengths */
+ s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
+ }
+
for (i = r1;; i = (i + 1) % 16) {
env->aregs[i] = cpu_ldl_data_ra(env, a2, ra);
a2 += 4;
@@ -709,6 +714,10 @@ void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
uintptr_t ra = GETPC();
int i;
+ if (a2 & 0x3) {
+ s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+ }
+
for (i = r1;; i = (i + 1) % 16) {
cpu_stl_data_ra(env, a2, env->aregs[i], ra);
a2 += 4;
@@ -1620,6 +1629,10 @@ void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
uint64_t src = a2;
uint32_t i;
+ if (src & 0x7) {
+ s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+ }
+
for (i = r1;; i = (i + 1) % 16) {
uint64_t val = cpu_ldq_data_ra(env, src, ra);
if (env->cregs[i] != val && i >= 9 && i <= 11) {
@@ -1650,6 +1663,10 @@ void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
uint64_t src = a2;
uint32_t i;
+ if (src & 0x3) {
+ s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+ }
+
for (i = r1;; i = (i + 1) % 16) {
uint32_t val = cpu_ldl_data_ra(env, src, ra);
if ((uint32_t)env->cregs[i] != val && i >= 9 && i <= 11) {
@@ -1677,6 +1694,10 @@ void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
uint64_t dest = a2;
uint32_t i;
+ if (dest & 0x7) {
+ s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+ }
+
for (i = r1;; i = (i + 1) % 16) {
cpu_stq_data_ra(env, dest, env->cregs[i], ra);
dest += sizeof(uint64_t);
@@ -1693,6 +1714,10 @@ void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
uint64_t dest = a2;
uint32_t i;
+ if (dest & 0x3) {
+ s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+ }
+
for (i = r1;; i = (i + 1) % 16) {
cpu_stl_data_ra(env, dest, env->cregs[i], ra);
dest += sizeof(uint32_t);