summary refs log tree commit diff stats
path: root/hw/s390x/css.c
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2015-11-04 18:40:54 +0100
committerCornelia Huck <cornelia.huck@de.ibm.com>2015-11-11 17:21:38 +0100
commitb498484ed49ab9d1fcada3468f95dda1a5f59366 (patch)
tree6a09ceff242d677ac896de65ab14dafa5fb35e03 /hw/s390x/css.c
parent3c07587d49458341510360557c849e93e9afaf59 (diff)
downloadfocaccia-qemu-b498484ed49ab9d1fcada3468f95dda1a5f59366.tar.gz
focaccia-qemu-b498484ed49ab9d1fcada3468f95dda1a5f59366.zip
s390x/css: sense data endianness
We keep the device's sense data in a byte array (following the
architecture), but the ecws are an array of 32 bit values. If we
just blindly copy the values, the sense data will change from
de-facto BE data to de-facto cpu-endian data, which means we end
up doing an incorrect conversion on LE hosts.

Let's just explicitly convert to cpu-endianness while assembling
the irb.

Reported-by: Andy Lutomirski <luto@kernel.org>
Tested-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'hw/s390x/css.c')
-rw-r--r--hw/s390x/css.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index c033612889..19851ce6a9 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -892,8 +892,14 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
         /* If a unit check is pending, copy sense data. */
         if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
             (p->chars & PMCW_CHARS_MASK_CSENSE)) {
+            int i;
+
             irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
+            /* Attention: sense_data is already BE! */
             memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
+            for (i = 0; i < ARRAY_SIZE(irb.ecw); i++) {
+                irb.ecw[i] = be32_to_cpu(irb.ecw[i]);
+            }
             irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
         }
     }