yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
a83cc2
From 0f4d8c51b51a23a87f1e3e9e764151352f652f3b Mon Sep 17 00:00:00 2001
a83cc2
From: Eric Farman <farman@linux.ibm.com>
a83cc2
Date: Thu, 24 Jun 2021 14:15:15 -0400
a83cc2
Subject: [PATCH 03/43] s390x/css: Refactor IRB construction
a83cc2
a83cc2
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
a83cc2
RH-Bugzilla: 1957194
a83cc2
a83cc2
Currently, all subchannel types have "sense data" copied into
a83cc2
the IRB.ECW space, and a couple flags enabled in the IRB.SCSW
a83cc2
and IRB.ESW. But for passthrough (vfio-ccw) subchannels,
a83cc2
this data isn't populated in the first place, so enabling
a83cc2
those flags leads to unexpected behavior if the guest tries to
a83cc2
process the sense data (zeros) in the IRB.ECW.
a83cc2
a83cc2
Let's add a subchannel callback that builds these portions of
a83cc2
the IRB, and move the existing code into a routine for those
a83cc2
virtual subchannels. The passthrough subchannels will be able
a83cc2
to piggy-back onto this later.
a83cc2
a83cc2
Signed-off-by: Eric Farman <farman@linux.ibm.com>
a83cc2
Message-Id: <20210617232537.1337506-4-farman@linux.ibm.com>
a83cc2
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
a83cc2
(cherry picked from commit 0599a046acf1b625e97cef0aa702b5d86528c642)
a83cc2
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
a83cc2
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
a83cc2
---
a83cc2
 hw/s390x/3270-ccw.c    |  1 +
a83cc2
 hw/s390x/css.c         | 45 +++++++++++++++++++++++++++---------------
a83cc2
 hw/s390x/virtio-ccw.c  |  1 +
a83cc2
 include/hw/s390x/css.h |  2 ++
a83cc2
 4 files changed, 33 insertions(+), 16 deletions(-)
a83cc2
a83cc2
diff --git a/hw/s390x/3270-ccw.c b/hw/s390x/3270-ccw.c
a83cc2
index f3e7342b1e..9efee591f9 100644
a83cc2
--- a/hw/s390x/3270-ccw.c
a83cc2
+++ b/hw/s390x/3270-ccw.c
a83cc2
@@ -130,6 +130,7 @@ static void emulated_ccw_3270_realize(DeviceState *ds, Error **errp)
a83cc2
                                 EMULATED_CCW_3270_CHPID_TYPE);
a83cc2
     sch->do_subchannel_work = do_subchannel_work_virtual;
a83cc2
     sch->ccw_cb = emulated_ccw_3270_cb;
a83cc2
+    sch->irb_cb = build_irb_virtual;
a83cc2
 
a83cc2
     ck->init(dev, &err;;
a83cc2
     if (err) {
a83cc2
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
a83cc2
index fac7d5b39d..e77a0e523d 100644
a83cc2
--- a/hw/s390x/css.c
a83cc2
+++ b/hw/s390x/css.c
a83cc2
@@ -1651,6 +1651,30 @@ static void build_irb_sense_data(SubchDev *sch, IRB *irb)
a83cc2
     }
a83cc2
 }
a83cc2
 
a83cc2
+void build_irb_virtual(SubchDev *sch, IRB *irb)
a83cc2
+{
a83cc2
+    SCHIB *schib = &sch->curr_status;
a83cc2
+    uint16_t stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
a83cc2
+
a83cc2
+    if (stctl & SCSW_STCTL_STATUS_PEND) {
a83cc2
+        if (schib->scsw.cstat & (SCSW_CSTAT_DATA_CHECK |
a83cc2
+                        SCSW_CSTAT_CHN_CTRL_CHK |
a83cc2
+                        SCSW_CSTAT_INTF_CTRL_CHK)) {
a83cc2
+            irb->scsw.flags |= SCSW_FLAGS_MASK_ESWF;
a83cc2
+            irb->esw.word0 = 0x04804000;
a83cc2
+        } else {
a83cc2
+            irb->esw.word0 = 0x00800000;
a83cc2
+        }
a83cc2
+        /* If a unit check is pending, copy sense data. */
a83cc2
+        if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
a83cc2
+            (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
a83cc2
+            irb->scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
a83cc2
+            build_irb_sense_data(sch, irb);
a83cc2
+            irb->esw.erw = ESW_ERW_SENSE | (sizeof(sch->sense_data) << 8);
a83cc2
+        }
a83cc2
+    }
a83cc2
+}
a83cc2
+
a83cc2
 int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
a83cc2
 {
a83cc2
     SCHIB *schib = &sch->curr_status;
a83cc2
@@ -1669,23 +1693,12 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
a83cc2
 
a83cc2
     /* Copy scsw from current status. */
a83cc2
     irb.scsw = schib->scsw;
a83cc2
-    if (stctl & SCSW_STCTL_STATUS_PEND) {
a83cc2
-        if (schib->scsw.cstat & (SCSW_CSTAT_DATA_CHECK |
a83cc2
-                        SCSW_CSTAT_CHN_CTRL_CHK |
a83cc2
-                        SCSW_CSTAT_INTF_CTRL_CHK)) {
a83cc2
-            irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
a83cc2
-            irb.esw.word0 = 0x04804000;
a83cc2
-        } else {
a83cc2
-            irb.esw.word0 = 0x00800000;
a83cc2
-        }
a83cc2
-        /* If a unit check is pending, copy sense data. */
a83cc2
-        if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
a83cc2
-            (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
a83cc2
-            irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
a83cc2
-            build_irb_sense_data(sch, &irb);
a83cc2
-            irb.esw.erw = ESW_ERW_SENSE | (sizeof(sch->sense_data) << 8);
a83cc2
-        }
a83cc2
+
a83cc2
+    /* Build other IRB data, if necessary */
a83cc2
+    if (sch->irb_cb) {
a83cc2
+        sch->irb_cb(sch, &irb);
a83cc2
     }
a83cc2
+
a83cc2
     /* Store the irb to the guest. */
a83cc2
     p = schib->pmcw;
a83cc2
     copy_irb_to_guest(target_irb, &irb, &p, irb_len);
a83cc2
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
a83cc2
index 8195f3546e..5a1eb39325 100644
a83cc2
--- a/hw/s390x/virtio-ccw.c
a83cc2
+++ b/hw/s390x/virtio-ccw.c
a83cc2
@@ -754,6 +754,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
a83cc2
     sch->id.reserved = 0xff;
a83cc2
     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
a83cc2
     sch->do_subchannel_work = do_subchannel_work_virtual;
a83cc2
+    sch->irb_cb = build_irb_virtual;
a83cc2
     ccw_dev->sch = sch;
a83cc2
     dev->indicators = NULL;
a83cc2
     dev->revision = -1;
a83cc2
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
a83cc2
index bba7593d2e..7c23a13f3d 100644
a83cc2
--- a/include/hw/s390x/css.h
a83cc2
+++ b/include/hw/s390x/css.h
a83cc2
@@ -138,6 +138,7 @@ struct SubchDev {
a83cc2
     int (*ccw_cb) (SubchDev *, CCW1);
a83cc2
     void (*disable_cb)(SubchDev *);
a83cc2
     IOInstEnding (*do_subchannel_work) (SubchDev *);
a83cc2
+    void (*irb_cb)(SubchDev *, IRB *);
a83cc2
     SenseId id;
a83cc2
     void *driver_data;
a83cc2
 };
a83cc2
@@ -215,6 +216,7 @@ void css_clear_sei_pending(void);
a83cc2
 IOInstEnding s390_ccw_cmd_request(SubchDev *sch);
a83cc2
 IOInstEnding do_subchannel_work_virtual(SubchDev *sub);
a83cc2
 IOInstEnding do_subchannel_work_passthrough(SubchDev *sub);
a83cc2
+void build_irb_virtual(SubchDev *sch, IRB *irb);
a83cc2
 
a83cc2
 int s390_ccw_halt(SubchDev *sch);
a83cc2
 int s390_ccw_clear(SubchDev *sch);
a83cc2
-- 
a83cc2
2.27.0
a83cc2