All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support
@ 2019-01-29 13:29 Jason J. Herne
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
                   ` (16 more replies)
  0 siblings, 17 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

This is to support booting from vfio-ccw dasd devices. We basically implement
the real hardware ipl procedure. This allows for booting Linux guests on
vfio-ccw devices.

vfio-ccw's channel program prefetch algorithm complicates ipl because most ipl
channel programs dynamically modify themselves. Details on the ipl process and
how we worked around this issue can be found in docs/devel/s390-dasd-ipl.txt.

This version brings better error handling, namely retrying I/O operations in the
event of some transient failure conditions. I've also renamed the sense data
structures and error output to indicate that they are for eckd dasd only. A few
other fixups as well, see changelog for details.

Changelog
==========
v2
---------
01/15: s390 vfio-ccw: Add bootindex property and IPLB data
- Remove accidental changes to roms/SLOF
- Fix bad include in hw/vfio/ccw.c
- ipl.c: Rename vc to vfio_ccw_dev

10/15: s390-bios: Support for running format-0/1 channel programs
- cio.c: Retry ssch on cc=1 or interface-control-check status
- cio.c: SLI now used instead of special code in irb_error
- Rename CU_TYPE_DASD to CU_TYPE_DASD_3990
- Rename dasd sense data structures and constants
- cio.c: Fix comment typos

11/15: s390-bios: cio error handling
- - Rename dasd sense data structures and constants

12/15: s390-bios: Refactor virtio to run channel programs via cio
- Use SLI for Sense ID ccws.

rfc -> v1
---------
- Retry start subchannel operations on unexpected unit check status
- Print more complete state information on i/o error
- Fixed asm constraints (Q -> QS)
- Align lowcore to 8k boundary
- Initialize next_cpa in run_dynamic_ccw_program to avoid compiler warning
- Cleanup: Rework handling of i/o interrupts in assembler
- Fix netboot image (include cio.o in make file)
- Misc cleanups

Jason J. Herne (15):
  s390 vfio-ccw: Add bootindex property and IPLB data
  s390-bios: decouple cio setup from virtio
  s390-bios: decouple common boot logic from virtio
  s390-bios: Extend find_dev() for non-virtio devices
  s390-bios: Factor finding boot device out of virtio code path
  s390-bios: Clean up cio.h
  s390-bios: Decouple channel i/o logic from virtio
  s390-bios: Map low core memory
  s390-bios: ptr2u32 and u32toptr
  s390-bios: Support for running format-0/1 channel programs
  s390-bios: cio error handling
  s390-bios: Refactor virtio to run channel programs via cio
  s390-bios: Use control unit type to determine boot method
  s390-bios: Add channel command codes/structs needed for dasd-ipl
  s390-bios: Support booting from real dasd device

 docs/devel/s390-dasd-ipl.txt     | 132 ++++++++++++++
 hw/s390x/ipl.c                   |  14 ++
 hw/s390x/s390-ccw.c              |   9 +
 hw/vfio/ccw.c                    |  13 +-
 include/hw/s390x/s390-ccw.h      |   1 +
 include/hw/s390x/vfio-ccw.h      |  38 ++++
 pc-bios/s390-ccw/Makefile        |   2 +-
 pc-bios/s390-ccw/cio.c           | 380 +++++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/cio.h           | 239 +++++++++++++++++++-----
 pc-bios/s390-ccw/dasd-ipl.c      | 249 +++++++++++++++++++++++++
 pc-bios/s390-ccw/dasd-ipl.h      |  16 ++
 pc-bios/s390-ccw/libc.h          |  23 +++
 pc-bios/s390-ccw/main.c          | 161 +++++++++++------
 pc-bios/s390-ccw/netboot.mak     |   2 +-
 pc-bios/s390-ccw/netmain.c       |   1 +
 pc-bios/s390-ccw/s390-arch.h     | 113 ++++++++++++
 pc-bios/s390-ccw/s390-ccw.h      |  10 +-
 pc-bios/s390-ccw/start.S         |  33 +++-
 pc-bios/s390-ccw/virtio-blkdev.c |   1 +
 pc-bios/s390-ccw/virtio.c        |  73 +++-----
 tests/boot-serial-test.c         |   2 +-
 21 files changed, 1332 insertions(+), 180 deletions(-)
 create mode 100644 docs/devel/s390-dasd-ipl.txt
 create mode 100644 include/hw/s390x/vfio-ccw.h
 create mode 100644 pc-bios/s390-ccw/cio.c
 create mode 100644 pc-bios/s390-ccw/dasd-ipl.c
 create mode 100644 pc-bios/s390-ccw/dasd-ipl.h
 create mode 100644 pc-bios/s390-ccw/s390-arch.h

--
2.7.4

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-01-30 16:56   ` Cornelia Huck
                     ` (4 more replies)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio Jason J. Herne
                   ` (15 subsequent siblings)
  16 siblings, 5 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Add bootindex property and iplb data for vfio-ccw devices. This allows us to
forward boot information into the bios for vfio-ccw devices.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
---
 hw/s390x/ipl.c              | 14 ++++++++++++++
 hw/s390x/s390-ccw.c         |  9 +++++++++
 hw/vfio/ccw.c               | 13 +------------
 include/hw/s390x/s390-ccw.h |  1 +
 include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 63 insertions(+), 12 deletions(-)
 create mode 100644 include/hw/s390x/vfio-ccw.h

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 21f64ad..a993f65 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -19,6 +19,7 @@
 #include "hw/loader.h"
 #include "hw/boards.h"
 #include "hw/s390x/virtio-ccw.h"
+#include "hw/s390x/vfio-ccw.h"
 #include "hw/s390x/css.h"
 #include "hw/s390x/ebcdic.h"
 #include "ipl.h"
@@ -311,8 +312,12 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
         VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
             object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
                                 TYPE_VIRTIO_CCW_DEVICE);
+        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
+            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
         if (virtio_ccw_dev) {
             ccw_dev = CCW_DEVICE(virtio_ccw_dev);
+        } else if (vfio_ccw_dev) {
+            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
         } else {
             SCSIDevice *sd = (SCSIDevice *)
                 object_dynamic_cast(OBJECT(dev_st),
@@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
     if (ccw_dev) {
         SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
                                                             TYPE_SCSI_DEVICE);
+        VFIOCCWDevice *vc = (VFIOCCWDevice *)
+            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
 
         if (sd) {
             ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
@@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
             ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
             ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
             ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
+        } else if (vc) {
+            CcwDevice *ccw_dev = CCW_DEVICE(vc);
+
+            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
+            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
+            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
         } else {
             VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
                                                               TYPE_VIRTIO_NET);
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index cad91ee..f5f025d 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -124,6 +124,14 @@ static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
     g_free(cdev->mdevid);
 }
 
+static void s390_ccw_instance_init(Object *obj)
+{
+    S390CCWDevice *dev = S390_CCW_DEVICE(obj);
+
+    device_add_bootindex_property(obj, &dev->bootindex, "bootindex",
+                                  "/disk@0,0", DEVICE(obj), NULL);
+}
+
 static void s390_ccw_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -137,6 +145,7 @@ static void s390_ccw_class_init(ObjectClass *klass, void *data)
 static const TypeInfo s390_ccw_info = {
     .name          = TYPE_S390_CCW,
     .parent        = TYPE_CCW_DEVICE,
+    .instance_init = s390_ccw_instance_init,
     .instance_size = sizeof(S390CCWDevice),
     .class_size    = sizeof(S390CCWDeviceClass),
     .class_init    = s390_ccw_class_init,
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 9246729..d815a4f 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -21,22 +21,11 @@
 #include "hw/vfio/vfio.h"
 #include "hw/vfio/vfio-common.h"
 #include "hw/s390x/s390-ccw.h"
+#include "hw/s390x/vfio-ccw.h"
 #include "hw/s390x/ccw-device.h"
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
 
-#define TYPE_VFIO_CCW "vfio-ccw"
-typedef struct VFIOCCWDevice {
-    S390CCWDevice cdev;
-    VFIODevice vdev;
-    uint64_t io_region_size;
-    uint64_t io_region_offset;
-    struct ccw_io_region *io_region;
-    EventNotifier io_notifier;
-    bool force_orb_pfch;
-    bool warned_orb_pfch;
-} VFIOCCWDevice;
-
 static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch,
                                   const char *msg)
 {
diff --git a/include/hw/s390x/s390-ccw.h b/include/hw/s390x/s390-ccw.h
index 7d15a1a..901d805 100644
--- a/include/hw/s390x/s390-ccw.h
+++ b/include/hw/s390x/s390-ccw.h
@@ -27,6 +27,7 @@ typedef struct S390CCWDevice {
     CcwDevice parent_obj;
     CssDevId hostid;
     char *mdevid;
+    int32_t bootindex;
 } S390CCWDevice;
 
 typedef struct S390CCWDeviceClass {
diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h
new file mode 100644
index 0000000..a7d699d
--- /dev/null
+++ b/include/hw/s390x/vfio-ccw.h
@@ -0,0 +1,38 @@
+/*
+ * vfio based subchannel assignment support
+ *
+ * Copyright 2018 IBM Corp.
+ * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+ *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
+ *            Pierre Morel <pmorel@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef HW_VFIO_CCW_H
+#define HW_VFIO_CCW_H
+
+#include "hw/vfio/vfio-common.h"
+#include "hw/s390x/s390-ccw.h"
+#include "hw/s390x/ccw-device.h"
+
+#define TYPE_VFIO_CCW "vfio-ccw"
+#define VFIO_CCW(obj) \
+        OBJECT_CHECK(VFIOCCWDevice, (obj), TYPE_VFIO_CCW)
+
+
+#define TYPE_VFIO_CCW "vfio-ccw"
+typedef struct VFIOCCWDevice {
+    S390CCWDevice cdev;
+    VFIODevice vdev;
+    uint64_t io_region_size;
+    uint64_t io_region_offset;
+    struct ccw_io_region *io_region;
+    EventNotifier io_notifier;
+    bool force_orb_pfch;
+    bool warned_orb_pfch;
+} VFIOCCWDevice;
+
+#endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-01-30 22:23   ` Farhan Ali
                     ` (2 more replies)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 03/15] s390-bios: decouple common boot logic " Jason J. Herne
                   ` (14 subsequent siblings)
  16 siblings, 3 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Move channel i/o setup code out to a separate function. This decouples cio
setup from the virtio code path and allows us to make use of it for booting
dasd devices.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: Collin Walling <walling@linux.ibm.com>
---
 pc-bios/s390-ccw/main.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 544851d..e82fe2c 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -99,6 +99,18 @@ static void menu_setup(void)
     }
 }
 
+/*
+ * Initialize the channel I/O subsystem so we can talk to our ipl/boot device.
+ */
+static void css_setup(void)
+{
+    /*
+     * Unconditionally enable mss support. In every sane configuration this
+     * will succeed; and even if it doesn't, stsch_err() can handle it.
+     */
+    enable_mss_facility();
+}
+
 static void virtio_setup(void)
 {
     Schib schib;
@@ -109,13 +121,6 @@ static void virtio_setup(void)
     VDev *vdev = virtio_get_device();
     QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
 
-    /*
-     * We unconditionally enable mss support. In every sane configuration,
-     * this will succeed; and even if it doesn't, stsch_err() can deal
-     * with the consequences.
-     */
-    enable_mss_facility();
-
     sclp_get_loadparm_ascii(loadparm_str);
     memcpy(ldp + 10, loadparm_str, LOADPARM_LEN);
     sclp_print(ldp);
@@ -168,6 +173,7 @@ static void virtio_setup(void)
 int main(void)
 {
     sclp_setup();
+    css_setup();
     virtio_setup();
 
     zipl_load(); /* no return */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 03/15] s390-bios: decouple common boot logic from virtio
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-01-30 22:27   ` Farhan Ali
  2019-02-04 10:31   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices Jason J. Herne
                   ` (13 subsequent siblings)
  16 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Create a boot_setup function to handle getting boot information from
the machine/hypervisor. This decouples common boot logic from the
virtio code path and allows us to make use of it for the real dasd boot
scenario.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: Collin Walling <walling@linux.ibm.com
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 pc-bios/s390-ccw/main.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index e82fe2c..67df421 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -14,16 +14,17 @@
 
 char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
 static SubChannelId blk_schid = { .one = 1 };
-IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
 static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 QemuIplParameters qipl;
+IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
+static bool have_iplb;
 
 #define LOADPARM_PROMPT "PROMPT  "
 #define LOADPARM_EMPTY  "        "
 #define BOOT_MENU_FLAG_MASK (QIPL_FLAG_BM_OPTS_CMD | QIPL_FLAG_BM_OPTS_ZIPL)
 
 /*
- * Priniciples of Operations (SA22-7832-09) chapter 17 requires that
+ * Principles of Operations (SA22-7832-09) chapter 17 requires that
  * a subsystem-identification is at 184-187 and bytes 188-191 are zero
  * after list-directed-IPL and ccw-IPL.
  */
@@ -111,23 +112,33 @@ static void css_setup(void)
     enable_mss_facility();
 }
 
+/*
+ * Collect various pieces of information from the hypervisor/hardware that
+ * we'll use to determine exactly how we'll boot.
+ */
+static void boot_setup(void)
+{
+    char lpmsg[] = "LOADPARM=[________]\n";
+
+    sclp_get_loadparm_ascii(loadparm_str);
+    memcpy(lpmsg + 10, loadparm_str, 8);
+    sclp_print(lpmsg);
+
+    have_iplb = store_iplb(&iplb);
+}
+
 static void virtio_setup(void)
 {
     Schib schib;
     int ssid;
     bool found = false;
     uint16_t dev_no;
-    char ldp[] = "LOADPARM=[________]\n";
     VDev *vdev = virtio_get_device();
     QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
 
-    sclp_get_loadparm_ascii(loadparm_str);
-    memcpy(ldp + 10, loadparm_str, LOADPARM_LEN);
-    sclp_print(ldp);
-
     memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
 
-    if (store_iplb(&iplb)) {
+    if (have_iplb) {
         switch (iplb.pbt) {
         case S390_IPL_TYPE_CCW:
             dev_no = iplb.ccw.devno;
@@ -174,6 +185,7 @@ int main(void)
 {
     sclp_setup();
     css_setup();
+    boot_setup();
     virtio_setup();
 
     zipl_load(); /* no return */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (2 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 03/15] s390-bios: decouple common boot logic " Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-02-04 10:33   ` Cornelia Huck
  2019-02-11 16:38   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path Jason J. Herne
                   ` (12 subsequent siblings)
  16 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

We need a method for finding the subchannel of a dasd device. Let's
modify find_dev to handle this since it mostly does what we need. Up to
this point find_dev has been specific to only virtio devices.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
---
 pc-bios/s390-ccw/main.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 67df421..7e3f65e 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -49,6 +49,12 @@ unsigned int get_loadparm_index(void)
     return atoui(loadparm_str);
 }
 
+/*
+ * Find the subchannel connected to the given device (dev_no) and fill in the
+ * subchannel information block (schib) with the connected subchannel's info.
+ * NOTE: The global variable blk_schid is updated to contain the subchannel
+ * information.
+ */
 static bool find_dev(Schib *schib, int dev_no)
 {
     int i, r;
@@ -62,15 +68,15 @@ static bool find_dev(Schib *schib, int dev_no)
         if (!schib->pmcw.dnv) {
             continue;
         }
-        if (!virtio_is_supported(blk_schid)) {
-            continue;
-        }
+
         /* Skip net devices since no IPLB is created and therefore no
-         * no network bootloader has been loaded
+         * network bootloader has been loaded
          */
-        if (virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
+        if (virtio_is_supported(blk_schid) &&
+            virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
             continue;
         }
+
         if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
             return true;
         }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (3 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-01-31 13:44   ` Farhan Ali
  2019-02-04 10:45   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 06/15] s390-bios: Clean up cio.h Jason J. Herne
                   ` (11 subsequent siblings)
  16 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Make a new routine find_boot_device to locate the boot device for all
cases. not just virtio.

In one case no boot device is specified and a suitable boot device can not
be auto detected. The error message for this case was specific to virtio
devices. We update this message to remove virtio specific wording.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/main.c  | 87 ++++++++++++++++++++++++++----------------------
 tests/boot-serial-test.c |  2 +-
 2 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 7e3f65e..2457752 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -55,17 +55,18 @@ unsigned int get_loadparm_index(void)
  * NOTE: The global variable blk_schid is updated to contain the subchannel
  * information.
  */
-static bool find_dev(Schib *schib, int dev_no)
+static bool find_subch(int dev_no)
 {
+    Schib schib;
     int i, r;
 
     for (i = 0; i < 0x10000; i++) {
         blk_schid.sch_no = i;
-        r = stsch_err(blk_schid, schib);
+        r = stsch_err(blk_schid, &schib);
         if ((r == 3) || (r == -EIO)) {
             break;
         }
-        if (!schib->pmcw.dnv) {
+        if (!schib.pmcw.dnv) {
             continue;
         }
 
@@ -77,7 +78,7 @@ static bool find_dev(Schib *schib, int dev_no)
             continue;
         }
 
-        if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
+        if ((dev_no < 0) || (schib.pmcw.dev == dev_no)) {
             return true;
         }
     }
@@ -133,56 +134,63 @@ static void boot_setup(void)
     have_iplb = store_iplb(&iplb);
 }
 
-static void virtio_setup(void)
+static void find_boot_device(void)
 {
-    Schib schib;
-    int ssid;
-    bool found = false;
-    uint16_t dev_no;
     VDev *vdev = virtio_get_device();
-    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
-
-    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
+    int ssid;
+    bool found;
 
-    if (have_iplb) {
-        switch (iplb.pbt) {
-        case S390_IPL_TYPE_CCW:
-            dev_no = iplb.ccw.devno;
-            debug_print_int("device no. ", dev_no);
-            blk_schid.ssid = iplb.ccw.ssid & 0x3;
-            debug_print_int("ssid ", blk_schid.ssid);
-            found = find_dev(&schib, dev_no);
-            break;
-        case S390_IPL_TYPE_QEMU_SCSI:
-            vdev->scsi_device_selected = true;
-            vdev->selected_scsi_device.channel = iplb.scsi.channel;
-            vdev->selected_scsi_device.target = iplb.scsi.target;
-            vdev->selected_scsi_device.lun = iplb.scsi.lun;
-            blk_schid.ssid = iplb.scsi.ssid & 0x3;
-            found = find_dev(&schib, iplb.scsi.devno);
-            break;
-        default:
-            panic("List-directed IPL not supported yet!\n");
-        }
-        menu_setup();
-    } else {
+    if (!have_iplb) {
         for (ssid = 0; ssid < 0x3; ssid++) {
             blk_schid.ssid = ssid;
-            found = find_dev(&schib, -1);
+            found = find_subch(-1);
             if (found) {
-                break;
+                return;
             }
         }
+        panic("Could not find a suitable boot device (none specified)\n");
     }
 
-    IPL_assert(found, "No virtio device found");
+    switch (iplb.pbt) {
+    case S390_IPL_TYPE_CCW:
+        debug_print_int("device no. ", iplb.ccw.devno);
+        blk_schid.ssid = iplb.ccw.ssid & 0x3;
+        debug_print_int("ssid ", blk_schid.ssid);
+        found = find_subch(iplb.ccw.devno);
+        break;
+    case S390_IPL_TYPE_QEMU_SCSI:
+        vdev->scsi_device_selected = true;
+        vdev->selected_scsi_device.channel = iplb.scsi.channel;
+        vdev->selected_scsi_device.target = iplb.scsi.target;
+        vdev->selected_scsi_device.lun = iplb.scsi.lun;
+        blk_schid.ssid = iplb.scsi.ssid & 0x3;
+        found = find_subch(iplb.scsi.devno);
+        break;
+    default:
+        panic("List-directed IPL not supported yet!\n");
+    }
+
+    if (!found) {
+        IPL_assert(found, "Boot device not found\n");
+    }
+}
+
+static void virtio_setup(void)
+{
+    VDev *vdev = virtio_get_device();
+    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
+
+    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
+
+    if (have_iplb) {
+        menu_setup();
+    }
 
     if (virtio_get_device_type() == VIRTIO_ID_NET) {
         sclp_print("Network boot device detected\n");
         vdev->netboot_start_addr = qipl.netboot_start_addr;
     } else {
         virtio_blk_setup_device(blk_schid);
-
         IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected");
     }
 }
@@ -192,8 +200,9 @@ int main(void)
     sclp_setup();
     css_setup();
     boot_setup();
-    virtio_setup();
+    find_boot_device();
 
+    virtio_setup();
     zipl_load(); /* no return */
 
     panic("Failed to load OS from hard disk\n");
diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
index 58a48f3..9daf2cb 100644
--- a/tests/boot-serial-test.c
+++ b/tests/boot-serial-test.c
@@ -112,7 +112,7 @@ static testdef_t tests[] = {
     { "sparc", "SS-4", "", "MB86904" },
     { "sparc", "SS-600MP", "", "TMS390Z55" },
     { "sparc64", "sun4u", "", "UltraSPARC" },
-    { "s390x", "s390-ccw-virtio", "", "virtio device" },
+    { "s390x", "s390-ccw-virtio", "", "device" },
     { "m68k", "mcf5208evb", "", "TT", sizeof(kernel_mcf5208), kernel_mcf5208 },
     { "microblaze", "petalogix-s3adsp1800", "", "TT",
       sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 06/15] s390-bios: Clean up cio.h
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (4 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-01-31 14:23   ` Farhan Ali
  2019-02-04 10:48   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio Jason J. Herne
                   ` (10 subsequent siblings)
  16 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Add proper typedefs to all structs and modify all bit fields to use consistent
formatting.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Collin Walling <walling@linux.ibm.com>
---
 pc-bios/s390-ccw/cio.h      | 86 ++++++++++++++++++++++-----------------------
 pc-bios/s390-ccw/s390-ccw.h |  8 -----
 2 files changed, 43 insertions(+), 51 deletions(-)

diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
index 1a0795f..a48eee5 100644
--- a/pc-bios/s390-ccw/cio.h
+++ b/pc-bios/s390-ccw/cio.h
@@ -53,12 +53,12 @@ struct schib_config {
     __u64 mba;
     __u32 intparm;
     __u16 mbi;
-    __u32 isc:3;
-    __u32 ena:1;
-    __u32 mme:2;
-    __u32 mp:1;
-    __u32 csense:1;
-    __u32 mbfc:1;
+    __u32 isc    : 3;
+    __u32 ena    : 1;
+    __u32 mme    : 2;
+    __u32 mp     : 1;
+    __u32 csense : 1;
+    __u32 mbfc   : 1;
 } __attribute__ ((packed));
 
 struct scsw {
@@ -77,41 +77,41 @@ struct scsw {
 /*
  * subchannel information block
  */
-struct schib {
+typedef struct schib {
     struct pmcw pmcw;     /* path management control word */
     struct scsw scsw;     /* subchannel status word */
     __u64 mba;            /* measurement block address */
     __u8 mda[4];          /* model dependent area */
-} __attribute__ ((packed,aligned(4)));
+} __attribute__ ((packed, aligned(4))) Schib;
 
-struct subchannel_id {
+typedef struct subchannel_id {
         __u32 cssid  : 8;
         __u32        : 4;
         __u32 m      : 1;
         __u32 ssid   : 2;
         __u32 one    : 1;
         __u32 sch_no : 16;
-} __attribute__ ((packed, aligned(4)));
+} __attribute__ ((packed, aligned(4))) SubChannelId;
 
 struct chsc_header {
     __u16 length;
     __u16 code;
 } __attribute__((packed));
 
-struct chsc_area_sda {
+typedef struct chsc_area_sda {
     struct chsc_header request;
-    __u8 reserved1:4;
-    __u8 format:4;
+    __u8 reserved1  : 4;
+    __u8 format     : 4;
     __u8 reserved2;
     __u16 operation_code;
     __u32 reserved3;
     __u32 reserved4;
     __u32 operation_data_area[252];
     struct chsc_header response;
-    __u32 reserved5:4;
-    __u32 format2:4;
-    __u32 reserved6:24;
-} __attribute__((packed));
+    __u32 reserved5 : 4;
+    __u32 format2   : 4;
+    __u32 reserved6 : 24;
+} __attribute__((packed)) ChscAreaSda;
 
 /*
  * TPI info structure
@@ -128,12 +128,12 @@ struct tpi_info {
 } __attribute__ ((packed, aligned(4)));
 
 /* channel command word (type 1) */
-struct ccw1 {
+typedef struct ccw1 {
     __u8 cmd_code;
     __u8 flags;
     __u16 count;
     __u32 cda;
-} __attribute__ ((packed, aligned(8)));
+} __attribute__ ((packed, aligned(8))) Ccw1;
 
 #define CCW_FLAG_DC              0x80
 #define CCW_FLAG_CC              0x40
@@ -162,27 +162,27 @@ struct ccw1 {
 /*
  * Command-mode operation request block
  */
-struct cmd_orb {
+typedef struct cmd_orb {
     __u32 intparm;    /* interruption parameter */
-    __u32 key:4;      /* flags, like key, suspend control, etc. */
-    __u32 spnd:1;     /* suspend control */
-    __u32 res1:1;     /* reserved */
-    __u32 mod:1;      /* modification control */
-    __u32 sync:1;     /* synchronize control */
-    __u32 fmt:1;      /* format control */
-    __u32 pfch:1;     /* prefetch control */
-    __u32 isic:1;     /* initial-status-interruption control */
-    __u32 alcc:1;     /* address-limit-checking control */
-    __u32 ssic:1;     /* suppress-suspended-interr. control */
-    __u32 res2:1;     /* reserved */
-    __u32 c64:1;      /* IDAW/QDIO 64 bit control  */
-    __u32 i2k:1;      /* IDAW 2/4kB block size control */
-    __u32 lpm:8;      /* logical path mask */
-    __u32 ils:1;      /* incorrect length */
-    __u32 zero:6;     /* reserved zeros */
-    __u32 orbx:1;     /* ORB extension control */
-    __u32 cpa;    /* channel program address */
-}  __attribute__ ((packed, aligned(4)));
+    __u32 key  : 4;   /* flags, like key, suspend control, etc. */
+    __u32 spnd : 1;   /* suspend control */
+    __u32 res1 : 1;   /* reserved */
+    __u32 mod  : 1;   /* modification control */
+    __u32 sync : 1;   /* synchronize control */
+    __u32 fmt  : 1;   /* format control */
+    __u32 pfch : 1;   /* prefetch control */
+    __u32 isic : 1;   /* initial-status-interruption control */
+    __u32 alcc : 1;   /* address-limit-checking control */
+    __u32 ssic : 1;   /* suppress-suspended-interr. control */
+    __u32 res2 : 1;   /* reserved */
+    __u32 c64  : 1;   /* IDAW/QDIO 64 bit control  */
+    __u32 i2k  : 1;   /* IDAW 2/4kB block size control */
+    __u32 lpm  : 8;   /* logical path mask */
+    __u32 ils  : 1;   /* incorrect length */
+    __u32 zero : 6;   /* reserved zeros */
+    __u32 orbx : 1;   /* ORB extension control */
+    __u32 cpa;        /* channel program address */
+}  __attribute__ ((packed, aligned(4))) CmdOrb;
 
 struct ciw {
     __u8 type;
@@ -193,7 +193,7 @@ struct ciw {
 /*
  * sense-id response buffer layout
  */
-struct senseid {
+typedef struct senseid {
     /* common part */
     __u8  reserved;   /* always 0x'FF' */
     __u16 cu_type;    /* control unit type */
@@ -203,15 +203,15 @@ struct senseid {
     __u8  unused;     /* padding byte */
     /* extended part */
     struct ciw ciw[62];
-}  __attribute__ ((packed, aligned(4)));
+}  __attribute__ ((packed, aligned(4))) SenseId;
 
 /* interruption response block */
-struct irb {
+typedef struct irb {
     struct scsw scsw;
     __u32 esw[5];
     __u32 ecw[8];
     __u32 emw[8];
-}  __attribute__ ((packed, aligned(4)));
+}  __attribute__ ((packed, aligned(4))) Irb;
 
 /*
  * Some S390 specific IO instructions as inline
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 9828aa2..241c6d0 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -49,14 +49,6 @@ typedef unsigned long long __u64;
 #include "cio.h"
 #include "iplb.h"
 
-typedef struct irb Irb;
-typedef struct ccw1 Ccw1;
-typedef struct cmd_orb CmdOrb;
-typedef struct schib Schib;
-typedef struct chsc_area_sda ChscAreaSda;
-typedef struct senseid SenseId;
-typedef struct subchannel_id SubChannelId;
-
 /* start.s */
 void disabled_wait(void);
 void consume_sclp_int(void);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (5 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 06/15] s390-bios: Clean up cio.h Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-01-31 14:38   ` Farhan Ali
  2019-02-04 10:57   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 08/15] s390-bios: Map low core memory Jason J. Herne
                   ` (9 subsequent siblings)
  16 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Create a separate library for channel i/o related code. This decouples
channel i/o operations from virtio and allows us to make use of them for
the real dasd boot path.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/Makefile        |  2 +-
 pc-bios/s390-ccw/cio.c           | 41 ++++++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/cio.h           |  3 +++
 pc-bios/s390-ccw/main.c          |  1 +
 pc-bios/s390-ccw/netboot.mak     |  2 +-
 pc-bios/s390-ccw/netmain.c       |  1 +
 pc-bios/s390-ccw/s390-ccw.h      |  1 -
 pc-bios/s390-ccw/virtio-blkdev.c |  1 +
 pc-bios/s390-ccw/virtio.c        | 27 ++------------------------
 9 files changed, 51 insertions(+), 28 deletions(-)
 create mode 100644 pc-bios/s390-ccw/cio.c

diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 1eb316b..12ad9c1 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -10,7 +10,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
 .PHONY : all clean build-all
 
 OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
-	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o
+	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o
 
 QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
 QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
new file mode 100644
index 0000000..095f79b
--- /dev/null
+++ b/pc-bios/s390-ccw/cio.c
@@ -0,0 +1,41 @@
+/*
+ * S390 Channel I/O
+ *
+ * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "libc.h"
+#include "s390-ccw.h"
+#include "cio.h"
+
+static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
+
+int enable_mss_facility(void)
+{
+    int ret;
+    ChscAreaSda *sda_area = (ChscAreaSda *) chsc_page;
+
+    memset(sda_area, 0, PAGE_SIZE);
+    sda_area->request.length = 0x0400;
+    sda_area->request.code = 0x0031;
+    sda_area->operation_code = 0x2;
+
+    ret = chsc(sda_area);
+    if ((ret == 0) && (sda_area->response.code == 0x0001)) {
+        return 0;
+    }
+    return -EIO;
+}
+
+void enable_subchannel(SubChannelId schid)
+{
+    Schib schib;
+
+    stsch_err(schid, &schib);
+    schib.pmcw.ena = 1;
+    msch(schid, &schib);
+}
diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
index a48eee5..7b07d75 100644
--- a/pc-bios/s390-ccw/cio.h
+++ b/pc-bios/s390-ccw/cio.h
@@ -213,6 +213,9 @@ typedef struct irb {
     __u32 emw[8];
 }  __attribute__ ((packed, aligned(4))) Irb;
 
+int enable_mss_facility(void);
+void enable_subchannel(SubChannelId schid);
+
 /*
  * Some S390 specific IO instructions as inline
  */
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 2457752..1bc61b5 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -10,6 +10,7 @@
 
 #include "libc.h"
 #include "s390-ccw.h"
+#include "cio.h"
 #include "virtio.h"
 
 char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak
index 14e96b2..5eefb7c 100644
--- a/pc-bios/s390-ccw/netboot.mak
+++ b/pc-bios/s390-ccw/netboot.mak
@@ -1,7 +1,7 @@
 
 SLOF_DIR := $(SRC_PATH)/roms/SLOF
 
-NETOBJS := start.o sclp.o virtio.o virtio-net.o jump2ipl.o netmain.o \
+NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o \
 	   libnet.a libc.a
 
 LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index 0392131..5189c0f 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -33,6 +33,7 @@
 #include <pxelinux.h>
 
 #include "s390-ccw.h"
+#include "cio.h"
 #include "virtio.h"
 
 #define DEFAULT_BOOT_RETRIES 10
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 241c6d0..b39ee5d 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -72,7 +72,6 @@ unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2,
 bool virtio_is_supported(SubChannelId schid);
 void virtio_blk_setup_device(SubChannelId schid);
 int virtio_read(ulong sector, void *load_addr);
-int enable_mss_facility(void);
 u64 get_clock(void);
 ulong get_second(void);
 
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 11c5626..d2e7fcd 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -10,6 +10,7 @@
 
 #include "libc.h"
 #include "s390-ccw.h"
+#include "cio.h"
 #include "virtio.h"
 #include "virtio-scsi.h"
 
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index cdb66f4..aa9da72 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -10,6 +10,7 @@
 
 #include "libc.h"
 #include "s390-ccw.h"
+#include "cio.h"
 #include "virtio.h"
 #include "virtio-scsi.h"
 #include "bswap.h"
@@ -20,8 +21,6 @@ static VRing block[VIRTIO_MAX_VQS];
 static char ring_area[VIRTIO_RING_SIZE * VIRTIO_MAX_VQS]
                      __attribute__((__aligned__(PAGE_SIZE)));
 
-static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
-
 static VDev vdev = {
     .nr_vqs = 1,
     .vrings = block,
@@ -94,14 +93,9 @@ static int run_ccw(VDev *vdev, int cmd, void *ptr, int len)
 {
     Ccw1 ccw = {};
     CmdOrb orb = {};
-    Schib schib;
     int r;
 
-    /* start command processing */
-    stsch_err(vdev->schid, &schib);
-    /* enable the subchannel for IPL device */
-    schib.pmcw.ena = 1;
-    msch(vdev->schid, &schib);
+    enable_subchannel(vdev->schid);
 
     /* start subchannel command */
     orb.fmt = 1;
@@ -343,20 +337,3 @@ bool virtio_is_supported(SubChannelId schid)
     }
     return false;
 }
-
-int enable_mss_facility(void)
-{
-    int ret;
-    ChscAreaSda *sda_area = (ChscAreaSda *) chsc_page;
-
-    memset(sda_area, 0, PAGE_SIZE);
-    sda_area->request.length = 0x0400;
-    sda_area->request.code = 0x0031;
-    sda_area->operation_code = 0x2;
-
-    ret = chsc(sda_area);
-    if ((ret == 0) && (sda_area->response.code == 0x0001)) {
-        return 0;
-    }
-    return -EIO;
-}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 08/15] s390-bios: Map low core memory
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (6 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-02-12 12:47   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 09/15] s390-bios: ptr2u32 and u32toptr Jason J. Herne
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Create a new header for basic architecture specific definitions and add a
mapping of low core memory. This mapping will be used by the real dasd boot
process.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/main.c      |   2 +
 pc-bios/s390-ccw/s390-arch.h | 100 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+)
 create mode 100644 pc-bios/s390-ccw/s390-arch.h

diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 1bc61b5..fa90aa3 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -9,6 +9,7 @@
  */
 
 #include "libc.h"
+#include "s390-arch.h"
 #include "s390-ccw.h"
 #include "cio.h"
 #include "virtio.h"
@@ -19,6 +20,7 @@ static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 QemuIplParameters qipl;
 IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
 static bool have_iplb;
+const LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
 
 #define LOADPARM_PROMPT "PROMPT  "
 #define LOADPARM_EMPTY  "        "
diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
new file mode 100644
index 0000000..47eaa04
--- /dev/null
+++ b/pc-bios/s390-ccw/s390-arch.h
@@ -0,0 +1,100 @@
+/*
+ * S390 Basic Architecture
+ *
+ * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef S390_ARCH_H
+#define S390_ARCH_H
+
+typedef struct PSW {
+    uint64_t mask;
+    uint64_t addr;
+} __attribute__ ((packed, aligned(8))) PSW;
+
+/* Older PSW format used by LPSW instruction */
+typedef struct PSWLegacy {
+    uint32_t mask;
+    uint32_t addr;
+} __attribute__ ((packed, aligned(8))) PSWLegacy;
+
+/* s390 psw bit masks */
+#define PSW_MASK_IOINT      0x0200000000000000ULL
+#define PSW_MASK_WAIT       0x0002000000000000ULL
+#define PSW_MASK_EAMODE     0x0000000100000000ULL
+#define PSW_MASK_BAMODE     0x0000000080000000ULL
+#define PSW_MASK_ZMODE      (PSW_MASK_EAMODE | PSW_MASK_BAMODE)
+
+/* Low core mapping */
+typedef struct LowCore {
+    /* prefix area: defined by architecture */
+    uint64_t        ipl_psw;                  /* 0x000 */
+    uint32_t        ccw1[2];                  /* 0x008 */
+    uint32_t        ccw2[2];                  /* 0x010 */
+    uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
+    uint32_t        ext_params;               /* 0x080 */
+    uint16_t        cpu_addr;                 /* 0x084 */
+    uint16_t        ext_int_code;             /* 0x086 */
+    uint16_t        svc_ilen;                 /* 0x088 */
+    uint16_t        svc_code;                 /* 0x08a */
+    uint16_t        pgm_ilen;                 /* 0x08c */
+    uint16_t        pgm_code;                 /* 0x08e */
+    uint32_t        data_exc_code;            /* 0x090 */
+    uint16_t        mon_class_num;            /* 0x094 */
+    uint16_t        per_perc_atmid;           /* 0x096 */
+    uint64_t        per_address;              /* 0x098 */
+    uint8_t         exc_access_id;            /* 0x0a0 */
+    uint8_t         per_access_id;            /* 0x0a1 */
+    uint8_t         op_access_id;             /* 0x0a2 */
+    uint8_t         ar_access_id;             /* 0x0a3 */
+    uint8_t         pad2[0xA8 - 0xA4];        /* 0x0a4 */
+    uint64_t        trans_exc_code;           /* 0x0a8 */
+    uint64_t        monitor_code;             /* 0x0b0 */
+    uint16_t        subchannel_id;            /* 0x0b8 */
+    uint16_t        subchannel_nr;            /* 0x0ba */
+    uint32_t        io_int_parm;              /* 0x0bc */
+    uint32_t        io_int_word;              /* 0x0c0 */
+    uint8_t         pad3[0xc8 - 0xc4];        /* 0x0c4 */
+    uint32_t        stfl_fac_list;            /* 0x0c8 */
+    uint8_t         pad4[0xe8 - 0xcc];        /* 0x0cc */
+    uint64_t        mcic;                     /* 0x0e8 */
+    uint8_t         pad5[0xf4 - 0xf0];        /* 0x0f0 */
+    uint32_t        external_damage_code;     /* 0x0f4 */
+    uint64_t        failing_storage_address;  /* 0x0f8 */
+    uint8_t         pad6[0x110 - 0x100];      /* 0x100 */
+    uint64_t        per_breaking_event_addr;  /* 0x110 */
+    uint8_t         pad7[0x120 - 0x118];      /* 0x118 */
+    PSW             restart_old_psw;          /* 0x120 */
+    PSW             external_old_psw;         /* 0x130 */
+    PSW             svc_old_psw;              /* 0x140 */
+    PSW             program_old_psw;          /* 0x150 */
+    PSW             mcck_old_psw;             /* 0x160 */
+    PSW             io_old_psw;               /* 0x170 */
+    uint8_t         pad8[0x1a0 - 0x180];      /* 0x180 */
+    PSW             restart_new_psw;          /* 0x1a0 */
+    PSW             external_new_psw;         /* 0x1b0 */
+    PSW             svc_new_psw;              /* 0x1c0 */
+    PSW             program_new_psw;          /* 0x1d0 */
+    PSW             mcck_new_psw;             /* 0x1e0 */
+    PSW             io_new_psw;               /* 0x1f0 */
+    PSW             return_psw;               /* 0x200 */
+    uint8_t         irb[64];                  /* 0x210 */
+    uint64_t        sync_enter_timer;         /* 0x250 */
+    uint64_t        async_enter_timer;        /* 0x258 */
+    uint64_t        exit_timer;               /* 0x260 */
+    uint64_t        last_update_timer;        /* 0x268 */
+    uint64_t        user_timer;               /* 0x270 */
+    uint64_t        system_timer;             /* 0x278 */
+    uint64_t        last_update_clock;        /* 0x280 */
+    uint64_t        steal_clock;              /* 0x288 */
+    PSW             return_mcck_psw;          /* 0x290 */
+    uint8_t         pad9[0xc00 - 0x2a0];      /* 0x2a0 */
+} __attribute__((packed, aligned(8192))) LowCore;
+
+extern const LowCore *lowcore;
+
+#endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 09/15] s390-bios: ptr2u32 and u32toptr
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (7 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 08/15] s390-bios: Map low core memory Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-02-04 11:03   ` Cornelia Huck
  2019-02-12 12:50   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs Jason J. Herne
                   ` (7 subsequent siblings)
  16 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Introduce inline functions to convert between pointers and unsigned 32-bit
ints. These are used to hide the ugliness required to  avoid compiler
warnings.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/libc.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h
index 818517f..e198f0b 100644
--- a/pc-bios/s390-ccw/libc.h
+++ b/pc-bios/s390-ccw/libc.h
@@ -19,6 +19,18 @@ typedef unsigned short     uint16_t;
 typedef unsigned int       uint32_t;
 typedef unsigned long long uint64_t;
 
+/* Avoids compiler warnings when casting a pointer to a u32 */
+static inline uint32_t ptr2u32(void *ptr)
+{
+    return (uint32_t)(uint64_t)ptr;
+}
+
+/* Avoids compiler warnings when casting a u32 to a pointer */
+static inline void *u32toptr(uint32_t n)
+{
+    return (void *)(uint64_t)n;
+}
+
 static inline void *memset(void *s, int c, size_t n)
 {
     size_t i;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (8 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 09/15] s390-bios: ptr2u32 and u32toptr Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-01-31 17:31   ` Farhan Ali
  2019-02-04 11:24   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 11/15] s390-bios: cio error handling Jason J. Herne
                   ` (6 subsequent siblings)
  16 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Add struct for format-0 ccws. Support executing format-0 channel
programs and waiting for their completion before continuing execution.
This will be used for real dasd ipl.

Add cu_type() to channel io library. This will be used to query control
unit type which is used to determine if we are booting a virtio device or a
real dasd device.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
 pc-bios/s390-ccw/s390-ccw.h |   1 +
 pc-bios/s390-ccw/start.S    |  33 +++++++++++-
 4 files changed, 270 insertions(+), 5 deletions(-)

diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
index 095f79b..63581c6 100644
--- a/pc-bios/s390-ccw/cio.c
+++ b/pc-bios/s390-ccw/cio.c
@@ -10,6 +10,7 @@
 
 #include "libc.h"
 #include "s390-ccw.h"
+#include "s390-arch.h"
 #include "cio.h"
 
 static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
@@ -39,3 +40,116 @@ void enable_subchannel(SubChannelId schid)
     schib.pmcw.ena = 1;
     msch(schid, &schib);
 }
+
+uint16_t cu_type(SubChannelId schid)
+{
+    Ccw1 sense_id_ccw;
+    SenseId sense_data;
+
+    sense_id_ccw.cmd_code = CCW_CMD_SENSE_ID;
+    sense_id_ccw.cda = ptr2u32(&sense_data);
+    sense_id_ccw.count = sizeof(sense_data);
+    sense_id_ccw.flags |= CCW_FLAG_SLI;
+
+    if (do_cio(schid, ptr2u32(&sense_id_ccw), CCW_FMT1)) {
+        panic("Failed to run SenseID CCw\n");
+    }
+
+    return sense_data.cu_type;
+}
+
+void basic_sense(SubChannelId schid, void *sense_data, uint16_t data_size)
+{
+    Ccw1 senseCcw;
+
+    senseCcw.cmd_code = CCW_CMD_BASIC_SENSE;
+    senseCcw.cda = ptr2u32(sense_data);
+    senseCcw.count = data_size;
+
+    if (do_cio(schid, ptr2u32(&senseCcw), CCW_FMT1)) {
+        panic("Failed to run Basic Sense CCW\n");
+    }
+}
+
+static bool irb_error(Irb *irb)
+{
+    if (irb->scsw.cstat) {
+        return true;
+    }
+    return irb->scsw.dstat != (SCSW_DSTAT_DEVEND | SCSW_DSTAT_CHEND);
+}
+
+/*
+ * Executes a channel program at a given subchannel. The request to run the
+ * channel program is sent to the subchannel, we then wait for the interrupt
+ * signaling completion of the I/O operation(s) performed by the channel
+ * program. Lastly we verify that the i/o operation completed without error and
+ * that the interrupt we received was for the subchannel used to run the
+ * channel program.
+ *
+ * Note: This function assumes it is running in an environment where no other
+ * cpus are generating or receiving I/O interrupts. So either run it in a
+ * single-cpu environment or make sure all other cpus are not doing I/O and
+ * have I/O interrupts masked off.
+ */
+int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
+{
+    CmdOrb orb = {};
+    Irb irb = {};
+    sense_data_eckd_dasd sd;
+    int rc, retries = 0;
+
+    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
+
+    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
+    if (fmt == 0) {
+        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
+    }
+
+    orb.fmt = fmt ;
+    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
+    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
+    orb.lpm = 0xFF; /* All paths allowed */
+    orb.cpa = ccw_addr;
+
+    while (true) {
+        rc = ssch(schid, &orb);
+        if (rc == 1) {
+            /* Status pending, not sure why. Let's eat the status and retry. */
+            tsch(schid, &irb);
+            retries++;
+            continue;
+        }
+        if (rc) {
+            print_int("ssch failed with rc=", rc);
+            break;
+        }
+
+        consume_io_int();
+
+        /* collect status */
+        rc = tsch(schid, &irb);
+        if (rc) {
+            print_int("tsch failed with rc=", rc);
+            break;
+        }
+
+        if (!irb_error(&irb)) {
+            break;
+        }
+
+        /*
+         * Unexpected unit check, or interface-control-check. Use sense to
+         * clear unit check then retry.
+         */
+        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
+            basic_sense(schid, &sd, sizeof(sd));
+            retries++;
+            continue;
+        }
+
+        break;
+    }
+
+    return rc;
+}
diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
index 7b07d75..1086f31 100644
--- a/pc-bios/s390-ccw/cio.h
+++ b/pc-bios/s390-ccw/cio.h
@@ -70,9 +70,46 @@ struct scsw {
     __u16 count;
 } __attribute__ ((packed));
 
-#define SCSW_FCTL_CLEAR_FUNC 0x1000
-#define SCSW_FCTL_HALT_FUNC 0x2000
+/* Function Control */
 #define SCSW_FCTL_START_FUNC 0x4000
+#define SCSW_FCTL_HALT_FUNC 0x2000
+#define SCSW_FCTL_CLEAR_FUNC 0x1000
+
+/* Activity Control */
+#define SCSW_ACTL_RESUME_PEND   0x0800
+#define SCSW_ACTL_START_PEND    0x0400
+#define SCSW_ACTL_HALT_PEND     0x0200
+#define SCSW_ACTL_CLEAR_PEND    0x0100
+#define SCSW_ACTL_CH_ACTIVE     0x0080
+#define SCSW_ACTL_DEV_ACTIVE    0x0040
+#define SCSW_ACTL_SUSPENDED     0x0020
+
+/* Status Control */
+#define SCSW_SCTL_ALERT         0x0010
+#define SCSW_SCTL_INTERMED      0x0008
+#define SCSW_SCTL_PRIMARY       0x0004
+#define SCSW_SCTL_SECONDARY     0x0002
+#define SCSW_SCTL_STATUS_PEND   0x0001
+
+/* SCSW Device Status Flags */
+#define SCSW_DSTAT_ATTN     0x80
+#define SCSW_DSTAT_STATMOD  0x40
+#define SCSW_DSTAT_CUEND    0x20
+#define SCSW_DSTAT_BUSY     0x10
+#define SCSW_DSTAT_CHEND    0x08
+#define SCSW_DSTAT_DEVEND   0x04
+#define SCSW_DSTAT_UCHK     0x02
+#define SCSW_DSTAT_UEXCP    0x01
+
+/* SCSW Subchannel Status Flags */
+#define SCSW_CSTAT_PCINT    0x80
+#define SCSW_CSTAT_BADLEN   0x40
+#define SCSW_CSTAT_PROGCHK  0x20
+#define SCSW_CSTAT_PROTCHK  0x10
+#define SCSW_CSTAT_CHDCHK   0x08
+#define SCSW_CSTAT_CHCCHK   0x04
+#define SCSW_CSTAT_ICCHK    0x02
+#define SCSW_CSTAT_CHAINCHK 0x01
 
 /*
  * subchannel information block
@@ -127,7 +164,23 @@ struct tpi_info {
     __u32 reserved4  : 12;
 } __attribute__ ((packed, aligned(4)));
 
-/* channel command word (type 1) */
+/* channel command word (format 0) */
+typedef struct ccw0 {
+    __u8 cmd_code;
+    __u32 cda        : 24;
+    __u32 chainData  : 1;
+    __u32 chain      : 1;
+    __u32 sli        : 1;
+    __u32 skip       : 1;
+    __u32 pci        : 1;
+    __u32 ida        : 1;
+    __u32 suspend    : 1;
+    __u32 mida       : 1;
+    __u8 reserved;
+    __u16 count;
+} __attribute__ ((packed, aligned(8))) Ccw0;
+
+/* channel command word (format 1) */
 typedef struct ccw1 {
     __u8 cmd_code;
     __u8 flags;
@@ -135,6 +188,10 @@ typedef struct ccw1 {
     __u32 cda;
 } __attribute__ ((packed, aligned(8))) Ccw1;
 
+/* do_cio() CCW formats */
+#define CCW_FMT0                 0x00
+#define CCW_FMT1                 0x01
+
 #define CCW_FLAG_DC              0x80
 #define CCW_FLAG_CC              0x40
 #define CCW_FLAG_SLI             0x20
@@ -190,6 +247,9 @@ struct ciw {
     __u16 count;
 };
 
+#define CU_TYPE_VIRTIO          0x3832
+#define CU_TYPE_DASD_3990       0x3990
+
 /*
  * sense-id response buffer layout
  */
@@ -205,6 +265,64 @@ typedef struct senseid {
     struct ciw ciw[62];
 }  __attribute__ ((packed, aligned(4))) SenseId;
 
+/*
+ * architected values for first sense byte - common_status. Bits 0-5 of this
+ * field are common to all device types.
+ */
+#define SNS_STAT0_CMD_REJECT         0x80
+#define SNS_STAT0_INTERVENTION_REQ   0x40
+#define SNS_STAT0_BUS_OUT_CHECK      0x20
+#define SNS_STAT0_EQUIPMENT_CHECK    0x10
+#define SNS_STAT0_DATA_CHECK         0x08
+#define SNS_STAT0_OVERRUN            0x04
+#define SNS_STAT0_INCOMPL_DOMAIN     0x01
+
+/* ECKD DASD status[0] byte */
+#define SNS_STAT1_PERM_ERR           0x80
+#define SNS_STAT1_INV_TRACK_FORMAT   0x40
+#define SNS_STAT1_EOC                0x20
+#define SNS_STAT1_MESSAGE_TO_OPER    0x10
+#define SNS_STAT1_NO_REC_FOUND       0x08
+#define SNS_STAT1_FILE_PROTECTED     0x04
+#define SNS_STAT1_WRITE_INHIBITED    0x02
+#define SNS_STAT1_IMPRECISE_END      0x01
+
+/* ECKD DASD status[1] byte */
+#define SNS_STAT2_REQ_INH_WRITE      0x80
+#define SNS_STAT2_CORRECTABLE        0x40
+#define SNS_STAT2_FIRST_LOG_ERR      0x20
+#define SNS_STAT2_ENV_DATA_PRESENT   0x10
+#define SNS_STAT2_IMPRECISE_END      0x04
+
+/* ECKD DASD 24-byte Sense fmt_msg codes */
+#define SENSE24_FMT_PROG_SYS    0x0
+#define SENSE24_FMT_EQUIPMENT   0x2
+#define SENSE24_FMT_CONTROLLER  0x3
+#define SENSE24_FMT_MISC        0xF
+
+/* basic sense response buffer layout */
+typedef struct sense_data_eckd_dasd {
+    uint8_t common_status;
+    uint8_t status[2];
+    uint8_t res_count;
+    uint8_t phys_drive_id;
+    uint8_t low_cyl_addr;
+    uint8_t head_high_cyl_addr;
+    uint8_t fmt_msg;
+    uint64_t fmt_dependent_info[2];
+    uint8_t reserved;
+    uint8_t program_action_code;
+    uint16_t config_info;
+    uint8_t mcode_hicyl;
+    uint8_t cyl_head_addr[3];
+}  __attribute__ ((packed, aligned(4))) sense_data_eckd_dasd;
+
+#define ECKD_SENSE24_GET_FMT(sd)     (sd->fmt_msg & 0xF0 >> 4)
+#define ECKD_SENSE24_GET_MSG(sd)     (sd->fmt_msg & 0x0F)
+
+#define unit_check(irb)         ((irb)->scsw.dstat & SCSW_DSTAT_UCHK)
+#define iface_ctrl_check(irb)   ((irb)->scsw.cstat & SCSW_CSTAT_ICCHK)
+
 /* interruption response block */
 typedef struct irb {
     struct scsw scsw;
@@ -215,6 +333,9 @@ typedef struct irb {
 
 int enable_mss_facility(void);
 void enable_subchannel(SubChannelId schid);
+uint16_t cu_type(SubChannelId schid);
+void basic_sense(SubChannelId schid, void *sense_data, uint16_t data_size);
+int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt);
 
 /*
  * Some S390 specific IO instructions as inline
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index b39ee5d..11bce7d 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -52,6 +52,7 @@ typedef unsigned long long __u64;
 /* start.s */
 void disabled_wait(void);
 void consume_sclp_int(void);
+void consume_io_int(void);
 
 /* main.c */
 void panic(const char *string);
diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
index eb8d024..22b38ec 100644
--- a/pc-bios/s390-ccw/start.S
+++ b/pc-bios/s390-ccw/start.S
@@ -65,12 +65,32 @@ consume_sclp_int:
         /* prepare external call handler */
         larl %r1, external_new_code
         stg %r1, 0x1b8
-        larl %r1, external_new_mask
+        larl %r1, int_new_mask
         mvc 0x1b0(8),0(%r1)
         /* load enabled wait PSW */
         larl %r1, enabled_wait_psw
         lpswe 0(%r1)
 
+/*
+ * void consume_io_int(void)
+ *
+ * eats one I/O interrupt
+ */
+        .globl consume_io_int
+consume_io_int:
+        /* enable I/O interrupts in cr6 */
+        stctg 6,6,0(15)
+        oi 4(15), 0xff
+        lctlg 6,6,0(15)
+        /* prepare i/o call handler */
+        larl %r1, io_new_code
+        stg %r1, 0x1f8
+        larl %r1, int_new_mask
+        mvc 0x1f0(8),0(%r1)
+        /* load enabled wait PSW */
+        larl %r1, enabled_wait_psw
+        lpswe 0(%r1)
+
 external_new_code:
         /* disable service interrupts in cr0 */
         stctg 0,0,0(15)
@@ -78,10 +98,19 @@ external_new_code:
         lctlg 0,0,0(15)
         br 14
 
+io_new_code:
+        /* disable I/O interrupts in cr6 */
+        stctg 6,6,0(15)
+        ni 4(15), 0x00
+        lctlg 6,6,0(15)
+        br 14
+
+
+
         .align  8
 disabled_wait_psw:
         .quad   0x0002000180000000,0x0000000000000000
 enabled_wait_psw:
         .quad   0x0302000180000000,0x0000000000000000
-external_new_mask:
+int_new_mask:
         .quad   0x0000000180000000
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 11/15] s390-bios: cio error handling
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (9 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-02-04 11:41   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 12/15] s390-bios: Refactor virtio to run channel programs via cio Jason J. Herne
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Add verbose error output for when unexpected i/o errors happen. This eases the
burden of debugging and reporting i/o errors. No error information is printed
in the success case, here is an example of what is output on error:

vfio-ccw device I/O error - Interrupt Response Block Data:
    Function Ctrl : [Start]
    Activity Ctrl : [Start-Pending]
    Status Ctrl : [Alert] [Primary] [Secondary] [Status-Pending]
    Device Status : [Unit-Check]
    Channel Status :
    cpa=: 0x0000000001e67098
    prev_ccw=: 0x0000000000000000
    this_ccw=: 0x0000000000000000

Sense Data (fmt 32-bytes):
    Sense Condition Flags : [Equipment-Check]
    Residual Count     =: 0x0000000000000000
    Phys Drive ID      =: 0x000000000000009e
    low cyl address    =: 0x0000000000000000
    head addr & hi cyl =: 0x0000000000000000
    format/message     =: 0x0000000000000008
    fmt-dependent[0-7] =: 0x0000000000000004
    fmt-dependent[8-15]=: 0xe561282305082fff
    prog action code   =: 0x0000000000000016
    Configuration info =: 0x00000000000040e0
    mcode / hi-cyl     =: 0x0000000000000000
    cyl & head addr [0]=: 0x0000000000000000
    cyl & head addr [1]=: 0x0000000000000000
    cyl & head addr [2]=: 0x0000000000000000

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>

# Conflicts:
#	pc-bios/s390-ccw/cio.c

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/cio.c  | 225 ++++++++++++++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/libc.h |  11 +++
 2 files changed, 236 insertions(+)

diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
index 63581c6..bd6051b 100644
--- a/pc-bios/s390-ccw/cio.c
+++ b/pc-bios/s390-ccw/cio.c
@@ -79,6 +79,228 @@ static bool irb_error(Irb *irb)
     return irb->scsw.dstat != (SCSW_DSTAT_DEVEND | SCSW_DSTAT_CHEND);
 }
 
+static void print_eckd_dasd_sense_data(sense_data_eckd_dasd *sd)
+{
+    char msgline[512];
+
+    if (sd->config_info & 0x8000) {
+        sclp_print("Eckd Dasd Sense Data (fmt 24-bytes):\n");
+    } else {
+        sclp_print("Eckd Dasd Sense Data (fmt 32-bytes):\n");
+    }
+
+    strcat(msgline, "    Sense Condition Flags :");
+    if (sd->status[0] & SNS_STAT0_CMD_REJECT) {
+        strcat(msgline, " [Cmd-Reject]");
+    }
+    if (sd->status[0] & SNS_STAT0_INTERVENTION_REQ) {
+        strcat(msgline, " [Intervention-Required]");
+    }
+    if (sd->status[0] & SNS_STAT0_BUS_OUT_CHECK) {
+        strcat(msgline, " [Bus-Out-Parity-Check]");
+    }
+    if (sd->status[0] & SNS_STAT0_EQUIPMENT_CHECK) {
+        strcat(msgline, " [Equipment-Check]");
+    }
+    if (sd->status[0] & SNS_STAT0_DATA_CHECK) {
+        strcat(msgline, " [Data-Check]");
+    }
+    if (sd->status[0] & SNS_STAT0_OVERRUN) {
+        strcat(msgline, " [Overrun]");
+    }
+    if (sd->status[0] & SNS_STAT0_INCOMPL_DOMAIN) {
+        strcat(msgline, " [Incomplete-Domain]");
+    }
+
+    if (sd->status[1] & SNS_STAT1_PERM_ERR) {
+        strcat(msgline, " [Permanent-Error]");
+    }
+    if (sd->status[1] & SNS_STAT1_INV_TRACK_FORMAT) {
+        strcat(msgline, " [Invalid-Track-Fmt]");
+    }
+    if (sd->status[1] & SNS_STAT1_EOC) {
+        strcat(msgline, " [End-of-Cyl]");
+    }
+    if (sd->status[1] & SNS_STAT1_MESSAGE_TO_OPER) {
+        strcat(msgline, " [Operator-Msg]");
+    }
+    if (sd->status[1] & SNS_STAT1_NO_REC_FOUND) {
+        strcat(msgline, " [No-Record-Found]");
+    }
+    if (sd->status[1] & SNS_STAT1_FILE_PROTECTED) {
+        strcat(msgline, " [File-Protected]");
+    }
+    if (sd->status[1] & SNS_STAT1_WRITE_INHIBITED) {
+        strcat(msgline, " [Write-Inhibited]");
+    }
+    if (sd->status[1] & SNS_STAT1_IMPRECISE_END) {
+        strcat(msgline, " [Imprecise-Ending]");
+    }
+
+    if (sd->status[2] & SNS_STAT2_REQ_INH_WRITE) {
+        strcat(msgline, " [Req-Inhibit-Write]");
+    }
+    if (sd->status[2] & SNS_STAT2_CORRECTABLE) {
+        strcat(msgline, " [Correctable-Data-Check]");
+    }
+    if (sd->status[2] & SNS_STAT2_FIRST_LOG_ERR) {
+        strcat(msgline, " [First-Error-Log]");
+    }
+    if (sd->status[2] & SNS_STAT2_ENV_DATA_PRESENT) {
+        strcat(msgline, " [Env-Data-Present]");
+    }
+    if (sd->status[2] & SNS_STAT2_IMPRECISE_END) {
+        strcat(msgline, " [Imprecise-End]");
+    }
+    strcat(msgline, "\n");
+    sclp_print(msgline);
+
+    print_int("    Residual Count     =", sd->res_count);
+    print_int("    Phys Drive ID      =", sd->phys_drive_id);
+    print_int("    low cyl address    =", sd->low_cyl_addr);
+    print_int("    head addr & hi cyl =", sd->head_high_cyl_addr);
+    print_int("    format/message     =", sd->fmt_msg);
+    print_int("    fmt-dependent[0-7] =", sd->fmt_dependent_info[0]);
+    print_int("    fmt-dependent[8-15]=", sd->fmt_dependent_info[1]);
+    print_int("    prog action code   =", sd->program_action_code);
+    print_int("    Configuration info =", sd->config_info);
+    print_int("    mcode / hi-cyl     =", sd->mcode_hicyl);
+    print_int("    cyl & head addr [0]=", sd->cyl_head_addr[0]);
+    print_int("    cyl & head addr [1]=", sd->cyl_head_addr[1]);
+    print_int("    cyl & head addr [2]=", sd->cyl_head_addr[2]);
+}
+
+static void print_irb_err(Irb *irb)
+{
+    Ccw0 *this_ccw = u32toptr(irb->scsw.cpa);
+    Ccw0 *prev_ccw = u32toptr(irb->scsw.cpa - 8);
+    char msgline[256];
+
+    sclp_print("vfio-ccw device I/O error - Interrupt Response Block Data:\n");
+
+    strcat(msgline, "    Function Ctrl :");
+    if (irb->scsw.ctrl & SCSW_FCTL_START_FUNC) {
+        strcat(msgline, " [Start]");
+    }
+    if (irb->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
+        strcat(msgline, " [Halt]");
+    }
+    if (irb->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
+        strcat(msgline, " [Clear]");
+    }
+    strcat(msgline, "\n");
+    sclp_print(msgline);
+
+    msgline[0] = '\0';
+    strcat(msgline, "    Activity Ctrl :");
+    if (irb->scsw.ctrl & SCSW_ACTL_RESUME_PEND) {
+        strcat(msgline, " [Resume-Pending]");
+    }
+    if (irb->scsw.ctrl & SCSW_ACTL_START_PEND) {
+        strcat(msgline, " [Start-Pending]");
+    }
+    if (irb->scsw.ctrl & SCSW_ACTL_HALT_PEND) {
+        strcat(msgline, " [Halt-Pending]");
+    }
+    if (irb->scsw.ctrl & SCSW_ACTL_CLEAR_PEND) {
+        strcat(msgline, " [Clear-Pending]");
+    }
+    if (irb->scsw.ctrl & SCSW_ACTL_CH_ACTIVE) {
+        strcat(msgline, " [Channel-Active]");
+    }
+    if (irb->scsw.ctrl & SCSW_ACTL_DEV_ACTIVE) {
+        strcat(msgline, " [Device-Active]");
+    }
+    if (irb->scsw.ctrl & SCSW_ACTL_SUSPENDED) {
+        strcat(msgline, " [Suspended]");
+    }
+    strcat(msgline, "\n");
+    sclp_print(msgline);
+
+    msgline[0] = '\0';
+    strcat(msgline, "    Status Ctrl :");
+    if (irb->scsw.ctrl & SCSW_SCTL_ALERT) {
+        strcat(msgline, " [Alert]");
+    }
+    if (irb->scsw.ctrl & SCSW_SCTL_INTERMED) {
+        strcat(msgline, " [Intermediate]");
+    }
+    if (irb->scsw.ctrl & SCSW_SCTL_PRIMARY) {
+        strcat(msgline, " [Primary]");
+    }
+    if (irb->scsw.ctrl & SCSW_SCTL_SECONDARY) {
+        strcat(msgline, " [Secondary]");
+    }
+    if (irb->scsw.ctrl & SCSW_SCTL_STATUS_PEND) {
+        strcat(msgline, " [Status-Pending]");
+    }
+
+    strcat(msgline, "\n");
+    sclp_print(msgline);
+
+    msgline[0] = '\0';
+    strcat(msgline, "    Device Status :");
+    if (irb->scsw.dstat & SCSW_DSTAT_ATTN) {
+        strcat(msgline, " [Attention]");
+    }
+    if (irb->scsw.dstat & SCSW_DSTAT_STATMOD) {
+        strcat(msgline, " [Status-Modifier]");
+    }
+    if (irb->scsw.dstat & SCSW_DSTAT_CUEND) {
+        strcat(msgline, " [Ctrl-Unit-End]");
+    }
+    if (irb->scsw.dstat & SCSW_DSTAT_BUSY) {
+        strcat(msgline, " [Busy]");
+    }
+    if (irb->scsw.dstat & SCSW_DSTAT_CHEND) {
+        strcat(msgline, " [Channel-End]");
+    }
+    if (irb->scsw.dstat & SCSW_DSTAT_DEVEND) {
+        strcat(msgline, " [Device-End]");
+    }
+    if (irb->scsw.dstat & SCSW_DSTAT_UCHK) {
+        strcat(msgline, " [Unit-Check]");
+    }
+    if (irb->scsw.dstat & SCSW_DSTAT_UEXCP) {
+        strcat(msgline, " [Unit-Exception]");
+    }
+    strcat(msgline, "\n");
+    sclp_print(msgline);
+
+    msgline[0] = '\0';
+    strcat(msgline, "    Channel Status :");
+    if (irb->scsw.cstat & SCSW_CSTAT_PCINT) {
+        strcat(msgline, " [Program-Ctrl-Interruption]");
+    }
+    if (irb->scsw.cstat & SCSW_CSTAT_BADLEN) {
+        strcat(msgline, " [Incorrect-Length]");
+    }
+    if (irb->scsw.cstat & SCSW_CSTAT_PROGCHK) {
+        strcat(msgline, " [Program-Check]");
+    }
+    if (irb->scsw.cstat & SCSW_CSTAT_PROTCHK) {
+        strcat(msgline, " [Protection-Check]");
+    }
+    if (irb->scsw.cstat & SCSW_CSTAT_CHDCHK) {
+        strcat(msgline, " [Channel-Data-Check]");
+    }
+    if (irb->scsw.cstat & SCSW_CSTAT_CHCCHK) {
+        strcat(msgline, " [Channel-Ctrl-Check]");
+    }
+    if (irb->scsw.cstat & SCSW_CSTAT_ICCHK) {
+        strcat(msgline, " [Interface-Ctrl-Check]");
+    }
+    if (irb->scsw.cstat & SCSW_CSTAT_CHAINCHK) {
+        strcat(msgline, " [Chaining-Check]");
+    }
+    strcat(msgline, "\n");
+    sclp_print(msgline);
+
+    print_int("    cpa=", irb->scsw.cpa);
+    print_int("    prev_ccw=", *((uint64_t *)prev_ccw));
+    print_int("    this_ccw=", *((uint64_t *)this_ccw));
+}
+
 /*
  * Executes a channel program at a given subchannel. The request to run the
  * channel program is sent to the subchannel, we then wait for the interrupt
@@ -148,6 +370,9 @@ int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
             continue;
         }
 
+        print_irb_err(&irb);
+        basic_sense(schid, &sd, sizeof(sd));
+        print_eckd_dasd_sense_data(&sd);
         break;
     }
 
diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h
index e198f0b..01b5de0 100644
--- a/pc-bios/s390-ccw/libc.h
+++ b/pc-bios/s390-ccw/libc.h
@@ -79,6 +79,17 @@ static inline size_t strlen(const char *str)
     return i;
 }
 
+static inline char *strcat(char *dest, const char *src)
+{
+    int i;
+    char *dest_end = dest + strlen(dest);
+
+    for (i = 0; i <= strlen(src); i++) {
+        dest_end[i] = src[i];
+    }
+    return dest;
+}
+
 static inline int isdigit(int c)
 {
     return (c >= '0') && (c <= '9');
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 12/15] s390-bios: Refactor virtio to run channel programs via cio
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (10 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 11/15] s390-bios: cio error handling Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-02-04 11:44   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 13/15] s390-bios: Use control unit type to determine boot method Jason J. Herne
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Now that we have a Channel I/O library let's modify virtio boot code to
make use of it for running channel programs.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/virtio.c | 48 +++++++++++++++++++----------------------------
 1 file changed, 19 insertions(+), 29 deletions(-)

diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index aa9da72..f8d71ed 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -89,33 +89,20 @@ int drain_irqs(SubChannelId schid)
     }
 }
 
-static int run_ccw(VDev *vdev, int cmd, void *ptr, int len)
+static int run_ccw(VDev *vdev, int cmd, void *ptr, int len, bool sli)
 {
     Ccw1 ccw = {};
-    CmdOrb orb = {};
-    int r;
-
-    enable_subchannel(vdev->schid);
-
-    /* start subchannel command */
-    orb.fmt = 1;
-    orb.cpa = (u32)(long)&ccw;
-    orb.lpm = 0x80;
 
     ccw.cmd_code = cmd;
     ccw.cda = (long)ptr;
     ccw.count = len;
 
-    r = ssch(vdev->schid, &orb);
-    /*
-     * XXX Wait until device is done processing the CCW. For now we can
-     *     assume that a simple tsch will have finished the CCW processing,
-     *     but the architecture allows for asynchronous operation
-     */
-    if (!r) {
-        r = drain_irqs(vdev->schid);
+    if (sli) {
+        ccw.flags |= CCW_FLAG_SLI;
     }
-    return r;
+
+    enable_subchannel(vdev->schid);
+    return do_cio(vdev->schid, ptr2u32(&ccw), CCW_FMT1);
 }
 
 static void vring_init(VRing *vr, VqInfo *info)
@@ -257,7 +244,7 @@ void virtio_setup_ccw(VDev *vdev)
     vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */
     vdev->guessed_disk_nature = VIRTIO_GDN_NONE;
 
-    run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0);
+    run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false);
 
     switch (vdev->senseid.cu_model) {
     case VIRTIO_ID_NET:
@@ -278,18 +265,19 @@ void virtio_setup_ccw(VDev *vdev)
     default:
         panic("Unsupported virtio device\n");
     }
-    IPL_assert(run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size) == 0,
-               "Could not get block device configuration");
+    IPL_assert(
+        run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false) == 0,
+       "Could not get block device configuration");
 
     /* Feature negotiation */
     for (i = 0; i < ARRAY_SIZE(vdev->guest_features); i++) {
         feats.features = 0;
         feats.index = i;
-        rc = run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats));
+        rc = run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false);
         IPL_assert(rc == 0, "Could not get features bits");
         vdev->guest_features[i] &= bswap32(feats.features);
         feats.features = bswap32(vdev->guest_features[i]);
-        rc = run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats));
+        rc = run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false);
         IPL_assert(rc == 0, "Could not set features bits");
     }
 
@@ -306,16 +294,17 @@ void virtio_setup_ccw(VDev *vdev)
         };
 
         IPL_assert(
-            run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config)) == 0,
+            run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config), false) == 0,
             "Could not get block device VQ configuration");
         info.num = config.num;
         vring_init(&vdev->vrings[i], &info);
         vdev->vrings[i].schid = vdev->schid;
-        IPL_assert(run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info)) == 0,
-                   "Cannot set VQ info");
+        IPL_assert(
+            run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false) == 0,
+            "Cannot set VQ info");
     }
     IPL_assert(
-        run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status)) == 0,
+        run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false) == 0,
         "Could not write status to host");
 }
 
@@ -324,7 +313,8 @@ bool virtio_is_supported(SubChannelId schid)
     vdev.schid = schid;
     memset(&vdev.senseid, 0, sizeof(vdev.senseid));
     /* run sense id command */
-    if (run_ccw(&vdev, CCW_CMD_SENSE_ID, &vdev.senseid, sizeof(vdev.senseid))) {
+    if (run_ccw(&vdev, CCW_CMD_SENSE_ID, &vdev.senseid, sizeof(vdev.senseid),
+                true)) {
         return false;
     }
     if (vdev.senseid.cu_type == 0x3832) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 13/15] s390-bios: Use control unit type to determine boot method
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (11 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 12/15] s390-bios: Refactor virtio to run channel programs via cio Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-02-04 11:46   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 14/15] s390-bios: Add channel command codes/structs needed for dasd-ipl Jason J. Herne
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

The boot method is different depending on which device type we are
booting from. Let's examine the control unit type to determine if we're
a virtio device. We'll eventually add a case to check for a real dasd device
here as well.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/main.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index fa90aa3..5ee02c3 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -200,13 +200,24 @@ static void virtio_setup(void)
 
 int main(void)
 {
+    uint16_t cutype;
+
     sclp_setup();
     css_setup();
     boot_setup();
     find_boot_device();
+    enable_subchannel(blk_schid);
 
-    virtio_setup();
-    zipl_load(); /* no return */
+    cutype = cu_type(blk_schid) ;
+    switch (cutype) {
+    case CU_TYPE_VIRTIO:
+        virtio_setup();
+        zipl_load(); /* no return */
+        break;
+    default:
+        print_int("Attempting to boot from unexpected device type", cutype);
+        panic("");
+    }
 
     panic("Failed to load OS from hard disk\n");
     return 0; /* make compiler happy */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 14/15] s390-bios: Add channel command codes/structs needed for dasd-ipl
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (12 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 13/15] s390-bios: Use control unit type to determine boot method Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-02-04 11:47   ` Cornelia Huck
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device Jason J. Herne
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

The dasd IPL procedure needs to execute a few previously unused
channel commands. Let's define them and their associated data
structures.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/cio.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
index 1086f31..6f60ea1 100644
--- a/pc-bios/s390-ccw/cio.h
+++ b/pc-bios/s390-ccw/cio.h
@@ -200,11 +200,14 @@ typedef struct ccw1 {
 #define CCW_FLAG_IDA             0x04
 #define CCW_FLAG_SUSPEND         0x02
 
+/* Common CCW commands */
+#define CCW_CMD_READ_IPL         0x02
 #define CCW_CMD_NOOP             0x03
 #define CCW_CMD_BASIC_SENSE      0x04
 #define CCW_CMD_TIC              0x08
 #define CCW_CMD_SENSE_ID         0xe4
 
+/* Virtio CCW commands */
 #define CCW_CMD_SET_VQ           0x13
 #define CCW_CMD_VDEV_RESET       0x33
 #define CCW_CMD_READ_FEAT        0x12
@@ -216,6 +219,12 @@ typedef struct ccw1 {
 #define CCW_CMD_SET_CONF_IND     0x53
 #define CCW_CMD_READ_VQ_CONF     0x32
 
+/* DASD CCW commands */
+#define CCW_CMD_DASD_READ             0x06
+#define CCW_CMD_DASD_SEEK             0x07
+#define CCW_CMD_DASD_SEARCH_ID_EQ     0x31
+#define CCW_CMD_DASD_READ_MT          0x86
+
 /*
  * Command-mode operation request block
  */
@@ -331,6 +340,20 @@ typedef struct irb {
     __u32 emw[8];
 }  __attribute__ ((packed, aligned(4))) Irb;
 
+/* Used for SEEK ccw commands */
+typedef struct CcwSeekData {
+    uint16_t reserved;
+    uint16_t cyl;
+    uint16_t head;
+} __attribute__((packed)) CcwSeekData;
+
+/* Used for SEARCH ID ccw commands */
+typedef struct CcwSearchIdData {
+    uint16_t cyl;
+    uint16_t head;
+    uint8_t record;
+} __attribute__((packed)) CcwSearchIdData;
+
 int enable_mss_facility(void);
 void enable_subchannel(SubChannelId schid);
 uint16_t cu_type(SubChannelId schid);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (13 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 14/15] s390-bios: Add channel command codes/structs needed for dasd-ipl Jason J. Herne
@ 2019-01-29 13:29 ` Jason J. Herne
  2019-01-31 18:23   ` Cornelia Huck
                     ` (2 more replies)
  2019-01-29 16:40 ` [Qemu-devel] [qemu-s390x] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
  2019-01-31 18:10 ` [Qemu-devel] " no-reply
  16 siblings, 3 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 13:29 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Allows guest to boot from a vfio configured real dasd device.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 docs/devel/s390-dasd-ipl.txt | 132 +++++++++++++++++++++++
 pc-bios/s390-ccw/Makefile    |   2 +-
 pc-bios/s390-ccw/dasd-ipl.c  | 249 +++++++++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/dasd-ipl.h  |  16 +++
 pc-bios/s390-ccw/main.c      |   4 +
 pc-bios/s390-ccw/s390-arch.h |  13 +++
 6 files changed, 415 insertions(+), 1 deletion(-)
 create mode 100644 docs/devel/s390-dasd-ipl.txt
 create mode 100644 pc-bios/s390-ccw/dasd-ipl.c
 create mode 100644 pc-bios/s390-ccw/dasd-ipl.h

diff --git a/docs/devel/s390-dasd-ipl.txt b/docs/devel/s390-dasd-ipl.txt
new file mode 100644
index 0000000..84ec7b8
--- /dev/null
+++ b/docs/devel/s390-dasd-ipl.txt
@@ -0,0 +1,132 @@
+*****************************
+***** s390 hardware IPL *****
+*****************************
+
+The s390 hardware IPL process consists of the following steps.
+
+1. A READ IPL ccw is constructed in memory location 0x0.
+    This ccw, by definition, reads the IPL1 record which is located on the disk
+    at cylinder 0 track 0 record 1. Note that the chain flag is on in this ccw
+    so when it is complete another ccw will be fetched and executed from memory
+    location 0x08.
+
+2. Execute the Read IPL ccw at 0x00, thereby reading IPL1 data into 0x00.
+    IPL1 data is 24 bytes in length and consists of the following pieces of
+    information: [psw][read ccw][tic ccw]. When the machine executes the Read
+    IPL ccw it read the 24-bytes of IPL1 to be read into memory starting at
+    location 0x0. Then the ccw program at 0x08 which consists of a read
+    ccw and a tic ccw is automatically executed because of the chain flag from
+    the original READ IPL ccw. The read ccw will read the IPL2 data into memory
+    and the TIC (Tranfer In Channel) will transfer control to the channel
+    program contained in the IPL2 data. The TIC channel command is the
+    equivalent of a branch/jump/goto instruction for channel programs.
+    NOTE: The ccws in IPL1 are defined by the architecture to be format 0.
+
+3. Execute IPL2.
+    The TIC ccw instruction at the end of the IPL1 channel program will begin
+    the execution of the IPL2 channel program. IPL2 is stage-2 of the boot
+    process and will contain a larger channel program than IPL1. The point of
+    IPL2 is to find and load either the operating system or a small program that
+    loads the operating system from disk. At the end of this step all or some of
+    the real operating system is loaded into memory and we are ready to hand
+    control over to the guest operating system. At this point the guest
+    operating system is entirely responsible for loading any more data it might
+    need to function. NOTE: The IPL2 channel program might read data into memory
+    location 0 thereby overwriting the IPL1 psw and channel program. This is ok
+    as long as the data placed in location 0 contains a psw whose instruction
+    address points to the guest operating system code to execute at the end of
+    the IPL/boot process.
+    NOTE: The ccws in IPL2 are defined by the architecture to be format 0.
+
+4. Start executing the guest operating system.
+    The psw that was loaded into memory location 0 as part of the ipl process
+    should contain the needed flags for the operating system we have loaded. The
+    psw's instruction address will point to the location in memory where we want
+    to start executing the operating system. This psw is loaded (via LPSW
+    instruction) causing control to be passed to the operating system code.
+
+In a non-virtualized environment this process, handled entirely by the hardware,
+is kicked off by the user initiating a "Load" procedure from the hardware
+management console. This "Load" procedure crafts a special "Read IPL" ccw in
+memory location 0x0 that reads IPL1. It then executes this ccw thereby kicking
+off the reading of IPL1 data. Since the channel program from IPL1 will be
+written immediately after the special "Read IPL" ccw, the IPL1 channel program
+will be executed immediately (the special read ccw has the chaining bit turned
+on). The TIC at the end of the IPL1 channel program will cause the IPL2 channel
+program to be executed automatically. After this sequence completes the "Load"
+procedure then loads the psw from 0x0.
+
+*****************************************
+***** How this all pertains to Qemu *****
+*****************************************
+
+In theory we should merely have to do the following to IPL/boot a guest
+operating system from a DASD device:
+
+1. Place a "Read IPL" ccw into memory location 0x0 with chaining bit on.
+2. Execute channel program at 0x0.
+3. LPSW 0x0.
+
+However, our emulation of the machine's channel program logic is missing one key
+feature that is required for this process to work: non-prefetch of ccw data.
+
+When we start a channel program we pass the channel subsystem parameters via an
+ORB (Operation Request Block). One of those parameters is a prefetch bit. If the
+bit is on then Qemu is allowed to read the entire channel program from guest
+memory before it starts executing it. This means that any channel commands that
+read additional channel commands will not work as expected because the newly
+read commands will only exist in guest memory and NOT within Qemu's channel
+subsystem memory. Qemu's channel subsystem's implementation currently requires
+this bit to be on for all channel programs. This is a problem because the IPL
+process consists of transferring control from the "Read IPL" ccw immediately to
+the IPL1 channel program that was read by "Read IPL".
+
+Not being able to turn off prefetch will also prevent the TIC at the end of the
+IPL1 channel program from transferring control to the IPL2 channel program.
+
+Lastly, in some cases (the zipl bootloader for example) the IPL2 program also
+tansfers control to another channel program segment immediately after reading it
+from the disk. So we need to be able to handle this case.
+
+**************************
+***** What Qemu does *****
+**************************
+
+Since we are forced to live with prefetch we cannot use the very simple IPL
+procedure we defined in the preceding section. So we compensate by doing the
+following.
+
+1. Place "Read IPL" ccw into memory location 0x0, but turn off chaining bit.
+2. Execute "Read IPL" at 0x0.
+
+   So now IPL1's psw is at 0x0 and IPL1's channel program is at 0x08.
+
+4. Write a custom channel program that will seek to the IPL2 record and then
+   execute the READ and TIC ccws from IPL1.  Normamly the seek is not required
+   because after reading the IPL1 record the disk is automatically positioned
+   to read the very next record which will be IPL2. But since we are not reading
+   both IPL1 and IPL2 as part of the same channel program we must manually set
+   the position.
+
+5. Grab the target address of the TIC instruction from the IPL1 channel program.
+   This address is where the IPL2 channel program starts.
+
+   Now IPL2 is loaded into memory somewhere, and we know the address.
+
+6. Execute the IPL2 channel program at the address obtained in step #5.
+
+   Because this channel program can be dynamic, we must use a special algorithm
+   that detects a READ immediately followed by a TIC and breaks the ccw chain
+   by turning off the chain bit in the READ ccw. When control is returned from
+   the kernel/hardware to the Qemu bios code we immediately issue another start
+   subchannel to execute the remaining TIC instruction. This causes the entire
+   channel program (starting from the TIC) and all needed data to be refetched
+   thereby stepping around the limitation that would otherwise prevent this
+   channel program from executing properly.
+
+   Now the operating system code is loaded somewhere in guest memory and the psw
+   in memory location 0x0 will point to entry code for the guest operating
+   system.
+
+7. LPSW 0x0.
+   LPSW transfers control to the guest operating system and we're done.
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 12ad9c1..a048b6b 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -10,7 +10,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
 .PHONY : all clean build-all
 
 OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
-	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o
+	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o dasd-ipl.o
 
 QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
 QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c
new file mode 100644
index 0000000..b7ce6d9
--- /dev/null
+++ b/pc-bios/s390-ccw/dasd-ipl.c
@@ -0,0 +1,249 @@
+/*
+ * S390 IPL (boot) from a real DASD device via vfio framework.
+ *
+ * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "libc.h"
+#include "s390-ccw.h"
+#include "s390-arch.h"
+#include "dasd-ipl.h"
+
+static char prefix_page[PAGE_SIZE * 2]
+            __attribute__((__aligned__(PAGE_SIZE * 2)));
+
+static void enable_prefixing(void)
+{
+    memcpy(&prefix_page, (void *)0, 4096);
+    set_prefix(ptr2u32(&prefix_page));
+}
+
+static void disable_prefixing(void)
+{
+    set_prefix(0);
+    /* Copy io interrupt info back to low core */
+    memcpy((void *)0xB8, prefix_page + 0xB8, 12);
+}
+
+static bool is_read_tic_ccw_chain(Ccw0 *ccw)
+{
+    Ccw0 *next_ccw = ccw + 1;
+
+    return ((ccw->cmd_code == CCW_CMD_DASD_READ ||
+            ccw->cmd_code == CCW_CMD_DASD_READ_MT) &&
+            ccw->chain && next_ccw->cmd_code == CCW_CMD_TIC);
+}
+
+static bool dynamic_cp_fixup(uint32_t ccw_addr, uint32_t  *next_cpa)
+{
+    Ccw0 *cur_ccw = (Ccw0 *)(uint64_t)ccw_addr;
+    Ccw0 *tic_ccw;
+
+    while (true) {
+        /* Skip over inline TIC (it might not have the chain bit on)  */
+        if (cur_ccw->cmd_code == CCW_CMD_TIC &&
+            cur_ccw->cda == ptr2u32(cur_ccw) - 8) {
+            cur_ccw += 1;
+            continue;
+        }
+
+        if (!cur_ccw->chain) {
+            break;
+        }
+        if (is_read_tic_ccw_chain(cur_ccw)) {
+            /*
+             * Breaking a chain of CCWs may alter the semantics or even the
+             * validity of a channel program. The heuristic implemented below
+             * seems to work well in practice for the channel programs
+             * generated by zipl.
+             */
+            tic_ccw = cur_ccw + 1;
+            *next_cpa = tic_ccw->cda;
+            cur_ccw->chain = 0;
+            return true;
+        }
+        cur_ccw += 1;
+    }
+    return false;
+}
+
+static int run_dynamic_ccw_program(SubChannelId schid, uint32_t cpa)
+{
+    bool has_next;
+    uint32_t next_cpa = 0;
+    int rc;
+
+    do {
+        has_next = dynamic_cp_fixup(cpa, &next_cpa);
+
+        print_int("executing ccw chain at ", cpa);
+        enable_prefixing();
+        rc = do_cio(schid, cpa, CCW_FMT0);
+        disable_prefixing();
+
+        if (rc) {
+            break;
+        }
+        cpa = next_cpa;
+    } while (has_next);
+
+    return rc;
+}
+
+
+static void make_readipl(void)
+{
+    Ccw0 *ccwIplRead = (Ccw0 *)0x00;
+
+    /* Create Read IPL ccw at address 0 */
+    ccwIplRead->cmd_code = CCW_CMD_READ_IPL;
+    ccwIplRead->cda = 0x00; /* Read into address 0x00 in main memory */
+    ccwIplRead->chain = 0; /* Chain flag */
+    ccwIplRead->count = 0x18; /* Read 0x18 bytes of data */
+}
+
+static void run_readipl(SubChannelId schid)
+{
+    if (do_cio(schid, 0x00, CCW_FMT0)) {
+        panic("dasd-ipl: Failed to run Read IPL channel program");
+    }
+}
+
+/*
+ * The architecture states that IPL1 data should consist of a psw followed by
+ * format-0 READ and TIC CCWs. Let's sanity check.
+ */
+static void check_ipl1(void)
+{
+    Ccw0 *ccwread = (Ccw0 *)0x08;
+    Ccw0 *ccwtic = (Ccw0 *)0x10;
+
+    if (ccwread->cmd_code != CCW_CMD_DASD_READ ||
+        ccwtic->cmd_code != CCW_CMD_TIC) {
+        panic("dasd-ipl: IPL1 data invalid. Is this disk really bootable?\n");
+    }
+}
+
+static void check_ipl2(uint32_t ipl2_addr)
+{
+    Ccw0 *ccw = u32toptr(ipl2_addr);
+
+    if (ipl2_addr == 0x00) {
+        panic("IPL2 address invalid. Is this disk really bootable?\n");
+    }
+    if (ccw->cmd_code == 0x00) {
+        panic("IPL2 ccw data invalid. Is this disk really bootable?\n");
+    }
+}
+
+static uint32_t read_ipl2_addr(void)
+{
+    Ccw0 *ccwtic = (Ccw0 *)0x10;
+
+    return ccwtic->cda;
+}
+
+static void ipl1_fixup(void)
+{
+    Ccw0 *ccwSeek = (Ccw0 *) 0x08;
+    Ccw0 *ccwSearchID = (Ccw0 *) 0x10;
+    Ccw0 *ccwSearchTic = (Ccw0 *) 0x18;
+    Ccw0 *ccwRead = (Ccw0 *) 0x20;
+    CcwSeekData *seekData = (CcwSeekData *) 0x30;
+    CcwSearchIdData *searchData = (CcwSearchIdData *) 0x38;
+
+    /* move IPL1 CCWs to make room for CCWs needed to locate record 2 */
+    memcpy(ccwRead, (void *)0x08, 16);
+
+    /* Disable chaining so we don't TIC to IPL2 channel program */
+    ccwRead->chain = 0x00;
+
+    ccwSeek->cmd_code = CCW_CMD_DASD_SEEK;
+    ccwSeek->cda = ptr2u32(seekData);
+    ccwSeek->chain = 1;
+    ccwSeek->count = sizeof(seekData);
+    seekData->reserved = 0x00;
+    seekData->cyl = 0x00;
+    seekData->head = 0x00;
+
+    ccwSearchID->cmd_code = CCW_CMD_DASD_SEARCH_ID_EQ;
+    ccwSearchID->cda = ptr2u32(searchData);
+    ccwSearchID->chain = 1;
+    ccwSearchID->count = sizeof(searchData);
+    searchData->cyl = 0;
+    searchData->head = 0;
+    searchData->record = 2;
+
+    /* Go back to Search CCW if correct record not yet found */
+    ccwSearchTic->cmd_code = CCW_CMD_TIC;
+    ccwSearchTic->cda = ptr2u32(ccwSearchID);
+}
+
+static void run_ipl1(SubChannelId schid)
+ {
+    uint32_t startAddr = 0x08;
+
+    if (do_cio(schid, startAddr, CCW_FMT0)) {
+        panic("dasd-ipl: Failed to run IPL1 channel program");
+    }
+}
+
+static void run_ipl2(SubChannelId schid, uint32_t addr)
+{
+
+    if (run_dynamic_ccw_program(schid, addr)) {
+        panic("dasd-ipl: Failed to run IPL2 channel program");
+    }
+}
+
+static void lpsw(void *psw_addr)
+{
+    PSWLegacy *pswl = (PSWLegacy *) psw_addr;
+
+    pswl->mask |= PSW_MASK_EAMODE;   /* Force z-mode */
+    pswl->addr |= PSW_MASK_BAMODE;
+    asm volatile("  llgtr 0,0\n llgtr 1,1\n"     /* Some OS's expect to be */
+                 "  llgtr 2,2\n llgtr 3,3\n"     /* in 32-bit mode. Clear  */
+                 "  llgtr 4,4\n llgtr 5,5\n"     /* high part of regs to   */
+                 "  llgtr 6,6\n llgtr 7,7\n"     /* avoid messing up       */
+                 "  llgtr 8,8\n llgtr 9,9\n"     /* instructions that work */
+                 "  llgtr 10,10\n llgtr 11,11\n" /* in both addressing     */
+                 "  llgtr 12,12\n llgtr 13,13\n" /* modes, like servc.     */
+                 "  llgtr 14,14\n llgtr 15,15\n"
+                 "  lpsw %0\n"
+                 : : "Q" (*pswl) : "cc");
+}
+
+/*
+ * Limitations in QEMU's CCW support complicate the IPL process. Details can
+ * be found in docs/devel/s390-dasd-ipl.txt
+ */
+void dasd_ipl(SubChannelId schid)
+{
+    uint32_t ipl2_addr;
+
+    /* Construct Read IPL CCW and run it to read IPL1 from boot disk */
+    make_readipl();
+    run_readipl(schid);
+    ipl2_addr = read_ipl2_addr();
+    check_ipl1();
+
+    /*
+     * Fixup IPL1 channel program to account for QEMU limitations, then run it
+     * to read IPL2 channel program from boot disk.
+     */
+    ipl1_fixup();
+    run_ipl1(schid);
+    check_ipl2(ipl2_addr);
+
+    /*
+     * Run IPL2 channel program to read operating system code from boot disk
+     * then transfer control to the guest operating system
+     */
+    run_ipl2(schid, ipl2_addr);
+    lpsw(0);
+}
diff --git a/pc-bios/s390-ccw/dasd-ipl.h b/pc-bios/s390-ccw/dasd-ipl.h
new file mode 100644
index 0000000..56bba82
--- /dev/null
+++ b/pc-bios/s390-ccw/dasd-ipl.h
@@ -0,0 +1,16 @@
+/*
+ * S390 IPL (boot) from a real DASD device via vfio framework.
+ *
+ * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef DASD_IPL_H
+#define DASD_IPL_H
+
+void dasd_ipl(SubChannelId schid);
+
+#endif /* DASD_IPL_H */
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 5ee02c3..0a46339 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -13,6 +13,7 @@
 #include "s390-ccw.h"
 #include "cio.h"
 #include "virtio.h"
+#include "dasd-ipl.h"
 
 char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
 static SubChannelId blk_schid = { .one = 1 };
@@ -210,6 +211,9 @@ int main(void)
 
     cutype = cu_type(blk_schid) ;
     switch (cutype) {
+    case CU_TYPE_DASD_3990:
+        dasd_ipl(blk_schid); /* no return */
+        break;
     case CU_TYPE_VIRTIO:
         virtio_setup();
         zipl_load(); /* no return */
diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
index 47eaa04..0438d42 100644
--- a/pc-bios/s390-ccw/s390-arch.h
+++ b/pc-bios/s390-ccw/s390-arch.h
@@ -97,4 +97,17 @@ typedef struct LowCore {
 
 extern const LowCore *lowcore;
 
+static inline void set_prefix(uint32_t address)
+{
+    asm volatile("spx %0" : : "m" (address) : "memory");
+}
+
+static inline uint32_t store_prefix(void)
+{
+    uint32_t address;
+
+    asm volatile("stpx %0" : "=m" (address));
+    return address;
+}
+
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 00/15] s390: vfio-ccw dasd ipl support
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (14 preceding siblings ...)
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device Jason J. Herne
@ 2019-01-29 16:40 ` Jason J. Herne
  2019-01-31 18:10 ` [Qemu-devel] " no-reply
  16 siblings, 0 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-29 16:40 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

On 1/29/19 8:29 AM, Jason J. Herne wrote:
> This is to support booting from vfio-ccw dasd devices. We basically implement
> the real hardware ipl procedure. This allows for booting Linux guests on
> vfio-ccw devices.
> 
> vfio-ccw's channel program prefetch algorithm complicates ipl because most ipl
> channel programs dynamically modify themselves. Details on the ipl process and
> how we worked around this issue can be found in docs/devel/s390-dasd-ipl.txt.
> 
> This version brings better error handling, namely retrying I/O operations in the
> event of some transient failure conditions. I've also renamed the sense data
> structures and error output to indicate that they are for eckd dasd only. A few
> other fixups as well, see changelog for details.
> 

Forgot to add the 2 tag, this is v2.

-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
@ 2019-01-30 16:56   ` Cornelia Huck
  2019-01-30 20:12     ` Jason J. Herne
  2019-01-30 22:21   ` Farhan Ali
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-01-30 16:56 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:08 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Add bootindex property and iplb data for vfio-ccw devices. This allows us to
> forward boot information into the bios for vfio-ccw devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> ---
>  hw/s390x/ipl.c              | 14 ++++++++++++++
>  hw/s390x/s390-ccw.c         |  9 +++++++++
>  hw/vfio/ccw.c               | 13 +------------
>  include/hw/s390x/s390-ccw.h |  1 +
>  include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 63 insertions(+), 12 deletions(-)
>  create mode 100644 include/hw/s390x/vfio-ccw.h

> diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h
> new file mode 100644
> index 0000000..a7d699d
> --- /dev/null
> +++ b/include/hw/s390x/vfio-ccw.h
> @@ -0,0 +1,38 @@
> +/*
> + * vfio based subchannel assignment support
> + *
> + * Copyright 2018 IBM Corp.

Why 2018? Should either be 2017 (the original date for hw/vfio/ccw.c)
or 2019.

> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> + *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> + *            Pierre Morel <pmorel@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
> + * your option) any later version. See the COPYING file in the top-level
> + * directory.
> + */
> +
> +#ifndef HW_VFIO_CCW_H
> +#define HW_VFIO_CCW_H
> +
> +#include "hw/vfio/vfio-common.h"
> +#include "hw/s390x/s390-ccw.h"
> +#include "hw/s390x/ccw-device.h"
> +
> +#define TYPE_VFIO_CCW "vfio-ccw"
> +#define VFIO_CCW(obj) \
> +        OBJECT_CHECK(VFIOCCWDevice, (obj), TYPE_VFIO_CCW)
> +
> +
> +#define TYPE_VFIO_CCW "vfio-ccw"
> +typedef struct VFIOCCWDevice {
> +    S390CCWDevice cdev;
> +    VFIODevice vdev;
> +    uint64_t io_region_size;
> +    uint64_t io_region_offset;
> +    struct ccw_io_region *io_region;
> +    EventNotifier io_notifier;
> +    bool force_orb_pfch;
> +    bool warned_orb_pfch;
> +} VFIOCCWDevice;
> +
> +#endif

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-01-30 16:56   ` Cornelia Huck
@ 2019-01-30 20:12     ` Jason J. Herne
  0 siblings, 0 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-30 20:12 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On 1/30/19 11:56 AM, Cornelia Huck wrote:
> On Tue, 29 Jan 2019 08:29:08 -0500
> "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> 
>> Add bootindex property and iplb data for vfio-ccw devices. This allows us to
>> forward boot information into the bios for vfio-ccw devices.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
>> ---
>>   hw/s390x/ipl.c              | 14 ++++++++++++++
>>   hw/s390x/s390-ccw.c         |  9 +++++++++
>>   hw/vfio/ccw.c               | 13 +------------
>>   include/hw/s390x/s390-ccw.h |  1 +
>>   include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++
>>   5 files changed, 63 insertions(+), 12 deletions(-)
>>   create mode 100644 include/hw/s390x/vfio-ccw.h
> 
>> diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h
>> new file mode 100644
>> index 0000000..a7d699d
>> --- /dev/null
>> +++ b/include/hw/s390x/vfio-ccw.h
>> @@ -0,0 +1,38 @@
>> +/*
>> + * vfio based subchannel assignment support
>> + *
>> + * Copyright 2018 IBM Corp.
> 
> Why 2018? Should either be 2017 (the original date for hw/vfio/ccw.c)
> or 2019.
> 

Okay. I will fix it.


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
  2019-01-30 16:56   ` Cornelia Huck
@ 2019-01-30 22:21   ` Farhan Ali
  2019-02-08 16:07     ` Jason J. Herne
  2019-01-31 18:20   ` Cornelia Huck
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 83+ messages in thread
From: Farhan Ali @ 2019-01-30 22:21 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger



On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> Add bootindex property and iplb data for vfio-ccw devices. This allows us to
> forward boot information into the bios for vfio-ccw devices.
> 
> Signed-off-by: Jason J. Herne<jjherne@linux.ibm.com>
> Acked-by: Halil Pasic<pasic@linux.vnet.ibm.com>
> ---
>   hw/s390x/ipl.c              | 14 ++++++++++++++
>   hw/s390x/s390-ccw.c         |  9 +++++++++
>   hw/vfio/ccw.c               | 13 +------------
>   include/hw/s390x/s390-ccw.h |  1 +
>   include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++
>   5 files changed, 63 insertions(+), 12 deletions(-)
>   create mode 100644 include/hw/s390x/vfio-ccw.h
> 
> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
> index 21f64ad..a993f65 100644
> --- a/hw/s390x/ipl.c
> +++ b/hw/s390x/ipl.c
> @@ -19,6 +19,7 @@
>   #include "hw/loader.h"
>   #include "hw/boards.h"
>   #include "hw/s390x/virtio-ccw.h"
> +#include "hw/s390x/vfio-ccw.h"
>   #include "hw/s390x/css.h"
>   #include "hw/s390x/ebcdic.h"
>   #include "ipl.h"
> @@ -311,8 +312,12 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
>           VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
>               object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
>                                   TYPE_VIRTIO_CCW_DEVICE);
> +        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>           if (virtio_ccw_dev) {
>               ccw_dev = CCW_DEVICE(virtio_ccw_dev);
> +        } else if (vfio_ccw_dev) {
> +            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
>           } else {
>               SCSIDevice *sd = (SCSIDevice *)
>                   object_dynamic_cast(OBJECT(dev_st),
> @@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>       if (ccw_dev) {
>           SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
>                                                               TYPE_SCSI_DEVICE);
> +        VFIOCCWDevice *vc = (VFIOCCWDevice *)
> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>   
>           if (sd) {
>               ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
> @@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>               ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
>               ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
>               ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
> +        } else if (vc) {
> +            CcwDevice *ccw_dev = CCW_DEVICE(vc);

Do we need this line here? I though ccw_dev was already correctly casted 
in s390_get_ccw_device?

> +
> +            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
> +            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
> +            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
> +            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
>           } else {
>               VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
>                                                                 TYPE_VIRTIO_NET);

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio Jason J. Herne
@ 2019-01-30 22:23   ` Farhan Ali
  2019-02-04 10:28   ` Cornelia Huck
  2019-02-05  9:55   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  2 siblings, 0 replies; 83+ messages in thread
From: Farhan Ali @ 2019-01-30 22:23 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger



On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> Move channel i/o setup code out to a separate function. This decouples cio
> setup from the virtio code path and allows us to make use of it for booting
> dasd devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> Reviewed-by: Collin Walling <walling@linux.ibm.com>
> ---
>   pc-bios/s390-ccw/main.c | 20 +++++++++++++-------
>   1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index 544851d..e82fe2c 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -99,6 +99,18 @@ static void menu_setup(void)
>       }
>   }
>   
> +/*
> + * Initialize the channel I/O subsystem so we can talk to our ipl/boot device.
> + */
> +static void css_setup(void)
> +{
> +    /*
> +     * Unconditionally enable mss support. In every sane configuration this
> +     * will succeed; and even if it doesn't, stsch_err() can handle it.
> +     */
> +    enable_mss_facility();
> +}
> +
>   static void virtio_setup(void)
>   {
>       Schib schib;
> @@ -109,13 +121,6 @@ static void virtio_setup(void)
>       VDev *vdev = virtio_get_device();
>       QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
>   
> -    /*
> -     * We unconditionally enable mss support. In every sane configuration,
> -     * this will succeed; and even if it doesn't, stsch_err() can deal
> -     * with the consequences.
> -     */
> -    enable_mss_facility();
> -
>       sclp_get_loadparm_ascii(loadparm_str);
>       memcpy(ldp + 10, loadparm_str, LOADPARM_LEN);
>       sclp_print(ldp);
> @@ -168,6 +173,7 @@ static void virtio_setup(void)
>   int main(void)
>   {
>       sclp_setup();
> +    css_setup();
>       virtio_setup();
>   
>       zipl_load(); /* no return */
> 
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 03/15] s390-bios: decouple common boot logic from virtio
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 03/15] s390-bios: decouple common boot logic " Jason J. Herne
@ 2019-01-30 22:27   ` Farhan Ali
  2019-02-04 10:31   ` Cornelia Huck
  1 sibling, 0 replies; 83+ messages in thread
From: Farhan Ali @ 2019-01-30 22:27 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger



On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> Create a boot_setup function to handle getting boot information from
> the machine/hypervisor. This decouples common boot logic from the
> virtio code path and allows us to make use of it for the real dasd boot
> scenario.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> Reviewed-by: Collin Walling <walling@linux.ibm.com
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> ---
>   pc-bios/s390-ccw/main.c | 28 ++++++++++++++++++++--------
>   1 file changed, 20 insertions(+), 8 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index e82fe2c..67df421 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -14,16 +14,17 @@
>   
>   char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
>   static SubChannelId blk_schid = { .one = 1 };
> -IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
>   static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
>   QemuIplParameters qipl;
> +IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
> +static bool have_iplb;
>   
>   #define LOADPARM_PROMPT "PROMPT  "
>   #define LOADPARM_EMPTY  "        "
>   #define BOOT_MENU_FLAG_MASK (QIPL_FLAG_BM_OPTS_CMD | QIPL_FLAG_BM_OPTS_ZIPL)
>   
>   /*
> - * Priniciples of Operations (SA22-7832-09) chapter 17 requires that
> + * Principles of Operations (SA22-7832-09) chapter 17 requires that
>    * a subsystem-identification is at 184-187 and bytes 188-191 are zero
>    * after list-directed-IPL and ccw-IPL.
>    */
> @@ -111,23 +112,33 @@ static void css_setup(void)
>       enable_mss_facility();
>   }
>   
> +/*
> + * Collect various pieces of information from the hypervisor/hardware that
> + * we'll use to determine exactly how we'll boot.
> + */
> +static void boot_setup(void)
> +{
> +    char lpmsg[] = "LOADPARM=[________]\n";
> +
> +    sclp_get_loadparm_ascii(loadparm_str);
> +    memcpy(lpmsg + 10, loadparm_str, 8);
> +    sclp_print(lpmsg);
> +
> +    have_iplb = store_iplb(&iplb);
> +}
> +
>   static void virtio_setup(void)
>   {
>       Schib schib;
>       int ssid;
>       bool found = false;
>       uint16_t dev_no;
> -    char ldp[] = "LOADPARM=[________]\n";
>       VDev *vdev = virtio_get_device();
>       QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
>   
> -    sclp_get_loadparm_ascii(loadparm_str);
> -    memcpy(ldp + 10, loadparm_str, LOADPARM_LEN);
> -    sclp_print(ldp);
> -
>       memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
>   
> -    if (store_iplb(&iplb)) {
> +    if (have_iplb) {
>           switch (iplb.pbt) {
>           case S390_IPL_TYPE_CCW:
>               dev_no = iplb.ccw.devno;
> @@ -174,6 +185,7 @@ int main(void)
>   {
>       sclp_setup();
>       css_setup();
> +    boot_setup();
>       virtio_setup();
>   
>       zipl_load(); /* no return */
> 
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path Jason J. Herne
@ 2019-01-31 13:44   ` Farhan Ali
  2019-02-04 10:45   ` Cornelia Huck
  1 sibling, 0 replies; 83+ messages in thread
From: Farhan Ali @ 2019-01-31 13:44 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger



On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> Make a new routine find_boot_device to locate the boot device for all
> cases. not just virtio.
> 
> In one case no boot device is specified and a suitable boot device can not
> be auto detected. The error message for this case was specific to virtio
> devices. We update this message to remove virtio specific wording.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>   pc-bios/s390-ccw/main.c  | 87 ++++++++++++++++++++++++++----------------------
>   tests/boot-serial-test.c |  2 +-
>   2 files changed, 49 insertions(+), 40 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index 7e3f65e..2457752 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -55,17 +55,18 @@ unsigned int get_loadparm_index(void)
>    * NOTE: The global variable blk_schid is updated to contain the subchannel
>    * information.
>    */
> -static bool find_dev(Schib *schib, int dev_no)
> +static bool find_subch(int dev_no)
>   {
> +    Schib schib;
>       int i, r;
>   
>       for (i = 0; i < 0x10000; i++) {
>           blk_schid.sch_no = i;
> -        r = stsch_err(blk_schid, schib);
> +        r = stsch_err(blk_schid, &schib);
>           if ((r == 3) || (r == -EIO)) {
>               break;
>           }
> -        if (!schib->pmcw.dnv) {
> +        if (!schib.pmcw.dnv) {
>               continue;
>           }
>   
> @@ -77,7 +78,7 @@ static bool find_dev(Schib *schib, int dev_no)
>               continue;
>           }
>   
> -        if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
> +        if ((dev_no < 0) || (schib.pmcw.dev == dev_no)) {
>               return true;
>           }
>       }
> @@ -133,56 +134,63 @@ static void boot_setup(void)
>       have_iplb = store_iplb(&iplb);
>   }
>   
> -static void virtio_setup(void)
> +static void find_boot_device(void)
>   {
> -    Schib schib;
> -    int ssid;
> -    bool found = false;
> -    uint16_t dev_no;
>       VDev *vdev = virtio_get_device();
> -    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
> -
> -    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
> +    int ssid;
> +    bool found;
>   
> -    if (have_iplb) {
> -        switch (iplb.pbt) {
> -        case S390_IPL_TYPE_CCW:
> -            dev_no = iplb.ccw.devno;
> -            debug_print_int("device no. ", dev_no);
> -            blk_schid.ssid = iplb.ccw.ssid & 0x3;
> -            debug_print_int("ssid ", blk_schid.ssid);
> -            found = find_dev(&schib, dev_no);
> -            break;
> -        case S390_IPL_TYPE_QEMU_SCSI:
> -            vdev->scsi_device_selected = true;
> -            vdev->selected_scsi_device.channel = iplb.scsi.channel;
> -            vdev->selected_scsi_device.target = iplb.scsi.target;
> -            vdev->selected_scsi_device.lun = iplb.scsi.lun;
> -            blk_schid.ssid = iplb.scsi.ssid & 0x3;
> -            found = find_dev(&schib, iplb.scsi.devno);
> -            break;
> -        default:
> -            panic("List-directed IPL not supported yet!\n");
> -        }
> -        menu_setup();
> -    } else {
> +    if (!have_iplb) {
>           for (ssid = 0; ssid < 0x3; ssid++) {
>               blk_schid.ssid = ssid;
> -            found = find_dev(&schib, -1);
> +            found = find_subch(-1);
>               if (found) {
> -                break;
> +                return;
>               }
>           }
> +        panic("Could not find a suitable boot device (none specified)\n");
>       }
>   
> -    IPL_assert(found, "No virtio device found");
> +    switch (iplb.pbt) {
> +    case S390_IPL_TYPE_CCW:
> +        debug_print_int("device no. ", iplb.ccw.devno);
> +        blk_schid.ssid = iplb.ccw.ssid & 0x3;
> +        debug_print_int("ssid ", blk_schid.ssid);
> +        found = find_subch(iplb.ccw.devno);
> +        break;
> +    case S390_IPL_TYPE_QEMU_SCSI:
> +        vdev->scsi_device_selected = true;
> +        vdev->selected_scsi_device.channel = iplb.scsi.channel;
> +        vdev->selected_scsi_device.target = iplb.scsi.target;
> +        vdev->selected_scsi_device.lun = iplb.scsi.lun;
> +        blk_schid.ssid = iplb.scsi.ssid & 0x3;
> +        found = find_subch(iplb.scsi.devno);
> +        break;
> +    default:
> +        panic("List-directed IPL not supported yet!\n");
> +    }
> +
> +    if (!found) {
> +        IPL_assert(found, "Boot device not found\n");
> +    }
> +}
> +
> +static void virtio_setup(void)
> +{
> +    VDev *vdev = virtio_get_device();
> +    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
> +
> +    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
> +
> +    if (have_iplb) {
> +        menu_setup();
> +    }
>   
>       if (virtio_get_device_type() == VIRTIO_ID_NET) {
>           sclp_print("Network boot device detected\n");
>           vdev->netboot_start_addr = qipl.netboot_start_addr;
>       } else {
>           virtio_blk_setup_device(blk_schid);
> -
>           IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected");
>       }
>   }
> @@ -192,8 +200,9 @@ int main(void)
>       sclp_setup();
>       css_setup();
>       boot_setup();
> -    virtio_setup();
> +    find_boot_device();
>   
> +    virtio_setup();
>       zipl_load(); /* no return */
>   
>       panic("Failed to load OS from hard disk\n");
> diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
> index 58a48f3..9daf2cb 100644
> --- a/tests/boot-serial-test.c
> +++ b/tests/boot-serial-test.c
> @@ -112,7 +112,7 @@ static testdef_t tests[] = {
>       { "sparc", "SS-4", "", "MB86904" },
>       { "sparc", "SS-600MP", "", "TMS390Z55" },
>       { "sparc64", "sun4u", "", "UltraSPARC" },
> -    { "s390x", "s390-ccw-virtio", "", "virtio device" },
> +    { "s390x", "s390-ccw-virtio", "", "device" },
>       { "m68k", "mcf5208evb", "", "TT", sizeof(kernel_mcf5208), kernel_mcf5208 },
>       { "microblaze", "petalogix-s3adsp1800", "", "TT",
>         sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
> 


Reviewed-by: Farhan Ali <alifm@linux.ibm.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 06/15] s390-bios: Clean up cio.h
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 06/15] s390-bios: Clean up cio.h Jason J. Herne
@ 2019-01-31 14:23   ` Farhan Ali
  2019-02-04 10:48   ` Cornelia Huck
  1 sibling, 0 replies; 83+ messages in thread
From: Farhan Ali @ 2019-01-31 14:23 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger



On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> Add proper typedefs to all structs and modify all bit fields to use consistent
> formatting.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Reviewed-by: Collin Walling <walling@linux.ibm.com>
> ---
>   pc-bios/s390-ccw/cio.h      | 86 ++++++++++++++++++++++-----------------------
>   pc-bios/s390-ccw/s390-ccw.h |  8 -----
>   2 files changed, 43 insertions(+), 51 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
> index 1a0795f..a48eee5 100644
> --- a/pc-bios/s390-ccw/cio.h
> +++ b/pc-bios/s390-ccw/cio.h
> @@ -53,12 +53,12 @@ struct schib_config {
>       __u64 mba;
>       __u32 intparm;
>       __u16 mbi;
> -    __u32 isc:3;
> -    __u32 ena:1;
> -    __u32 mme:2;
> -    __u32 mp:1;
> -    __u32 csense:1;
> -    __u32 mbfc:1;
> +    __u32 isc    : 3;
> +    __u32 ena    : 1;
> +    __u32 mme    : 2;
> +    __u32 mp     : 1;
> +    __u32 csense : 1;
> +    __u32 mbfc   : 1;
>   } __attribute__ ((packed));
>   
>   struct scsw {
> @@ -77,41 +77,41 @@ struct scsw {
>   /*
>    * subchannel information block
>    */
> -struct schib {
> +typedef struct schib {
>       struct pmcw pmcw;     /* path management control word */
>       struct scsw scsw;     /* subchannel status word */
>       __u64 mba;            /* measurement block address */
>       __u8 mda[4];          /* model dependent area */
> -} __attribute__ ((packed,aligned(4)));
> +} __attribute__ ((packed, aligned(4))) Schib;
>   
> -struct subchannel_id {
> +typedef struct subchannel_id {
>           __u32 cssid  : 8;
>           __u32        : 4;
>           __u32 m      : 1;
>           __u32 ssid   : 2;
>           __u32 one    : 1;
>           __u32 sch_no : 16;
> -} __attribute__ ((packed, aligned(4)));
> +} __attribute__ ((packed, aligned(4))) SubChannelId;
>   
>   struct chsc_header {
>       __u16 length;
>       __u16 code;
>   } __attribute__((packed));
>   
> -struct chsc_area_sda {
> +typedef struct chsc_area_sda {
>       struct chsc_header request;
> -    __u8 reserved1:4;
> -    __u8 format:4;
> +    __u8 reserved1  : 4;
> +    __u8 format     : 4;
>       __u8 reserved2;
>       __u16 operation_code;
>       __u32 reserved3;
>       __u32 reserved4;
>       __u32 operation_data_area[252];
>       struct chsc_header response;
> -    __u32 reserved5:4;
> -    __u32 format2:4;
> -    __u32 reserved6:24;
> -} __attribute__((packed));
> +    __u32 reserved5 : 4;
> +    __u32 format2   : 4;
> +    __u32 reserved6 : 24;
> +} __attribute__((packed)) ChscAreaSda;
>   
>   /*
>    * TPI info structure
> @@ -128,12 +128,12 @@ struct tpi_info {
>   } __attribute__ ((packed, aligned(4)));
>   
>   /* channel command word (type 1) */
> -struct ccw1 {
> +typedef struct ccw1 {
>       __u8 cmd_code;
>       __u8 flags;
>       __u16 count;
>       __u32 cda;
> -} __attribute__ ((packed, aligned(8)));
> +} __attribute__ ((packed, aligned(8))) Ccw1;
>   
>   #define CCW_FLAG_DC              0x80
>   #define CCW_FLAG_CC              0x40
> @@ -162,27 +162,27 @@ struct ccw1 {
>   /*
>    * Command-mode operation request block
>    */
> -struct cmd_orb {
> +typedef struct cmd_orb {
>       __u32 intparm;    /* interruption parameter */
> -    __u32 key:4;      /* flags, like key, suspend control, etc. */
> -    __u32 spnd:1;     /* suspend control */
> -    __u32 res1:1;     /* reserved */
> -    __u32 mod:1;      /* modification control */
> -    __u32 sync:1;     /* synchronize control */
> -    __u32 fmt:1;      /* format control */
> -    __u32 pfch:1;     /* prefetch control */
> -    __u32 isic:1;     /* initial-status-interruption control */
> -    __u32 alcc:1;     /* address-limit-checking control */
> -    __u32 ssic:1;     /* suppress-suspended-interr. control */
> -    __u32 res2:1;     /* reserved */
> -    __u32 c64:1;      /* IDAW/QDIO 64 bit control  */
> -    __u32 i2k:1;      /* IDAW 2/4kB block size control */
> -    __u32 lpm:8;      /* logical path mask */
> -    __u32 ils:1;      /* incorrect length */
> -    __u32 zero:6;     /* reserved zeros */
> -    __u32 orbx:1;     /* ORB extension control */
> -    __u32 cpa;    /* channel program address */
> -}  __attribute__ ((packed, aligned(4)));
> +    __u32 key  : 4;   /* flags, like key, suspend control, etc. */
> +    __u32 spnd : 1;   /* suspend control */
> +    __u32 res1 : 1;   /* reserved */
> +    __u32 mod  : 1;   /* modification control */
> +    __u32 sync : 1;   /* synchronize control */
> +    __u32 fmt  : 1;   /* format control */
> +    __u32 pfch : 1;   /* prefetch control */
> +    __u32 isic : 1;   /* initial-status-interruption control */
> +    __u32 alcc : 1;   /* address-limit-checking control */
> +    __u32 ssic : 1;   /* suppress-suspended-interr. control */
> +    __u32 res2 : 1;   /* reserved */
> +    __u32 c64  : 1;   /* IDAW/QDIO 64 bit control  */
> +    __u32 i2k  : 1;   /* IDAW 2/4kB block size control */
> +    __u32 lpm  : 8;   /* logical path mask */
> +    __u32 ils  : 1;   /* incorrect length */
> +    __u32 zero : 6;   /* reserved zeros */
> +    __u32 orbx : 1;   /* ORB extension control */
> +    __u32 cpa;        /* channel program address */
> +}  __attribute__ ((packed, aligned(4))) CmdOrb;
>   
>   struct ciw {
>       __u8 type;
> @@ -193,7 +193,7 @@ struct ciw {
>   /*
>    * sense-id response buffer layout
>    */
> -struct senseid {
> +typedef struct senseid {
>       /* common part */
>       __u8  reserved;   /* always 0x'FF' */
>       __u16 cu_type;    /* control unit type */
> @@ -203,15 +203,15 @@ struct senseid {
>       __u8  unused;     /* padding byte */
>       /* extended part */
>       struct ciw ciw[62];
> -}  __attribute__ ((packed, aligned(4)));
> +}  __attribute__ ((packed, aligned(4))) SenseId;
>   
>   /* interruption response block */
> -struct irb {
> +typedef struct irb {
>       struct scsw scsw;
>       __u32 esw[5];
>       __u32 ecw[8];
>       __u32 emw[8];
> -}  __attribute__ ((packed, aligned(4)));
> +}  __attribute__ ((packed, aligned(4))) Irb;
>   
>   /*
>    * Some S390 specific IO instructions as inline
> diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
> index 9828aa2..241c6d0 100644
> --- a/pc-bios/s390-ccw/s390-ccw.h
> +++ b/pc-bios/s390-ccw/s390-ccw.h
> @@ -49,14 +49,6 @@ typedef unsigned long long __u64;
>   #include "cio.h"
>   #include "iplb.h"
>   
> -typedef struct irb Irb;
> -typedef struct ccw1 Ccw1;
> -typedef struct cmd_orb CmdOrb;
> -typedef struct schib Schib;
> -typedef struct chsc_area_sda ChscAreaSda;
> -typedef struct senseid SenseId;
> -typedef struct subchannel_id SubChannelId;
> -
>   /* start.s */
>   void disabled_wait(void);
>   void consume_sclp_int(void);
> 


Reviewed-by: Farhan Ali <alifm@linux.ibm.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio Jason J. Herne
@ 2019-01-31 14:38   ` Farhan Ali
  2019-01-31 14:45     ` Jason J. Herne
  2019-02-04 10:57   ` Cornelia Huck
  1 sibling, 1 reply; 83+ messages in thread
From: Farhan Ali @ 2019-01-31 14:38 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger



On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> Create a separate library for channel i/o related code. This decouples
> channel i/o operations from virtio and allows us to make use of them for
> the real dasd boot path.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>   pc-bios/s390-ccw/Makefile        |  2 +-
>   pc-bios/s390-ccw/cio.c           | 41 ++++++++++++++++++++++++++++++++++++++++
>   pc-bios/s390-ccw/cio.h           |  3 +++
>   pc-bios/s390-ccw/main.c          |  1 +
>   pc-bios/s390-ccw/netboot.mak     |  2 +-
>   pc-bios/s390-ccw/netmain.c       |  1 +
>   pc-bios/s390-ccw/s390-ccw.h      |  1 -
>   pc-bios/s390-ccw/virtio-blkdev.c |  1 +
>   pc-bios/s390-ccw/virtio.c        | 27 ++------------------------
>   9 files changed, 51 insertions(+), 28 deletions(-)
>   create mode 100644 pc-bios/s390-ccw/cio.c
> 
> diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
> index 1eb316b..12ad9c1 100644
> --- a/pc-bios/s390-ccw/Makefile
> +++ b/pc-bios/s390-ccw/Makefile
> @@ -10,7 +10,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
>   .PHONY : all clean build-all
>   
>   OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
> -	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o
> +	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o
>   
>   QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
>   QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
> diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
> new file mode 100644
> index 0000000..095f79b
> --- /dev/null
> +++ b/pc-bios/s390-ccw/cio.c
> @@ -0,0 +1,41 @@
> +/*
> + * S390 Channel I/O
> + *
> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
> + * your option) any later version. See the COPYING file in the top-level
> + * directory.
> + */
> +

shouldn't the year be 2019 now? :)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio
  2019-01-31 14:38   ` Farhan Ali
@ 2019-01-31 14:45     ` Jason J. Herne
  0 siblings, 0 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-01-31 14:45 UTC (permalink / raw)
  To: Farhan Ali, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger

On 1/31/19 9:38 AM, Farhan Ali wrote:
> 
> 
> On 01/29/2019 08:29 AM, Jason J. Herne wrote:
>> Create a separate library for channel i/o related code. This decouples
>> channel i/o operations from virtio and allows us to make use of them for
>> the real dasd boot path.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> ---
>>   pc-bios/s390-ccw/Makefile        |  2 +-
>>   pc-bios/s390-ccw/cio.c           | 41 ++++++++++++++++++++++++++++++++++++++++
>>   pc-bios/s390-ccw/cio.h           |  3 +++
>>   pc-bios/s390-ccw/main.c          |  1 +
>>   pc-bios/s390-ccw/netboot.mak     |  2 +-
>>   pc-bios/s390-ccw/netmain.c       |  1 +
>>   pc-bios/s390-ccw/s390-ccw.h      |  1 -
>>   pc-bios/s390-ccw/virtio-blkdev.c |  1 +
>>   pc-bios/s390-ccw/virtio.c        | 27 ++------------------------
>>   9 files changed, 51 insertions(+), 28 deletions(-)
>>   create mode 100644 pc-bios/s390-ccw/cio.c
>>
>> diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
>> index 1eb316b..12ad9c1 100644
>> --- a/pc-bios/s390-ccw/Makefile
>> +++ b/pc-bios/s390-ccw/Makefile
>> @@ -10,7 +10,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
>>   .PHONY : all clean build-all
>>   OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
>> -      virtio.o virtio-scsi.o virtio-blkdev.o libc.o
>> +      virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o
>>   QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
>>   QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
>> diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
>> new file mode 100644
>> index 0000000..095f79b
>> --- /dev/null
>> +++ b/pc-bios/s390-ccw/cio.c
>> @@ -0,0 +1,41 @@
>> +/*
>> + * S390 Channel I/O
>> + *
>> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
>> + * your option) any later version. See the COPYING file in the top-level
>> + * directory.
>> + */
>> +
> 
> shouldn't the year be 2019 now? :)

I suppose. I did write it in 2018 :-P I'll update it.

-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs Jason J. Herne
@ 2019-01-31 17:31   ` Farhan Ali
  2019-02-04 11:13     ` Cornelia Huck
  2019-02-04 11:24   ` Cornelia Huck
  1 sibling, 1 reply; 83+ messages in thread
From: Farhan Ali @ 2019-01-31 17:31 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger



On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> Add struct for format-0 ccws. Support executing format-0 channel
> programs and waiting for their completion before continuing execution.
> This will be used for real dasd ipl.
> 
> Add cu_type() to channel io library. This will be used to query control
> unit type which is used to determine if we are booting a virtio device or a
> real dasd device.
> 
> Signed-off-by: Jason J. Herne<jjherne@linux.ibm.com>
> ---
>   pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
>   pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
>   pc-bios/s390-ccw/s390-ccw.h |   1 +
>   pc-bios/s390-ccw/start.S    |  33 +++++++++++-
>   4 files changed, 270 insertions(+), 5 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
> index 095f79b..63581c6 100644
> --- a/pc-bios/s390-ccw/cio.c
> +++ b/pc-bios/s390-ccw/cio.c
> @@ -10,6 +10,7 @@
>   
>   #include "libc.h"
>   #include "s390-ccw.h"
> +#include "s390-arch.h"
>   #include "cio.h"
>   
>   static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
> @@ -39,3 +40,116 @@ void enable_subchannel(SubChannelId schid)
>       schib.pmcw.ena = 1;
>       msch(schid, &schib);
>   }
> +
> +uint16_t cu_type(SubChannelId schid)
> +{
> +    Ccw1 sense_id_ccw;
> +    SenseId sense_data;
> +
> +    sense_id_ccw.cmd_code = CCW_CMD_SENSE_ID;
> +    sense_id_ccw.cda = ptr2u32(&sense_data);
> +    sense_id_ccw.count = sizeof(sense_data);
> +    sense_id_ccw.flags |= CCW_FLAG_SLI;
> +
> +    if (do_cio(schid, ptr2u32(&sense_id_ccw), CCW_FMT1)) {
> +        panic("Failed to run SenseID CCw\n");
> +    }
> +
> +    return sense_data.cu_type;
> +}
> +
> +void basic_sense(SubChannelId schid, void *sense_data, uint16_t data_size)
> +{
> +    Ccw1 senseCcw;
> +
> +    senseCcw.cmd_code = CCW_CMD_BASIC_SENSE;
> +    senseCcw.cda = ptr2u32(sense_data);
> +    senseCcw.count = data_size;
> +
> +    if (do_cio(schid, ptr2u32(&senseCcw), CCW_FMT1)) {
> +        panic("Failed to run Basic Sense CCW\n");
> +    }
> +}
> +
> +static bool irb_error(Irb *irb)
> +{
> +    if (irb->scsw.cstat) {
> +        return true;
> +    }
> +    return irb->scsw.dstat != (SCSW_DSTAT_DEVEND | SCSW_DSTAT_CHEND);
> +}
> +
> +/*
> + * Executes a channel program at a given subchannel. The request to run the
> + * channel program is sent to the subchannel, we then wait for the interrupt
> + * signaling completion of the I/O operation(s) performed by the channel
> + * program. Lastly we verify that the i/o operation completed without error and
> + * that the interrupt we received was for the subchannel used to run the
> + * channel program.
> + *
> + * Note: This function assumes it is running in an environment where no other
> + * cpus are generating or receiving I/O interrupts. So either run it in a
> + * single-cpu environment or make sure all other cpus are not doing I/O and
> + * have I/O interrupts masked off.
> + */
> +int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
> +{
> +    CmdOrb orb = {};
> +    Irb irb = {};
> +    sense_data_eckd_dasd sd;
> +    int rc, retries = 0;
> +
> +    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
> +
> +    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
> +    if (fmt == 0) {
> +        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
> +    }
> +
> +    orb.fmt = fmt ;
> +    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
> +    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
> +    orb.lpm = 0xFF; /* All paths allowed */
> +    orb.cpa = ccw_addr;
> +
> +    while (true) {
> +        rc = ssch(schid, &orb);
> +        if (rc == 1) {
> +            /* Status pending, not sure why. Let's eat the status and retry. */
> +            tsch(schid, &irb);
> +            retries++;
> +            continue;
> +        }
> +        if (rc) {
> +            print_int("ssch failed with rc=", rc);
> +            break;
> +        }
> +
> +        consume_io_int();
> +
> +        /* collect status */
> +        rc = tsch(schid, &irb);
> +        if (rc) {
> +            print_int("tsch failed with rc=", rc);
> +            break;
> +        }
> +
> +        if (!irb_error(&irb)) {
> +            break;
> +        }
> +
> +        /*
> +         * Unexpected unit check, or interface-control-check. Use sense to
> +         * clear unit check then retry.
> +         */
> +        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
> +            basic_sense(schid, &sd, sizeof(sd));

We are using basic sense to clear any unit check or ifcc, but is it 
possible for the basic sense to cause another unit check?

The chapter on Basic Sense in the Common I/O Device Commands 
(http://publibz.boulder.ibm.com/support/libraryserver/FRAMESET/dz9ar501/2.1?SHELF=&DT=19920409154647&CASE=) 
  says this:

""
The basic sense command initiates a sense operation  at  all  devices 
and cannot  cause  the  command-reject,  intervention-required, 
data-check, or overrun bit to be set to one.  If the control unit 
detects  an  equipment malfunction  or  invalid  checking-block  code 
(CBC) on the sense-command code, the equipment-check or bus-out-check 
bit is set  to  one,  and  unit check is indicated in the device-status 
byte.
""

If my understanding is correct, if there is an equipment malfunction 
then the control unit can return a unit check even for a basic sense. 
This can lead to infinite recursion in the bios.



> +            retries++;
> +            continue;
> +        }
> +
> +        break;
> +    }
> +
> +    return rc;
> +}

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support
  2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
                   ` (15 preceding siblings ...)
  2019-01-29 16:40 ` [Qemu-devel] [qemu-s390x] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
@ 2019-01-31 18:10 ` no-reply
  16 siblings, 0 replies; 83+ messages in thread
From: no-reply @ 2019-01-31 18:10 UTC (permalink / raw)
  To: jjherne; +Cc: fam, qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

Patchew URL: https://patchew.org/QEMU/1548768562-20007-1-git-send-email-jjherne@linux.ibm.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support
Type: series
Message-id: 1548768562-20007-1-git-send-email-jjherne@linux.ibm.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
2bd738843d s390-bios: Support booting from real dasd device
a17332c8bf s390-bios: Add channel command codes/structs needed for dasd-ipl
1a0fc7faff s390-bios: Use control unit type to determine boot method
8f5f2c10de s390-bios: Refactor virtio to run channel programs via cio
9ede1038cd s390-bios: cio error handling
ab1f7e87aa s390-bios: Support for running format-0/1 channel programs
1b481ab578 s390-bios: ptr2u32 and u32toptr
0ff2ea42d5 s390-bios: Map low core memory
481d2eb86b s390-bios: Decouple channel i/o logic from virtio
b8bf17c714 s390-bios: Clean up cio.h
1b326192a9 s390-bios: Factor finding boot device out of virtio code path
66a8e27697 s390-bios: Extend find_dev() for non-virtio devices
bb7c632ef8 s390-bios: decouple common boot logic from virtio
c75b9d09eb s390-bios: decouple cio setup from virtio
7edc7ef234 s390 vfio-ccw: Add bootindex property and IPLB data

=== OUTPUT BEGIN ===
1/15 Checking commit 7edc7ef234c8 (s390 vfio-ccw: Add bootindex property and IPLB data)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#130: 
new file mode 100644

total: 0 errors, 1 warnings, 129 lines checked

Patch 1/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/15 Checking commit c75b9d09eb61 (s390-bios: decouple cio setup from virtio)
3/15 Checking commit bb7c632ef8b4 (s390-bios: decouple common boot logic from virtio)
ERROR: externs should be avoided in .c files
#30: FILE: pc-bios/s390-ccw/main.c:19:
+IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));

total: 1 errors, 0 warnings, 65 lines checked

Patch 3/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

4/15 Checking commit 66a8e27697df (s390-bios: Extend find_dev() for non-virtio devices)
5/15 Checking commit 1b326192a91e (s390-bios: Factor finding boot device out of virtio code path)
6/15 Checking commit b8bf17c71419 (s390-bios: Clean up cio.h)
ERROR: spaces prohibited around that ':' (ctx:WxW)
#29: FILE: pc-bios/s390-ccw/cio.h:56:
+    __u32 isc    : 3;
                  ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#30: FILE: pc-bios/s390-ccw/cio.h:57:
+    __u32 ena    : 1;
                  ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#31: FILE: pc-bios/s390-ccw/cio.h:58:
+    __u32 mme    : 2;
                  ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#32: FILE: pc-bios/s390-ccw/cio.h:59:
+    __u32 mp     : 1;
                  ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#33: FILE: pc-bios/s390-ccw/cio.h:60:
+    __u32 csense : 1;
                  ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#34: FILE: pc-bios/s390-ccw/cio.h:61:
+    __u32 mbfc   : 1;
                  ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#84: FILE: pc-bios/s390-ccw/cio.h:111:
+    __u32 reserved5 : 4;
                     ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#85: FILE: pc-bios/s390-ccw/cio.h:112:
+    __u32 format2   : 4;
                     ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#86: FILE: pc-bios/s390-ccw/cio.h:113:
+    __u32 reserved6 : 24;
                     ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#132: FILE: pc-bios/s390-ccw/cio.h:167:
+    __u32 key  : 4;   /* flags, like key, suspend control, etc. */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#133: FILE: pc-bios/s390-ccw/cio.h:168:
+    __u32 spnd : 1;   /* suspend control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#134: FILE: pc-bios/s390-ccw/cio.h:169:
+    __u32 res1 : 1;   /* reserved */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#135: FILE: pc-bios/s390-ccw/cio.h:170:
+    __u32 mod  : 1;   /* modification control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#136: FILE: pc-bios/s390-ccw/cio.h:171:
+    __u32 sync : 1;   /* synchronize control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#137: FILE: pc-bios/s390-ccw/cio.h:172:
+    __u32 fmt  : 1;   /* format control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#138: FILE: pc-bios/s390-ccw/cio.h:173:
+    __u32 pfch : 1;   /* prefetch control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#139: FILE: pc-bios/s390-ccw/cio.h:174:
+    __u32 isic : 1;   /* initial-status-interruption control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#140: FILE: pc-bios/s390-ccw/cio.h:175:
+    __u32 alcc : 1;   /* address-limit-checking control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#141: FILE: pc-bios/s390-ccw/cio.h:176:
+    __u32 ssic : 1;   /* suppress-suspended-interr. control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#142: FILE: pc-bios/s390-ccw/cio.h:177:
+    __u32 res2 : 1;   /* reserved */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#143: FILE: pc-bios/s390-ccw/cio.h:178:
+    __u32 c64  : 1;   /* IDAW/QDIO 64 bit control  */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#144: FILE: pc-bios/s390-ccw/cio.h:179:
+    __u32 i2k  : 1;   /* IDAW 2/4kB block size control */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#145: FILE: pc-bios/s390-ccw/cio.h:180:
+    __u32 lpm  : 8;   /* logical path mask */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#146: FILE: pc-bios/s390-ccw/cio.h:181:
+    __u32 ils  : 1;   /* incorrect length */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#147: FILE: pc-bios/s390-ccw/cio.h:182:
+    __u32 zero : 6;   /* reserved zeros */
                ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#148: FILE: pc-bios/s390-ccw/cio.h:183:
+    __u32 orbx : 1;   /* ORB extension control */
                ^

total: 26 errors, 0 warnings, 171 lines checked

Patch 6/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

7/15 Checking commit 481d2eb86b1a (s390-bios: Decouple channel i/o logic from virtio)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#28: 
new file mode 100644

total: 0 errors, 1 warnings, 127 lines checked

Patch 7/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
8/15 Checking commit 0ff2ea42d5e9 (s390-bios: Map low core memory)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#35: 
new file mode 100644

total: 0 errors, 1 warnings, 114 lines checked

Patch 8/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/15 Checking commit 1b481ab57836 (s390-bios: ptr2u32 and u32toptr)
10/15 Checking commit ab1f7e87aa13 (s390-bios: Support for running format-0/1 channel programs)
ERROR: spaces prohibited around that ':' (ctx:WxW)
#208: FILE: pc-bios/s390-ccw/cio.h:170:
+    __u32 cda        : 24;
                      ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#209: FILE: pc-bios/s390-ccw/cio.h:171:
+    __u32 chainData  : 1;
                      ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#210: FILE: pc-bios/s390-ccw/cio.h:172:
+    __u32 chain      : 1;
                      ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#211: FILE: pc-bios/s390-ccw/cio.h:173:
+    __u32 sli        : 1;
                      ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#212: FILE: pc-bios/s390-ccw/cio.h:174:
+    __u32 skip       : 1;
                      ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#213: FILE: pc-bios/s390-ccw/cio.h:175:
+    __u32 pci        : 1;
                      ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#214: FILE: pc-bios/s390-ccw/cio.h:176:
+    __u32 ida        : 1;
                      ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#215: FILE: pc-bios/s390-ccw/cio.h:177:
+    __u32 suspend    : 1;
                      ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#216: FILE: pc-bios/s390-ccw/cio.h:178:
+    __u32 mida       : 1;
                      ^

total: 9 errors, 0 warnings, 347 lines checked

Patch 10/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

11/15 Checking commit 9ede1038cd66 (s390-bios: cio error handling)
12/15 Checking commit 8f5f2c10dea5 (s390-bios: Refactor virtio to run channel programs via cio)
WARNING: line over 80 characters
#95: FILE: pc-bios/s390-ccw/virtio.c:297:
+            run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config), false) == 0,

WARNING: line over 80 characters
#108: FILE: pc-bios/s390-ccw/virtio.c:307:
+        run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false) == 0,

total: 0 errors, 2 warnings, 100 lines checked

Patch 12/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
13/15 Checking commit 1a0fc7faff50 (s390-bios: Use control unit type to determine boot method)
14/15 Checking commit a17332c8bfa1 (s390-bios: Add channel command codes/structs needed for dasd-ipl)
15/15 Checking commit 2bd738843dfe (s390-bios: Support booting from real dasd device)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#13: 
new file mode 100644

total: 0 errors, 1 warnings, 438 lines checked

Patch 15/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/1548768562-20007-1-git-send-email-jjherne@linux.ibm.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
  2019-01-30 16:56   ` Cornelia Huck
  2019-01-30 22:21   ` Farhan Ali
@ 2019-01-31 18:20   ` Cornelia Huck
  2019-02-04 10:26   ` Cornelia Huck
  2019-02-06 11:30   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  4 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-01-31 18:20 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:08 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Add bootindex property and iplb data for vfio-ccw devices. This allows us to
> forward boot information into the bios for vfio-ccw devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> ---
>  hw/s390x/ipl.c              | 14 ++++++++++++++
>  hw/s390x/s390-ccw.c         |  9 +++++++++
>  hw/vfio/ccw.c               | 13 +------------
>  include/hw/s390x/s390-ccw.h |  1 +
>  include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++

This split-out file should probably go into the vfio-ccw section in
MAINTAINERS as well.

>  5 files changed, 63 insertions(+), 12 deletions(-)
>  create mode 100644 include/hw/s390x/vfio-ccw.h

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device Jason J. Herne
@ 2019-01-31 18:23   ` Cornelia Huck
  2019-02-04 12:02   ` Cornelia Huck
  2019-02-21  2:52   ` [Qemu-devel] [qemu-s390x] " Eric Farman
  2 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-01-31 18:23 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:22 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Allows guest to boot from a vfio configured real dasd device.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  docs/devel/s390-dasd-ipl.txt | 132 +++++++++++++++++++++++
>  pc-bios/s390-ccw/Makefile    |   2 +-
>  pc-bios/s390-ccw/dasd-ipl.c  | 249 +++++++++++++++++++++++++++++++++++++++++++
>  pc-bios/s390-ccw/dasd-ipl.h  |  16 +++
>  pc-bios/s390-ccw/main.c      |   4 +
>  pc-bios/s390-ccw/s390-arch.h |  13 +++
>  6 files changed, 415 insertions(+), 1 deletion(-)
>  create mode 100644 docs/devel/s390-dasd-ipl.txt

This file should probably be added to the s390-ccw boot section in
MAINTAINERS (the other new files are already covered.)

>  create mode 100644 pc-bios/s390-ccw/dasd-ipl.c
>  create mode 100644 pc-bios/s390-ccw/dasd-ipl.h

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
                     ` (2 preceding siblings ...)
  2019-01-31 18:20   ` Cornelia Huck
@ 2019-02-04 10:26   ` Cornelia Huck
  2019-02-13 13:41     ` Jason J. Herne
  2019-02-06 11:30   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  4 siblings, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 10:26 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:08 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Add bootindex property and iplb data for vfio-ccw devices. This allows us to
> forward boot information into the bios for vfio-ccw devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> ---
>  hw/s390x/ipl.c              | 14 ++++++++++++++
>  hw/s390x/s390-ccw.c         |  9 +++++++++
>  hw/vfio/ccw.c               | 13 +------------
>  include/hw/s390x/s390-ccw.h |  1 +
>  include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 63 insertions(+), 12 deletions(-)
>  create mode 100644 include/hw/s390x/vfio-ccw.h
> 
> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
> index 21f64ad..a993f65 100644
> --- a/hw/s390x/ipl.c
> +++ b/hw/s390x/ipl.c
> @@ -19,6 +19,7 @@
>  #include "hw/loader.h"
>  #include "hw/boards.h"
>  #include "hw/s390x/virtio-ccw.h"
> +#include "hw/s390x/vfio-ccw.h"
>  #include "hw/s390x/css.h"
>  #include "hw/s390x/ebcdic.h"
>  #include "ipl.h"
> @@ -311,8 +312,12 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
>          VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
>              object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
>                                  TYPE_VIRTIO_CCW_DEVICE);
> +        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>          if (virtio_ccw_dev) {
>              ccw_dev = CCW_DEVICE(virtio_ccw_dev);
> +        } else if (vfio_ccw_dev) {
> +            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
>          } else {
>              SCSIDevice *sd = (SCSIDevice *)
>                  object_dynamic_cast(OBJECT(dev_st),
> @@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>      if (ccw_dev) {
>          SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
>                                                              TYPE_SCSI_DEVICE);
> +        VFIOCCWDevice *vc = (VFIOCCWDevice *)
> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>  
>          if (sd) {
>              ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
> @@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>              ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
>              ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
>              ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
> +        } else if (vc) {
> +            CcwDevice *ccw_dev = CCW_DEVICE(vc);
> +
> +            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
> +            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
> +            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
> +            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
>          } else {
>              VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
>                                                                TYPE_VIRTIO_NET);

Hm, I think that this find-out-the-boot-type-and-set-up-the-right-thing
mechanism is getting a bit unwieldy. Basically, we

- call s390_get_ccw_device() to find out the device type via a bunch of
  casts and return a pointer to a CcwDevice if it's a supported type
- do a bunch of casts here *again* to find out what we have and fill
  out the iplb, while we really only need to do grab a non-CcwDevice
  for the scsi case

Should maybe s390_get_ccw_device() give us an ipl type in addition to
the pointer to the CcwDevice, so we can use a switch/case statement to
fill out the iplb here?

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio Jason J. Herne
  2019-01-30 22:23   ` Farhan Ali
@ 2019-02-04 10:28   ` Cornelia Huck
  2019-02-05  9:55   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  2 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 10:28 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:09 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Move channel i/o setup code out to a separate function. This decouples cio
> setup from the virtio code path and allows us to make use of it for booting
> dasd devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> Reviewed-by: Collin Walling <walling@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/main.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)

Reviewed-by: Cornelia Huck <cohuck@redhat.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 03/15] s390-bios: decouple common boot logic from virtio
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 03/15] s390-bios: decouple common boot logic " Jason J. Herne
  2019-01-30 22:27   ` Farhan Ali
@ 2019-02-04 10:31   ` Cornelia Huck
  1 sibling, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 10:31 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:10 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Create a boot_setup function to handle getting boot information from
> the machine/hypervisor. This decouples common boot logic from the
> virtio code path and allows us to make use of it for the real dasd boot
> scenario.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> Reviewed-by: Collin Walling <walling@linux.ibm.com
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> ---
>  pc-bios/s390-ccw/main.c | 28 ++++++++++++++++++++--------
>  1 file changed, 20 insertions(+), 8 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index e82fe2c..67df421 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -14,16 +14,17 @@
>  
>  char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
>  static SubChannelId blk_schid = { .one = 1 };
> -IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
>  static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
>  QemuIplParameters qipl;
> +IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
> +static bool have_iplb;
>  
>  #define LOADPARM_PROMPT "PROMPT  "
>  #define LOADPARM_EMPTY  "        "
>  #define BOOT_MENU_FLAG_MASK (QIPL_FLAG_BM_OPTS_CMD | QIPL_FLAG_BM_OPTS_ZIPL)
>  
>  /*
> - * Priniciples of Operations (SA22-7832-09) chapter 17 requires that
> + * Principles of Operations (SA22-7832-09) chapter 17 requires that
>   * a subsystem-identification is at 184-187 and bytes 188-191 are zero
>   * after list-directed-IPL and ccw-IPL.
>   */

Some unrelated change :) But it really does not make sense to split
this out.

Reviewed-by: Cornelia Huck <cohuck@redhat.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices Jason J. Herne
@ 2019-02-04 10:33   ` Cornelia Huck
  2019-02-11 16:38   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  1 sibling, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 10:33 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:11 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> We need a method for finding the subchannel of a dasd device. Let's
> modify find_dev to handle this since it mostly does what we need. Up to
> this point find_dev has been specific to only virtio devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> ---
>  pc-bios/s390-ccw/main.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)

Reviewed-by: Cornelia Huck <cohuck@redhat.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path Jason J. Herne
  2019-01-31 13:44   ` Farhan Ali
@ 2019-02-04 10:45   ` Cornelia Huck
  2019-02-11 17:57     ` Jason J. Herne
  1 sibling, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 10:45 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:12 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Make a new routine find_boot_device to locate the boot device for all
> cases. not just virtio.

s/cases./cases,/

> 
> In one case no boot device is specified and a suitable boot device can not
> be auto detected. The error message for this case was specific to virtio
> devices. We update this message to remove virtio specific wording.

"The error message for the case where no boot device has been specified
and a suitable boot device cannot be auto detected was specific to
virtio devices. We update..."

> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/main.c  | 87 ++++++++++++++++++++++++++----------------------
>  tests/boot-serial-test.c |  2 +-
>  2 files changed, 49 insertions(+), 40 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index 7e3f65e..2457752 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -55,17 +55,18 @@ unsigned int get_loadparm_index(void)
>   * NOTE: The global variable blk_schid is updated to contain the subchannel
>   * information.
>   */
> -static bool find_dev(Schib *schib, int dev_no)
> +static bool find_subch(int dev_no)

I'm wondering why you drop passing in the schib here? But OTOH, the
usage of global variables or not is a bit confused in the bios anyway...

>  {
> +    Schib schib;
>      int i, r;
>  
>      for (i = 0; i < 0x10000; i++) {
>          blk_schid.sch_no = i;
> -        r = stsch_err(blk_schid, schib);
> +        r = stsch_err(blk_schid, &schib);
>          if ((r == 3) || (r == -EIO)) {
>              break;
>          }
> -        if (!schib->pmcw.dnv) {
> +        if (!schib.pmcw.dnv) {
>              continue;
>          }
>  
> @@ -77,7 +78,7 @@ static bool find_dev(Schib *schib, int dev_no)
>              continue;
>          }
>  
> -        if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
> +        if ((dev_no < 0) || (schib.pmcw.dev == dev_no)) {
>              return true;
>          }
>      }
> @@ -133,56 +134,63 @@ static void boot_setup(void)
>      have_iplb = store_iplb(&iplb);
>  }
>  
> -static void virtio_setup(void)
> +static void find_boot_device(void)
>  {
> -    Schib schib;
> -    int ssid;
> -    bool found = false;
> -    uint16_t dev_no;
>      VDev *vdev = virtio_get_device();
> -    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
> -
> -    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
> +    int ssid;
> +    bool found;
>  
> -    if (have_iplb) {
> -        switch (iplb.pbt) {
> -        case S390_IPL_TYPE_CCW:
> -            dev_no = iplb.ccw.devno;
> -            debug_print_int("device no. ", dev_no);
> -            blk_schid.ssid = iplb.ccw.ssid & 0x3;
> -            debug_print_int("ssid ", blk_schid.ssid);
> -            found = find_dev(&schib, dev_no);
> -            break;
> -        case S390_IPL_TYPE_QEMU_SCSI:
> -            vdev->scsi_device_selected = true;
> -            vdev->selected_scsi_device.channel = iplb.scsi.channel;
> -            vdev->selected_scsi_device.target = iplb.scsi.target;
> -            vdev->selected_scsi_device.lun = iplb.scsi.lun;
> -            blk_schid.ssid = iplb.scsi.ssid & 0x3;
> -            found = find_dev(&schib, iplb.scsi.devno);
> -            break;
> -        default:
> -            panic("List-directed IPL not supported yet!\n");
> -        }
> -        menu_setup();
> -    } else {
> +    if (!have_iplb) {
>          for (ssid = 0; ssid < 0x3; ssid++) {
>              blk_schid.ssid = ssid;
> -            found = find_dev(&schib, -1);
> +            found = find_subch(-1);
>              if (found) {
> -                break;
> +                return;
>              }
>          }
> +        panic("Could not find a suitable boot device (none specified)\n");
>      }
>  
> -    IPL_assert(found, "No virtio device found");
> +    switch (iplb.pbt) {
> +    case S390_IPL_TYPE_CCW:
> +        debug_print_int("device no. ", iplb.ccw.devno);
> +        blk_schid.ssid = iplb.ccw.ssid & 0x3;
> +        debug_print_int("ssid ", blk_schid.ssid);
> +        found = find_subch(iplb.ccw.devno);
> +        break;
> +    case S390_IPL_TYPE_QEMU_SCSI:
> +        vdev->scsi_device_selected = true;
> +        vdev->selected_scsi_device.channel = iplb.scsi.channel;
> +        vdev->selected_scsi_device.target = iplb.scsi.target;
> +        vdev->selected_scsi_device.lun = iplb.scsi.lun;
> +        blk_schid.ssid = iplb.scsi.ssid & 0x3;
> +        found = find_subch(iplb.scsi.devno);
> +        break;
> +    default:
> +        panic("List-directed IPL not supported yet!\n");
> +    }
> +
> +    if (!found) {
> +        IPL_assert(found, "Boot device not found\n");

You can simply call IPL_assert(found, ...) here, as it does the check
already.

> +    }
> +}

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 06/15] s390-bios: Clean up cio.h
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 06/15] s390-bios: Clean up cio.h Jason J. Herne
  2019-01-31 14:23   ` Farhan Ali
@ 2019-02-04 10:48   ` Cornelia Huck
  2019-02-12 12:32     ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  1 sibling, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 10:48 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:13 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Add proper typedefs to all structs and modify all bit fields to use consistent
> formatting.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Reviewed-by: Collin Walling <walling@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/cio.h      | 86 ++++++++++++++++++++++-----------------------
>  pc-bios/s390-ccw/s390-ccw.h |  8 -----
>  2 files changed, 43 insertions(+), 51 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
> index 1a0795f..a48eee5 100644
> --- a/pc-bios/s390-ccw/cio.h
> +++ b/pc-bios/s390-ccw/cio.h
> @@ -53,12 +53,12 @@ struct schib_config {
>      __u64 mba;
>      __u32 intparm;
>      __u16 mbi;
> -    __u32 isc:3;
> -    __u32 ena:1;
> -    __u32 mme:2;
> -    __u32 mp:1;
> -    __u32 csense:1;
> -    __u32 mbfc:1;
> +    __u32 isc    : 3;
> +    __u32 ena    : 1;
> +    __u32 mme    : 2;
> +    __u32 mp     : 1;
> +    __u32 csense : 1;
> +    __u32 mbfc   : 1;
>  } __attribute__ ((packed));

This seems to make checkpatch unhappy... maybe consolidate to the other
formatting instead?

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio Jason J. Herne
  2019-01-31 14:38   ` Farhan Ali
@ 2019-02-04 10:57   ` Cornelia Huck
  2019-02-13 14:40     ` Jason J. Herne
  1 sibling, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 10:57 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:14 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Create a separate library for channel i/o related code. This decouples
> channel i/o operations from virtio and allows us to make use of them for
> the real dasd boot path.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/Makefile        |  2 +-
>  pc-bios/s390-ccw/cio.c           | 41 ++++++++++++++++++++++++++++++++++++++++
>  pc-bios/s390-ccw/cio.h           |  3 +++
>  pc-bios/s390-ccw/main.c          |  1 +
>  pc-bios/s390-ccw/netboot.mak     |  2 +-
>  pc-bios/s390-ccw/netmain.c       |  1 +
>  pc-bios/s390-ccw/s390-ccw.h      |  1 -
>  pc-bios/s390-ccw/virtio-blkdev.c |  1 +
>  pc-bios/s390-ccw/virtio.c        | 27 ++------------------------
>  9 files changed, 51 insertions(+), 28 deletions(-)
>  create mode 100644 pc-bios/s390-ccw/cio.c
> 

> diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
> new file mode 100644
> index 0000000..095f79b
> --- /dev/null
> +++ b/pc-bios/s390-ccw/cio.c
> @@ -0,0 +1,41 @@
> +/*
> + * S390 Channel I/O
> + *
> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
> + * your option) any later version. See the COPYING file in the top-level
> + * directory.
> + */

Not sure that copyright header is correct. You moved some code that
probably should be copyright IBM (although that was never added to the
header in the first place...) Also not sure if Alex has some copyrights
on the code you moved, or if that is only trivial stuff. (Don't want to
be difficult, but we should try to get this right.)

> +
> +#include "libc.h"
> +#include "s390-ccw.h"
> +#include "cio.h"
> +
> +static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
> +
> +int enable_mss_facility(void)
> +{
> +    int ret;
> +    ChscAreaSda *sda_area = (ChscAreaSda *) chsc_page;
> +
> +    memset(sda_area, 0, PAGE_SIZE);
> +    sda_area->request.length = 0x0400;
> +    sda_area->request.code = 0x0031;
> +    sda_area->operation_code = 0x2;
> +
> +    ret = chsc(sda_area);
> +    if ((ret == 0) && (sda_area->response.code == 0x0001)) {
> +        return 0;
> +    }
> +    return -EIO;
> +}
> +
> +void enable_subchannel(SubChannelId schid)
> +{
> +    Schib schib;
> +
> +    stsch_err(schid, &schib);
> +    schib.pmcw.ena = 1;
> +    msch(schid, &schib);
> +}

(...)

> diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
> index 11c5626..d2e7fcd 100644
> --- a/pc-bios/s390-ccw/virtio-blkdev.c
> +++ b/pc-bios/s390-ccw/virtio-blkdev.c
> @@ -10,6 +10,7 @@
>  
>  #include "libc.h"
>  #include "s390-ccw.h"
> +#include "cio.h"

Not sure why you need to add this here?

>  #include "virtio.h"
>  #include "virtio-scsi.h"
>  

Otherwise, looks good.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 09/15] s390-bios: ptr2u32 and u32toptr
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 09/15] s390-bios: ptr2u32 and u32toptr Jason J. Herne
@ 2019-02-04 11:03   ` Cornelia Huck
  2019-02-12 12:50   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
  1 sibling, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 11:03 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:16 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Introduce inline functions to convert between pointers and unsigned 32-bit
> ints. These are used to hide the ugliness required to  avoid compiler
> warnings.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/libc.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h
> index 818517f..e198f0b 100644
> --- a/pc-bios/s390-ccw/libc.h
> +++ b/pc-bios/s390-ccw/libc.h
> @@ -19,6 +19,18 @@ typedef unsigned short     uint16_t;
>  typedef unsigned int       uint32_t;
>  typedef unsigned long long uint64_t;
>  
> +/* Avoids compiler warnings when casting a pointer to a u32 */
> +static inline uint32_t ptr2u32(void *ptr)
> +{
> +    return (uint32_t)(uint64_t)ptr;
> +}
> +
> +/* Avoids compiler warnings when casting a u32 to a pointer */
> +static inline void *u32toptr(uint32_t n)
> +{
> +    return (void *)(uint64_t)n;
> +}
> +
>  static inline void *memset(void *s, int c, size_t n)
>  {
>      size_t i;

Ugly, but I hope any users of these already know what they're doing :)

Acked-by: Cornelia Huck <cohuck@redhat.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-01-31 17:31   ` Farhan Ali
@ 2019-02-04 11:13     ` Cornelia Huck
  2019-02-04 19:29       ` Farhan Ali
  2019-02-27 13:32       ` Jason J. Herne
  0 siblings, 2 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 11:13 UTC (permalink / raw)
  To: Farhan Ali; +Cc: Jason J. Herne, qemu-devel, qemu-s390x, pasic, borntraeger

On Thu, 31 Jan 2019 12:31:00 -0500
Farhan Ali <alifm@linux.ibm.com> wrote:

> On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> > Add struct for format-0 ccws. Support executing format-0 channel
> > programs and waiting for their completion before continuing execution.
> > This will be used for real dasd ipl.
> > 
> > Add cu_type() to channel io library. This will be used to query control
> > unit type which is used to determine if we are booting a virtio device or a
> > real dasd device.
> > 
> > Signed-off-by: Jason J. Herne<jjherne@linux.ibm.com>
> > ---
> >   pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
> >   pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
> >   pc-bios/s390-ccw/s390-ccw.h |   1 +
> >   pc-bios/s390-ccw/start.S    |  33 +++++++++++-
> >   4 files changed, 270 insertions(+), 5 deletions(-)

> > +/*
> > + * Executes a channel program at a given subchannel. The request to run the
> > + * channel program is sent to the subchannel, we then wait for the interrupt
> > + * signaling completion of the I/O operation(s) performed by the channel
> > + * program. Lastly we verify that the i/o operation completed without error and
> > + * that the interrupt we received was for the subchannel used to run the
> > + * channel program.
> > + *
> > + * Note: This function assumes it is running in an environment where no other
> > + * cpus are generating or receiving I/O interrupts. So either run it in a
> > + * single-cpu environment or make sure all other cpus are not doing I/O and
> > + * have I/O interrupts masked off.
> > + */
> > +int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
> > +{
> > +    CmdOrb orb = {};
> > +    Irb irb = {};
> > +    sense_data_eckd_dasd sd;
> > +    int rc, retries = 0;
> > +
> > +    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
> > +
> > +    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
> > +    if (fmt == 0) {
> > +        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
> > +    }
> > +
> > +    orb.fmt = fmt ;
> > +    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
> > +    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
> > +    orb.lpm = 0xFF; /* All paths allowed */
> > +    orb.cpa = ccw_addr;
> > +
> > +    while (true) {
> > +        rc = ssch(schid, &orb);
> > +        if (rc == 1) {
> > +            /* Status pending, not sure why. Let's eat the status and retry. */
> > +            tsch(schid, &irb);
> > +            retries++;
> > +            continue;
> > +        }
> > +        if (rc) {
> > +            print_int("ssch failed with rc=", rc);
> > +            break;
> > +        }
> > +
> > +        consume_io_int();
> > +
> > +        /* collect status */
> > +        rc = tsch(schid, &irb);
> > +        if (rc) {
> > +            print_int("tsch failed with rc=", rc);
> > +            break;
> > +        }
> > +
> > +        if (!irb_error(&irb)) {
> > +            break;
> > +        }
> > +
> > +        /*
> > +         * Unexpected unit check, or interface-control-check. Use sense to
> > +         * clear unit check then retry.
> > +         */
> > +        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
> > +            basic_sense(schid, &sd, sizeof(sd));  
> 
> We are using basic sense to clear any unit check or ifcc, but is it 
> possible for the basic sense to cause another unit check?
> 
> The chapter on Basic Sense in the Common I/O Device Commands 
> (http://publibz.boulder.ibm.com/support/libraryserver/FRAMESET/dz9ar501/2.1?SHELF=&DT=19920409154647&CASE=) 
>   says this:
> 
> ""
> The basic sense command initiates a sense operation  at  all  devices 
> and cannot  cause  the  command-reject,  intervention-required, 
> data-check, or overrun bit to be set to one.  If the control unit 
> detects  an  equipment malfunction  or  invalid  checking-block  code 
> (CBC) on the sense-command code, the equipment-check or bus-out-check 
> bit is set  to  one,  and  unit check is indicated in the device-status 
> byte.
> ""
> 
> If my understanding is correct, if there is an equipment malfunction 
> then the control unit can return a unit check even for a basic sense. 
> This can lead to infinite recursion in the bios.

I think the retries variable is supposed to take care of that.

What I don't understand is why we do the basic sense after an IFCC?
Wouldn't it make more sense to simply retry the original command in
that case?

> 
> 
> 
> > +            retries++;
> > +            continue;
> > +        }
> > +
> > +        break;
> > +    }
> > +
> > +    return rc;
> > +}  
> 

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs Jason J. Herne
  2019-01-31 17:31   ` Farhan Ali
@ 2019-02-04 11:24   ` Cornelia Huck
  2019-02-21 18:01     ` Jason J. Herne
  1 sibling, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 11:24 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:17 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Add struct for format-0 ccws. Support executing format-0 channel
> programs and waiting for their completion before continuing execution.
> This will be used for real dasd ipl.
> 
> Add cu_type() to channel io library. This will be used to query control
> unit type which is used to determine if we are booting a virtio device or a
> real dasd device.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
>  pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
>  pc-bios/s390-ccw/s390-ccw.h |   1 +
>  pc-bios/s390-ccw/start.S    |  33 +++++++++++-
>  4 files changed, 270 insertions(+), 5 deletions(-)

> diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
> index 7b07d75..1086f31 100644
> --- a/pc-bios/s390-ccw/cio.h
> +++ b/pc-bios/s390-ccw/cio.h
> @@ -70,9 +70,46 @@ struct scsw {
>      __u16 count;
>  } __attribute__ ((packed));
>  
> -#define SCSW_FCTL_CLEAR_FUNC 0x1000
> -#define SCSW_FCTL_HALT_FUNC 0x2000
> +/* Function Control */
>  #define SCSW_FCTL_START_FUNC 0x4000
> +#define SCSW_FCTL_HALT_FUNC 0x2000
> +#define SCSW_FCTL_CLEAR_FUNC 0x1000
> +
> +/* Activity Control */
> +#define SCSW_ACTL_RESUME_PEND   0x0800
> +#define SCSW_ACTL_START_PEND    0x0400
> +#define SCSW_ACTL_HALT_PEND     0x0200
> +#define SCSW_ACTL_CLEAR_PEND    0x0100
> +#define SCSW_ACTL_CH_ACTIVE     0x0080
> +#define SCSW_ACTL_DEV_ACTIVE    0x0040
> +#define SCSW_ACTL_SUSPENDED     0x0020
> +
> +/* Status Control */
> +#define SCSW_SCTL_ALERT         0x0010
> +#define SCSW_SCTL_INTERMED      0x0008
> +#define SCSW_SCTL_PRIMARY       0x0004
> +#define SCSW_SCTL_SECONDARY     0x0002
> +#define SCSW_SCTL_STATUS_PEND   0x0001
> +
> +/* SCSW Device Status Flags */
> +#define SCSW_DSTAT_ATTN     0x80
> +#define SCSW_DSTAT_STATMOD  0x40
> +#define SCSW_DSTAT_CUEND    0x20
> +#define SCSW_DSTAT_BUSY     0x10
> +#define SCSW_DSTAT_CHEND    0x08
> +#define SCSW_DSTAT_DEVEND   0x04
> +#define SCSW_DSTAT_UCHK     0x02
> +#define SCSW_DSTAT_UEXCP    0x01
> +
> +/* SCSW Subchannel Status Flags */
> +#define SCSW_CSTAT_PCINT    0x80
> +#define SCSW_CSTAT_BADLEN   0x40
> +#define SCSW_CSTAT_PROGCHK  0x20
> +#define SCSW_CSTAT_PROTCHK  0x10
> +#define SCSW_CSTAT_CHDCHK   0x08
> +#define SCSW_CSTAT_CHCCHK   0x04
> +#define SCSW_CSTAT_ICCHK    0x02
> +#define SCSW_CSTAT_CHAINCHK 0x01

Any reason you're not following the Linux kernel definitions here?
Might make it easier for folks familiar with the kernel implementation.

>  
>  /*
>   * subchannel information block

(...)

> +/* basic sense response buffer layout */
> +typedef struct sense_data_eckd_dasd {
> +    uint8_t common_status;
> +    uint8_t status[2];
> +    uint8_t res_count;
> +    uint8_t phys_drive_id;
> +    uint8_t low_cyl_addr;
> +    uint8_t head_high_cyl_addr;
> +    uint8_t fmt_msg;
> +    uint64_t fmt_dependent_info[2];
> +    uint8_t reserved;
> +    uint8_t program_action_code;
> +    uint16_t config_info;
> +    uint8_t mcode_hicyl;
> +    uint8_t cyl_head_addr[3];
> +}  __attribute__ ((packed, aligned(4))) sense_data_eckd_dasd;

SenseDataEckdDasd would be more QEMU-y.

> +
> +#define ECKD_SENSE24_GET_FMT(sd)     (sd->fmt_msg & 0xF0 >> 4)
> +#define ECKD_SENSE24_GET_MSG(sd)     (sd->fmt_msg & 0x0F)
> +
> +#define unit_check(irb)         ((irb)->scsw.dstat & SCSW_DSTAT_UCHK)
> +#define iface_ctrl_check(irb)   ((irb)->scsw.cstat & SCSW_CSTAT_ICCHK)
> +
>  /* interruption response block */
>  typedef struct irb {
>      struct scsw scsw;

(...)

> diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
> index eb8d024..22b38ec 100644
> --- a/pc-bios/s390-ccw/start.S
> +++ b/pc-bios/s390-ccw/start.S
> @@ -65,12 +65,32 @@ consume_sclp_int:
>          /* prepare external call handler */
>          larl %r1, external_new_code
>          stg %r1, 0x1b8
> -        larl %r1, external_new_mask
> +        larl %r1, int_new_mask

Isn't that for external interrupts?

>          mvc 0x1b0(8),0(%r1)
>          /* load enabled wait PSW */
>          larl %r1, enabled_wait_psw
>          lpswe 0(%r1)
>  
> +/*
> + * void consume_io_int(void)
> + *
> + * eats one I/O interrupt
> + */
> +        .globl consume_io_int
> +consume_io_int:
> +        /* enable I/O interrupts in cr6 */
> +        stctg 6,6,0(15)
> +        oi 4(15), 0xff
> +        lctlg 6,6,0(15)
> +        /* prepare i/o call handler */
> +        larl %r1, io_new_code
> +        stg %r1, 0x1f8
> +        larl %r1, int_new_mask
> +        mvc 0x1f0(8),0(%r1)
> +        /* load enabled wait PSW */
> +        larl %r1, enabled_wait_psw
> +        lpswe 0(%r1)
> +
>  external_new_code:
>          /* disable service interrupts in cr0 */
>          stctg 0,0,0(15)
> @@ -78,10 +98,19 @@ external_new_code:
>          lctlg 0,0,0(15)
>          br 14
>  
> +io_new_code:
> +        /* disable I/O interrupts in cr6 */
> +        stctg 6,6,0(15)
> +        ni 4(15), 0x00
> +        lctlg 6,6,0(15)

What about leaving the isc enabled in cr6 all the time and just
controlling interrupts via enabling/disabling I/O interrupts?

> +        br 14
> +
> +
> +
>          .align  8
>  disabled_wait_psw:
>          .quad   0x0002000180000000,0x0000000000000000
>  enabled_wait_psw:
>          .quad   0x0302000180000000,0x0000000000000000
> -external_new_mask:
> +int_new_mask:

Ah, I see. But I'd probably have two masks instead.

>          .quad   0x0000000180000000

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 11/15] s390-bios: cio error handling
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 11/15] s390-bios: cio error handling Jason J. Herne
@ 2019-02-04 11:41   ` Cornelia Huck
  2019-02-28 15:59     ` Jason J. Herne
  0 siblings, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 11:41 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:18 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Add verbose error output for when unexpected i/o errors happen. This eases the
> burden of debugging and reporting i/o errors. No error information is printed
> in the success case, here is an example of what is output on error:
> 
> vfio-ccw device I/O error - Interrupt Response Block Data:
>     Function Ctrl : [Start]
>     Activity Ctrl : [Start-Pending]
>     Status Ctrl : [Alert] [Primary] [Secondary] [Status-Pending]
>     Device Status : [Unit-Check]
>     Channel Status :
>     cpa=: 0x0000000001e67098
>     prev_ccw=: 0x0000000000000000
>     this_ccw=: 0x0000000000000000
> 
> Sense Data (fmt 32-bytes):
>     Sense Condition Flags : [Equipment-Check]
>     Residual Count     =: 0x0000000000000000
>     Phys Drive ID      =: 0x000000000000009e
>     low cyl address    =: 0x0000000000000000
>     head addr & hi cyl =: 0x0000000000000000
>     format/message     =: 0x0000000000000008
>     fmt-dependent[0-7] =: 0x0000000000000004
>     fmt-dependent[8-15]=: 0xe561282305082fff
>     prog action code   =: 0x0000000000000016
>     Configuration info =: 0x00000000000040e0
>     mcode / hi-cyl     =: 0x0000000000000000
>     cyl & head addr [0]=: 0x0000000000000000
>     cyl & head addr [1]=: 0x0000000000000000
>     cyl & head addr [2]=: 0x0000000000000000

Looks cool.

> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> 
> # Conflicts:
> #	pc-bios/s390-ccw/cio.c

You probably don't want to keep that :)

> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/cio.c  | 225 ++++++++++++++++++++++++++++++++++++++++++++++++
>  pc-bios/s390-ccw/libc.h |  11 +++
>  2 files changed, 236 insertions(+)
> 

(...)

> +static void print_irb_err(Irb *irb)
> +{
> +    Ccw0 *this_ccw = u32toptr(irb->scsw.cpa);
> +    Ccw0 *prev_ccw = u32toptr(irb->scsw.cpa - 8);

I don't think you can cast this conditionally to format 0 -- I'd pass
in the format from do_cio and handle it accordingly.

> +    char msgline[256];
> +
> +    sclp_print("vfio-ccw device I/O error - Interrupt Response Block Data:\n");

If you call this from the generic function, you shouldn't talk about
vfio-ccw here; but it might make sense to print subchannel/devno and
the cu type.

(...)

> @@ -148,6 +370,9 @@ int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
>              continue;
>          }
>  
> +        print_irb_err(&irb);
> +        basic_sense(schid, &sd, sizeof(sd));
> +        print_eckd_dasd_sense_data(&sd);

I think this should only be printed for actual dasds (and maybe only
print it if there is actually sense data available)?

>          break;
>      }
>  

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 12/15] s390-bios: Refactor virtio to run channel programs via cio
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 12/15] s390-bios: Refactor virtio to run channel programs via cio Jason J. Herne
@ 2019-02-04 11:44   ` Cornelia Huck
  2019-02-25 13:20     ` Jason J. Herne
  0 siblings, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 11:44 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:19 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Now that we have a Channel I/O library let's modify virtio boot code to
> make use of it for running channel programs.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/virtio.c | 48 +++++++++++++++++++----------------------------
>  1 file changed, 19 insertions(+), 29 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
> index aa9da72..f8d71ed 100644
> --- a/pc-bios/s390-ccw/virtio.c
> +++ b/pc-bios/s390-ccw/virtio.c
> @@ -89,33 +89,20 @@ int drain_irqs(SubChannelId schid)
>      }
>  }
>  
> -static int run_ccw(VDev *vdev, int cmd, void *ptr, int len)
> +static int run_ccw(VDev *vdev, int cmd, void *ptr, int len, bool sli)
>  {
>      Ccw1 ccw = {};
> -    CmdOrb orb = {};
> -    int r;
> -
> -    enable_subchannel(vdev->schid);
> -
> -    /* start subchannel command */
> -    orb.fmt = 1;
> -    orb.cpa = (u32)(long)&ccw;
> -    orb.lpm = 0x80;
>  
>      ccw.cmd_code = cmd;
>      ccw.cda = (long)ptr;
>      ccw.count = len;
>  
> -    r = ssch(vdev->schid, &orb);
> -    /*
> -     * XXX Wait until device is done processing the CCW. For now we can
> -     *     assume that a simple tsch will have finished the CCW processing,
> -     *     but the architecture allows for asynchronous operation
> -     */
> -    if (!r) {
> -        r = drain_irqs(vdev->schid);
> +    if (sli) {
> +        ccw.flags |= CCW_FLAG_SLI;
>      }
> -    return r;
> +
> +    enable_subchannel(vdev->schid);
> +    return do_cio(vdev->schid, ptr2u32(&ccw), CCW_FMT1);

That still has the very odd pattern that you enable the subchannel
every time you run a channel program...

>  }
>  
>  static void vring_init(VRing *vr, VqInfo *info)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 13/15] s390-bios: Use control unit type to determine boot method
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 13/15] s390-bios: Use control unit type to determine boot method Jason J. Herne
@ 2019-02-04 11:46   ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 11:46 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:20 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> The boot method is different depending on which device type we are
> booting from. Let's examine the control unit type to determine if we're
> a virtio device. We'll eventually add a case to check for a real dasd device
> here as well.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/main.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index fa90aa3..5ee02c3 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -200,13 +200,24 @@ static void virtio_setup(void)
>  
>  int main(void)
>  {
> +    uint16_t cutype;
> +
>      sclp_setup();
>      css_setup();
>      boot_setup();
>      find_boot_device();
> +    enable_subchannel(blk_schid);

You even enable the subchannel here already -- no need to do that in
run_ccw again ;)

>  
> -    virtio_setup();
> -    zipl_load(); /* no return */
> +    cutype = cu_type(blk_schid) ;

extra ' '

> +    switch (cutype) {
> +    case CU_TYPE_VIRTIO:
> +        virtio_setup();
> +        zipl_load(); /* no return */
> +        break;
> +    default:
> +        print_int("Attempting to boot from unexpected device type", cutype);
> +        panic("");
> +    }
>  
>      panic("Failed to load OS from hard disk\n");
>      return 0; /* make compiler happy */

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 14/15] s390-bios: Add channel command codes/structs needed for dasd-ipl
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 14/15] s390-bios: Add channel command codes/structs needed for dasd-ipl Jason J. Herne
@ 2019-02-04 11:47   ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 11:47 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:21 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> The dasd IPL procedure needs to execute a few previously unused
> channel commands. Let's define them and their associated data
> structures.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/cio.h | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)

Acked-by: Cornelia Huck <cohuck@redhat.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device Jason J. Herne
  2019-01-31 18:23   ` Cornelia Huck
@ 2019-02-04 12:02   ` Cornelia Huck
  2019-02-19 14:57     ` Jason J. Herne
  2019-02-21  2:52   ` [Qemu-devel] [qemu-s390x] " Eric Farman
  2 siblings, 1 reply; 83+ messages in thread
From: Cornelia Huck @ 2019-02-04 12:02 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Tue, 29 Jan 2019 08:29:22 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> Allows guest to boot from a vfio configured real dasd device.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  docs/devel/s390-dasd-ipl.txt | 132 +++++++++++++++++++++++
>  pc-bios/s390-ccw/Makefile    |   2 +-
>  pc-bios/s390-ccw/dasd-ipl.c  | 249 +++++++++++++++++++++++++++++++++++++++++++
>  pc-bios/s390-ccw/dasd-ipl.h  |  16 +++
>  pc-bios/s390-ccw/main.c      |   4 +
>  pc-bios/s390-ccw/s390-arch.h |  13 +++
>  6 files changed, 415 insertions(+), 1 deletion(-)
>  create mode 100644 docs/devel/s390-dasd-ipl.txt
>  create mode 100644 pc-bios/s390-ccw/dasd-ipl.c
>  create mode 100644 pc-bios/s390-ccw/dasd-ipl.h
> 
> diff --git a/docs/devel/s390-dasd-ipl.txt b/docs/devel/s390-dasd-ipl.txt
> new file mode 100644
> index 0000000..84ec7b8
> --- /dev/null
> +++ b/docs/devel/s390-dasd-ipl.txt
> @@ -0,0 +1,132 @@
> +*****************************
> +***** s390 hardware IPL *****
> +*****************************
> +
> +The s390 hardware IPL process consists of the following steps.
> +
> +1. A READ IPL ccw is constructed in memory location 0x0.
> +    This ccw, by definition, reads the IPL1 record which is located on the disk
> +    at cylinder 0 track 0 record 1. Note that the chain flag is on in this ccw
> +    so when it is complete another ccw will be fetched and executed from memory
> +    location 0x08.
> +
> +2. Execute the Read IPL ccw at 0x00, thereby reading IPL1 data into 0x00.
> +    IPL1 data is 24 bytes in length and consists of the following pieces of
> +    information: [psw][read ccw][tic ccw]. When the machine executes the Read
> +    IPL ccw it read the 24-bytes of IPL1 to be read into memory starting at
> +    location 0x0. Then the ccw program at 0x08 which consists of a read
> +    ccw and a tic ccw is automatically executed because of the chain flag from
> +    the original READ IPL ccw. The read ccw will read the IPL2 data into memory
> +    and the TIC (Tranfer In Channel) will transfer control to the channel
> +    program contained in the IPL2 data. The TIC channel command is the
> +    equivalent of a branch/jump/goto instruction for channel programs.
> +    NOTE: The ccws in IPL1 are defined by the architecture to be format 0.
> +
> +3. Execute IPL2.
> +    The TIC ccw instruction at the end of the IPL1 channel program will begin
> +    the execution of the IPL2 channel program. IPL2 is stage-2 of the boot
> +    process and will contain a larger channel program than IPL1. The point of
> +    IPL2 is to find and load either the operating system or a small program that
> +    loads the operating system from disk. At the end of this step all or some of
> +    the real operating system is loaded into memory and we are ready to hand
> +    control over to the guest operating system. At this point the guest
> +    operating system is entirely responsible for loading any more data it might
> +    need to function. NOTE: The IPL2 channel program might read data into memory
> +    location 0 thereby overwriting the IPL1 psw and channel program. This is ok
> +    as long as the data placed in location 0 contains a psw whose instruction
> +    address points to the guest operating system code to execute at the end of
> +    the IPL/boot process.
> +    NOTE: The ccws in IPL2 are defined by the architecture to be format 0.
> +
> +4. Start executing the guest operating system.
> +    The psw that was loaded into memory location 0 as part of the ipl process
> +    should contain the needed flags for the operating system we have loaded. The
> +    psw's instruction address will point to the location in memory where we want
> +    to start executing the operating system. This psw is loaded (via LPSW
> +    instruction) causing control to be passed to the operating system code.
> +
> +In a non-virtualized environment this process, handled entirely by the hardware,
> +is kicked off by the user initiating a "Load" procedure from the hardware
> +management console. This "Load" procedure crafts a special "Read IPL" ccw in
> +memory location 0x0 that reads IPL1. It then executes this ccw thereby kicking
> +off the reading of IPL1 data. Since the channel program from IPL1 will be
> +written immediately after the special "Read IPL" ccw, the IPL1 channel program
> +will be executed immediately (the special read ccw has the chaining bit turned
> +on). The TIC at the end of the IPL1 channel program will cause the IPL2 channel
> +program to be executed automatically. After this sequence completes the "Load"
> +procedure then loads the psw from 0x0.

Nice summary!

> +
> +*****************************************
> +***** How this all pertains to Qemu *****

s/Qemu/QEMU/

(also below)

> +*****************************************
> +
> +In theory we should merely have to do the following to IPL/boot a guest
> +operating system from a DASD device:
> +
> +1. Place a "Read IPL" ccw into memory location 0x0 with chaining bit on.
> +2. Execute channel program at 0x0.
> +3. LPSW 0x0.
> +
> +However, our emulation of the machine's channel program logic is missing one key
> +feature that is required for this process to work: non-prefetch of ccw data.
> +
> +When we start a channel program we pass the channel subsystem parameters via an
> +ORB (Operation Request Block). One of those parameters is a prefetch bit. If the
> +bit is on then Qemu is allowed to read the entire channel program from guest
> +memory before it starts executing it. This means that any channel commands that
> +read additional channel commands will not work as expected because the newly
> +read commands will only exist in guest memory and NOT within Qemu's channel
> +subsystem memory. Qemu's channel subsystem's implementation currently requires

But isn't that the vfio-ccw backend, rather than the channel subsystem
implementation?

> +this bit to be on for all channel programs. This is a problem because the IPL
> +process consists of transferring control from the "Read IPL" ccw immediately to
> +the IPL1 channel program that was read by "Read IPL".
> +
> +Not being able to turn off prefetch will also prevent the TIC at the end of the
> +IPL1 channel program from transferring control to the IPL2 channel program.
> +
> +Lastly, in some cases (the zipl bootloader for example) the IPL2 program also
> +tansfers control to another channel program segment immediately after reading it
> +from the disk. So we need to be able to handle this case.
> +
> +**************************
> +***** What Qemu does *****
> +**************************
> +
> +Since we are forced to live with prefetch we cannot use the very simple IPL
> +procedure we defined in the preceding section. So we compensate by doing the
> +following.
> +
> +1. Place "Read IPL" ccw into memory location 0x0, but turn off chaining bit.
> +2. Execute "Read IPL" at 0x0.
> +
> +   So now IPL1's psw is at 0x0 and IPL1's channel program is at 0x08.
> +
> +4. Write a custom channel program that will seek to the IPL2 record and then
> +   execute the READ and TIC ccws from IPL1.  Normamly the seek is not required
> +   because after reading the IPL1 record the disk is automatically positioned
> +   to read the very next record which will be IPL2. But since we are not reading
> +   both IPL1 and IPL2 as part of the same channel program we must manually set
> +   the position.
> +
> +5. Grab the target address of the TIC instruction from the IPL1 channel program.
> +   This address is where the IPL2 channel program starts.
> +
> +   Now IPL2 is loaded into memory somewhere, and we know the address.
> +
> +6. Execute the IPL2 channel program at the address obtained in step #5.
> +
> +   Because this channel program can be dynamic, we must use a special algorithm
> +   that detects a READ immediately followed by a TIC and breaks the ccw chain
> +   by turning off the chain bit in the READ ccw. When control is returned from
> +   the kernel/hardware to the Qemu bios code we immediately issue another start
> +   subchannel to execute the remaining TIC instruction. This causes the entire
> +   channel program (starting from the TIC) and all needed data to be refetched
> +   thereby stepping around the limitation that would otherwise prevent this
> +   channel program from executing properly.
> +
> +   Now the operating system code is loaded somewhere in guest memory and the psw
> +   in memory location 0x0 will point to entry code for the guest operating
> +   system.
> +
> +7. LPSW 0x0.
> +   LPSW transfers control to the guest operating system and we're done.

Also a good explanation of the procedure here!

(...)

> +static int run_dynamic_ccw_program(SubChannelId schid, uint32_t cpa)
> +{
> +    bool has_next;
> +    uint32_t next_cpa = 0;
> +    int rc;
> +
> +    do {
> +        has_next = dynamic_cp_fixup(cpa, &next_cpa);
> +
> +        print_int("executing ccw chain at ", cpa);

Do you want to keep the unconditional print here? Or make it a
debug_print_int, and maybe an unconditional print on error?

> +        enable_prefixing();
> +        rc = do_cio(schid, cpa, CCW_FMT0);
> +        disable_prefixing();
> +
> +        if (rc) {
> +            break;
> +        }
> +        cpa = next_cpa;
> +    } while (has_next);
> +
> +    return rc;
> +}

Code looks fine after a quick browse.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-04 11:13     ` Cornelia Huck
@ 2019-02-04 19:29       ` Farhan Ali
  2019-02-05 10:18         ` Cornelia Huck
  2019-02-27 13:32       ` Jason J. Herne
  1 sibling, 1 reply; 83+ messages in thread
From: Farhan Ali @ 2019-02-04 19:29 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: Jason J. Herne, qemu-devel, qemu-s390x, pasic, borntraeger



On 02/04/2019 06:13 AM, Cornelia Huck wrote:
> On Thu, 31 Jan 2019 12:31:00 -0500
> Farhan Ali <alifm@linux.ibm.com> wrote:
> 
>> On 01/29/2019 08:29 AM, Jason J. Herne wrote:
>>> Add struct for format-0 ccws. Support executing format-0 channel
>>> programs and waiting for their completion before continuing execution.
>>> This will be used for real dasd ipl.
>>>
>>> Add cu_type() to channel io library. This will be used to query control
>>> unit type which is used to determine if we are booting a virtio device or a
>>> real dasd device.
>>>
>>> Signed-off-by: Jason J. Herne<jjherne@linux.ibm.com>
>>> ---
>>>    pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
>>>    pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
>>>    pc-bios/s390-ccw/s390-ccw.h |   1 +
>>>    pc-bios/s390-ccw/start.S    |  33 +++++++++++-
>>>    4 files changed, 270 insertions(+), 5 deletions(-)
> 
>>> +/*
>>> + * Executes a channel program at a given subchannel. The request to run the
>>> + * channel program is sent to the subchannel, we then wait for the interrupt
>>> + * signaling completion of the I/O operation(s) performed by the channel
>>> + * program. Lastly we verify that the i/o operation completed without error and
>>> + * that the interrupt we received was for the subchannel used to run the
>>> + * channel program.
>>> + *
>>> + * Note: This function assumes it is running in an environment where no other
>>> + * cpus are generating or receiving I/O interrupts. So either run it in a
>>> + * single-cpu environment or make sure all other cpus are not doing I/O and
>>> + * have I/O interrupts masked off.
>>> + */
>>> +int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
>>> +{
>>> +    CmdOrb orb = {};
>>> +    Irb irb = {};
>>> +    sense_data_eckd_dasd sd;
>>> +    int rc, retries = 0;
>>> +
>>> +    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
>>> +
>>> +    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
>>> +    if (fmt == 0) {
>>> +        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
>>> +    }
>>> +
>>> +    orb.fmt = fmt ;
>>> +    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
>>> +    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
>>> +    orb.lpm = 0xFF; /* All paths allowed */
>>> +    orb.cpa = ccw_addr;
>>> +
>>> +    while (true) {
>>> +        rc = ssch(schid, &orb);
>>> +        if (rc == 1) {
>>> +            /* Status pending, not sure why. Let's eat the status and retry. */
>>> +            tsch(schid, &irb);
>>> +            retries++;
>>> +            continue;
>>> +        }
>>> +        if (rc) {
>>> +            print_int("ssch failed with rc=", rc);
>>> +            break;
>>> +        }
>>> +
>>> +        consume_io_int();
>>> +
>>> +        /* collect status */
>>> +        rc = tsch(schid, &irb);
>>> +        if (rc) {
>>> +            print_int("tsch failed with rc=", rc);
>>> +            break;
>>> +        }
>>> +
>>> +        if (!irb_error(&irb)) {
>>> +            break;
>>> +        }
>>> +
>>> +        /*
>>> +         * Unexpected unit check, or interface-control-check. Use sense to
>>> +         * clear unit check then retry.
>>> +         */
>>> +        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
>>> +            basic_sense(schid, &sd, sizeof(sd));
>>
>> We are using basic sense to clear any unit check or ifcc, but is it
>> possible for the basic sense to cause another unit check?
>>
>> The chapter on Basic Sense in the Common I/O Device Commands
>> (http://publibz.boulder.ibm.com/support/libraryserver/FRAMESET/dz9ar501/2.1?SHELF=&DT=19920409154647&CASE=)
>>    says this:
>>
>> ""
>> The basic sense command initiates a sense operation  at  all  devices
>> and cannot  cause  the  command-reject,  intervention-required,
>> data-check, or overrun bit to be set to one.  If the control unit
>> detects  an  equipment malfunction  or  invalid  checking-block  code
>> (CBC) on the sense-command code, the equipment-check or bus-out-check
>> bit is set  to  one,  and  unit check is indicated in the device-status
>> byte.
>> ""
>>
>> If my understanding is correct, if there is an equipment malfunction
>> then the control unit can return a unit check even for a basic sense.
>> This can lead to infinite recursion in the bios.
> 
> I think the retries variable is supposed to take care of that.
> 

If I understand the code correctly, the retries variable cannot prevent 
infinite recursion. Because every time we get a unit check we do a basic 
sense which calls the do_cio function again. If that basic sense returns 
a unit check we do another basic sense....

> What I don't understand is why we do the basic sense after an IFCC?
> Wouldn't it make more sense to simply retry the original command in
> that case?
> 
>>
>>
>>
>>> +            retries++;
>>> +            continue;
>>> +        }
>>> +
>>> +        break;
>>> +    }
>>> +
>>> +    return rc;
>>> +}
>>
> 
> 

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 02/15] s390-bios: decouple cio setup from virtio
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio Jason J. Herne
  2019-01-30 22:23   ` Farhan Ali
  2019-02-04 10:28   ` Cornelia Huck
@ 2019-02-05  9:55   ` Thomas Huth
  2 siblings, 0 replies; 83+ messages in thread
From: Thomas Huth @ 2019-02-05  9:55 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, alifm,
	borntraeger

On 2019-01-29 14:29, Jason J. Herne wrote:
> Move channel i/o setup code out to a separate function. This decouples cio
> setup from the virtio code path and allows us to make use of it for booting
> dasd devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> Reviewed-by: Collin Walling <walling@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/main.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)

Please CC: me on s390-ccw bios related patches!

Reviewed-by: Thomas Huth <thuth@redhat.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-04 19:29       ` Farhan Ali
@ 2019-02-05 10:18         ` Cornelia Huck
  2019-02-12 13:10           ` Halil Pasic
  2019-02-27 13:35           ` Jason J. Herne
  0 siblings, 2 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-05 10:18 UTC (permalink / raw)
  To: Farhan Ali; +Cc: Jason J. Herne, qemu-devel, qemu-s390x, pasic, borntraeger

On Mon, 4 Feb 2019 14:29:18 -0500
Farhan Ali <alifm@linux.ibm.com> wrote:

> On 02/04/2019 06:13 AM, Cornelia Huck wrote:
> > On Thu, 31 Jan 2019 12:31:00 -0500
> > Farhan Ali <alifm@linux.ibm.com> wrote:
> >   
> >> On 01/29/2019 08:29 AM, Jason J. Herne wrote:  
> >>> Add struct for format-0 ccws. Support executing format-0 channel
> >>> programs and waiting for their completion before continuing execution.
> >>> This will be used for real dasd ipl.
> >>>
> >>> Add cu_type() to channel io library. This will be used to query control
> >>> unit type which is used to determine if we are booting a virtio device or a
> >>> real dasd device.
> >>>
> >>> Signed-off-by: Jason J. Herne<jjherne@linux.ibm.com>
> >>> ---
> >>>    pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
> >>>    pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
> >>>    pc-bios/s390-ccw/s390-ccw.h |   1 +
> >>>    pc-bios/s390-ccw/start.S    |  33 +++++++++++-
> >>>    4 files changed, 270 insertions(+), 5 deletions(-)  
> >   
> >>> +/*
> >>> + * Executes a channel program at a given subchannel. The request to run the
> >>> + * channel program is sent to the subchannel, we then wait for the interrupt
> >>> + * signaling completion of the I/O operation(s) performed by the channel
> >>> + * program. Lastly we verify that the i/o operation completed without error and
> >>> + * that the interrupt we received was for the subchannel used to run the
> >>> + * channel program.
> >>> + *
> >>> + * Note: This function assumes it is running in an environment where no other
> >>> + * cpus are generating or receiving I/O interrupts. So either run it in a
> >>> + * single-cpu environment or make sure all other cpus are not doing I/O and
> >>> + * have I/O interrupts masked off.
> >>> + */
> >>> +int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
> >>> +{
> >>> +    CmdOrb orb = {};
> >>> +    Irb irb = {};
> >>> +    sense_data_eckd_dasd sd;
> >>> +    int rc, retries = 0;
> >>> +
> >>> +    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
> >>> +
> >>> +    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
> >>> +    if (fmt == 0) {
> >>> +        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
> >>> +    }
> >>> +
> >>> +    orb.fmt = fmt ;
> >>> +    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
> >>> +    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
> >>> +    orb.lpm = 0xFF; /* All paths allowed */
> >>> +    orb.cpa = ccw_addr;
> >>> +
> >>> +    while (true) {
> >>> +        rc = ssch(schid, &orb);
> >>> +        if (rc == 1) {
> >>> +            /* Status pending, not sure why. Let's eat the status and retry. */
> >>> +            tsch(schid, &irb);
> >>> +            retries++;
> >>> +            continue;
> >>> +        }
> >>> +        if (rc) {
> >>> +            print_int("ssch failed with rc=", rc);
> >>> +            break;
> >>> +        }
> >>> +
> >>> +        consume_io_int();
> >>> +
> >>> +        /* collect status */
> >>> +        rc = tsch(schid, &irb);
> >>> +        if (rc) {
> >>> +            print_int("tsch failed with rc=", rc);
> >>> +            break;
> >>> +        }
> >>> +
> >>> +        if (!irb_error(&irb)) {
> >>> +            break;
> >>> +        }
> >>> +
> >>> +        /*
> >>> +         * Unexpected unit check, or interface-control-check. Use sense to
> >>> +         * clear unit check then retry.
> >>> +         */
> >>> +        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
> >>> +            basic_sense(schid, &sd, sizeof(sd));  
> >>
> >> We are using basic sense to clear any unit check or ifcc, but is it
> >> possible for the basic sense to cause another unit check?
> >>
> >> The chapter on Basic Sense in the Common I/O Device Commands
> >> (http://publibz.boulder.ibm.com/support/libraryserver/FRAMESET/dz9ar501/2.1?SHELF=&DT=19920409154647&CASE=)
> >>    says this:
> >>
> >> ""
> >> The basic sense command initiates a sense operation  at  all  devices
> >> and cannot  cause  the  command-reject,  intervention-required,
> >> data-check, or overrun bit to be set to one.  If the control unit
> >> detects  an  equipment malfunction  or  invalid  checking-block  code
> >> (CBC) on the sense-command code, the equipment-check or bus-out-check
> >> bit is set  to  one,  and  unit check is indicated in the device-status
> >> byte.
> >> ""
> >>
> >> If my understanding is correct, if there is an equipment malfunction
> >> then the control unit can return a unit check even for a basic sense.
> >> This can lead to infinite recursion in the bios.  
> > 
> > I think the retries variable is supposed to take care of that.
> >   
> 
> If I understand the code correctly, the retries variable cannot prevent 
> infinite recursion. Because every time we get a unit check we do a basic 
> sense which calls the do_cio function again. If that basic sense returns 
> a unit check we do another basic sense....

Eww, you're right...

I think that the routine needs to be split:
- inner routine that does the ssch, retries if the subchannel is status
  pending, and waits for a final status (regardless whether it is a
  special condition or not)
- outer routine that does error handling, if needed (like retrying on
  IFCC, or doing a basic sense on unit check)

The inner routine will probably only be called by the outer routine
(and not directly by other code).

Does that make sense? It's hopefully enough; we really don't want to
transplant the whole Linux cio state machine into the bios...

> 
> > What I don't understand is why we do the basic sense after an IFCC?
> > Wouldn't it make more sense to simply retry the original command in
> > that case?
> >   
> >>
> >>
> >>  
> >>> +            retries++;
> >>> +            continue;
> >>> +        }
> >>> +
> >>> +        break;
> >>> +    }
> >>> +
> >>> +    return rc;
> >>> +}  
> >>  
> > 
> >   
> 

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
                     ` (3 preceding siblings ...)
  2019-02-04 10:26   ` Cornelia Huck
@ 2019-02-06 11:30   ` Thomas Huth
  2019-02-08 16:04     ` Jason J. Herne
  4 siblings, 1 reply; 83+ messages in thread
From: Thomas Huth @ 2019-02-06 11:30 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, alifm,
	borntraeger

On 2019-01-29 14:29, Jason J. Herne wrote:
> Add bootindex property and iplb data for vfio-ccw devices. This allows us to
> forward boot information into the bios for vfio-ccw devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> ---
>  hw/s390x/ipl.c              | 14 ++++++++++++++
>  hw/s390x/s390-ccw.c         |  9 +++++++++
>  hw/vfio/ccw.c               | 13 +------------
>  include/hw/s390x/s390-ccw.h |  1 +
>  include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 63 insertions(+), 12 deletions(-)
>  create mode 100644 include/hw/s390x/vfio-ccw.h
> 
> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
> index 21f64ad..a993f65 100644
> --- a/hw/s390x/ipl.c
> +++ b/hw/s390x/ipl.c
> @@ -19,6 +19,7 @@
>  #include "hw/loader.h"
>  #include "hw/boards.h"
>  #include "hw/s390x/virtio-ccw.h"
> +#include "hw/s390x/vfio-ccw.h"
>  #include "hw/s390x/css.h"
>  #include "hw/s390x/ebcdic.h"
>  #include "ipl.h"
> @@ -311,8 +312,12 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
>          VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
>              object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
>                                  TYPE_VIRTIO_CCW_DEVICE);
> +        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>          if (virtio_ccw_dev) {
>              ccw_dev = CCW_DEVICE(virtio_ccw_dev);
> +        } else if (vfio_ccw_dev) {
> +            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
>          } else {
>              SCSIDevice *sd = (SCSIDevice *)
>                  object_dynamic_cast(OBJECT(dev_st),
> @@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>      if (ccw_dev) {
>          SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
>                                                              TYPE_SCSI_DEVICE);
> +        VFIOCCWDevice *vc = (VFIOCCWDevice *)
> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>  
>          if (sd) {
>              ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
> @@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>              ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
>              ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
>              ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
> +        } else if (vc) {
> +            CcwDevice *ccw_dev = CCW_DEVICE(vc);
> +
> +            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
> +            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
> +            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
> +            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
>          } else {
>              VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
>                                                                TYPE_VIRTIO_NET);
> diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
> index cad91ee..f5f025d 100644
> --- a/hw/s390x/s390-ccw.c
> +++ b/hw/s390x/s390-ccw.c
> @@ -124,6 +124,14 @@ static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
>      g_free(cdev->mdevid);
>  }
>  
> +static void s390_ccw_instance_init(Object *obj)
> +{
> +    S390CCWDevice *dev = S390_CCW_DEVICE(obj);
> +
> +    device_add_bootindex_property(obj, &dev->bootindex, "bootindex",
> +                                  "/disk@0,0", DEVICE(obj), NULL);
> +}
> +
>  static void s390_ccw_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -137,6 +145,7 @@ static void s390_ccw_class_init(ObjectClass *klass, void *data)
>  static const TypeInfo s390_ccw_info = {
>      .name          = TYPE_S390_CCW,
>      .parent        = TYPE_CCW_DEVICE,
> +    .instance_init = s390_ccw_instance_init,
>      .instance_size = sizeof(S390CCWDevice),
>      .class_size    = sizeof(S390CCWDeviceClass),
>      .class_init    = s390_ccw_class_init,
> diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
> index 9246729..d815a4f 100644
> --- a/hw/vfio/ccw.c
> +++ b/hw/vfio/ccw.c
> @@ -21,22 +21,11 @@
>  #include "hw/vfio/vfio.h"
>  #include "hw/vfio/vfio-common.h"
>  #include "hw/s390x/s390-ccw.h"
> +#include "hw/s390x/vfio-ccw.h"
>  #include "hw/s390x/ccw-device.h"
>  #include "exec/address-spaces.h"
>  #include "qemu/error-report.h"
>  
> -#define TYPE_VFIO_CCW "vfio-ccw"
> -typedef struct VFIOCCWDevice {
> -    S390CCWDevice cdev;
> -    VFIODevice vdev;
> -    uint64_t io_region_size;
> -    uint64_t io_region_offset;
> -    struct ccw_io_region *io_region;
> -    EventNotifier io_notifier;
> -    bool force_orb_pfch;
> -    bool warned_orb_pfch;
> -} VFIOCCWDevice;
> -
>  static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch,
>                                    const char *msg)
>  {
> diff --git a/include/hw/s390x/s390-ccw.h b/include/hw/s390x/s390-ccw.h
> index 7d15a1a..901d805 100644
> --- a/include/hw/s390x/s390-ccw.h
> +++ b/include/hw/s390x/s390-ccw.h
> @@ -27,6 +27,7 @@ typedef struct S390CCWDevice {
>      CcwDevice parent_obj;
>      CssDevId hostid;
>      char *mdevid;
> +    int32_t bootindex;
>  } S390CCWDevice;
>  
>  typedef struct S390CCWDeviceClass {
> diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h
> new file mode 100644
> index 0000000..a7d699d
> --- /dev/null
> +++ b/include/hw/s390x/vfio-ccw.h
> @@ -0,0 +1,38 @@
> +/*
> + * vfio based subchannel assignment support
> + *
> + * Copyright 2018 IBM Corp.
> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> + *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> + *            Pierre Morel <pmorel@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
> + * your option) any later version. See the COPYING file in the top-level
> + * directory.
> + */
> +
> +#ifndef HW_VFIO_CCW_H
> +#define HW_VFIO_CCW_H
> +
> +#include "hw/vfio/vfio-common.h"
> +#include "hw/s390x/s390-ccw.h"
> +#include "hw/s390x/ccw-device.h"
> +
> +#define TYPE_VFIO_CCW "vfio-ccw"
> +#define VFIO_CCW(obj) \
> +        OBJECT_CHECK(VFIOCCWDevice, (obj), TYPE_VFIO_CCW)
> +
> +

Remove one empty line, please.

> +#define TYPE_VFIO_CCW "vfio-ccw"
> +typedef struct VFIOCCWDevice {
> +    S390CCWDevice cdev;
> +    VFIODevice vdev;
> +    uint64_t io_region_size;
> +    uint64_t io_region_offset;
> +    struct ccw_io_region *io_region;
> +    EventNotifier io_notifier;
> +    bool force_orb_pfch;
> +    bool warned_orb_pfch;
> +} VFIOCCWDevice;

Do you really need to make the whole structure public here? If not, I
think it would be sufficient to only have the "anonymous" typedef here:

typedef struct VFIOCCWDevice VFIOCCWDevice;

 Thomas

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-02-06 11:30   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
@ 2019-02-08 16:04     ` Jason J. Herne
  2019-02-11  8:15       ` Cornelia Huck
  2019-02-11  8:39       ` Thomas Huth
  0 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-02-08 16:04 UTC (permalink / raw)
  To: Thomas Huth, qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

On 2/6/19 6:30 AM, Thomas Huth wrote:
> On 2019-01-29 14:29, Jason J. Herne wrote:
>> Add bootindex property and iplb data for vfio-ccw devices. This allows us to
>> forward boot information into the bios for vfio-ccw devices.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
>> ---
>>   hw/s390x/ipl.c              | 14 ++++++++++++++
>>   hw/s390x/s390-ccw.c         |  9 +++++++++
>>   hw/vfio/ccw.c               | 13 +------------
>>   include/hw/s390x/s390-ccw.h |  1 +
>>   include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++
>>   5 files changed, 63 insertions(+), 12 deletions(-)
>>   create mode 100644 include/hw/s390x/vfio-ccw.h
>>
>> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
>> index 21f64ad..a993f65 100644
>> --- a/hw/s390x/ipl.c
>> +++ b/hw/s390x/ipl.c
>> @@ -19,6 +19,7 @@
>>   #include "hw/loader.h"
>>   #include "hw/boards.h"
>>   #include "hw/s390x/virtio-ccw.h"
>> +#include "hw/s390x/vfio-ccw.h"
>>   #include "hw/s390x/css.h"
>>   #include "hw/s390x/ebcdic.h"
>>   #include "ipl.h"
>> @@ -311,8 +312,12 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
>>           VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
>>               object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
>>                                   TYPE_VIRTIO_CCW_DEVICE);
>> +        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
>> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>>           if (virtio_ccw_dev) {
>>               ccw_dev = CCW_DEVICE(virtio_ccw_dev);
>> +        } else if (vfio_ccw_dev) {
>> +            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
>>           } else {
>>               SCSIDevice *sd = (SCSIDevice *)
>>                   object_dynamic_cast(OBJECT(dev_st),
>> @@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>>       if (ccw_dev) {
>>           SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
>>                                                               TYPE_SCSI_DEVICE);
>> +        VFIOCCWDevice *vc = (VFIOCCWDevice *)
>> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>>   
>>           if (sd) {
>>               ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
>> @@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>>               ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
>>               ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
>>               ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
>> +        } else if (vc) {
>> +            CcwDevice *ccw_dev = CCW_DEVICE(vc);
>> +
>> +            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
>> +            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
>> +            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
>> +            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
>>           } else {
>>               VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
>>                                                                 TYPE_VIRTIO_NET);
>> diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
>> index cad91ee..f5f025d 100644
>> --- a/hw/s390x/s390-ccw.c
>> +++ b/hw/s390x/s390-ccw.c
>> @@ -124,6 +124,14 @@ static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
>>       g_free(cdev->mdevid);
>>   }
>>   
>> +static void s390_ccw_instance_init(Object *obj)
>> +{
>> +    S390CCWDevice *dev = S390_CCW_DEVICE(obj);
>> +
>> +    device_add_bootindex_property(obj, &dev->bootindex, "bootindex",
>> +                                  "/disk@0,0", DEVICE(obj), NULL);
>> +}
>> +
>>   static void s390_ccw_class_init(ObjectClass *klass, void *data)
>>   {
>>       DeviceClass *dc = DEVICE_CLASS(klass);
>> @@ -137,6 +145,7 @@ static void s390_ccw_class_init(ObjectClass *klass, void *data)
>>   static const TypeInfo s390_ccw_info = {
>>       .name          = TYPE_S390_CCW,
>>       .parent        = TYPE_CCW_DEVICE,
>> +    .instance_init = s390_ccw_instance_init,
>>       .instance_size = sizeof(S390CCWDevice),
>>       .class_size    = sizeof(S390CCWDeviceClass),
>>       .class_init    = s390_ccw_class_init,
>> diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
>> index 9246729..d815a4f 100644
>> --- a/hw/vfio/ccw.c
>> +++ b/hw/vfio/ccw.c
>> @@ -21,22 +21,11 @@
>>   #include "hw/vfio/vfio.h"
>>   #include "hw/vfio/vfio-common.h"
>>   #include "hw/s390x/s390-ccw.h"
>> +#include "hw/s390x/vfio-ccw.h"
>>   #include "hw/s390x/ccw-device.h"
>>   #include "exec/address-spaces.h"
>>   #include "qemu/error-report.h"
>>   
>> -#define TYPE_VFIO_CCW "vfio-ccw"
>> -typedef struct VFIOCCWDevice {
>> -    S390CCWDevice cdev;
>> -    VFIODevice vdev;
>> -    uint64_t io_region_size;
>> -    uint64_t io_region_offset;
>> -    struct ccw_io_region *io_region;
>> -    EventNotifier io_notifier;
>> -    bool force_orb_pfch;
>> -    bool warned_orb_pfch;
>> -} VFIOCCWDevice;
>> -
>>   static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch,
>>                                     const char *msg)
>>   {
>> diff --git a/include/hw/s390x/s390-ccw.h b/include/hw/s390x/s390-ccw.h
>> index 7d15a1a..901d805 100644
>> --- a/include/hw/s390x/s390-ccw.h
>> +++ b/include/hw/s390x/s390-ccw.h
>> @@ -27,6 +27,7 @@ typedef struct S390CCWDevice {
>>       CcwDevice parent_obj;
>>       CssDevId hostid;
>>       char *mdevid;
>> +    int32_t bootindex;
>>   } S390CCWDevice;
>>   
>>   typedef struct S390CCWDeviceClass {
>> diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h
>> new file mode 100644
>> index 0000000..a7d699d
>> --- /dev/null
>> +++ b/include/hw/s390x/vfio-ccw.h
>> @@ -0,0 +1,38 @@
>> +/*
>> + * vfio based subchannel assignment support
>> + *
>> + * Copyright 2018 IBM Corp.
>> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
>> + *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
>> + *            Pierre Morel <pmorel@linux.vnet.ibm.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
>> + * your option) any later version. See the COPYING file in the top-level
>> + * directory.
>> + */
>> +
>> +#ifndef HW_VFIO_CCW_H
>> +#define HW_VFIO_CCW_H
>> +
>> +#include "hw/vfio/vfio-common.h"
>> +#include "hw/s390x/s390-ccw.h"
>> +#include "hw/s390x/ccw-device.h"
>> +
>> +#define TYPE_VFIO_CCW "vfio-ccw"
>> +#define VFIO_CCW(obj) \
>> +        OBJECT_CHECK(VFIOCCWDevice, (obj), TYPE_VFIO_CCW)
>> +
>> +
> 
> Remove one empty line, please.
> 
>> +#define TYPE_VFIO_CCW "vfio-ccw"
>> +typedef struct VFIOCCWDevice {
>> +    S390CCWDevice cdev;
>> +    VFIODevice vdev;
>> +    uint64_t io_region_size;
>> +    uint64_t io_region_offset;
>> +    struct ccw_io_region *io_region;
>> +    EventNotifier io_notifier;
>> +    bool force_orb_pfch;
>> +    bool warned_orb_pfch;
>> +} VFIOCCWDevice;
> 
> Do you really need to make the whole structure public here? If not, I
> think it would be sufficient to only have the "anonymous" typedef here:
> 
> typedef struct VFIOCCWDevice VFIOCCWDevice;
> 
>   Thomas
Perhaps the entire struct is not needed in ipl.c, and we could get by with only the 
typedef. But then the only thing in vfio-ccw.h will be the one line. Seems a little 
confusing to me. What do we gain by doing this?

-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-01-30 22:21   ` Farhan Ali
@ 2019-02-08 16:07     ` Jason J. Herne
  0 siblings, 0 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-02-08 16:07 UTC (permalink / raw)
  To: Farhan Ali, qemu-devel, qemu-s390x, cohuck, pasic, borntraeger

On 1/30/19 5:21 PM, Farhan Ali wrote:
>> ...
>> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
>> index 21f64ad..a993f65 100644
>> --- a/hw/s390x/ipl.c
>> +++ b/hw/s390x/ipl.c
>> @@ -19,6 +19,7 @@
>>   #include "hw/loader.h"
>>   #include "hw/boards.h"
>>   #include "hw/s390x/virtio-ccw.h"
>> +#include "hw/s390x/vfio-ccw.h"
>>   #include "hw/s390x/css.h"
>>   #include "hw/s390x/ebcdic.h"
>>   #include "ipl.h"
>> @@ -311,8 +312,12 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
>>           VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
>>               object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
>>                                   TYPE_VIRTIO_CCW_DEVICE);
>> +        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
>> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>>           if (virtio_ccw_dev) {
>>               ccw_dev = CCW_DEVICE(virtio_ccw_dev);
>> +        } else if (vfio_ccw_dev) {
>> +            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
>>           } else {
>>               SCSIDevice *sd = (SCSIDevice *)
>>                   object_dynamic_cast(OBJECT(dev_st),
>> @@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>>       if (ccw_dev) {
>>           SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
>>                                                               TYPE_SCSI_DEVICE);
>> +        VFIOCCWDevice *vc = (VFIOCCWDevice *)
>> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>>           if (sd) {
>>               ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
>> @@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>>               ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
>>               ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
>>               ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
>> +        } else if (vc) {
>> +            CcwDevice *ccw_dev = CCW_DEVICE(vc);
> 
> Do we need this line here? I though ccw_dev was already correctly casted in 
> s390_get_ccw_device?
> 
>> +
>> +            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
>> +            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
>> +            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
>> +            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
>>           } else {
>>               VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
>>                                                                 TYPE_VIRTIO_NET);
> 

Good catch, we don't need the extra cast. This is a relic of an older way of handling the 
data. I should have removed it when I simplified the code after the RFC version.

-- 
-- Jason J. Herne (jjherne@linux.ibm.com)


^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-02-08 16:04     ` Jason J. Herne
@ 2019-02-11  8:15       ` Cornelia Huck
  2019-02-11  8:39       ` Thomas Huth
  1 sibling, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-11  8:15 UTC (permalink / raw)
  To: Jason J. Herne
  Cc: Thomas Huth, qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Fri, 8 Feb 2019 11:04:29 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/6/19 6:30 AM, Thomas Huth wrote:
> > On 2019-01-29 14:29, Jason J. Herne wrote:  

> >> diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h
> >> new file mode 100644
> >> index 0000000..a7d699d
> >> --- /dev/null
> >> +++ b/include/hw/s390x/vfio-ccw.h
> >> @@ -0,0 +1,38 @@
> >> +/*
> >> + * vfio based subchannel assignment support
> >> + *
> >> + * Copyright 2018 IBM Corp.
> >> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
> >> + *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
> >> + *            Pierre Morel <pmorel@linux.vnet.ibm.com>
> >> + *
> >> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
> >> + * your option) any later version. See the COPYING file in the top-level
> >> + * directory.
> >> + */
> >> +
> >> +#ifndef HW_VFIO_CCW_H
> >> +#define HW_VFIO_CCW_H
> >> +
> >> +#include "hw/vfio/vfio-common.h"
> >> +#include "hw/s390x/s390-ccw.h"
> >> +#include "hw/s390x/ccw-device.h"
> >> +
> >> +#define TYPE_VFIO_CCW "vfio-ccw"
> >> +#define VFIO_CCW(obj) \
> >> +        OBJECT_CHECK(VFIOCCWDevice, (obj), TYPE_VFIO_CCW)
> >> +
> >> +  
> > 
> > Remove one empty line, please.
> >   
> >> +#define TYPE_VFIO_CCW "vfio-ccw"
> >> +typedef struct VFIOCCWDevice {
> >> +    S390CCWDevice cdev;
> >> +    VFIODevice vdev;
> >> +    uint64_t io_region_size;
> >> +    uint64_t io_region_offset;
> >> +    struct ccw_io_region *io_region;
> >> +    EventNotifier io_notifier;
> >> +    bool force_orb_pfch;
> >> +    bool warned_orb_pfch;
> >> +} VFIOCCWDevice;  
> > 
> > Do you really need to make the whole structure public here? If not, I
> > think it would be sufficient to only have the "anonymous" typedef here:
> > 
> > typedef struct VFIOCCWDevice VFIOCCWDevice;
> > 
> >   Thomas  
> Perhaps the entire struct is not needed in ipl.c, and we could get by with only the 
> typedef. But then the only thing in vfio-ccw.h will be the one line. Seems a little 
> confusing to me. What do we gain by doing this?

What parts of VFIOCCWDevice are, in general, interesting to other code
parts? I believe most parts are not potentially useful to anything
else...

The ipl code needs this mainly to find out what kind of device it deals
with. Would it make sense to define a helper function instead and keep
the actual definition private to the vfio-ccw code? That also would
make the intention more clear.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-02-08 16:04     ` Jason J. Herne
  2019-02-11  8:15       ` Cornelia Huck
@ 2019-02-11  8:39       ` Thomas Huth
  1 sibling, 0 replies; 83+ messages in thread
From: Thomas Huth @ 2019-02-11  8:39 UTC (permalink / raw)
  To: jjherne, qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

On 2019-02-08 17:04, Jason J. Herne wrote:
> On 2/6/19 6:30 AM, Thomas Huth wrote:
>> On 2019-01-29 14:29, Jason J. Herne wrote:
>>> Add bootindex property and iplb data for vfio-ccw devices. This
>>> allows us to
>>> forward boot information into the bios for vfio-ccw devices.
>>>
>>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>>> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
>>> ---
>>>   hw/s390x/ipl.c              | 14 ++++++++++++++
>>>   hw/s390x/s390-ccw.c         |  9 +++++++++
>>>   hw/vfio/ccw.c               | 13 +------------
>>>   include/hw/s390x/s390-ccw.h |  1 +
>>>   include/hw/s390x/vfio-ccw.h | 38
>>> ++++++++++++++++++++++++++++++++++++++
>>>   5 files changed, 63 insertions(+), 12 deletions(-)
>>>   create mode 100644 include/hw/s390x/vfio-ccw.h
>>>
>>> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
>>> index 21f64ad..a993f65 100644
>>> --- a/hw/s390x/ipl.c
>>> +++ b/hw/s390x/ipl.c
>>> @@ -19,6 +19,7 @@
>>>   #include "hw/loader.h"
>>>   #include "hw/boards.h"
>>>   #include "hw/s390x/virtio-ccw.h"
>>> +#include "hw/s390x/vfio-ccw.h"
>>>   #include "hw/s390x/css.h"
>>>   #include "hw/s390x/ebcdic.h"
>>>   #include "ipl.h"
>>> @@ -311,8 +312,12 @@ static CcwDevice
>>> *s390_get_ccw_device(DeviceState *dev_st)
>>>           VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
>>>              
>>> object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
>>>                                   TYPE_VIRTIO_CCW_DEVICE);
>>> +        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
>>> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>>>           if (virtio_ccw_dev) {
>>>               ccw_dev = CCW_DEVICE(virtio_ccw_dev);
>>> +        } else if (vfio_ccw_dev) {
>>> +            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
>>>           } else {
>>>               SCSIDevice *sd = (SCSIDevice *)
>>>                   object_dynamic_cast(OBJECT(dev_st),
>>> @@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>>>       if (ccw_dev) {
>>>           SCSIDevice *sd = (SCSIDevice *)
>>> object_dynamic_cast(OBJECT(dev_st),
>>>                                                              
>>> TYPE_SCSI_DEVICE);
>>> +        VFIOCCWDevice *vc = (VFIOCCWDevice *)
>>> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>>>             if (sd) {
>>>               ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
>>> @@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState
>>> *ipl)
>>>               ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
>>>               ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
>>>               ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
>>> +        } else if (vc) {
>>> +            CcwDevice *ccw_dev = CCW_DEVICE(vc);
>>> +
>>> +            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
>>> +            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
>>> +            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
>>> +            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
>>>           } else {
>>>               VirtIONet *vn = (VirtIONet *)
>>> object_dynamic_cast(OBJECT(dev_st),
>>>                                                                
>>> TYPE_VIRTIO_NET);
>>> diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
>>> index cad91ee..f5f025d 100644
>>> --- a/hw/s390x/s390-ccw.c
>>> +++ b/hw/s390x/s390-ccw.c
>>> @@ -124,6 +124,14 @@ static void s390_ccw_unrealize(S390CCWDevice
>>> *cdev, Error **errp)
>>>       g_free(cdev->mdevid);
>>>   }
>>>   +static void s390_ccw_instance_init(Object *obj)
>>> +{
>>> +    S390CCWDevice *dev = S390_CCW_DEVICE(obj);
>>> +
>>> +    device_add_bootindex_property(obj, &dev->bootindex, "bootindex",
>>> +                                  "/disk@0,0", DEVICE(obj), NULL);
>>> +}
>>> +
>>>   static void s390_ccw_class_init(ObjectClass *klass, void *data)
>>>   {
>>>       DeviceClass *dc = DEVICE_CLASS(klass);
>>> @@ -137,6 +145,7 @@ static void s390_ccw_class_init(ObjectClass
>>> *klass, void *data)
>>>   static const TypeInfo s390_ccw_info = {
>>>       .name          = TYPE_S390_CCW,
>>>       .parent        = TYPE_CCW_DEVICE,
>>> +    .instance_init = s390_ccw_instance_init,
>>>       .instance_size = sizeof(S390CCWDevice),
>>>       .class_size    = sizeof(S390CCWDeviceClass),
>>>       .class_init    = s390_ccw_class_init,
>>> diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
>>> index 9246729..d815a4f 100644
>>> --- a/hw/vfio/ccw.c
>>> +++ b/hw/vfio/ccw.c
>>> @@ -21,22 +21,11 @@
>>>   #include "hw/vfio/vfio.h"
>>>   #include "hw/vfio/vfio-common.h"
>>>   #include "hw/s390x/s390-ccw.h"
>>> +#include "hw/s390x/vfio-ccw.h"
>>>   #include "hw/s390x/ccw-device.h"
>>>   #include "exec/address-spaces.h"
>>>   #include "qemu/error-report.h"
>>>   -#define TYPE_VFIO_CCW "vfio-ccw"
>>> -typedef struct VFIOCCWDevice {
>>> -    S390CCWDevice cdev;
>>> -    VFIODevice vdev;
>>> -    uint64_t io_region_size;
>>> -    uint64_t io_region_offset;
>>> -    struct ccw_io_region *io_region;
>>> -    EventNotifier io_notifier;
>>> -    bool force_orb_pfch;
>>> -    bool warned_orb_pfch;
>>> -} VFIOCCWDevice;
>>> -
>>>   static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch,
>>>                                     const char *msg)
>>>   {
>>> diff --git a/include/hw/s390x/s390-ccw.h b/include/hw/s390x/s390-ccw.h
>>> index 7d15a1a..901d805 100644
>>> --- a/include/hw/s390x/s390-ccw.h
>>> +++ b/include/hw/s390x/s390-ccw.h
>>> @@ -27,6 +27,7 @@ typedef struct S390CCWDevice {
>>>       CcwDevice parent_obj;
>>>       CssDevId hostid;
>>>       char *mdevid;
>>> +    int32_t bootindex;
>>>   } S390CCWDevice;
>>>     typedef struct S390CCWDeviceClass {
>>> diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h
>>> new file mode 100644
>>> index 0000000..a7d699d
>>> --- /dev/null
>>> +++ b/include/hw/s390x/vfio-ccw.h
>>> @@ -0,0 +1,38 @@
>>> +/*
>>> + * vfio based subchannel assignment support
>>> + *
>>> + * Copyright 2018 IBM Corp.
>>> + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
>>> + *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
>>> + *            Pierre Morel <pmorel@linux.vnet.ibm.com>
>>> + *
>>> + * This work is licensed under the terms of the GNU GPL, version 2
>>> or (at
>>> + * your option) any later version. See the COPYING file in the
>>> top-level
>>> + * directory.
>>> + */
>>> +
>>> +#ifndef HW_VFIO_CCW_H
>>> +#define HW_VFIO_CCW_H
>>> +
>>> +#include "hw/vfio/vfio-common.h"
>>> +#include "hw/s390x/s390-ccw.h"
>>> +#include "hw/s390x/ccw-device.h"
>>> +
>>> +#define TYPE_VFIO_CCW "vfio-ccw"
>>> +#define VFIO_CCW(obj) \
>>> +        OBJECT_CHECK(VFIOCCWDevice, (obj), TYPE_VFIO_CCW)
>>> +
>>> +
>>
>> Remove one empty line, please.
>>
>>> +#define TYPE_VFIO_CCW "vfio-ccw"
>>> +typedef struct VFIOCCWDevice {
>>> +    S390CCWDevice cdev;
>>> +    VFIODevice vdev;
>>> +    uint64_t io_region_size;
>>> +    uint64_t io_region_offset;
>>> +    struct ccw_io_region *io_region;
>>> +    EventNotifier io_notifier;
>>> +    bool force_orb_pfch;
>>> +    bool warned_orb_pfch;
>>> +} VFIOCCWDevice;
>>
>> Do you really need to make the whole structure public here? If not, I
>> think it would be sufficient to only have the "anonymous" typedef here:
>>
>> typedef struct VFIOCCWDevice VFIOCCWDevice;
>>
>>   Thomas
> Perhaps the entire struct is not needed in ipl.c, and we could get by
> with only the typedef. But then the only thing in vfio-ccw.h will be the
> one line. Seems a little confusing to me. What do we gain by doing this?

That's the coding principle of "information hiding". Don't expose
internal data to other parts of the code if it is not really necessary.
I'm fine with making the structure public here if it is really
necessary, but as far as I can see until now, it's not, so there is also
no need to expose those internal information to other parts of the code.

 Thomas

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices Jason J. Herne
  2019-02-04 10:33   ` Cornelia Huck
@ 2019-02-11 16:38   ` Thomas Huth
  2019-02-13 13:59     ` Jason J. Herne
  1 sibling, 1 reply; 83+ messages in thread
From: Thomas Huth @ 2019-02-11 16:38 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, alifm,
	borntraeger

On 2019-01-29 14:29, Jason J. Herne wrote:
> We need a method for finding the subchannel of a dasd device. Let's
> modify find_dev to handle this since it mostly does what we need. Up to
> this point find_dev has been specific to only virtio devices.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
> ---
>  pc-bios/s390-ccw/main.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index 67df421..7e3f65e 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -49,6 +49,12 @@ unsigned int get_loadparm_index(void)
>      return atoui(loadparm_str);
>  }
>  
> +/*
> + * Find the subchannel connected to the given device (dev_no) and fill in the
> + * subchannel information block (schib) with the connected subchannel's info.
> + * NOTE: The global variable blk_schid is updated to contain the subchannel
> + * information.
> + */
>  static bool find_dev(Schib *schib, int dev_no)
>  {
>      int i, r;
> @@ -62,15 +68,15 @@ static bool find_dev(Schib *schib, int dev_no)
>          if (!schib->pmcw.dnv) {
>              continue;
>          }
> -        if (!virtio_is_supported(blk_schid)) {
> -            continue;
> -        }
> +
>          /* Skip net devices since no IPLB is created and therefore no
> -         * no network bootloader has been loaded
> +         * network bootloader has been loaded
>           */
> -        if (virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
> +        if (virtio_is_supported(blk_schid) &&
> +            virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
>              continue;
>          }
> +
>          if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
>              return true;
>          }
> 

Not sure whether this really works as expected? If dev_no is -1, this
used to return the first supported virtio device. Now it returns the
first device that could be found - but how are we sure that we can boot
from that device?

 Thomas

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path
  2019-02-04 10:45   ` Cornelia Huck
@ 2019-02-11 17:57     ` Jason J. Herne
  2019-02-12  9:32       ` Cornelia Huck
  0 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-02-11 17:57 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On 2/4/19 5:45 AM, Cornelia Huck wrote:
> On Tue, 29 Jan 2019 08:29:12 -0500
> "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> 
>> Make a new routine find_boot_device to locate the boot device for all
>> cases. not just virtio.
> 
> s/cases./cases,/
> 
>>
>> In one case no boot device is specified and a suitable boot device can not
>> be auto detected. The error message for this case was specific to virtio
>> devices. We update this message to remove virtio specific wording.
> 
> "The error message for the case where no boot device has been specified
> and a suitable boot device cannot be auto detected was specific to
> virtio devices. We update..."
> 
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> ---
>>   pc-bios/s390-ccw/main.c  | 87 ++++++++++++++++++++++++++----------------------
>>   tests/boot-serial-test.c |  2 +-
>>   2 files changed, 49 insertions(+), 40 deletions(-)
>>
>> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
>> index 7e3f65e..2457752 100644
>> --- a/pc-bios/s390-ccw/main.c
>> +++ b/pc-bios/s390-ccw/main.c
>> @@ -55,17 +55,18 @@ unsigned int get_loadparm_index(void)
>>    * NOTE: The global variable blk_schid is updated to contain the subchannel
>>    * information.
>>    */
>> -static bool find_dev(Schib *schib, int dev_no)
>> +static bool find_subch(int dev_no)
> 
> I'm wondering why you drop passing in the schib here? But OTOH, the
> usage of global variables or not is a bit confused in the bios anyway...
> 

I dropped it as an argument because the schib was never used outside of find_dev. Seems to 
make sense to make it a local variable in this case.

-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path
  2019-02-11 17:57     ` Jason J. Herne
@ 2019-02-12  9:32       ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-12  9:32 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Mon, 11 Feb 2019 12:57:36 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/4/19 5:45 AM, Cornelia Huck wrote:
> > On Tue, 29 Jan 2019 08:29:12 -0500
> > "Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> >> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> >> index 7e3f65e..2457752 100644
> >> --- a/pc-bios/s390-ccw/main.c
> >> +++ b/pc-bios/s390-ccw/main.c
> >> @@ -55,17 +55,18 @@ unsigned int get_loadparm_index(void)
> >>    * NOTE: The global variable blk_schid is updated to contain the subchannel
> >>    * information.
> >>    */
> >> -static bool find_dev(Schib *schib, int dev_no)
> >> +static bool find_subch(int dev_no)  
> > 
> > I'm wondering why you drop passing in the schib here? But OTOH, the
> > usage of global variables or not is a bit confused in the bios anyway...
> >   
> 
> I dropped it as an argument because the schib was never used outside of find_dev. Seems to 
> make sense to make it a local variable in this case.
> 

Fair enough.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 06/15] s390-bios: Clean up cio.h
  2019-02-04 10:48   ` Cornelia Huck
@ 2019-02-12 12:32     ` Thomas Huth
  0 siblings, 0 replies; 83+ messages in thread
From: Thomas Huth @ 2019-02-12 12:32 UTC (permalink / raw)
  To: Cornelia Huck, Jason J. Herne
  Cc: pasic, borntraeger, qemu-s390x, alifm, qemu-devel

On 2019-02-04 11:48, Cornelia Huck wrote:
> On Tue, 29 Jan 2019 08:29:13 -0500
> "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> 
>> Add proper typedefs to all structs and modify all bit fields to use consistent
>> formatting.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> Reviewed-by: Collin Walling <walling@linux.ibm.com>
>> ---
>>  pc-bios/s390-ccw/cio.h      | 86 ++++++++++++++++++++++-----------------------
>>  pc-bios/s390-ccw/s390-ccw.h |  8 -----
>>  2 files changed, 43 insertions(+), 51 deletions(-)
>>
>> diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
>> index 1a0795f..a48eee5 100644
>> --- a/pc-bios/s390-ccw/cio.h
>> +++ b/pc-bios/s390-ccw/cio.h
>> @@ -53,12 +53,12 @@ struct schib_config {
>>      __u64 mba;
>>      __u32 intparm;
>>      __u16 mbi;
>> -    __u32 isc:3;
>> -    __u32 ena:1;
>> -    __u32 mme:2;
>> -    __u32 mp:1;
>> -    __u32 csense:1;
>> -    __u32 mbfc:1;
>> +    __u32 isc    : 3;
>> +    __u32 ena    : 1;
>> +    __u32 mme    : 2;
>> +    __u32 mp     : 1;
>> +    __u32 csense : 1;
>> +    __u32 mbfc   : 1;
>>  } __attribute__ ((packed));
> 
> This seems to make checkpatch unhappy... maybe consolidate to the other
> formatting instead?

Yeah, you get lots of these errors this way:

ERROR: spaces prohibited around that ':' (ctx:WxW)
#141: FILE: pc-bios/s390-ccw/cio.h:56:
+    __u32 isc    : 3;
                  ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#142: FILE: pc-bios/s390-ccw/cio.h:57:
+    __u32 ena    : 1;
                  ^

ERROR: spaces prohibited around that ':' (ctx:WxW)
#143: FILE: pc-bios/s390-ccw/cio.h:58:
+    __u32 mme    : 2;
                  ^
...

Not sure whether it's a checkpatch warning or really our official coding
style, but anyway, I'd rather prefer to keep checkpatch calm here and
thus no spaces around the ':' please.

 Thomas

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 08/15] s390-bios: Map low core memory
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 08/15] s390-bios: Map low core memory Jason J. Herne
@ 2019-02-12 12:47   ` Thomas Huth
  2019-02-18 15:40     ` Jason J. Herne
  0 siblings, 1 reply; 83+ messages in thread
From: Thomas Huth @ 2019-02-12 12:47 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, alifm,
	borntraeger

On 2019-01-29 14:29, Jason J. Herne wrote:
> Create a new header for basic architecture specific definitions and add a
> mapping of low core memory. This mapping will be used by the real dasd boot
> process.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/main.c      |   2 +
>  pc-bios/s390-ccw/s390-arch.h | 100 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 102 insertions(+)
>  create mode 100644 pc-bios/s390-ccw/s390-arch.h
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index 1bc61b5..fa90aa3 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -9,6 +9,7 @@
>   */
>  
>  #include "libc.h"
> +#include "s390-arch.h"
>  #include "s390-ccw.h"
>  #include "cio.h"
>  #include "virtio.h"
> @@ -19,6 +20,7 @@ static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
>  QemuIplParameters qipl;
>  IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
>  static bool have_iplb;
> +const LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
>  
>  #define LOADPARM_PROMPT "PROMPT  "
>  #define LOADPARM_EMPTY  "        "
> diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
> new file mode 100644
> index 0000000..47eaa04
> --- /dev/null
> +++ b/pc-bios/s390-ccw/s390-arch.h
> @@ -0,0 +1,100 @@
> +/*
> + * S390 Basic Architecture
> + *
> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>

2019 ?

> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
> + * your option) any later version. See the COPYING file in the top-level
> + * directory.
> + */
> +
> +#ifndef S390_ARCH_H
> +#define S390_ARCH_H
> +
> +typedef struct PSW {
> +    uint64_t mask;
> +    uint64_t addr;
> +} __attribute__ ((packed, aligned(8))) PSW;

We've seen quite some trouble with "packed" in the past... See
3b8afb41bc8e or 55281a2c53b884d0 for example ... This is only the
s390-ccw bios code here, so it is likely ok, but still, since this
structure is "naturally" packed, I'd rather go without that attribute
here (even if it's only to allow the compiler to generate better code in
some cases). You could still _Static_assert(sizeof(struct PSW) == 16)
afterwards, just to be sure.

> +
> +/* Older PSW format used by LPSW instruction */
> +typedef struct PSWLegacy {
> +    uint32_t mask;
> +    uint32_t addr;
> +} __attribute__ ((packed, aligned(8))) PSWLegacy;

dito, I'd drop the packed attribute here.

> +/* s390 psw bit masks */
> +#define PSW_MASK_IOINT      0x0200000000000000ULL
> +#define PSW_MASK_WAIT       0x0002000000000000ULL
> +#define PSW_MASK_EAMODE     0x0000000100000000ULL
> +#define PSW_MASK_BAMODE     0x0000000080000000ULL
> +#define PSW_MASK_ZMODE      (PSW_MASK_EAMODE | PSW_MASK_BAMODE)
> +
> +/* Low core mapping */
> +typedef struct LowCore {
> +    /* prefix area: defined by architecture */
> +    uint64_t        ipl_psw;                  /* 0x000 */

No PSWLegacy here? ;-)

> +    uint32_t        ccw1[2];                  /* 0x008 */
> +    uint32_t        ccw2[2];                  /* 0x010 */
> +    uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
> +    uint32_t        ext_params;               /* 0x080 */
> +    uint16_t        cpu_addr;                 /* 0x084 */
> +    uint16_t        ext_int_code;             /* 0x086 */
> +    uint16_t        svc_ilen;                 /* 0x088 */
> +    uint16_t        svc_code;                 /* 0x08a */
> +    uint16_t        pgm_ilen;                 /* 0x08c */
> +    uint16_t        pgm_code;                 /* 0x08e */
> +    uint32_t        data_exc_code;            /* 0x090 */
> +    uint16_t        mon_class_num;            /* 0x094 */
> +    uint16_t        per_perc_atmid;           /* 0x096 */
> +    uint64_t        per_address;              /* 0x098 */
> +    uint8_t         exc_access_id;            /* 0x0a0 */
> +    uint8_t         per_access_id;            /* 0x0a1 */
> +    uint8_t         op_access_id;             /* 0x0a2 */
> +    uint8_t         ar_access_id;             /* 0x0a3 */
> +    uint8_t         pad2[0xA8 - 0xA4];        /* 0x0a4 */
> +    uint64_t        trans_exc_code;           /* 0x0a8 */
> +    uint64_t        monitor_code;             /* 0x0b0 */
> +    uint16_t        subchannel_id;            /* 0x0b8 */
> +    uint16_t        subchannel_nr;            /* 0x0ba */
> +    uint32_t        io_int_parm;              /* 0x0bc */
> +    uint32_t        io_int_word;              /* 0x0c0 */
> +    uint8_t         pad3[0xc8 - 0xc4];        /* 0x0c4 */
> +    uint32_t        stfl_fac_list;            /* 0x0c8 */
> +    uint8_t         pad4[0xe8 - 0xcc];        /* 0x0cc */
> +    uint64_t        mcic;                     /* 0x0e8 */
> +    uint8_t         pad5[0xf4 - 0xf0];        /* 0x0f0 */
> +    uint32_t        external_damage_code;     /* 0x0f4 */
> +    uint64_t        failing_storage_address;  /* 0x0f8 */
> +    uint8_t         pad6[0x110 - 0x100];      /* 0x100 */
> +    uint64_t        per_breaking_event_addr;  /* 0x110 */
> +    uint8_t         pad7[0x120 - 0x118];      /* 0x118 */
> +    PSW             restart_old_psw;          /* 0x120 */
> +    PSW             external_old_psw;         /* 0x130 */
> +    PSW             svc_old_psw;              /* 0x140 */
> +    PSW             program_old_psw;          /* 0x150 */
> +    PSW             mcck_old_psw;             /* 0x160 */
> +    PSW             io_old_psw;               /* 0x170 */
> +    uint8_t         pad8[0x1a0 - 0x180];      /* 0x180 */
> +    PSW             restart_new_psw;          /* 0x1a0 */
> +    PSW             external_new_psw;         /* 0x1b0 */
> +    PSW             svc_new_psw;              /* 0x1c0 */
> +    PSW             program_new_psw;          /* 0x1d0 */
> +    PSW             mcck_new_psw;             /* 0x1e0 */
> +    PSW             io_new_psw;               /* 0x1f0 */
> +    PSW             return_psw;               /* 0x200 */
> +    uint8_t         irb[64];                  /* 0x210 */
> +    uint64_t        sync_enter_timer;         /* 0x250 */
> +    uint64_t        async_enter_timer;        /* 0x258 */
> +    uint64_t        exit_timer;               /* 0x260 */
> +    uint64_t        last_update_timer;        /* 0x268 */
> +    uint64_t        user_timer;               /* 0x270 */
> +    uint64_t        system_timer;             /* 0x278 */
> +    uint64_t        last_update_clock;        /* 0x280 */
> +    uint64_t        steal_clock;              /* 0x288 */
> +    PSW             return_mcck_psw;          /* 0x290 */
> +    uint8_t         pad9[0xc00 - 0x2a0];      /* 0x2a0 */
> +} __attribute__((packed, aligned(8192))) LowCore;

dito, please avoid packed, use _Static_assert instead.

> +extern const LowCore *lowcore;
> +
> +#endif

 Thomas

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 09/15] s390-bios: ptr2u32 and u32toptr
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 09/15] s390-bios: ptr2u32 and u32toptr Jason J. Herne
  2019-02-04 11:03   ` Cornelia Huck
@ 2019-02-12 12:50   ` Thomas Huth
  1 sibling, 0 replies; 83+ messages in thread
From: Thomas Huth @ 2019-02-12 12:50 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, alifm,
	borntraeger

On 2019-01-29 14:29, Jason J. Herne wrote:
> Introduce inline functions to convert between pointers and unsigned 32-bit
> ints. These are used to hide the ugliness required to  avoid compiler
> warnings.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/libc.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h
> index 818517f..e198f0b 100644
> --- a/pc-bios/s390-ccw/libc.h
> +++ b/pc-bios/s390-ccw/libc.h
> @@ -19,6 +19,18 @@ typedef unsigned short     uint16_t;
>  typedef unsigned int       uint32_t;
>  typedef unsigned long long uint64_t;
>  
> +/* Avoids compiler warnings when casting a pointer to a u32 */
> +static inline uint32_t ptr2u32(void *ptr)
> +{
> +    return (uint32_t)(uint64_t)ptr;
> +}
> +
> +/* Avoids compiler warnings when casting a u32 to a pointer */
> +static inline void *u32toptr(uint32_t n)
> +{
> +    return (void *)(uint64_t)n;
> +}

Could you please put this into another header? libc.h is for
standard-compliant libc functions, and these are no standard functions,
as far as I know.

 Thanks,
  Thomas

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-05 10:18         ` Cornelia Huck
@ 2019-02-12 13:10           ` Halil Pasic
  2019-02-27 13:35           ` Jason J. Herne
  1 sibling, 0 replies; 83+ messages in thread
From: Halil Pasic @ 2019-02-12 13:10 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Farhan Ali, Jason J. Herne, qemu-devel, qemu-s390x, borntraeger

On Tue, 5 Feb 2019 11:18:38 +0100
Cornelia Huck <cohuck@redhat.com> wrote:

> On Mon, 4 Feb 2019 14:29:18 -0500
> Farhan Ali <alifm@linux.ibm.com> wrote:
> 
> > On 02/04/2019 06:13 AM, Cornelia Huck wrote:
> > > On Thu, 31 Jan 2019 12:31:00 -0500
> > > Farhan Ali <alifm@linux.ibm.com> wrote:
> > >   
> > >> On 01/29/2019 08:29 AM, Jason J. Herne wrote:  
> > >>> Add struct for format-0 ccws. Support executing format-0 channel
> > >>> programs and waiting for their completion before continuing execution.
> > >>> This will be used for real dasd ipl.
> > >>>
> > >>> Add cu_type() to channel io library. This will be used to query control
> > >>> unit type which is used to determine if we are booting a virtio device or a
> > >>> real dasd device.
> > >>>
> > >>> Signed-off-by: Jason J. Herne<jjherne@linux.ibm.com>
> > >>> ---
> > >>>    pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
> > >>>    pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
> > >>>    pc-bios/s390-ccw/s390-ccw.h |   1 +
> > >>>    pc-bios/s390-ccw/start.S    |  33 +++++++++++-
> > >>>    4 files changed, 270 insertions(+), 5 deletions(-)  
> > >   
> > >>> +/*
> > >>> + * Executes a channel program at a given subchannel. The request to run the
> > >>> + * channel program is sent to the subchannel, we then wait for the interrupt
> > >>> + * signaling completion of the I/O operation(s) performed by the channel
> > >>> + * program. Lastly we verify that the i/o operation completed without error and
> > >>> + * that the interrupt we received was for the subchannel used to run the
> > >>> + * channel program.
> > >>> + *
> > >>> + * Note: This function assumes it is running in an environment where no other
> > >>> + * cpus are generating or receiving I/O interrupts. So either run it in a
> > >>> + * single-cpu environment or make sure all other cpus are not doing I/O and
> > >>> + * have I/O interrupts masked off.
> > >>> + */
> > >>> +int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
> > >>> +{
> > >>> +    CmdOrb orb = {};
> > >>> +    Irb irb = {};
> > >>> +    sense_data_eckd_dasd sd;
> > >>> +    int rc, retries = 0;
> > >>> +
> > >>> +    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
> > >>> +
> > >>> +    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
> > >>> +    if (fmt == 0) {
> > >>> +        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
> > >>> +    }
> > >>> +
> > >>> +    orb.fmt = fmt ;
> > >>> +    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
> > >>> +    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
> > >>> +    orb.lpm = 0xFF; /* All paths allowed */
> > >>> +    orb.cpa = ccw_addr;
> > >>> +
> > >>> +    while (true) {
> > >>> +        rc = ssch(schid, &orb);
> > >>> +        if (rc == 1) {
> > >>> +            /* Status pending, not sure why. Let's eat the status and retry. */
> > >>> +            tsch(schid, &irb);
> > >>> +            retries++;
> > >>> +            continue;
> > >>> +        }
> > >>> +        if (rc) {
> > >>> +            print_int("ssch failed with rc=", rc);
> > >>> +            break;
> > >>> +        }
> > >>> +
> > >>> +        consume_io_int();
> > >>> +
> > >>> +        /* collect status */
> > >>> +        rc = tsch(schid, &irb);
> > >>> +        if (rc) {
> > >>> +            print_int("tsch failed with rc=", rc);
> > >>> +            break;
> > >>> +        }
> > >>> +
> > >>> +        if (!irb_error(&irb)) {
> > >>> +            break;
> > >>> +        }
> > >>> +
> > >>> +        /*
> > >>> +         * Unexpected unit check, or interface-control-check. Use sense to
> > >>> +         * clear unit check then retry.
> > >>> +         */
> > >>> +        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
> > >>> +            basic_sense(schid, &sd, sizeof(sd));  
> > >>
> > >> We are using basic sense to clear any unit check or ifcc, but is it
> > >> possible for the basic sense to cause another unit check?
> > >>
> > >> The chapter on Basic Sense in the Common I/O Device Commands
> > >> (http://publibz.boulder.ibm.com/support/libraryserver/FRAMESET/dz9ar501/2.1?SHELF=&DT=19920409154647&CASE=)
> > >>    says this:
> > >>
> > >> ""
> > >> The basic sense command initiates a sense operation  at  all  devices
> > >> and cannot  cause  the  command-reject,  intervention-required,
> > >> data-check, or overrun bit to be set to one.  If the control unit
> > >> detects  an  equipment malfunction  or  invalid  checking-block  code
> > >> (CBC) on the sense-command code, the equipment-check or bus-out-check
> > >> bit is set  to  one,  and  unit check is indicated in the device-status
> > >> byte.
> > >> ""
> > >>
> > >> If my understanding is correct, if there is an equipment malfunction
> > >> then the control unit can return a unit check even for a basic sense.
> > >> This can lead to infinite recursion in the bios.  
> > > 
> > > I think the retries variable is supposed to take care of that.
> > >   
> > 
> > If I understand the code correctly, the retries variable cannot prevent 
> > infinite recursion. Because every time we get a unit check we do a basic 
> > sense which calls the do_cio function again. If that basic sense returns 
> > a unit check we do another basic sense....
> 
> Eww, you're right...
> 
> I think that the routine needs to be split:
> - inner routine that does the ssch, retries if the subchannel is status
>   pending, and waits for a final status (regardless whether it is a
>   special condition or not)
> - outer routine that does error handling, if needed (like retrying on
>   IFCC, or doing a basic sense on unit check)
> 
> The inner routine will probably only be called by the outer routine
> (and not directly by other code).
> 
> Does that make sense? It's hopefully enough; we really don't want to
> transplant the whole Linux cio state machine into the bios...
> 

IMHO we should orient ourselves after the corresponding section in the
PoP. We do have this reset notification we have to work around though,
but for that one sense and retry should work.

Regards,
Halil

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-02-04 10:26   ` Cornelia Huck
@ 2019-02-13 13:41     ` Jason J. Herne
  2019-02-13 14:52       ` Cornelia Huck
  0 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-02-13 13:41 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger, Thomas Huth

On 2/4/19 5:26 AM, Cornelia Huck wrote:
> On Tue, 29 Jan 2019 08:29:08 -0500
> "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> 
>> Add bootindex property and iplb data for vfio-ccw devices. This allows us to
>> forward boot information into the bios for vfio-ccw devices.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
>> ---
>>   hw/s390x/ipl.c              | 14 ++++++++++++++
>>   hw/s390x/s390-ccw.c         |  9 +++++++++
>>   hw/vfio/ccw.c               | 13 +------------
>>   include/hw/s390x/s390-ccw.h |  1 +
>>   include/hw/s390x/vfio-ccw.h | 38 ++++++++++++++++++++++++++++++++++++++
>>   5 files changed, 63 insertions(+), 12 deletions(-)
>>   create mode 100644 include/hw/s390x/vfio-ccw.h
>>
>> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
>> index 21f64ad..a993f65 100644
>> --- a/hw/s390x/ipl.c
>> +++ b/hw/s390x/ipl.c
>> @@ -19,6 +19,7 @@
>>   #include "hw/loader.h"
>>   #include "hw/boards.h"
>>   #include "hw/s390x/virtio-ccw.h"
>> +#include "hw/s390x/vfio-ccw.h"
>>   #include "hw/s390x/css.h"
>>   #include "hw/s390x/ebcdic.h"
>>   #include "ipl.h"
>> @@ -311,8 +312,12 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
>>           VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
>>               object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
>>                                   TYPE_VIRTIO_CCW_DEVICE);
>> +        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
>> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>>           if (virtio_ccw_dev) {
>>               ccw_dev = CCW_DEVICE(virtio_ccw_dev);
>> +        } else if (vfio_ccw_dev) {
>> +            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
>>           } else {
>>               SCSIDevice *sd = (SCSIDevice *)
>>                   object_dynamic_cast(OBJECT(dev_st),
>> @@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>>       if (ccw_dev) {
>>           SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
>>                                                               TYPE_SCSI_DEVICE);
>> +        VFIOCCWDevice *vc = (VFIOCCWDevice *)
>> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
>>   
>>           if (sd) {
>>               ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
>> @@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
>>               ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
>>               ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
>>               ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
>> +        } else if (vc) {
>> +            CcwDevice *ccw_dev = CCW_DEVICE(vc);
>> +
>> +            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
>> +            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
>> +            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
>> +            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
>>           } else {
>>               VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
>>                                                                 TYPE_VIRTIO_NET);
> 
> Hm, I think that this find-out-the-boot-type-and-set-up-the-right-thing
> mechanism is getting a bit unwieldy. Basically, we
> 
> - call s390_get_ccw_device() to find out the device type via a bunch of
>    casts and return a pointer to a CcwDevice if it's a supported type
> - do a bunch of casts here *again* to find out what we have and fill
>    out the iplb, while we really only need to do grab a non-CcwDevice
>    for the scsi case
> 
> Should maybe s390_get_ccw_device() give us an ipl type in addition to
> the pointer to the CcwDevice, so we can use a switch/case statement to
> fill out the iplb here?

I think this idea makes sense. s390_ipl_reset_request also calls s390_get_ccw_device but 
does not care bout the device type, so how about a separate function instead of 
integrating it with s390_get_ccw_device? Maybe s390_get_ccw_device_type?

Is there any easy way to grab the type or are we just hiding the ugly casting inside our 
helper function?


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices
  2019-02-11 16:38   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
@ 2019-02-13 13:59     ` Jason J. Herne
  2019-03-04 19:23       ` Thomas Huth
  0 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-02-13 13:59 UTC (permalink / raw)
  To: Thomas Huth, qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

On 2/11/19 11:38 AM, Thomas Huth wrote:
> On 2019-01-29 14:29, Jason J. Herne wrote:
>> We need a method for finding the subchannel of a dasd device. Let's
>> modify find_dev to handle this since it mostly does what we need. Up to
>> this point find_dev has been specific to only virtio devices.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
>> ---
>>   pc-bios/s390-ccw/main.c | 16 +++++++++++-----
>>   1 file changed, 11 insertions(+), 5 deletions(-)
>>
>> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
>> index 67df421..7e3f65e 100644
>> --- a/pc-bios/s390-ccw/main.c
>> +++ b/pc-bios/s390-ccw/main.c
>> @@ -49,6 +49,12 @@ unsigned int get_loadparm_index(void)
>>       return atoui(loadparm_str);
>>   }
>>   
>> +/*
>> + * Find the subchannel connected to the given device (dev_no) and fill in the
>> + * subchannel information block (schib) with the connected subchannel's info.
>> + * NOTE: The global variable blk_schid is updated to contain the subchannel
>> + * information.
>> + */
>>   static bool find_dev(Schib *schib, int dev_no)
>>   {
>>       int i, r;
>> @@ -62,15 +68,15 @@ static bool find_dev(Schib *schib, int dev_no)
>>           if (!schib->pmcw.dnv) {
>>               continue;
>>           }
>> -        if (!virtio_is_supported(blk_schid)) {
>> -            continue;
>> -        }
>> +
>>           /* Skip net devices since no IPLB is created and therefore no
>> -         * no network bootloader has been loaded
>> +         * network bootloader has been loaded
>>            */
>> -        if (virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
>> +        if (virtio_is_supported(blk_schid) &&
>> +            virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
>>               continue;
>>           }
>> +
>>           if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
>>               return true;
>>           }
>>
> 
> Not sure whether this really works as expected? If dev_no is -1, this
> used to return the first supported virtio device. Now it returns the
> first device that could be found - but how are we sure that we can boot
> from that device?
> 

How could we ever be sure we could boot from the first virtio device? The dev_no=1 case 
means we don't know which device to boot from so we're guessing.  The only thing that is 
changing here is that we're allowing non-virtio devices as well. We do this because we now 
support booting from a device type that is not virtio.


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio
  2019-02-04 10:57   ` Cornelia Huck
@ 2019-02-13 14:40     ` Jason J. Herne
  0 siblings, 0 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-02-13 14:40 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On 2/4/19 5:57 AM, Cornelia Huck wrote:
> On Tue, 29 Jan 2019 08:29:14 -0500
> "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> 
>> Create a separate library for channel i/o related code. This decouples
>> channel i/o operations from virtio and allows us to make use of them for
>> the real dasd boot path.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> ---
>>   pc-bios/s390-ccw/Makefile        |  2 +-
>>   pc-bios/s390-ccw/cio.c           | 41 ++++++++++++++++++++++++++++++++++++++++
>>   pc-bios/s390-ccw/cio.h           |  3 +++
>>   pc-bios/s390-ccw/main.c          |  1 +
>>   pc-bios/s390-ccw/netboot.mak     |  2 +-
>>   pc-bios/s390-ccw/netmain.c       |  1 +
>>   pc-bios/s390-ccw/s390-ccw.h      |  1 -
>>   pc-bios/s390-ccw/virtio-blkdev.c |  1 +
>>   pc-bios/s390-ccw/virtio.c        | 27 ++------------------------
>>   9 files changed, 51 insertions(+), 28 deletions(-)
>>   create mode 100644 pc-bios/s390-ccw/cio.c
>>
> 
>> diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
>> new file mode 100644
>> index 0000000..095f79b
>> --- /dev/null
>> +++ b/pc-bios/s390-ccw/cio.c
>> @@ -0,0 +1,41 @@
>> +/*
>> + * S390 Channel I/O
>> + *
>> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
>> + * your option) any later version. See the COPYING file in the top-level
>> + * directory.
>> + */
> 
> Not sure that copyright header is correct. You moved some code that
> probably should be copyright IBM (although that was never added to the
> header in the first place...) Also not sure if Alex has some copyrights
> on the code you moved, or if that is only trivial stuff. (Don't want to
> be difficult, but we should try to get this right.)
> 
>> +
>> +#include "libc.h"
>> +#include "s390-ccw.h"
>> +#include "cio.h"
>> +
>> +static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
>> +
>> +int enable_mss_facility(void)
>> +{
>> +    int ret;
>> +    ChscAreaSda *sda_area = (ChscAreaSda *) chsc_page;
>> +
>> +    memset(sda_area, 0, PAGE_SIZE);
>> +    sda_area->request.length = 0x0400;
>> +    sda_area->request.code = 0x0031;
>> +    sda_area->operation_code = 0x2;
>> +
>> +    ret = chsc(sda_area);
>> +    if ((ret == 0) && (sda_area->response.code == 0x0001)) {
>> +        return 0;
>> +    }
>> +    return -EIO;
>> +}
>> +
>> +void enable_subchannel(SubChannelId schid)
>> +{
>> +    Schib schib;
>> +
>> +    stsch_err(schid, &schib);
>> +    schib.pmcw.ena = 1;
>> +    msch(schid, &schib);
>> +}
> 
> (...)
> 
>> diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
>> index 11c5626..d2e7fcd 100644
>> --- a/pc-bios/s390-ccw/virtio-blkdev.c
>> +++ b/pc-bios/s390-ccw/virtio-blkdev.c
>> @@ -10,6 +10,7 @@
>>   
>>   #include "libc.h"
>>   #include "s390-ccw.h"
>> +#include "cio.h"
> 
> Not sure why you need to add this here?

Hmmm... I removed it and the code compiles cleanly... I was *sure* I needed this a while 
go. Perhaps something changed? --
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data
  2019-02-13 13:41     ` Jason J. Herne
@ 2019-02-13 14:52       ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-13 14:52 UTC (permalink / raw)
  To: Jason J. Herne
  Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger, Thomas Huth

On Wed, 13 Feb 2019 08:41:43 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/4/19 5:26 AM, Cornelia Huck wrote:
> > On Tue, 29 Jan 2019 08:29:08 -0500
> > "Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> >> @@ -311,8 +312,12 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
> >>           VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
> >>               object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
> >>                                   TYPE_VIRTIO_CCW_DEVICE);
> >> +        VFIOCCWDevice *vfio_ccw_dev = (VFIOCCWDevice *)
> >> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
> >>           if (virtio_ccw_dev) {
> >>               ccw_dev = CCW_DEVICE(virtio_ccw_dev);
> >> +        } else if (vfio_ccw_dev) {
> >> +            ccw_dev = CCW_DEVICE(vfio_ccw_dev);
> >>           } else {
> >>               SCSIDevice *sd = (SCSIDevice *)
> >>                   object_dynamic_cast(OBJECT(dev_st),
> >> @@ -347,6 +352,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
> >>       if (ccw_dev) {
> >>           SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
> >>                                                               TYPE_SCSI_DEVICE);
> >> +        VFIOCCWDevice *vc = (VFIOCCWDevice *)
> >> +            object_dynamic_cast(OBJECT(dev_st), TYPE_VFIO_CCW);
> >>   
> >>           if (sd) {
> >>               ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
> >> @@ -358,6 +365,13 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
> >>               ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
> >>               ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
> >>               ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
> >> +        } else if (vc) {
> >> +            CcwDevice *ccw_dev = CCW_DEVICE(vc);
> >> +
> >> +            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
> >> +            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
> >> +            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
> >> +            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
> >>           } else {
> >>               VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
> >>                                                                 TYPE_VIRTIO_NET);  
> > 
> > Hm, I think that this find-out-the-boot-type-and-set-up-the-right-thing
> > mechanism is getting a bit unwieldy. Basically, we
> > 
> > - call s390_get_ccw_device() to find out the device type via a bunch of
> >    casts and return a pointer to a CcwDevice if it's a supported type
> > - do a bunch of casts here *again* to find out what we have and fill
> >    out the iplb, while we really only need to do grab a non-CcwDevice
> >    for the scsi case
> > 
> > Should maybe s390_get_ccw_device() give us an ipl type in addition to
> > the pointer to the CcwDevice, so we can use a switch/case statement to
> > fill out the iplb here?  
> 
> I think this idea makes sense. s390_ipl_reset_request also calls s390_get_ccw_device but 
> does not care bout the device type, so how about a separate function instead of 
> integrating it with s390_get_ccw_device? Maybe s390_get_ccw_device_type?

If I understand it correctly, we always want to be able to grab a
CcwDevice if supported and for generating the iplb, we also need to
know the actual type of the device. We basically need to follow the
same procedure for both; so it probably makes most sense to have one
function that provides both (the reset code can simply disregard the
type).

> Is there any easy way to grab the type or are we just hiding the ugly casting inside our 
> helper function?

I'm not aware of an alternative to the casting, so the helper function
would just hide the ugliness, I guess...

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 08/15] s390-bios: Map low core memory
  2019-02-12 12:47   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
@ 2019-02-18 15:40     ` Jason J. Herne
  2019-02-18 15:49       ` Cornelia Huck
  2019-02-18 16:52       ` Thomas Huth
  0 siblings, 2 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-02-18 15:40 UTC (permalink / raw)
  To: Thomas Huth, qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

On 2/12/19 7:47 AM, Thomas Huth wrote:
> On 2019-01-29 14:29, Jason J. Herne wrote:
>> Create a new header for basic architecture specific definitions and add a
>> mapping of low core memory. This mapping will be used by the real dasd boot
>> process.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> ---
>>   pc-bios/s390-ccw/main.c      |   2 +
>>   pc-bios/s390-ccw/s390-arch.h | 100 +++++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 102 insertions(+)
>>   create mode 100644 pc-bios/s390-ccw/s390-arch.h
>>
>> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
>> index 1bc61b5..fa90aa3 100644
>> --- a/pc-bios/s390-ccw/main.c
>> +++ b/pc-bios/s390-ccw/main.c
>> @@ -9,6 +9,7 @@
>>    */
>>   
>>   #include "libc.h"
>> +#include "s390-arch.h"
>>   #include "s390-ccw.h"
>>   #include "cio.h"
>>   #include "virtio.h"
>> @@ -19,6 +20,7 @@ static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
>>   QemuIplParameters qipl;
>>   IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
>>   static bool have_iplb;
>> +const LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
>>   
>>   #define LOADPARM_PROMPT "PROMPT  "
>>   #define LOADPARM_EMPTY  "        "
>> diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
>> new file mode 100644
>> index 0000000..47eaa04
>> --- /dev/null
>> +++ b/pc-bios/s390-ccw/s390-arch.h
>> @@ -0,0 +1,100 @@
>> +/*
>> + * S390 Basic Architecture
>> + *
>> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
> 
> 2019 ?
> 

Yep, I will update this,

>> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
>> + * your option) any later version. See the COPYING file in the top-level
>> + * directory.
>> + */
>> +
>> +#ifndef S390_ARCH_H
>> +#define S390_ARCH_H
>> +
>> +typedef struct PSW {
>> +    uint64_t mask;
>> +    uint64_t addr;
>> +} __attribute__ ((packed, aligned(8))) PSW;
> 
> We've seen quite some trouble with "packed" in the past... See
> 3b8afb41bc8e or 55281a2c53b884d0 for example ... This is only the
> s390-ccw bios code here, so it is likely ok, but still, since this
> structure is "naturally" packed, I'd rather go without that attribute
> here (even if it's only to allow the compiler to generate better code in
> some cases). You could still _Static_assert(sizeof(struct PSW) == 16)
> afterwards, just to be sure.
> 

So the problem is that this struct, if baked into another struct, will not be aligned 
properly? Given that this struct is only two 64-bit fields I guess we could get away 
without packed.

>> +
>> +/* Older PSW format used by LPSW instruction */
>> +typedef struct PSWLegacy {
>> +    uint32_t mask;
>> +    uint32_t addr;
>> +} __attribute__ ((packed, aligned(8))) PSWLegacy;
> 
> dito, I'd drop the packed attribute here.
> 

Are we sure the compiler will never insert space here if we drop packed? I don't see why 
it would but I'll admit that I don't fully know all of the rules.

>> +/* s390 psw bit masks */
>> +#define PSW_MASK_IOINT      0x0200000000000000ULL
>> +#define PSW_MASK_WAIT       0x0002000000000000ULL
>> +#define PSW_MASK_EAMODE     0x0000000100000000ULL
>> +#define PSW_MASK_BAMODE     0x0000000080000000ULL
>> +#define PSW_MASK_ZMODE      (PSW_MASK_EAMODE | PSW_MASK_BAMODE)
>> +
>> +/* Low core mapping */
>> +typedef struct LowCore {
>> +    /* prefix area: defined by architecture */
>> +    uint64_t        ipl_psw;                  /* 0x000 */
> 
> No PSWLegacy here? ;-)
> 

I could *probably* use PSWLegacy here.

>> +    uint32_t        ccw1[2];                  /* 0x008 */
>> +    uint32_t        ccw2[2];                  /* 0x010 */
>> +    uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
>> +    uint32_t        ext_params;               /* 0x080 */
>> +    uint16_t        cpu_addr;                 /* 0x084 */
>> +    uint16_t        ext_int_code;             /* 0x086 */
>> +    uint16_t        svc_ilen;                 /* 0x088 */
>> +    uint16_t        svc_code;                 /* 0x08a */
>> +    uint16_t        pgm_ilen;                 /* 0x08c */
>> +    uint16_t        pgm_code;                 /* 0x08e */
>> +    uint32_t        data_exc_code;            /* 0x090 */
>> +    uint16_t        mon_class_num;            /* 0x094 */
>> +    uint16_t        per_perc_atmid;           /* 0x096 */
>> +    uint64_t        per_address;              /* 0x098 */
>> +    uint8_t         exc_access_id;            /* 0x0a0 */
>> +    uint8_t         per_access_id;            /* 0x0a1 */
>> +    uint8_t         op_access_id;             /* 0x0a2 */
>> +    uint8_t         ar_access_id;             /* 0x0a3 */
>> +    uint8_t         pad2[0xA8 - 0xA4];        /* 0x0a4 */
>> +    uint64_t        trans_exc_code;           /* 0x0a8 */
>> +    uint64_t        monitor_code;             /* 0x0b0 */
>> +    uint16_t        subchannel_id;            /* 0x0b8 */
>> +    uint16_t        subchannel_nr;            /* 0x0ba */
>> +    uint32_t        io_int_parm;              /* 0x0bc */
>> +    uint32_t        io_int_word;              /* 0x0c0 */
>> +    uint8_t         pad3[0xc8 - 0xc4];        /* 0x0c4 */
>> +    uint32_t        stfl_fac_list;            /* 0x0c8 */
>> +    uint8_t         pad4[0xe8 - 0xcc];        /* 0x0cc */
>> +    uint64_t        mcic;                     /* 0x0e8 */
>> +    uint8_t         pad5[0xf4 - 0xf0];        /* 0x0f0 */
>> +    uint32_t        external_damage_code;     /* 0x0f4 */
>> +    uint64_t        failing_storage_address;  /* 0x0f8 */
>> +    uint8_t         pad6[0x110 - 0x100];      /* 0x100 */
>> +    uint64_t        per_breaking_event_addr;  /* 0x110 */
>> +    uint8_t         pad7[0x120 - 0x118];      /* 0x118 */
>> +    PSW             restart_old_psw;          /* 0x120 */
>> +    PSW             external_old_psw;         /* 0x130 */
>> +    PSW             svc_old_psw;              /* 0x140 */
>> +    PSW             program_old_psw;          /* 0x150 */
>> +    PSW             mcck_old_psw;             /* 0x160 */
>> +    PSW             io_old_psw;               /* 0x170 */
>> +    uint8_t         pad8[0x1a0 - 0x180];      /* 0x180 */
>> +    PSW             restart_new_psw;          /* 0x1a0 */
>> +    PSW             external_new_psw;         /* 0x1b0 */
>> +    PSW             svc_new_psw;              /* 0x1c0 */
>> +    PSW             program_new_psw;          /* 0x1d0 */
>> +    PSW             mcck_new_psw;             /* 0x1e0 */
>> +    PSW             io_new_psw;               /* 0x1f0 */
>> +    PSW             return_psw;               /* 0x200 */
>> +    uint8_t         irb[64];                  /* 0x210 */
>> +    uint64_t        sync_enter_timer;         /* 0x250 */
>> +    uint64_t        async_enter_timer;        /* 0x258 */
>> +    uint64_t        exit_timer;               /* 0x260 */
>> +    uint64_t        last_update_timer;        /* 0x268 */
>> +    uint64_t        user_timer;               /* 0x270 */
>> +    uint64_t        system_timer;             /* 0x278 */
>> +    uint64_t        last_update_clock;        /* 0x280 */
>> +    uint64_t        steal_clock;              /* 0x288 */
>> +    PSW             return_mcck_psw;          /* 0x290 */
>> +    uint8_t         pad9[0xc00 - 0x2a0];      /* 0x2a0 */
>> +} __attribute__((packed, aligned(8192))) LowCore;
> 
> dito, please avoid packed, use _Static_assert instead.
> 

I'm not convinced this is a good thing to do. Lowcore freely mixes fields of size 64, 32, 
and 8 bits. If we drop packed then the compiler will perform all sorts of automatic 
alignment thereby completely messing up offsets.


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 08/15] s390-bios: Map low core memory
  2019-02-18 15:40     ` Jason J. Herne
@ 2019-02-18 15:49       ` Cornelia Huck
  2019-02-18 16:52       ` Thomas Huth
  1 sibling, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-18 15:49 UTC (permalink / raw)
  To: Jason J. Herne
  Cc: Thomas Huth, qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Mon, 18 Feb 2019 10:40:45 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/12/19 7:47 AM, Thomas Huth wrote:
> > On 2019-01-29 14:29, Jason J. Herne wrote:  
> >> Create a new header for basic architecture specific definitions and add a
> >> mapping of low core memory. This mapping will be used by the real dasd boot
> >> process.
> >>
> >> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> >> ---
> >>   pc-bios/s390-ccw/main.c      |   2 +
> >>   pc-bios/s390-ccw/s390-arch.h | 100 +++++++++++++++++++++++++++++++++++++++++++
> >>   2 files changed, 102 insertions(+)
> >>   create mode 100644 pc-bios/s390-ccw/s390-arch.h
> >>

> >> +typedef struct PSW {
> >> +    uint64_t mask;
> >> +    uint64_t addr;
> >> +} __attribute__ ((packed, aligned(8))) PSW;  
> > 
> > We've seen quite some trouble with "packed" in the past... See
> > 3b8afb41bc8e or 55281a2c53b884d0 for example ... This is only the
> > s390-ccw bios code here, so it is likely ok, but still, since this
> > structure is "naturally" packed, I'd rather go without that attribute
> > here (even if it's only to allow the compiler to generate better code in
> > some cases). You could still _Static_assert(sizeof(struct PSW) == 16)
> > afterwards, just to be sure.
> >   
> 
> So the problem is that this struct, if baked into another struct, will not be aligned 
> properly? Given that this struct is only two 64-bit fields I guess we could get away 
> without packed.

I would advise to try to build with clang, but there are other issues
in the ccw bios that prevent that :(

In general, the build assert way seems to be more portable, though.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 08/15] s390-bios: Map low core memory
  2019-02-18 15:40     ` Jason J. Herne
  2019-02-18 15:49       ` Cornelia Huck
@ 2019-02-18 16:52       ` Thomas Huth
  1 sibling, 0 replies; 83+ messages in thread
From: Thomas Huth @ 2019-02-18 16:52 UTC (permalink / raw)
  To: jjherne, qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

On 18/02/2019 16.40, Jason J. Herne wrote:
> On 2/12/19 7:47 AM, Thomas Huth wrote:
>> On 2019-01-29 14:29, Jason J. Herne wrote:
>>> Create a new header for basic architecture specific definitions and
>>> add a
>>> mapping of low core memory. This mapping will be used by the real
>>> dasd boot
>>> process.
>>>
>>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>>> ---
>>>   pc-bios/s390-ccw/main.c      |   2 +
>>>   pc-bios/s390-ccw/s390-arch.h | 100
>>> +++++++++++++++++++++++++++++++++++++++++++
>>>   2 files changed, 102 insertions(+)
>>>   create mode 100644 pc-bios/s390-ccw/s390-arch.h
>>>
>>> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
>>> index 1bc61b5..fa90aa3 100644
>>> --- a/pc-bios/s390-ccw/main.c
>>> +++ b/pc-bios/s390-ccw/main.c
>>> @@ -9,6 +9,7 @@
>>>    */
>>>     #include "libc.h"
>>> +#include "s390-arch.h"
>>>   #include "s390-ccw.h"
>>>   #include "cio.h"
>>>   #include "virtio.h"
>>> @@ -19,6 +20,7 @@ static char loadparm_str[LOADPARM_LEN + 1] = { 0,
>>> 0, 0, 0, 0, 0, 0, 0, 0 };
>>>   QemuIplParameters qipl;
>>>   IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
>>>   static bool have_iplb;
>>> +const LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
>>>     #define LOADPARM_PROMPT "PROMPT  "
>>>   #define LOADPARM_EMPTY  "        "
>>> diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
>>> new file mode 100644
>>> index 0000000..47eaa04
>>> --- /dev/null
>>> +++ b/pc-bios/s390-ccw/s390-arch.h
>>> @@ -0,0 +1,100 @@
>>> +/*
>>> + * S390 Basic Architecture
>>> + *
>>> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
>>
>> 2019 ?
>>
> 
> Yep, I will update this,
> 
>>> + * This work is licensed under the terms of the GNU GPL, version 2
>>> or (at
>>> + * your option) any later version. See the COPYING file in the
>>> top-level
>>> + * directory.
>>> + */
>>> +
>>> +#ifndef S390_ARCH_H
>>> +#define S390_ARCH_H
>>> +
>>> +typedef struct PSW {
>>> +    uint64_t mask;
>>> +    uint64_t addr;
>>> +} __attribute__ ((packed, aligned(8))) PSW;
>>
>> We've seen quite some trouble with "packed" in the past... See
>> 3b8afb41bc8e or 55281a2c53b884d0 for example ... This is only the
>> s390-ccw bios code here, so it is likely ok, but still, since this
>> structure is "naturally" packed, I'd rather go without that attribute
>> here (even if it's only to allow the compiler to generate better code in
>> some cases). You could still _Static_assert(sizeof(struct PSW) == 16)
>> afterwards, just to be sure.
> 
> So the problem is that this struct, if baked into another struct, will
> not be aligned properly?

Yeah, stuff like that. Maybe you can get along here because you also
specified aligned(8) ... but from my experience, it's better to avoid
"packed" if possible.

>>> +
>>> +/* Older PSW format used by LPSW instruction */
>>> +typedef struct PSWLegacy {
>>> +    uint32_t mask;
>>> +    uint32_t addr;
>>> +} __attribute__ ((packed, aligned(8))) PSWLegacy;
>>
>> dito, I'd drop the packed attribute here.
> 
> Are we sure the compiler will never insert space here if we drop packed?
> I don't see why it would but I'll admit that I don't fully know all of
> the rules.

That's why I suggested to also use _Static_assert(sizeof(x) == y). That
way you can be sure that the compiler does not add any unwanted padding.

[...]
>>> +} __attribute__((packed, aligned(8192))) LowCore;
>>
>> dito, please avoid packed, use _Static_assert instead.
> 
> I'm not convinced this is a good thing to do. Lowcore freely mixes
> fields of size 64, 32, and 8 bits. If we drop packed then the compiler
> will perform all sorts of automatic alignment thereby completely messing
> up offsets.

You should be fine if you also use _Static_assert() afterwards here.

... but since this is the s390-ccw bios and we can be sure that we only
compile this code for s390x and with gcc, I'm also fine if you keep the
attribute here. The problems we've seen so far only occurred on
non-s390x systems (Sparc...) or with Clang, so unlike we want to share
this header with the common QEMU code later, it should not really matter.

 Thomas

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device
  2019-02-04 12:02   ` Cornelia Huck
@ 2019-02-19 14:57     ` Jason J. Herne
  0 siblings, 0 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-02-19 14:57 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On 2/4/19 7:02 AM, Cornelia Huck wrote:
> On Tue, 29 Jan 2019 08:29:22 -0500
> "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> 
>> Allows guest to boot from a vfio configured real dasd device.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> ---
>>   docs/devel/s390-dasd-ipl.txt | 132 +++++++++++++++++++++++
>>   pc-bios/s390-ccw/Makefile    |   2 +-
>>   pc-bios/s390-ccw/dasd-ipl.c  | 249 +++++++++++++++++++++++++++++++++++++++++++
>>   pc-bios/s390-ccw/dasd-ipl.h  |  16 +++
>>   pc-bios/s390-ccw/main.c      |   4 +
>>   pc-bios/s390-ccw/s390-arch.h |  13 +++
>>   6 files changed, 415 insertions(+), 1 deletion(-)
>>   create mode 100644 docs/devel/s390-dasd-ipl.txt
>>   create mode 100644 pc-bios/s390-ccw/dasd-ipl.c
>>   create mode 100644 pc-bios/s390-ccw/dasd-ipl.h
>>
>> diff --git a/docs/devel/s390-dasd-ipl.txt b/docs/devel/s390-dasd-ipl.txt
>> new file mode 100644
>> index 0000000..84ec7b8
>> --- /dev/null
>> +++ b/docs/devel/s390-dasd-ipl.txt
>> @@ -0,0 +1,132 @@
>> +*****************************
>> +***** s390 hardware IPL *****
>> +*****************************
>> +
>> +The s390 hardware IPL process consists of the following steps.
>> +
>> +1. A READ IPL ccw is constructed in memory location 0x0.
>> +    This ccw, by definition, reads the IPL1 record which is located on the disk
>> +    at cylinder 0 track 0 record 1. Note that the chain flag is on in this ccw
>> +    so when it is complete another ccw will be fetched and executed from memory
>> +    location 0x08.
>> +
>> +2. Execute the Read IPL ccw at 0x00, thereby reading IPL1 data into 0x00.
>> +    IPL1 data is 24 bytes in length and consists of the following pieces of
>> +    information: [psw][read ccw][tic ccw]. When the machine executes the Read
>> +    IPL ccw it read the 24-bytes of IPL1 to be read into memory starting at
>> +    location 0x0. Then the ccw program at 0x08 which consists of a read
>> +    ccw and a tic ccw is automatically executed because of the chain flag from
>> +    the original READ IPL ccw. The read ccw will read the IPL2 data into memory
>> +    and the TIC (Tranfer In Channel) will transfer control to the channel
>> +    program contained in the IPL2 data. The TIC channel command is the
>> +    equivalent of a branch/jump/goto instruction for channel programs.
>> +    NOTE: The ccws in IPL1 are defined by the architecture to be format 0.
>> +
>> +3. Execute IPL2.
>> +    The TIC ccw instruction at the end of the IPL1 channel program will begin
>> +    the execution of the IPL2 channel program. IPL2 is stage-2 of the boot
>> +    process and will contain a larger channel program than IPL1. The point of
>> +    IPL2 is to find and load either the operating system or a small program that
>> +    loads the operating system from disk. At the end of this step all or some of
>> +    the real operating system is loaded into memory and we are ready to hand
>> +    control over to the guest operating system. At this point the guest
>> +    operating system is entirely responsible for loading any more data it might
>> +    need to function. NOTE: The IPL2 channel program might read data into memory
>> +    location 0 thereby overwriting the IPL1 psw and channel program. This is ok
>> +    as long as the data placed in location 0 contains a psw whose instruction
>> +    address points to the guest operating system code to execute at the end of
>> +    the IPL/boot process.
>> +    NOTE: The ccws in IPL2 are defined by the architecture to be format 0.
>> +
>> +4. Start executing the guest operating system.
>> +    The psw that was loaded into memory location 0 as part of the ipl process
>> +    should contain the needed flags for the operating system we have loaded. The
>> +    psw's instruction address will point to the location in memory where we want
>> +    to start executing the operating system. This psw is loaded (via LPSW
>> +    instruction) causing control to be passed to the operating system code.
>> +
>> +In a non-virtualized environment this process, handled entirely by the hardware,
>> +is kicked off by the user initiating a "Load" procedure from the hardware
>> +management console. This "Load" procedure crafts a special "Read IPL" ccw in
>> +memory location 0x0 that reads IPL1. It then executes this ccw thereby kicking
>> +off the reading of IPL1 data. Since the channel program from IPL1 will be
>> +written immediately after the special "Read IPL" ccw, the IPL1 channel program
>> +will be executed immediately (the special read ccw has the chaining bit turned
>> +on). The TIC at the end of the IPL1 channel program will cause the IPL2 channel
>> +program to be executed automatically. After this sequence completes the "Load"
>> +procedure then loads the psw from 0x0.
> 
> Nice summary!
> 
>> +
>> +*****************************************
>> +***** How this all pertains to Qemu *****
> 
> s/Qemu/QEMU/
> 
> (also below)
> 

Fixed.

>> +*****************************************
>> +
>> +In theory we should merely have to do the following to IPL/boot a guest
>> +operating system from a DASD device:
>> +
>> +1. Place a "Read IPL" ccw into memory location 0x0 with chaining bit on.
>> +2. Execute channel program at 0x0.
>> +3. LPSW 0x0.
>> +
>> +However, our emulation of the machine's channel program logic is missing one key
>> +feature that is required for this process to work: non-prefetch of ccw data.
>> +
>> +When we start a channel program we pass the channel subsystem parameters via an
>> +ORB (Operation Request Block). One of those parameters is a prefetch bit. If the
>> +bit is on then Qemu is allowed to read the entire channel program from guest
>> +memory before it starts executing it. This means that any channel commands that
>> +read additional channel commands will not work as expected because the newly
>> +read commands will only exist in guest memory and NOT within Qemu's channel
>> +subsystem memory. Qemu's channel subsystem's implementation currently requires
> 
> But isn't that the vfio-ccw backend, rather than the channel subsystem
> implementation?
> 

Yep, you're right. I'll clarify this.

>> +this bit to be on for all channel programs. This is a problem because the IPL
>> +process consists of transferring control from the "Read IPL" ccw immediately to
>> +the IPL1 channel program that was read by "Read IPL".
>> +
>> +Not being able to turn off prefetch will also prevent the TIC at the end of the
>> +IPL1 channel program from transferring control to the IPL2 channel program.
>> +
>> +Lastly, in some cases (the zipl bootloader for example) the IPL2 program also
>> +tansfers control to another channel program segment immediately after reading it
>> +from the disk. So we need to be able to handle this case.
>> +
>> +**************************
>> +***** What Qemu does *****
>> +**************************
>> +
>> +Since we are forced to live with prefetch we cannot use the very simple IPL
>> +procedure we defined in the preceding section. So we compensate by doing the
>> +following.
>> +
>> +1. Place "Read IPL" ccw into memory location 0x0, but turn off chaining bit.
>> +2. Execute "Read IPL" at 0x0.
>> +
>> +   So now IPL1's psw is at 0x0 and IPL1's channel program is at 0x08.
>> +
>> +4. Write a custom channel program that will seek to the IPL2 record and then
>> +   execute the READ and TIC ccws from IPL1.  Normamly the seek is not required
>> +   because after reading the IPL1 record the disk is automatically positioned
>> +   to read the very next record which will be IPL2. But since we are not reading
>> +   both IPL1 and IPL2 as part of the same channel program we must manually set
>> +   the position.
>> +
>> +5. Grab the target address of the TIC instruction from the IPL1 channel program.
>> +   This address is where the IPL2 channel program starts.
>> +
>> +   Now IPL2 is loaded into memory somewhere, and we know the address.
>> +
>> +6. Execute the IPL2 channel program at the address obtained in step #5.
>> +
>> +   Because this channel program can be dynamic, we must use a special algorithm
>> +   that detects a READ immediately followed by a TIC and breaks the ccw chain
>> +   by turning off the chain bit in the READ ccw. When control is returned from
>> +   the kernel/hardware to the Qemu bios code we immediately issue another start
>> +   subchannel to execute the remaining TIC instruction. This causes the entire
>> +   channel program (starting from the TIC) and all needed data to be refetched
>> +   thereby stepping around the limitation that would otherwise prevent this
>> +   channel program from executing properly.
>> +
>> +   Now the operating system code is loaded somewhere in guest memory and the psw
>> +   in memory location 0x0 will point to entry code for the guest operating
>> +   system.
>> +
>> +7. LPSW 0x0.
>> +   LPSW transfers control to the guest operating system and we're done.
> 
> Also a good explanation of the procedure here!
> 
> (...)
> 
>> +static int run_dynamic_ccw_program(SubChannelId schid, uint32_t cpa)
>> +{
>> +    bool has_next;
>> +    uint32_t next_cpa = 0;
>> +    int rc;
>> +
>> +    do {
>> +        has_next = dynamic_cp_fixup(cpa, &next_cpa);
>> +
>> +        print_int("executing ccw chain at ", cpa);
> 
> Do you want to keep the unconditional print here? Or make it a
> debug_print_int, and maybe an unconditional print on error?
> 

Personally, I like having this here unconditionally. If things hang up or go wrong this 
lets us know if it was before or after we jumped into actual guest OS code. I know I could 
make it debug only, but having it all the time means better first failure data capture.

-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 15/15] s390-bios: Support booting from real dasd device
  2019-01-29 13:29 ` [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device Jason J. Herne
  2019-01-31 18:23   ` Cornelia Huck
  2019-02-04 12:02   ` Cornelia Huck
@ 2019-02-21  2:52   ` Eric Farman
  2019-02-21 13:22     ` Jason J. Herne
  2 siblings, 1 reply; 83+ messages in thread
From: Eric Farman @ 2019-02-21  2:52 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger



On 01/29/2019 08:29 AM, Jason J. Herne wrote:
> Allows guest to boot from a vfio configured real dasd device.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>   docs/devel/s390-dasd-ipl.txt | 132 +++++++++++++++++++++++
>   pc-bios/s390-ccw/Makefile    |   2 +-
>   pc-bios/s390-ccw/dasd-ipl.c  | 249 +++++++++++++++++++++++++++++++++++++++++++
>   pc-bios/s390-ccw/dasd-ipl.h  |  16 +++
>   pc-bios/s390-ccw/main.c      |   4 +
>   pc-bios/s390-ccw/s390-arch.h |  13 +++
>   6 files changed, 415 insertions(+), 1 deletion(-)
>   create mode 100644 docs/devel/s390-dasd-ipl.txt
>   create mode 100644 pc-bios/s390-ccw/dasd-ipl.c
>   create mode 100644 pc-bios/s390-ccw/dasd-ipl.h

...snip...

> diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c
> new file mode 100644
> index 0000000..b7ce6d9
> --- /dev/null
> +++ b/pc-bios/s390-ccw/dasd-ipl.c
> @@ -0,0 +1,249 @@

...snip...

> +static void ipl1_fixup(void)
> +{
> +    Ccw0 *ccwSeek = (Ccw0 *) 0x08;
> +    Ccw0 *ccwSearchID = (Ccw0 *) 0x10;
> +    Ccw0 *ccwSearchTic = (Ccw0 *) 0x18;
> +    Ccw0 *ccwRead = (Ccw0 *) 0x20;
> +    CcwSeekData *seekData = (CcwSeekData *) 0x30;
> +    CcwSearchIdData *searchData = (CcwSearchIdData *) 0x38;
> +
> +    /* move IPL1 CCWs to make room for CCWs needed to locate record 2 */
> +    memcpy(ccwRead, (void *)0x08, 16);
> +
> +    /* Disable chaining so we don't TIC to IPL2 channel program */
> +    ccwRead->chain = 0x00;
> +
> +    ccwSeek->cmd_code = CCW_CMD_DASD_SEEK;
> +    ccwSeek->cda = ptr2u32(seekData);
> +    ccwSeek->chain = 1;
> +    ccwSeek->count = sizeof(seekData);

This needs to be sizeof(*seekData)

> +    seekData->reserved = 0x00;
> +    seekData->cyl = 0x00;
> +    seekData->head = 0x00;
> +
> +    ccwSearchID->cmd_code = CCW_CMD_DASD_SEARCH_ID_EQ;
> +    ccwSearchID->cda = ptr2u32(searchData);
> +    ccwSearchID->chain = 1;
> +    ccwSearchID->count = sizeof(searchData);

sizeof(*searchData)

I notice that vfio sees the count for each of these as 8 bytes despite 
them being packed structs of 6 or 5 bytes.

> +    searchData->cyl = 0;
> +    searchData->head = 0;
> +    searchData->record = 2;
> +
> +    /* Go back to Search CCW if correct record not yet found */
> +    ccwSearchTic->cmd_code = CCW_CMD_TIC;
> +    ccwSearchTic->cda = ptr2u32(ccwSearchID);
> +}
> +
> +static void run_ipl1(SubChannelId schid)
> + {
> +    uint32_t startAddr = 0x08;
> +
> +    if (do_cio(schid, startAddr, CCW_FMT0)) {
> +        panic("dasd-ipl: Failed to run IPL1 channel program");
> +    }
> +}
> +
> +static void run_ipl2(SubChannelId schid, uint32_t addr)
> +{
> +
> +    if (run_dynamic_ccw_program(schid, addr)) {
> +        panic("dasd-ipl: Failed to run IPL2 channel program");
> +    }
> +}
> +
> +static void lpsw(void *psw_addr)
> +{
> +    PSWLegacy *pswl = (PSWLegacy *) psw_addr;
> +
> +    pswl->mask |= PSW_MASK_EAMODE;   /* Force z-mode */
> +    pswl->addr |= PSW_MASK_BAMODE;
> +    asm volatile("  llgtr 0,0\n llgtr 1,1\n"     /* Some OS's expect to be */
> +                 "  llgtr 2,2\n llgtr 3,3\n"     /* in 32-bit mode. Clear  */
> +                 "  llgtr 4,4\n llgtr 5,5\n"     /* high part of regs to   */
> +                 "  llgtr 6,6\n llgtr 7,7\n"     /* avoid messing up       */
> +                 "  llgtr 8,8\n llgtr 9,9\n"     /* instructions that work */
> +                 "  llgtr 10,10\n llgtr 11,11\n" /* in both addressing     */
> +                 "  llgtr 12,12\n llgtr 13,13\n" /* modes, like servc.     */
> +                 "  llgtr 14,14\n llgtr 15,15\n"
> +                 "  lpsw %0\n"
> +                 : : "Q" (*pswl) : "cc");
> +}
> +
> +/*
> + * Limitations in QEMU's CCW support complicate the IPL process. Details can
> + * be found in docs/devel/s390-dasd-ipl.txt
> + */
> +void dasd_ipl(SubChannelId schid)
> +{
> +    uint32_t ipl2_addr;
> +
> +    /* Construct Read IPL CCW and run it to read IPL1 from boot disk */
> +    make_readipl();
> +    run_readipl(schid);
> +    ipl2_addr = read_ipl2_addr();
> +    check_ipl1();
> +
> +    /*
> +     * Fixup IPL1 channel program to account for QEMU limitations, then run it
> +     * to read IPL2 channel program from boot disk.
> +     */
> +    ipl1_fixup();
> +    run_ipl1(schid);
> +    check_ipl2(ipl2_addr);
> +
> +    /*
> +     * Run IPL2 channel program to read operating system code from boot disk
> +     * then transfer control to the guest operating system
> +     */
> +    run_ipl2(schid, ipl2_addr);
> +    lpsw(0);
> +}
> diff --git a/pc-bios/s390-ccw/dasd-ipl.h b/pc-bios/s390-ccw/dasd-ipl.h
> new file mode 100644
> index 0000000..56bba82
> --- /dev/null
> +++ b/pc-bios/s390-ccw/dasd-ipl.h
> @@ -0,0 +1,16 @@
> +/*
> + * S390 IPL (boot) from a real DASD device via vfio framework.
> + *
> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
> + * your option) any later version. See the COPYING file in the top-level
> + * directory.
> + */
> +
> +#ifndef DASD_IPL_H
> +#define DASD_IPL_H
> +
> +void dasd_ipl(SubChannelId schid);
> +
> +#endif /* DASD_IPL_H */
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index 5ee02c3..0a46339 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -13,6 +13,7 @@
>   #include "s390-ccw.h"
>   #include "cio.h"
>   #include "virtio.h"
> +#include "dasd-ipl.h"
>   
>   char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
>   static SubChannelId blk_schid = { .one = 1 };
> @@ -210,6 +211,9 @@ int main(void)
>   
>       cutype = cu_type(blk_schid) ;
>       switch (cutype) {
> +    case CU_TYPE_DASD_3990:
> +        dasd_ipl(blk_schid); /* no return */
> +        break;
>       case CU_TYPE_VIRTIO:
>           virtio_setup();
>           zipl_load(); /* no return */
> diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
> index 47eaa04..0438d42 100644
> --- a/pc-bios/s390-ccw/s390-arch.h
> +++ b/pc-bios/s390-ccw/s390-arch.h
> @@ -97,4 +97,17 @@ typedef struct LowCore {
>   
>   extern const LowCore *lowcore;
>   
> +static inline void set_prefix(uint32_t address)
> +{
> +    asm volatile("spx %0" : : "m" (address) : "memory");
> +}
> +
> +static inline uint32_t store_prefix(void)
> +{
> +    uint32_t address;
> +
> +    asm volatile("stpx %0" : "=m" (address));
> +    return address;
> +}
> +
>   #endif
> 

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 15/15] s390-bios: Support booting from real dasd device
  2019-02-21  2:52   ` [Qemu-devel] [qemu-s390x] " Eric Farman
@ 2019-02-21 13:22     ` Jason J. Herne
  0 siblings, 0 replies; 83+ messages in thread
From: Jason J. Herne @ 2019-02-21 13:22 UTC (permalink / raw)
  To: Eric Farman; +Cc: qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

On 2/20/19 9:52 PM, Eric Farman wrote:
> 
> 
> On 01/29/2019 08:29 AM, Jason J. Herne wrote:
>> Allows guest to boot from a vfio configured real dasd device.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> ---
>>   docs/devel/s390-dasd-ipl.txt | 132 +++++++++++++++++++++++
>>   pc-bios/s390-ccw/Makefile    |   2 +-
>>   pc-bios/s390-ccw/dasd-ipl.c  | 249 +++++++++++++++++++++++++++++++++++++++++++
>>   pc-bios/s390-ccw/dasd-ipl.h  |  16 +++
>>   pc-bios/s390-ccw/main.c      |   4 +
>>   pc-bios/s390-ccw/s390-arch.h |  13 +++
>>   6 files changed, 415 insertions(+), 1 deletion(-)
>>   create mode 100644 docs/devel/s390-dasd-ipl.txt
>>   create mode 100644 pc-bios/s390-ccw/dasd-ipl.c
>>   create mode 100644 pc-bios/s390-ccw/dasd-ipl.h
> 
> ...snip...
> 
>> diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c
>> new file mode 100644
>> index 0000000..b7ce6d9
>> --- /dev/null
>> +++ b/pc-bios/s390-ccw/dasd-ipl.c
>> @@ -0,0 +1,249 @@
> 
> ...snip...
> 
>> +static void ipl1_fixup(void)
>> +{
>> +    Ccw0 *ccwSeek = (Ccw0 *) 0x08;
>> +    Ccw0 *ccwSearchID = (Ccw0 *) 0x10;
>> +    Ccw0 *ccwSearchTic = (Ccw0 *) 0x18;
>> +    Ccw0 *ccwRead = (Ccw0 *) 0x20;
>> +    CcwSeekData *seekData = (CcwSeekData *) 0x30;
>> +    CcwSearchIdData *searchData = (CcwSearchIdData *) 0x38;
>> +
>> +    /* move IPL1 CCWs to make room for CCWs needed to locate record 2 */
>> +    memcpy(ccwRead, (void *)0x08, 16);
>> +
>> +    /* Disable chaining so we don't TIC to IPL2 channel program */
>> +    ccwRead->chain = 0x00;
>> +
>> +    ccwSeek->cmd_code = CCW_CMD_DASD_SEEK;
>> +    ccwSeek->cda = ptr2u32(seekData);
>> +    ccwSeek->chain = 1;
>> +    ccwSeek->count = sizeof(seekData);
> 
> This needs to be sizeof(*seekData)
> 

Good catch! Thanks. C can be such a pain sometimes. It should do what I WANT... not what I 
SAY :-).

>> +    seekData->reserved = 0x00;
>> +    seekData->cyl = 0x00;
>> +    seekData->head = 0x00;
>> +
>> +    ccwSearchID->cmd_code = CCW_CMD_DASD_SEARCH_ID_EQ;
>> +    ccwSearchID->cda = ptr2u32(searchData);
>> +    ccwSearchID->chain = 1;
>> +    ccwSearchID->count = sizeof(searchData);
> 
> sizeof(*searchData)
> 
> I notice that vfio sees the count for each of these as 8 bytes despite them being packed 
> structs of 6 or 5 bytes.
> 
>> +    searchData->cyl = 0;
>> +    searchData->head = 0;
>> +    searchData->record = 2;
>> +
>> +    /* Go back to Search CCW if correct record not yet found */
>> +    ccwSearchTic->cmd_code = CCW_CMD_TIC;
>> +    ccwSearchTic->cda = ptr2u32(ccwSearchID);
>> +}
>> +
>> +static void run_ipl1(SubChannelId schid)
>> + {
>> +    uint32_t startAddr = 0x08;
>> +
>> +    if (do_cio(schid, startAddr, CCW_FMT0)) {
>> +        panic("dasd-ipl: Failed to run IPL1 channel program");
>> +    }
>> +}
>> +
>> +static void run_ipl2(SubChannelId schid, uint32_t addr)
>> +{
>> +
>> +    if (run_dynamic_ccw_program(schid, addr)) {
>> +        panic("dasd-ipl: Failed to run IPL2 channel program");
>> +    }
>> +}
>> +
>> +static void lpsw(void *psw_addr)
>> +{
>> +    PSWLegacy *pswl = (PSWLegacy *) psw_addr;
>> +
>> +    pswl->mask |= PSW_MASK_EAMODE;   /* Force z-mode */
>> +    pswl->addr |= PSW_MASK_BAMODE;
>> +    asm volatile("  llgtr 0,0\n llgtr 1,1\n"     /* Some OS's expect to be */
>> +                 "  llgtr 2,2\n llgtr 3,3\n"     /* in 32-bit mode. Clear  */
>> +                 "  llgtr 4,4\n llgtr 5,5\n"     /* high part of regs to   */
>> +                 "  llgtr 6,6\n llgtr 7,7\n"     /* avoid messing up       */
>> +                 "  llgtr 8,8\n llgtr 9,9\n"     /* instructions that work */
>> +                 "  llgtr 10,10\n llgtr 11,11\n" /* in both addressing     */
>> +                 "  llgtr 12,12\n llgtr 13,13\n" /* modes, like servc.     */
>> +                 "  llgtr 14,14\n llgtr 15,15\n"
>> +                 "  lpsw %0\n"
>> +                 : : "Q" (*pswl) : "cc");
>> +}
>> +
>> +/*
>> + * Limitations in QEMU's CCW support complicate the IPL process. Details can
>> + * be found in docs/devel/s390-dasd-ipl.txt
>> + */
>> +void dasd_ipl(SubChannelId schid)
>> +{
>> +    uint32_t ipl2_addr;
>> +
>> +    /* Construct Read IPL CCW and run it to read IPL1 from boot disk */
>> +    make_readipl();
>> +    run_readipl(schid);
>> +    ipl2_addr = read_ipl2_addr();
>> +    check_ipl1();
>> +
>> +    /*
>> +     * Fixup IPL1 channel program to account for QEMU limitations, then run it
>> +     * to read IPL2 channel program from boot disk.
>> +     */
>> +    ipl1_fixup();
>> +    run_ipl1(schid);
>> +    check_ipl2(ipl2_addr);
>> +
>> +    /*
>> +     * Run IPL2 channel program to read operating system code from boot disk
>> +     * then transfer control to the guest operating system
>> +     */
>> +    run_ipl2(schid, ipl2_addr);
>> +    lpsw(0);
>> +}
>> diff --git a/pc-bios/s390-ccw/dasd-ipl.h b/pc-bios/s390-ccw/dasd-ipl.h
>> new file mode 100644
>> index 0000000..56bba82
>> --- /dev/null
>> +++ b/pc-bios/s390-ccw/dasd-ipl.h
>> @@ -0,0 +1,16 @@
>> +/*
>> + * S390 IPL (boot) from a real DASD device via vfio framework.
>> + *
>> + * Copyright (c) 2018 Jason J. Herne <jjherne@us.ibm.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or (at
>> + * your option) any later version. See the COPYING file in the top-level
>> + * directory.
>> + */
>> +
>> +#ifndef DASD_IPL_H
>> +#define DASD_IPL_H
>> +
>> +void dasd_ipl(SubChannelId schid);
>> +
>> +#endif /* DASD_IPL_H */
>> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
>> index 5ee02c3..0a46339 100644
>> --- a/pc-bios/s390-ccw/main.c
>> +++ b/pc-bios/s390-ccw/main.c
>> @@ -13,6 +13,7 @@
>>   #include "s390-ccw.h"
>>   #include "cio.h"
>>   #include "virtio.h"
>> +#include "dasd-ipl.h"
>>   char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
>>   static SubChannelId blk_schid = { .one = 1 };
>> @@ -210,6 +211,9 @@ int main(void)
>>       cutype = cu_type(blk_schid) ;
>>       switch (cutype) {
>> +    case CU_TYPE_DASD_3990:
>> +        dasd_ipl(blk_schid); /* no return */
>> +        break;
>>       case CU_TYPE_VIRTIO:
>>           virtio_setup();
>>           zipl_load(); /* no return */
>> diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
>> index 47eaa04..0438d42 100644
>> --- a/pc-bios/s390-ccw/s390-arch.h
>> +++ b/pc-bios/s390-ccw/s390-arch.h
>> @@ -97,4 +97,17 @@ typedef struct LowCore {
>>   extern const LowCore *lowcore;
>> +static inline void set_prefix(uint32_t address)
>> +{
>> +    asm volatile("spx %0" : : "m" (address) : "memory");
>> +}
>> +
>> +static inline uint32_t store_prefix(void)
>> +{
>> +    uint32_t address;
>> +
>> +    asm volatile("stpx %0" : "=m" (address));
>> +    return address;
>> +}
>> +
>>   #endif
>>
> 


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)


^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-04 11:24   ` Cornelia Huck
@ 2019-02-21 18:01     ` Jason J. Herne
  2019-02-22  8:35       ` Cornelia Huck
  0 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-02-21 18:01 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On 2/4/19 6:24 AM, Cornelia Huck wrote:
> On Tue, 29 Jan 2019 08:29:17 -0500
> "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> 
>> Add struct for format-0 ccws. Support executing format-0 channel
>> programs and waiting for their completion before continuing execution.
>> This will be used for real dasd ipl.
>>
>> Add cu_type() to channel io library. This will be used to query control
>> unit type which is used to determine if we are booting a virtio device or a
>> real dasd device.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> ---
>>   pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
>>   pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
>>   pc-bios/s390-ccw/s390-ccw.h |   1 +
>>   pc-bios/s390-ccw/start.S    |  33 +++++++++++-
>>   4 files changed, 270 insertions(+), 5 deletions(-)
> 
>> diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
>> index 7b07d75..1086f31 100644
>> --- a/pc-bios/s390-ccw/cio.h
>> +++ b/pc-bios/s390-ccw/cio.h
>> @@ -70,9 +70,46 @@ struct scsw {
>>       __u16 count;
>>   } __attribute__ ((packed));
>>   
>> -#define SCSW_FCTL_CLEAR_FUNC 0x1000
>> -#define SCSW_FCTL_HALT_FUNC 0x2000
>> +/* Function Control */
>>   #define SCSW_FCTL_START_FUNC 0x4000
>> +#define SCSW_FCTL_HALT_FUNC 0x2000
>> +#define SCSW_FCTL_CLEAR_FUNC 0x1000
>> +
>> +/* Activity Control */
>> +#define SCSW_ACTL_RESUME_PEND   0x0800
>> +#define SCSW_ACTL_START_PEND    0x0400
>> +#define SCSW_ACTL_HALT_PEND     0x0200
>> +#define SCSW_ACTL_CLEAR_PEND    0x0100
>> +#define SCSW_ACTL_CH_ACTIVE     0x0080
>> +#define SCSW_ACTL_DEV_ACTIVE    0x0040
>> +#define SCSW_ACTL_SUSPENDED     0x0020
>> +
>> +/* Status Control */
>> +#define SCSW_SCTL_ALERT         0x0010
>> +#define SCSW_SCTL_INTERMED      0x0008
>> +#define SCSW_SCTL_PRIMARY       0x0004
>> +#define SCSW_SCTL_SECONDARY     0x0002
>> +#define SCSW_SCTL_STATUS_PEND   0x0001
>> +
>> +/* SCSW Device Status Flags */
>> +#define SCSW_DSTAT_ATTN     0x80
>> +#define SCSW_DSTAT_STATMOD  0x40
>> +#define SCSW_DSTAT_CUEND    0x20
>> +#define SCSW_DSTAT_BUSY     0x10
>> +#define SCSW_DSTAT_CHEND    0x08
>> +#define SCSW_DSTAT_DEVEND   0x04
>> +#define SCSW_DSTAT_UCHK     0x02
>> +#define SCSW_DSTAT_UEXCP    0x01
>> +
>> +/* SCSW Subchannel Status Flags */
>> +#define SCSW_CSTAT_PCINT    0x80
>> +#define SCSW_CSTAT_BADLEN   0x40
>> +#define SCSW_CSTAT_PROGCHK  0x20
>> +#define SCSW_CSTAT_PROTCHK  0x10
>> +#define SCSW_CSTAT_CHDCHK   0x08
>> +#define SCSW_CSTAT_CHCCHK   0x04
>> +#define SCSW_CSTAT_ICCHK    0x02
>> +#define SCSW_CSTAT_CHAINCHK 0x01
> 
> Any reason you're not following the Linux kernel definitions here?
> Might make it easier for folks familiar with the kernel implementation.
> 

There wasn't any real reason. I do like some of my names better as I feel that they all 
should start with SCSW_. But in the interest of homogenizing I could change to the kernel 
implementation. Let me know if you think its worth the time, I could go either way on it.

>>   
>>   /*
>>    * subchannel information block
> 
> (...)
> 
>> +/* basic sense response buffer layout */
>> +typedef struct sense_data_eckd_dasd {
>> +    uint8_t common_status;
>> +    uint8_t status[2];
>> +    uint8_t res_count;
>> +    uint8_t phys_drive_id;
>> +    uint8_t low_cyl_addr;
>> +    uint8_t head_high_cyl_addr;
>> +    uint8_t fmt_msg;
>> +    uint64_t fmt_dependent_info[2];
>> +    uint8_t reserved;
>> +    uint8_t program_action_code;
>> +    uint16_t config_info;
>> +    uint8_t mcode_hicyl;
>> +    uint8_t cyl_head_addr[3];
>> +}  __attribute__ ((packed, aligned(4))) sense_data_eckd_dasd;
> 
> SenseDataEckdDasd would be more QEMU-y.
>

I'll change this.


>> +
>> +#define ECKD_SENSE24_GET_FMT(sd)     (sd->fmt_msg & 0xF0 >> 4)
>> +#define ECKD_SENSE24_GET_MSG(sd)     (sd->fmt_msg & 0x0F)
>> +
>> +#define unit_check(irb)         ((irb)->scsw.dstat & SCSW_DSTAT_UCHK)
>> +#define iface_ctrl_check(irb)   ((irb)->scsw.cstat & SCSW_CSTAT_ICCHK)
>> +
>>   /* interruption response block */
>>   typedef struct irb {
>>       struct scsw scsw;
> 
> (...)
> 
>> diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
>> index eb8d024..22b38ec 100644
>> --- a/pc-bios/s390-ccw/start.S
>> +++ b/pc-bios/s390-ccw/start.S
>> @@ -65,12 +65,32 @@ consume_sclp_int:
>>           /* prepare external call handler */
>>           larl %r1, external_new_code
>>           stg %r1, 0x1b8
>> -        larl %r1, external_new_mask
>> +        larl %r1, int_new_mask
> 
> Isn't that for external interrupts?
> 
>>           mvc 0x1b0(8),0(%r1)
>>           /* load enabled wait PSW */
>>           larl %r1, enabled_wait_psw
>>           lpswe 0(%r1)
>>   
>> +/*
>> + * void consume_io_int(void)
>> + *
>> + * eats one I/O interrupt
>> + */
>> +        .globl consume_io_int
>> +consume_io_int:
>> +        /* enable I/O interrupts in cr6 */
>> +        stctg 6,6,0(15)
>> +        oi 4(15), 0xff
>> +        lctlg 6,6,0(15)
>> +        /* prepare i/o call handler */
>> +        larl %r1, io_new_code
>> +        stg %r1, 0x1f8
>> +        larl %r1, int_new_mask
>> +        mvc 0x1f0(8),0(%r1)
>> +        /* load enabled wait PSW */
>> +        larl %r1, enabled_wait_psw
>> +        lpswe 0(%r1)
>> +
>>   external_new_code:
>>           /* disable service interrupts in cr0 */
>>           stctg 0,0,0(15)
>> @@ -78,10 +98,19 @@ external_new_code:
>>           lctlg 0,0,0(15)
>>           br 14
>>   
>> +io_new_code:
>> +        /* disable I/O interrupts in cr6 */
>> +        stctg 6,6,0(15)
>> +        ni 4(15), 0x00
>> +        lctlg 6,6,0(15)
> 
> What about leaving the isc enabled in cr6 all the time and just
> controlling interrupts via enabling/disabling I/O interrupts?
> 

Its really all about leaving the system in as close to a default and unaltered state as 
possible. I could just set isc sometime at the beginning of dasd ipl and clear it right 
before transferring control, if you feel strongly about it.


>> +        br 14
>> +
>> +
>> +
>>           .align  8
>>   disabled_wait_psw:
>>           .quad   0x0002000180000000,0x0000000000000000
>>   enabled_wait_psw:
>>           .quad   0x0302000180000000,0x0000000000000000
>> -external_new_mask:
>> +int_new_mask:
> 
> Ah, I see. But I'd probably have two masks instead.
> 

I'll separate them.


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-21 18:01     ` Jason J. Herne
@ 2019-02-22  8:35       ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-22  8:35 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Thu, 21 Feb 2019 13:01:40 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/4/19 6:24 AM, Cornelia Huck wrote:
> > On Tue, 29 Jan 2019 08:29:17 -0500
> > "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
(...)
> >> -#define SCSW_FCTL_CLEAR_FUNC 0x1000
> >> -#define SCSW_FCTL_HALT_FUNC 0x2000
> >> +/* Function Control */
> >>   #define SCSW_FCTL_START_FUNC 0x4000
> >> +#define SCSW_FCTL_HALT_FUNC 0x2000
> >> +#define SCSW_FCTL_CLEAR_FUNC 0x1000
> >> +
> >> +/* Activity Control */
> >> +#define SCSW_ACTL_RESUME_PEND   0x0800
> >> +#define SCSW_ACTL_START_PEND    0x0400
> >> +#define SCSW_ACTL_HALT_PEND     0x0200
> >> +#define SCSW_ACTL_CLEAR_PEND    0x0100
> >> +#define SCSW_ACTL_CH_ACTIVE     0x0080
> >> +#define SCSW_ACTL_DEV_ACTIVE    0x0040
> >> +#define SCSW_ACTL_SUSPENDED     0x0020
> >> +
> >> +/* Status Control */
> >> +#define SCSW_SCTL_ALERT         0x0010
> >> +#define SCSW_SCTL_INTERMED      0x0008
> >> +#define SCSW_SCTL_PRIMARY       0x0004
> >> +#define SCSW_SCTL_SECONDARY     0x0002
> >> +#define SCSW_SCTL_STATUS_PEND   0x0001
> >> +
> >> +/* SCSW Device Status Flags */
> >> +#define SCSW_DSTAT_ATTN     0x80
> >> +#define SCSW_DSTAT_STATMOD  0x40
> >> +#define SCSW_DSTAT_CUEND    0x20
> >> +#define SCSW_DSTAT_BUSY     0x10
> >> +#define SCSW_DSTAT_CHEND    0x08
> >> +#define SCSW_DSTAT_DEVEND   0x04
> >> +#define SCSW_DSTAT_UCHK     0x02
> >> +#define SCSW_DSTAT_UEXCP    0x01
> >> +
> >> +/* SCSW Subchannel Status Flags */
> >> +#define SCSW_CSTAT_PCINT    0x80
> >> +#define SCSW_CSTAT_BADLEN   0x40
> >> +#define SCSW_CSTAT_PROGCHK  0x20
> >> +#define SCSW_CSTAT_PROTCHK  0x10
> >> +#define SCSW_CSTAT_CHDCHK   0x08
> >> +#define SCSW_CSTAT_CHCCHK   0x04
> >> +#define SCSW_CSTAT_ICCHK    0x02
> >> +#define SCSW_CSTAT_CHAINCHK 0x01  
> > 
> > Any reason you're not following the Linux kernel definitions here?
> > Might make it easier for folks familiar with the kernel implementation.
> >   
> 
> There wasn't any real reason. I do like some of my names better as I feel that they all 
> should start with SCSW_. But in the interest of homogenizing I could change to the kernel 
> implementation. Let me know if you think its worth the time, I could go either way on it.

TBH, some of the kernel defines _are_ a bit wonky, but I'm used to
them :)

Not sure if any of the others who will look at this code are that
familiar with the kernel code, though, so I'll leave the decision to
the bios maintainers. (Your names are more consistent...)

(...)
> >> +io_new_code:
> >> +        /* disable I/O interrupts in cr6 */
> >> +        stctg 6,6,0(15)
> >> +        ni 4(15), 0x00
> >> +        lctlg 6,6,0(15)  
> > 
> > What about leaving the isc enabled in cr6 all the time and just
> > controlling interrupts via enabling/disabling I/O interrupts?
> >   
> 
> Its really all about leaving the system in as close to a default and unaltered state as 
> possible. I could just set isc sometime at the beginning of dasd ipl and clear it right 
> before transferring control, if you feel strongly about it.

Not feeling strongly. Nobody probably cares about how often you change
cr6 during load...

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 12/15] s390-bios: Refactor virtio to run channel programs via cio
  2019-02-04 11:44   ` Cornelia Huck
@ 2019-02-25 13:20     ` Jason J. Herne
  2019-02-25 17:07       ` Cornelia Huck
  0 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-02-25 13:20 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On 2/4/19 6:44 AM, Cornelia Huck wrote:
> On Tue, 29 Jan 2019 08:29:19 -0500
> "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> 
>> Now that we have a Channel I/O library let's modify virtio boot code to
>> make use of it for running channel programs.
>>
>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>> ---
>>   pc-bios/s390-ccw/virtio.c | 48 +++++++++++++++++++----------------------------
>>   1 file changed, 19 insertions(+), 29 deletions(-)
>>
>> diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
>> index aa9da72..f8d71ed 100644
>> --- a/pc-bios/s390-ccw/virtio.c
>> +++ b/pc-bios/s390-ccw/virtio.c
>> @@ -89,33 +89,20 @@ int drain_irqs(SubChannelId schid)
>>       }
>>   }
>>   
>> -static int run_ccw(VDev *vdev, int cmd, void *ptr, int len)
>> +static int run_ccw(VDev *vdev, int cmd, void *ptr, int len, bool sli)
>>   {
>>       Ccw1 ccw = {};
>> -    CmdOrb orb = {};
>> -    int r;
>> -
>> -    enable_subchannel(vdev->schid);
>> -
>> -    /* start subchannel command */
>> -    orb.fmt = 1;
>> -    orb.cpa = (u32)(long)&ccw;
>> -    orb.lpm = 0x80;
>>   
>>       ccw.cmd_code = cmd;
>>       ccw.cda = (long)ptr;
>>       ccw.count = len;
>>   
>> -    r = ssch(vdev->schid, &orb);
>> -    /*
>> -     * XXX Wait until device is done processing the CCW. For now we can
>> -     *     assume that a simple tsch will have finished the CCW processing,
>> -     *     but the architecture allows for asynchronous operation
>> -     */
>> -    if (!r) {
>> -        r = drain_irqs(vdev->schid);
>> +    if (sli) {
>> +        ccw.flags |= CCW_FLAG_SLI;
>>       }
>> -    return r;
>> +
>> +    enable_subchannel(vdev->schid);
>> +    return do_cio(vdev->schid, ptr2u32(&ccw), CCW_FMT1);
> 
> That still has the very odd pattern that you enable the subchannel
> every time you run a channel program...
> 

I originally agreed and removed this. But now that I've gotten around to doing some 
testing I've discovered that  we actually rely on this for one important code path.

Here is the call chain before my patches:
main -> virtio_setup -> find_dev -> virtio_is_supported -> run_ccw

Here is the call chain after my patches:
main -> find_boot_device -> find_subch -> virtio_is_supported -> run_ccw

We end up in the same situation in both scenarios. If we remove the enable_subchannel() 
call from run_ccw() then we end up in run_ccw() for a disabled subchannel.

That said, I can remove the enable_subchannel call from run_ccw and instead add it to 
find_subch() if that seems cleaner to you.

Thoughts?

-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 12/15] s390-bios: Refactor virtio to run channel programs via cio
  2019-02-25 13:20     ` Jason J. Herne
@ 2019-02-25 17:07       ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-25 17:07 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Mon, 25 Feb 2019 08:20:04 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/4/19 6:44 AM, Cornelia Huck wrote:
> > On Tue, 29 Jan 2019 08:29:19 -0500
> > "Jason J. Herne" <jjherne@linux.ibm.com> wrote:
> >   
> >> Now that we have a Channel I/O library let's modify virtio boot code to
> >> make use of it for running channel programs.
> >>
> >> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> >> ---
> >>   pc-bios/s390-ccw/virtio.c | 48 +++++++++++++++++++----------------------------
> >>   1 file changed, 19 insertions(+), 29 deletions(-)
> >>
> >> diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
> >> index aa9da72..f8d71ed 100644
> >> --- a/pc-bios/s390-ccw/virtio.c
> >> +++ b/pc-bios/s390-ccw/virtio.c
> >> @@ -89,33 +89,20 @@ int drain_irqs(SubChannelId schid)
> >>       }
> >>   }
> >>   
> >> -static int run_ccw(VDev *vdev, int cmd, void *ptr, int len)
> >> +static int run_ccw(VDev *vdev, int cmd, void *ptr, int len, bool sli)
> >>   {
> >>       Ccw1 ccw = {};
> >> -    CmdOrb orb = {};
> >> -    int r;
> >> -
> >> -    enable_subchannel(vdev->schid);
> >> -
> >> -    /* start subchannel command */
> >> -    orb.fmt = 1;
> >> -    orb.cpa = (u32)(long)&ccw;
> >> -    orb.lpm = 0x80;
> >>   
> >>       ccw.cmd_code = cmd;
> >>       ccw.cda = (long)ptr;
> >>       ccw.count = len;
> >>   
> >> -    r = ssch(vdev->schid, &orb);
> >> -    /*
> >> -     * XXX Wait until device is done processing the CCW. For now we can
> >> -     *     assume that a simple tsch will have finished the CCW processing,
> >> -     *     but the architecture allows for asynchronous operation
> >> -     */
> >> -    if (!r) {
> >> -        r = drain_irqs(vdev->schid);
> >> +    if (sli) {
> >> +        ccw.flags |= CCW_FLAG_SLI;
> >>       }
> >> -    return r;
> >> +
> >> +    enable_subchannel(vdev->schid);
> >> +    return do_cio(vdev->schid, ptr2u32(&ccw), CCW_FMT1);  
> > 
> > That still has the very odd pattern that you enable the subchannel
> > every time you run a channel program...
> >   
> 
> I originally agreed and removed this. But now that I've gotten around to doing some 
> testing I've discovered that  we actually rely on this for one important code path.
> 
> Here is the call chain before my patches:
> main -> virtio_setup -> find_dev -> virtio_is_supported -> run_ccw
> 
> Here is the call chain after my patches:
> main -> find_boot_device -> find_subch -> virtio_is_supported -> run_ccw
> 
> We end up in the same situation in both scenarios. If we remove the enable_subchannel() 
> call from run_ccw() then we end up in run_ccw() for a disabled subchannel.
> 
> That said, I can remove the enable_subchannel call from run_ccw and instead add it to 
> find_subch() if that seems cleaner to you.
> 
> Thoughts?
> 

If I recall the flow correctly, we have two categories of wanting to do
I/O (and needing an enabled subchannel for that):
- initial detection, when we do sense id to find out the type (done for
  every device, until we located the wanted one)
- actually setting up etc. that specific device

I think two ways make sense:
- enable/sense id/disable for every device, enable/do specific
  stuff/disable for the actual boot device
- same as above, but don't disable when you found the device

That said, if reordering this is too involved, just keep it as in your
patch. It's just a bit odd, not really wrong :)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-04 11:13     ` Cornelia Huck
  2019-02-04 19:29       ` Farhan Ali
@ 2019-02-27 13:32       ` Jason J. Herne
  2019-02-27 14:06         ` Cornelia Huck
  1 sibling, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-02-27 13:32 UTC (permalink / raw)
  To: Cornelia Huck, Farhan Ali; +Cc: qemu-devel, qemu-s390x, pasic, borntraeger

On 2/4/19 6:13 AM, Cornelia Huck wrote:
> On Thu, 31 Jan 2019 12:31:00 -0500
> Farhan Ali <alifm@linux.ibm.com> wrote:
> 
>> On 01/29/2019 08:29 AM, Jason J. Herne wrote:
>>> Add struct for format-0 ccws. Support executing format-0 channel
>>> programs and waiting for their completion before continuing execution.
>>> This will be used for real dasd ipl.
>>>
>>> Add cu_type() to channel io library. This will be used to query control
>>> unit type which is used to determine if we are booting a virtio device or a
>>> real dasd device.
>>>
>>> Signed-off-by: Jason J. Herne<jjherne@linux.ibm.com>
>>> ---
>>>    pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
>>>    pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
>>>    pc-bios/s390-ccw/s390-ccw.h |   1 +
>>>    pc-bios/s390-ccw/start.S    |  33 +++++++++++-
>>>    4 files changed, 270 insertions(+), 5 deletions(-)
> 
>>> +/*
>>> + * Executes a channel program at a given subchannel. The request to run the
>>> + * channel program is sent to the subchannel, we then wait for the interrupt
>>> + * signaling completion of the I/O operation(s) performed by the channel
>>> + * program. Lastly we verify that the i/o operation completed without error and
>>> + * that the interrupt we received was for the subchannel used to run the
>>> + * channel program.
>>> + *
>>> + * Note: This function assumes it is running in an environment where no other
>>> + * cpus are generating or receiving I/O interrupts. So either run it in a
>>> + * single-cpu environment or make sure all other cpus are not doing I/O and
>>> + * have I/O interrupts masked off.
>>> + */
>>> +int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
>>> +{
>>> +    CmdOrb orb = {};
>>> +    Irb irb = {};
>>> +    sense_data_eckd_dasd sd;
>>> +    int rc, retries = 0;
>>> +
>>> +    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
>>> +
>>> +    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
>>> +    if (fmt == 0) {
>>> +        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
>>> +    }
>>> +
>>> +    orb.fmt = fmt ;
>>> +    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
>>> +    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
>>> +    orb.lpm = 0xFF; /* All paths allowed */
>>> +    orb.cpa = ccw_addr;
>>> +
>>> +    while (true) {
>>> +        rc = ssch(schid, &orb);
>>> +        if (rc == 1) {
>>> +            /* Status pending, not sure why. Let's eat the status and retry. */
>>> +            tsch(schid, &irb);
>>> +            retries++;
>>> +            continue;
>>> +        }
>>> +        if (rc) {
>>> +            print_int("ssch failed with rc=", rc);
>>> +            break;
>>> +        }
>>> +
>>> +        consume_io_int();
>>> +
>>> +        /* collect status */
>>> +        rc = tsch(schid, &irb);
>>> +        if (rc) {
>>> +            print_int("tsch failed with rc=", rc);
>>> +            break;
>>> +        }
>>> +
>>> +        if (!irb_error(&irb)) {
>>> +            break;
>>> +        }
>>> +
>>> +        /*
>>> +         * Unexpected unit check, or interface-control-check. Use sense to
>>> +         * clear unit check then retry.
>>> +         */
>>> +        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
>>> +            basic_sense(schid, &sd, sizeof(sd));
>>
>> We are using basic sense to clear any unit check or ifcc, but is it
>> possible for the basic sense to cause another unit check?
>>
>> The chapter on Basic Sense in the Common I/O Device Commands
>> (http://publibz.boulder.ibm.com/support/libraryserver/FRAMESET/dz9ar501/2.1?SHELF=&DT=19920409154647&CASE=)
>>    says this:
>>
>> ""
>> The basic sense command initiates a sense operation  at  all  devices
>> and cannot  cause  the  command-reject,  intervention-required,
>> data-check, or overrun bit to be set to one.  If the control unit
>> detects  an  equipment malfunction  or  invalid  checking-block  code
>> (CBC) on the sense-command code, the equipment-check or bus-out-check
>> bit is set  to  one,  and  unit check is indicated in the device-status
>> byte.
>> ""
>>
>> If my understanding is correct, if there is an equipment malfunction
>> then the control unit can return a unit check even for a basic sense.
>> This can lead to infinite recursion in the bios.
> 
> I think the retries variable is supposed to take care of that.
> 
> What I don't understand is why we do the basic sense after an IFCC?
> Wouldn't it make more sense to simply retry the original command in
> that case?
> 

I assumed it might be needed to clear status. It seems not. I'll modify that code path 
accordingly.


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-05 10:18         ` Cornelia Huck
  2019-02-12 13:10           ` Halil Pasic
@ 2019-02-27 13:35           ` Jason J. Herne
  2019-02-27 14:07             ` Cornelia Huck
  1 sibling, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-02-27 13:35 UTC (permalink / raw)
  To: Cornelia Huck, Farhan Ali; +Cc: qemu-devel, qemu-s390x, pasic, borntraeger

On 2/5/19 5:18 AM, Cornelia Huck wrote:
> On Mon, 4 Feb 2019 14:29:18 -0500
> Farhan Ali <alifm@linux.ibm.com> wrote:
> 
>> On 02/04/2019 06:13 AM, Cornelia Huck wrote:
>>> On Thu, 31 Jan 2019 12:31:00 -0500
>>> Farhan Ali <alifm@linux.ibm.com> wrote:
>>>    
>>>> On 01/29/2019 08:29 AM, Jason J. Herne wrote:
>>>>> Add struct for format-0 ccws. Support executing format-0 channel
>>>>> programs and waiting for their completion before continuing execution.
>>>>> This will be used for real dasd ipl.
>>>>>
>>>>> Add cu_type() to channel io library. This will be used to query control
>>>>> unit type which is used to determine if we are booting a virtio device or a
>>>>> real dasd device.
>>>>>
>>>>> Signed-off-by: Jason J. Herne<jjherne@linux.ibm.com>
>>>>> ---
>>>>>     pc-bios/s390-ccw/cio.c      | 114 +++++++++++++++++++++++++++++++++++++++
>>>>>     pc-bios/s390-ccw/cio.h      | 127 ++++++++++++++++++++++++++++++++++++++++++--
>>>>>     pc-bios/s390-ccw/s390-ccw.h |   1 +
>>>>>     pc-bios/s390-ccw/start.S    |  33 +++++++++++-
>>>>>     4 files changed, 270 insertions(+), 5 deletions(-)
>>>    
>>>>> +/*
>>>>> + * Executes a channel program at a given subchannel. The request to run the
>>>>> + * channel program is sent to the subchannel, we then wait for the interrupt
>>>>> + * signaling completion of the I/O operation(s) performed by the channel
>>>>> + * program. Lastly we verify that the i/o operation completed without error and
>>>>> + * that the interrupt we received was for the subchannel used to run the
>>>>> + * channel program.
>>>>> + *
>>>>> + * Note: This function assumes it is running in an environment where no other
>>>>> + * cpus are generating or receiving I/O interrupts. So either run it in a
>>>>> + * single-cpu environment or make sure all other cpus are not doing I/O and
>>>>> + * have I/O interrupts masked off.
>>>>> + */
>>>>> +int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
>>>>> +{
>>>>> +    CmdOrb orb = {};
>>>>> +    Irb irb = {};
>>>>> +    sense_data_eckd_dasd sd;
>>>>> +    int rc, retries = 0;
>>>>> +
>>>>> +    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
>>>>> +
>>>>> +    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
>>>>> +    if (fmt == 0) {
>>>>> +        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
>>>>> +    }
>>>>> +
>>>>> +    orb.fmt = fmt ;
>>>>> +    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
>>>>> +    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
>>>>> +    orb.lpm = 0xFF; /* All paths allowed */
>>>>> +    orb.cpa = ccw_addr;
>>>>> +
>>>>> +    while (true) {
>>>>> +        rc = ssch(schid, &orb);
>>>>> +        if (rc == 1) {
>>>>> +            /* Status pending, not sure why. Let's eat the status and retry. */
>>>>> +            tsch(schid, &irb);
>>>>> +            retries++;
>>>>> +            continue;
>>>>> +        }
>>>>> +        if (rc) {
>>>>> +            print_int("ssch failed with rc=", rc);
>>>>> +            break;
>>>>> +        }
>>>>> +
>>>>> +        consume_io_int();
>>>>> +
>>>>> +        /* collect status */
>>>>> +        rc = tsch(schid, &irb);
>>>>> +        if (rc) {
>>>>> +            print_int("tsch failed with rc=", rc);
>>>>> +            break;
>>>>> +        }
>>>>> +
>>>>> +        if (!irb_error(&irb)) {
>>>>> +            break;
>>>>> +        }
>>>>> +
>>>>> +        /*
>>>>> +         * Unexpected unit check, or interface-control-check. Use sense to
>>>>> +         * clear unit check then retry.
>>>>> +         */
>>>>> +        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
>>>>> +            basic_sense(schid, &sd, sizeof(sd));
>>>>
>>>> We are using basic sense to clear any unit check or ifcc, but is it
>>>> possible for the basic sense to cause another unit check?
>>>>
>>>> The chapter on Basic Sense in the Common I/O Device Commands
>>>> (http://publibz.boulder.ibm.com/support/libraryserver/FRAMESET/dz9ar501/2.1?SHELF=&DT=19920409154647&CASE=)
>>>>     says this:
>>>>
>>>> ""
>>>> The basic sense command initiates a sense operation  at  all  devices
>>>> and cannot  cause  the  command-reject,  intervention-required,
>>>> data-check, or overrun bit to be set to one.  If the control unit
>>>> detects  an  equipment malfunction  or  invalid  checking-block  code
>>>> (CBC) on the sense-command code, the equipment-check or bus-out-check
>>>> bit is set  to  one,  and  unit check is indicated in the device-status
>>>> byte.
>>>> ""
>>>>
>>>> If my understanding is correct, if there is an equipment malfunction
>>>> then the control unit can return a unit check even for a basic sense.
>>>> This can lead to infinite recursion in the bios.
>>>
>>> I think the retries variable is supposed to take care of that.
>>>    
>>
>> If I understand the code correctly, the retries variable cannot prevent
>> infinite recursion. Because every time we get a unit check we do a basic
>> sense which calls the do_cio function again. If that basic sense returns
>> a unit check we do another basic sense....
> 
> Eww, you're right...
> 
> I think that the routine needs to be split:
> - inner routine that does the ssch, retries if the subchannel is status
>    pending, and waits for a final status (regardless whether it is a
>    special condition or not)
> - outer routine that does error handling, if needed (like retrying on
>    IFCC, or doing a basic sense on unit check)
> 
> The inner routine will probably only be called by the outer routine
> (and not directly by other code).
> 
> Does that make sense? It's hopefully enough; we really don't want to
> transplant the whole Linux cio state machine into the bios...
> 

I had a hard time following what you were suggesting here. Its most likely me,not you :). 
That said, I did redesign it to remove the potential infinite recursion. I'll be posting 
v3 soon, let me know what you think.


-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-27 13:32       ` Jason J. Herne
@ 2019-02-27 14:06         ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-27 14:06 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: Farhan Ali, qemu-devel, qemu-s390x, pasic, borntraeger

On Wed, 27 Feb 2019 08:32:58 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/4/19 6:13 AM, Cornelia Huck wrote:

> > What I don't understand is why we do the basic sense after an IFCC?
> > Wouldn't it make more sense to simply retry the original command in
> > that case?
> >   
> 
> I assumed it might be needed to clear status. It seems not. I'll modify that code path 
> accordingly.

Yes, a tsch should be enough to clear any pending status. It doesn't
clear available sense data, but if you get sense data on an ifcc, the
hardware/hypervisor is doing something really really strange :)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs
  2019-02-27 13:35           ` Jason J. Herne
@ 2019-02-27 14:07             ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-27 14:07 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: Farhan Ali, qemu-devel, qemu-s390x, pasic, borntraeger

On Wed, 27 Feb 2019 08:35:37 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/5/19 5:18 AM, Cornelia Huck wrote:

> > I think that the routine needs to be split:
> > - inner routine that does the ssch, retries if the subchannel is status
> >    pending, and waits for a final status (regardless whether it is a
> >    special condition or not)
> > - outer routine that does error handling, if needed (like retrying on
> >    IFCC, or doing a basic sense on unit check)
> > 
> > The inner routine will probably only be called by the outer routine
> > (and not directly by other code).
> > 
> > Does that make sense? It's hopefully enough; we really don't want to
> > transplant the whole Linux cio state machine into the bios...
> >   
> 
> I had a hard time following what you were suggesting here. Its most likely me,not you :). 
> That said, I did redesign it to remove the potential infinite recursion. I'll be posting 
> v3 soon, let me know what you think.

I might have been not clear enough; but looking forward to your v3 :)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 11/15] s390-bios: cio error handling
  2019-02-04 11:41   ` Cornelia Huck
@ 2019-02-28 15:59     ` Jason J. Herne
  2019-02-28 16:11       ` Cornelia Huck
  0 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2019-02-28 15:59 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On 2/4/19 6:41 AM, Cornelia Huck wrote:
...
> 
>> +static void print_irb_err(Irb *irb)
>> +{
>> +    Ccw0 *this_ccw = u32toptr(irb->scsw.cpa);
>> +    Ccw0 *prev_ccw = u32toptr(irb->scsw.cpa - 8);
> 
> I don't think you can cast this conditionally to format 0 -- I'd pass
> in the format from do_cio and handle it accordingly.
> 
>> +    char msgline[256];
>> +
>> +    sclp_print("vfio-ccw device I/O error - Interrupt Response Block Data:\n");
> 
> If you call this from the generic function, you shouldn't talk about
> vfio-ccw here; but it might make sense to print subchannel/devno and
> the cu type.
> 
> (...)
>

Fixed for v3.


>> @@ -148,6 +370,9 @@ int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
>>               continue;
>>           }
>>   
>> +        print_irb_err(&irb);
>> +        basic_sense(schid, &sd, sizeof(sd));
>> +        print_eckd_dasd_sense_data(&sd);
> 
> I think this should only be printed for actual dasds (and maybe only
> print it if there is actually sense data available)?
> 

Good point. Currently do_cio doesn't have any info on its device type. Should I pass in 
the controller type? Thats the easiest way I can think of to make the decision.

-- 
-- Jason J. Herne (jjherne@linux.ibm.com)

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 11/15] s390-bios: cio error handling
  2019-02-28 15:59     ` Jason J. Herne
@ 2019-02-28 16:11       ` Cornelia Huck
  0 siblings, 0 replies; 83+ messages in thread
From: Cornelia Huck @ 2019-02-28 16:11 UTC (permalink / raw)
  To: Jason J. Herne; +Cc: qemu-devel, qemu-s390x, pasic, alifm, borntraeger

On Thu, 28 Feb 2019 10:59:13 -0500
"Jason J. Herne" <jjherne@linux.ibm.com> wrote:

> On 2/4/19 6:41 AM, Cornelia Huck wrote:

> >> @@ -148,6 +370,9 @@ int do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt)
> >>               continue;
> >>           }
> >>   
> >> +        print_irb_err(&irb);
> >> +        basic_sense(schid, &sd, sizeof(sd));
> >> +        print_eckd_dasd_sense_data(&sd);  
> > 
> > I think this should only be printed for actual dasds (and maybe only
> > print it if there is actually sense data available)?
> >   
> 
> Good point. Currently do_cio doesn't have any info on its device type. Should I pass in 
> the controller type? Thats the easiest way I can think of to make the decision.
> 

Sounds reasonable to me!

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [qemu-s390x] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices
  2019-02-13 13:59     ` Jason J. Herne
@ 2019-03-04 19:23       ` Thomas Huth
  0 siblings, 0 replies; 83+ messages in thread
From: Thomas Huth @ 2019-03-04 19:23 UTC (permalink / raw)
  To: jjherne, qemu-devel, qemu-s390x, cohuck, pasic, alifm, borntraeger

On 13/02/2019 14.59, Jason J. Herne wrote:
> On 2/11/19 11:38 AM, Thomas Huth wrote:
>> On 2019-01-29 14:29, Jason J. Herne wrote:
>>> We need a method for finding the subchannel of a dasd device. Let's
>>> modify find_dev to handle this since it mostly does what we need. Up to
>>> this point find_dev has been specific to only virtio devices.
>>>
>>> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
>>> Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
>>> ---
>>>   pc-bios/s390-ccw/main.c | 16 +++++++++++-----
>>>   1 file changed, 11 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
>>> index 67df421..7e3f65e 100644
>>> --- a/pc-bios/s390-ccw/main.c
>>> +++ b/pc-bios/s390-ccw/main.c
>>> @@ -49,6 +49,12 @@ unsigned int get_loadparm_index(void)
>>>       return atoui(loadparm_str);
>>>   }
>>>   +/*
>>> + * Find the subchannel connected to the given device (dev_no) and
>>> fill in the
>>> + * subchannel information block (schib) with the connected
>>> subchannel's info.
>>> + * NOTE: The global variable blk_schid is updated to contain the
>>> subchannel
>>> + * information.
>>> + */
>>>   static bool find_dev(Schib *schib, int dev_no)
>>>   {
>>>       int i, r;
>>> @@ -62,15 +68,15 @@ static bool find_dev(Schib *schib, int dev_no)
>>>           if (!schib->pmcw.dnv) {
>>>               continue;
>>>           }
>>> -        if (!virtio_is_supported(blk_schid)) {
>>> -            continue;
>>> -        }
>>> +
>>>           /* Skip net devices since no IPLB is created and therefore no
>>> -         * no network bootloader has been loaded
>>> +         * network bootloader has been loaded
>>>            */
>>> -        if (virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
>>> +        if (virtio_is_supported(blk_schid) &&
>>> +            virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
>>>               continue;
>>>           }
>>> +
>>>           if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
>>>               return true;
>>>           }
>>>
>>
>> Not sure whether this really works as expected? If dev_no is -1, this
>> used to return the first supported virtio device. Now it returns the
>> first device that could be found - but how are we sure that we can boot
>> from that device?
> 
> How could we ever be sure we could boot from the first virtio device?
> The dev_no=1 case means we don't know which device to boot from so we're
> guessing.  The only thing that is changing here is that we're allowing
> non-virtio devices as well. We do this because we now support booting
> from a device type that is not virtio.

For example, this command line used to work fine in the past:

s390x-softmmu/qemu-system-s390x -enable-kvm -nographic \
  -device x-terminal3270 -device virtio-blk-ccw,drive=dr1 \
  -drive if=none,id=dr1,format=qcow2,file=guest.qcow2

With this patch applied, the guest is now not bootable anymore. So I'm
sorry, but you break setups here that worked fine in the past. Isn't
there an easy way to determine whether a device is a bootable block
device or not?

 Thomas

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path
  2018-12-12 14:11 ` [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path Jason J. Herne
@ 2018-12-13 13:55   ` Farhan Ali
  0 siblings, 0 replies; 83+ messages in thread
From: Farhan Ali @ 2018-12-13 13:55 UTC (permalink / raw)
  To: Jason J. Herne, qemu-devel, qemu-s390x, cohuck, pasic, bjsdjshi,
	borntraeger



On 12/12/2018 09:11 AM, Jason J. Herne wrote:
> Make a new routine find_boot_device to locate the boot device for all
> cases. not just virtio.

I don't think there should be a period after cases?

> 
> In one case no boot device is specified and a suitable boot device can not
> be auto detected. The error message for this case was specific to virtio
> devices. We update this message to remove virtio specific wording.
> 
> Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
> ---
>   pc-bios/s390-ccw/main.c  | 87 ++++++++++++++++++++++++++----------------------
>   tests/boot-serial-test.c |  2 +-
>   2 files changed, 49 insertions(+), 40 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index 7e3f65e..2457752 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -55,17 +55,18 @@ unsigned int get_loadparm_index(void)
>    * NOTE: The global variable blk_schid is updated to contain the subchannel
>    * information.
>    */
> -static bool find_dev(Schib *schib, int dev_no)
> +static bool find_subch(int dev_no)
>   {
> +    Schib schib;
>       int i, r;
> 
>       for (i = 0; i < 0x10000; i++) {
>           blk_schid.sch_no = i;
> -        r = stsch_err(blk_schid, schib);
> +        r = stsch_err(blk_schid, &schib);
>           if ((r == 3) || (r == -EIO)) {
>               break;
>           }
> -        if (!schib->pmcw.dnv) {
> +        if (!schib.pmcw.dnv) {
>               continue;
>           }
> 
> @@ -77,7 +78,7 @@ static bool find_dev(Schib *schib, int dev_no)
>               continue;
>           }
> 
> -        if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
> +        if ((dev_no < 0) || (schib.pmcw.dev == dev_no)) {
>               return true;
>           }
>       }
> @@ -133,56 +134,63 @@ static void boot_setup(void)
>       have_iplb = store_iplb(&iplb);
>   }
> 
> -static void virtio_setup(void)
> +static void find_boot_device(void)
>   {
> -    Schib schib;
> -    int ssid;
> -    bool found = false;
> -    uint16_t dev_no;
>       VDev *vdev = virtio_get_device();
> -    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
> -
> -    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
> +    int ssid;
> +    bool found;
> 
> -    if (have_iplb) {
> -        switch (iplb.pbt) {
> -        case S390_IPL_TYPE_CCW:
> -            dev_no = iplb.ccw.devno;
> -            debug_print_int("device no. ", dev_no);
> -            blk_schid.ssid = iplb.ccw.ssid & 0x3;
> -            debug_print_int("ssid ", blk_schid.ssid);
> -            found = find_dev(&schib, dev_no);
> -            break;
> -        case S390_IPL_TYPE_QEMU_SCSI:
> -            vdev->scsi_device_selected = true;
> -            vdev->selected_scsi_device.channel = iplb.scsi.channel;
> -            vdev->selected_scsi_device.target = iplb.scsi.target;
> -            vdev->selected_scsi_device.lun = iplb.scsi.lun;
> -            blk_schid.ssid = iplb.scsi.ssid & 0x3;
> -            found = find_dev(&schib, iplb.scsi.devno);
> -            break;
> -        default:
> -            panic("List-directed IPL not supported yet!\n");
> -        }
> -        menu_setup();
> -    } else {
> +    if (!have_iplb) {
>           for (ssid = 0; ssid < 0x3; ssid++) {
>               blk_schid.ssid = ssid;
> -            found = find_dev(&schib, -1);
> +            found = find_subch(-1);
>               if (found) {
> -                break;
> +                return;
>               }
>           }
> +        panic("Could not find a suitable boot device (none specified)\n");
>       }
> 
> -    IPL_assert(found, "No virtio device found");
> +    switch (iplb.pbt) {
> +    case S390_IPL_TYPE_CCW:
> +        debug_print_int("device no. ", iplb.ccw.devno);
> +        blk_schid.ssid = iplb.ccw.ssid & 0x3;
> +        debug_print_int("ssid ", blk_schid.ssid);
> +        found = find_subch(iplb.ccw.devno);
> +        break;
> +    case S390_IPL_TYPE_QEMU_SCSI:
> +        vdev->scsi_device_selected = true;
> +        vdev->selected_scsi_device.channel = iplb.scsi.channel;
> +        vdev->selected_scsi_device.target = iplb.scsi.target;
> +        vdev->selected_scsi_device.lun = iplb.scsi.lun;
> +        blk_schid.ssid = iplb.scsi.ssid & 0x3;
> +        found = find_subch(iplb.scsi.devno);
> +        break;
> +    default:
> +        panic("List-directed IPL not supported yet!\n");
> +    }
> +
> +    if (!found) {
> +        IPL_assert(found, "Boot device not found\n");
> +    }
> +}
> +
> +static void virtio_setup(void)
> +{
> +    VDev *vdev = virtio_get_device();
> +    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
> +
> +    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
> +
> +    if (have_iplb) {
> +        menu_setup();
> +    }
> 
>       if (virtio_get_device_type() == VIRTIO_ID_NET) {
>           sclp_print("Network boot device detected\n");
>           vdev->netboot_start_addr = qipl.netboot_start_addr;
>       } else {
>           virtio_blk_setup_device(blk_schid);
> -
>           IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected");
>       }
>   }
> @@ -192,8 +200,9 @@ int main(void)
>       sclp_setup();
>       css_setup();
>       boot_setup();
> -    virtio_setup();
> +    find_boot_device();
> 
> +    virtio_setup();
>       zipl_load(); /* no return */
> 
>       panic("Failed to load OS from hard disk\n");
> diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
> index 8ec6aed..064f5de 100644
> --- a/tests/boot-serial-test.c
> +++ b/tests/boot-serial-test.c
> @@ -112,7 +112,7 @@ static testdef_t tests[] = {
>       { "sparc", "SS-4", "", "MB86904" },
>       { "sparc", "SS-600MP", "", "TMS390Z55" },
>       { "sparc64", "sun4u", "", "UltraSPARC" },
> -    { "s390x", "s390-ccw-virtio", "", "virtio device" },
> +    { "s390x", "s390-ccw-virtio", "", "device" },
>       { "m68k", "mcf5208evb", "", "TT", sizeof(kernel_mcf5208), kernel_mcf5208 },
>       { "microblaze", "petalogix-s3adsp1800", "", "TT",
>         sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
> 

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path
  2018-12-12 14:11 Jason J. Herne
@ 2018-12-12 14:11 ` Jason J. Herne
  2018-12-13 13:55   ` Farhan Ali
  0 siblings, 1 reply; 83+ messages in thread
From: Jason J. Herne @ 2018-12-12 14:11 UTC (permalink / raw)
  To: qemu-devel, qemu-s390x, cohuck, pasic, bjsdjshi, borntraeger

Make a new routine find_boot_device to locate the boot device for all
cases. not just virtio.

In one case no boot device is specified and a suitable boot device can not
be auto detected. The error message for this case was specific to virtio
devices. We update this message to remove virtio specific wording.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
---
 pc-bios/s390-ccw/main.c  | 87 ++++++++++++++++++++++++++----------------------
 tests/boot-serial-test.c |  2 +-
 2 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 7e3f65e..2457752 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -55,17 +55,18 @@ unsigned int get_loadparm_index(void)
  * NOTE: The global variable blk_schid is updated to contain the subchannel
  * information.
  */
-static bool find_dev(Schib *schib, int dev_no)
+static bool find_subch(int dev_no)
 {
+    Schib schib;
     int i, r;
 
     for (i = 0; i < 0x10000; i++) {
         blk_schid.sch_no = i;
-        r = stsch_err(blk_schid, schib);
+        r = stsch_err(blk_schid, &schib);
         if ((r == 3) || (r == -EIO)) {
             break;
         }
-        if (!schib->pmcw.dnv) {
+        if (!schib.pmcw.dnv) {
             continue;
         }
 
@@ -77,7 +78,7 @@ static bool find_dev(Schib *schib, int dev_no)
             continue;
         }
 
-        if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
+        if ((dev_no < 0) || (schib.pmcw.dev == dev_no)) {
             return true;
         }
     }
@@ -133,56 +134,63 @@ static void boot_setup(void)
     have_iplb = store_iplb(&iplb);
 }
 
-static void virtio_setup(void)
+static void find_boot_device(void)
 {
-    Schib schib;
-    int ssid;
-    bool found = false;
-    uint16_t dev_no;
     VDev *vdev = virtio_get_device();
-    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
-
-    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
+    int ssid;
+    bool found;
 
-    if (have_iplb) {
-        switch (iplb.pbt) {
-        case S390_IPL_TYPE_CCW:
-            dev_no = iplb.ccw.devno;
-            debug_print_int("device no. ", dev_no);
-            blk_schid.ssid = iplb.ccw.ssid & 0x3;
-            debug_print_int("ssid ", blk_schid.ssid);
-            found = find_dev(&schib, dev_no);
-            break;
-        case S390_IPL_TYPE_QEMU_SCSI:
-            vdev->scsi_device_selected = true;
-            vdev->selected_scsi_device.channel = iplb.scsi.channel;
-            vdev->selected_scsi_device.target = iplb.scsi.target;
-            vdev->selected_scsi_device.lun = iplb.scsi.lun;
-            blk_schid.ssid = iplb.scsi.ssid & 0x3;
-            found = find_dev(&schib, iplb.scsi.devno);
-            break;
-        default:
-            panic("List-directed IPL not supported yet!\n");
-        }
-        menu_setup();
-    } else {
+    if (!have_iplb) {
         for (ssid = 0; ssid < 0x3; ssid++) {
             blk_schid.ssid = ssid;
-            found = find_dev(&schib, -1);
+            found = find_subch(-1);
             if (found) {
-                break;
+                return;
             }
         }
+        panic("Could not find a suitable boot device (none specified)\n");
     }
 
-    IPL_assert(found, "No virtio device found");
+    switch (iplb.pbt) {
+    case S390_IPL_TYPE_CCW:
+        debug_print_int("device no. ", iplb.ccw.devno);
+        blk_schid.ssid = iplb.ccw.ssid & 0x3;
+        debug_print_int("ssid ", blk_schid.ssid);
+        found = find_subch(iplb.ccw.devno);
+        break;
+    case S390_IPL_TYPE_QEMU_SCSI:
+        vdev->scsi_device_selected = true;
+        vdev->selected_scsi_device.channel = iplb.scsi.channel;
+        vdev->selected_scsi_device.target = iplb.scsi.target;
+        vdev->selected_scsi_device.lun = iplb.scsi.lun;
+        blk_schid.ssid = iplb.scsi.ssid & 0x3;
+        found = find_subch(iplb.scsi.devno);
+        break;
+    default:
+        panic("List-directed IPL not supported yet!\n");
+    }
+
+    if (!found) {
+        IPL_assert(found, "Boot device not found\n");
+    }
+}
+
+static void virtio_setup(void)
+{
+    VDev *vdev = virtio_get_device();
+    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
+
+    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
+
+    if (have_iplb) {
+        menu_setup();
+    }
 
     if (virtio_get_device_type() == VIRTIO_ID_NET) {
         sclp_print("Network boot device detected\n");
         vdev->netboot_start_addr = qipl.netboot_start_addr;
     } else {
         virtio_blk_setup_device(blk_schid);
-
         IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected");
     }
 }
@@ -192,8 +200,9 @@ int main(void)
     sclp_setup();
     css_setup();
     boot_setup();
-    virtio_setup();
+    find_boot_device();
 
+    virtio_setup();
     zipl_load(); /* no return */
 
     panic("Failed to load OS from hard disk\n");
diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
index 8ec6aed..064f5de 100644
--- a/tests/boot-serial-test.c
+++ b/tests/boot-serial-test.c
@@ -112,7 +112,7 @@ static testdef_t tests[] = {
     { "sparc", "SS-4", "", "MB86904" },
     { "sparc", "SS-600MP", "", "TMS390Z55" },
     { "sparc64", "sun4u", "", "UltraSPARC" },
-    { "s390x", "s390-ccw-virtio", "", "virtio device" },
+    { "s390x", "s390-ccw-virtio", "", "device" },
     { "m68k", "mcf5208evb", "", "TT", sizeof(kernel_mcf5208), kernel_mcf5208 },
     { "microblaze", "petalogix-s3adsp1800", "", "TT",
       sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 83+ messages in thread

end of thread, other threads:[~2019-03-04 19:23 UTC | newest]

Thread overview: 83+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-29 13:29 [Qemu-devel] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
2019-01-29 13:29 ` [Qemu-devel] [PATCH 01/15] s390 vfio-ccw: Add bootindex property and IPLB data Jason J. Herne
2019-01-30 16:56   ` Cornelia Huck
2019-01-30 20:12     ` Jason J. Herne
2019-01-30 22:21   ` Farhan Ali
2019-02-08 16:07     ` Jason J. Herne
2019-01-31 18:20   ` Cornelia Huck
2019-02-04 10:26   ` Cornelia Huck
2019-02-13 13:41     ` Jason J. Herne
2019-02-13 14:52       ` Cornelia Huck
2019-02-06 11:30   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
2019-02-08 16:04     ` Jason J. Herne
2019-02-11  8:15       ` Cornelia Huck
2019-02-11  8:39       ` Thomas Huth
2019-01-29 13:29 ` [Qemu-devel] [PATCH 02/15] s390-bios: decouple cio setup from virtio Jason J. Herne
2019-01-30 22:23   ` Farhan Ali
2019-02-04 10:28   ` Cornelia Huck
2019-02-05  9:55   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
2019-01-29 13:29 ` [Qemu-devel] [PATCH 03/15] s390-bios: decouple common boot logic " Jason J. Herne
2019-01-30 22:27   ` Farhan Ali
2019-02-04 10:31   ` Cornelia Huck
2019-01-29 13:29 ` [Qemu-devel] [PATCH 04/15] s390-bios: Extend find_dev() for non-virtio devices Jason J. Herne
2019-02-04 10:33   ` Cornelia Huck
2019-02-11 16:38   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
2019-02-13 13:59     ` Jason J. Herne
2019-03-04 19:23       ` Thomas Huth
2019-01-29 13:29 ` [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path Jason J. Herne
2019-01-31 13:44   ` Farhan Ali
2019-02-04 10:45   ` Cornelia Huck
2019-02-11 17:57     ` Jason J. Herne
2019-02-12  9:32       ` Cornelia Huck
2019-01-29 13:29 ` [Qemu-devel] [PATCH 06/15] s390-bios: Clean up cio.h Jason J. Herne
2019-01-31 14:23   ` Farhan Ali
2019-02-04 10:48   ` Cornelia Huck
2019-02-12 12:32     ` [Qemu-devel] [qemu-s390x] " Thomas Huth
2019-01-29 13:29 ` [Qemu-devel] [PATCH 07/15] s390-bios: Decouple channel i/o logic from virtio Jason J. Herne
2019-01-31 14:38   ` Farhan Ali
2019-01-31 14:45     ` Jason J. Herne
2019-02-04 10:57   ` Cornelia Huck
2019-02-13 14:40     ` Jason J. Herne
2019-01-29 13:29 ` [Qemu-devel] [PATCH 08/15] s390-bios: Map low core memory Jason J. Herne
2019-02-12 12:47   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
2019-02-18 15:40     ` Jason J. Herne
2019-02-18 15:49       ` Cornelia Huck
2019-02-18 16:52       ` Thomas Huth
2019-01-29 13:29 ` [Qemu-devel] [PATCH 09/15] s390-bios: ptr2u32 and u32toptr Jason J. Herne
2019-02-04 11:03   ` Cornelia Huck
2019-02-12 12:50   ` [Qemu-devel] [qemu-s390x] " Thomas Huth
2019-01-29 13:29 ` [Qemu-devel] [PATCH 10/15] s390-bios: Support for running format-0/1 channel programs Jason J. Herne
2019-01-31 17:31   ` Farhan Ali
2019-02-04 11:13     ` Cornelia Huck
2019-02-04 19:29       ` Farhan Ali
2019-02-05 10:18         ` Cornelia Huck
2019-02-12 13:10           ` Halil Pasic
2019-02-27 13:35           ` Jason J. Herne
2019-02-27 14:07             ` Cornelia Huck
2019-02-27 13:32       ` Jason J. Herne
2019-02-27 14:06         ` Cornelia Huck
2019-02-04 11:24   ` Cornelia Huck
2019-02-21 18:01     ` Jason J. Herne
2019-02-22  8:35       ` Cornelia Huck
2019-01-29 13:29 ` [Qemu-devel] [PATCH 11/15] s390-bios: cio error handling Jason J. Herne
2019-02-04 11:41   ` Cornelia Huck
2019-02-28 15:59     ` Jason J. Herne
2019-02-28 16:11       ` Cornelia Huck
2019-01-29 13:29 ` [Qemu-devel] [PATCH 12/15] s390-bios: Refactor virtio to run channel programs via cio Jason J. Herne
2019-02-04 11:44   ` Cornelia Huck
2019-02-25 13:20     ` Jason J. Herne
2019-02-25 17:07       ` Cornelia Huck
2019-01-29 13:29 ` [Qemu-devel] [PATCH 13/15] s390-bios: Use control unit type to determine boot method Jason J. Herne
2019-02-04 11:46   ` Cornelia Huck
2019-01-29 13:29 ` [Qemu-devel] [PATCH 14/15] s390-bios: Add channel command codes/structs needed for dasd-ipl Jason J. Herne
2019-02-04 11:47   ` Cornelia Huck
2019-01-29 13:29 ` [Qemu-devel] [PATCH 15/15] s390-bios: Support booting from real dasd device Jason J. Herne
2019-01-31 18:23   ` Cornelia Huck
2019-02-04 12:02   ` Cornelia Huck
2019-02-19 14:57     ` Jason J. Herne
2019-02-21  2:52   ` [Qemu-devel] [qemu-s390x] " Eric Farman
2019-02-21 13:22     ` Jason J. Herne
2019-01-29 16:40 ` [Qemu-devel] [qemu-s390x] [PATCH 00/15] s390: vfio-ccw dasd ipl support Jason J. Herne
2019-01-31 18:10 ` [Qemu-devel] " no-reply
  -- strict thread matches above, loose matches on Subject: below --
2018-12-12 14:11 Jason J. Herne
2018-12-12 14:11 ` [Qemu-devel] [PATCH 05/15] s390-bios: Factor finding boot device out of virtio code path Jason J. Herne
2018-12-13 13:55   ` Farhan Ali

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.