From: Cornelia Huck Date: Tue, 27 May 2014 10:40:44 +0000 (+0200) Subject: s390x/css: handle emw correctly for tsch X-Git-Tag: qemu-xen-4.5.0-rc1^2~52 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=0d38666664f9805535766c5d5feb5c849cf793db;p=qemu-upstream-4.6-testing.git s390x/css: handle emw correctly for tsch We should not try to store the emw portion of the irb if extended measurements are not applicable. In particular, we should not surprise the guest by storing a larger irb if it did not enable extended measurements. Cc: qemu-stable@nongnu.org Reviewed-by: David Hildenbrand Tested-by: Christian Borntraeger Signed-off-by: Cornelia Huck (cherry picked from commit f068d320def7fd83bf0fcdca37b305f1c2ac5413) Signed-off-by: Michael Roth --- diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 7074d2b3d..d68a29a82 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -734,9 +734,11 @@ out: return ret; } -static void copy_irb_to_guest(IRB *dest, const IRB *src) +static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw) { int i; + uint16_t stctl = src->scsw.ctrl & SCSW_CTRL_MASK_STCTL; + uint16_t actl = src->scsw.ctrl & SCSW_CTRL_MASK_ACTL; copy_scsw_to_guest(&dest->scsw, &src->scsw); @@ -746,8 +748,22 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src) for (i = 0; i < ARRAY_SIZE(dest->ecw); i++) { dest->ecw[i] = cpu_to_be32(src->ecw[i]); } - for (i = 0; i < ARRAY_SIZE(dest->emw); i++) { - dest->emw[i] = cpu_to_be32(src->emw[i]); + /* extended measurements enabled? */ + if ((src->scsw.flags & SCSW_FLAGS_MASK_ESWF) || + !(pmcw->flags & PMCW_FLAGS_MASK_TF) || + !(pmcw->chars & PMCW_CHARS_MASK_XMWME)) { + return; + } + /* extended measurements pending? */ + if (!(stctl & SCSW_STCTL_STATUS_PEND)) { + return; + } + if ((stctl & SCSW_STCTL_PRIMARY) || + (stctl == SCSW_STCTL_SECONDARY) || + ((stctl & SCSW_STCTL_INTERMEDIATE) && (actl & SCSW_ACTL_SUSP))) { + for (i = 0; i < ARRAY_SIZE(dest->emw); i++) { + dest->emw[i] = cpu_to_be32(src->emw[i]); + } } } @@ -793,7 +809,7 @@ int css_do_tsch(SubchDev *sch, IRB *target_irb) } } /* Store the irb to the guest. */ - copy_irb_to_guest(target_irb, &irb); + copy_irb_to_guest(target_irb, &irb, p); /* Clear conditions on subchannel, if applicable. */ if (stctl & SCSW_STCTL_STATUS_PEND) {