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