From b498484ed49ab9d1fcada3468f95dda1a5f59366 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 4 Nov 2015 18:40:54 +0100 Subject: [PATCH] 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 Tested-by: Andy Lutomirski Signed-off-by: Cornelia Huck Reviewed-by: Christian Borntraeger --- hw/s390x/css.c | 6 ++++++ 1 file changed, 6 insertions(+) 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); } } -- 2.11.4.GIT