From b498484ed49ab9d1fcada3468f95dda1a5f59366 Mon Sep 17 00:00:00 2001
From: Cornelia Huck <cornelia.huck@de.ibm.com>
Date: Wed, 4 Nov 2015 18:40:54 +0100
Subject: [PATCH 01/15] s390x/css: sense data endianness

We keep the device's sense data in a byte array (following the
architecture), but the ecws are an array of 32 bit values. If we
just blindly copy the values, the sense data will change from
de-facto BE data to de-facto cpu-endian data, which means we end
up doing an incorrect conversion on LE hosts.

Let's just explicitly convert to cpu-endianness while assembling
the irb.

Reported-by: Andy Lutomirski <luto@kernel.org>
Tested-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 hw/s390x/css.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index c033612889..19851ce6a9 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -892,8 +892,14 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
         /* If a unit check is pending, copy sense data. */
         if ((s->dstat & SCSW_DSTAT_UNIT_CHECK) &&
             (p->chars & PMCW_CHARS_MASK_CSENSE)) {
+            int i;
+
             irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
+            /* Attention: sense_data is already BE! */
             memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
+            for (i = 0; i < ARRAY_SIZE(irb.ecw); i++) {
+                irb.ecw[i] = be32_to_cpu(irb.ecw[i]);
+            }
             irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
         }
     }

From dce1b089249f52c053cf74dc3da98aea16656961 Mon Sep 17 00:00:00 2001
From: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Date: Wed, 28 Oct 2015 11:30:23 +0800
Subject: [PATCH 02/15] s390x/pci : fix up s390 pci iommu translation function

On s390x, each pci device has its own iommu, which is only properly
setup in qemu once the mpcifc instruction used to register the
translation table has been intercepted. Therefore, for a pci device that
is not configured or has not been initialized, proper translation is
neither required nor possible. Moreover, we may not have a host bridge
device ready yet.

This was exposed by a recent vfio change that triggers iommu translation
during the initialization of the vfio pci device. Let's do an early exit
in that case.

Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/s390-pci-bus.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 560b66a501..d5712ae754 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -309,8 +309,7 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
     uint64_t pte;
     uint32_t flags;
     S390PCIBusDevice *pbdev = container_of(iommu, S390PCIBusDevice, mr);
-    S390pciState *s = S390_PCI_HOST_BRIDGE(pci_device_root_bus(pbdev->pdev)
-                                           ->qbus.parent);
+    S390pciState *s;
     IOMMUTLBEntry ret = {
         .target_as = &address_space_memory,
         .iova = 0,
@@ -319,8 +318,13 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
         .perm = IOMMU_NONE,
     };
 
+    if (!pbdev->configured || !pbdev->pdev) {
+        return ret;
+    }
+
     DPRINTF("iommu trans addr 0x%" PRIx64 "\n", addr);
 
+    s = S390_PCI_HOST_BRIDGE(pci_device_root_bus(pbdev->pdev)->qbus.parent);
     /* s390 does not have an APIC mapped to main storage so we use
      * a separate AddressSpace only for msix notifications
      */

From c5bfb202bb3bcdc1a368e85fef336e89d6254f8c Mon Sep 17 00:00:00 2001
From: Cornelia Huck <cornelia.huck@de.ibm.com>
Date: Wed, 4 Nov 2015 15:59:55 +0100
Subject: [PATCH 03/15] MAINTAINERS: update s390 file patterns

We were missing some files, and some files should get an additional
entry to add the people actually looking after the code.

Reported-by: Thomas Huth <thuth@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 MAINTAINERS | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index fc8abe8dd3..9585a8b8eb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -237,9 +237,12 @@ M: Cornelia Huck <cornelia.huck@de.ibm.com>
 M: Alexander Graf <agraf@suse.de>
 S: Maintained
 F: target-s390x/kvm.c
+F: target-s390x/ioinst.[ch]
+F: target-s390x/machine.c
 F: hw/intc/s390_flic.c
 F: hw/intc/s390_flic_kvm.c
 F: include/hw/s390x/s390_flic.h
+F: gdb-xml/s390*.xml
 
 X86
 M: Paolo Bonzini <pbonzini@redhat.com>
@@ -637,14 +640,11 @@ M: Christian Borntraeger <borntraeger@de.ibm.com>
 M: Alexander Graf <agraf@suse.de>
 S: Supported
 F: hw/char/sclp*.[hc]
-F: hw/s390x/s390-virtio-ccw.c
-F: hw/s390x/css.[hc]
-F: hw/s390x/sclp*.[hc]
-F: hw/s390x/ipl*.[hc]
-F: hw/s390x/*pci*.[hc]
-F: hw/s390x/s390-skeys*.c
+F: hw/s390x/
+X: hw/s390x/s390-virtio-bus.[ch]
 F: include/hw/s390x/
 F: pc-bios/s390-ccw/
+F: hw/watchdog/wdt_diag288.c
 T: git git://github.com/cohuck/qemu virtio-ccw-upstr
 
 UniCore32 Machines

From 3e9ed24b84c4acdd077904a74eaec6d95cfef928 Mon Sep 17 00:00:00 2001
From: Cornelia Huck <cornelia.huck@de.ibm.com>
Date: Wed, 4 Nov 2015 16:08:20 +0100
Subject: [PATCH 04/15] MAINTAINERS: update virtio-ccw/s390 git tree

Let's reference the git branch I actually use, and add Christian's
git tree.

Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 MAINTAINERS | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9585a8b8eb..9e1fa7236a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -243,6 +243,8 @@ F: hw/intc/s390_flic.c
 F: hw/intc/s390_flic_kvm.c
 F: include/hw/s390x/s390_flic.h
 F: gdb-xml/s390*.xml
+T: git git://github.com/cohuck/qemu.git s390-next
+T: git git://github.com/borntraeger/qemu.git s390-next
 
 X86
 M: Paolo Bonzini <pbonzini@redhat.com>
@@ -645,7 +647,8 @@ X: hw/s390x/s390-virtio-bus.[ch]
 F: include/hw/s390x/
 F: pc-bios/s390-ccw/
 F: hw/watchdog/wdt_diag288.c
-T: git git://github.com/cohuck/qemu virtio-ccw-upstr
+T: git git://github.com/cohuck/qemu.git s390-next
+T: git git://github.com/borntraeger/qemu.git s390-next
 
 UniCore32 Machines
 -------------
@@ -872,7 +875,8 @@ M: Cornelia Huck <cornelia.huck@de.ibm.com>
 M: Christian Borntraeger <borntraeger@de.ibm.com>
 S: Supported
 F: hw/s390x/virtio-ccw.[hc]
-T: git git://github.com/cohuck/qemu virtio-ccw-upstr
+T: git git://github.com/cohuck/qemu.git s390-next
+T: git git://github.com/borntraeger/qemu.git s390-next
 
 virtio-input
 M: Gerd Hoffmann <kraxel@redhat.com>

From ae23a33591056d6349753766047ebc511158da9c Mon Sep 17 00:00:00 2001
From: Dominik Dingel <dingel@linux.vnet.ibm.com>
Date: Tue, 12 May 2015 13:21:30 +0200
Subject: [PATCH 05/15] s390x: switch to memory_region_allocate_system_memory

By replacing memory_region_init_ram with memory_region_allocate_system_memory
we gain goodies like mem-path backends. This will allow us to use hugetlbfs
once the kernel supports it.

Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/s390-virtio-ccw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 84221f4f57..5a52ff26eb 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -104,8 +104,7 @@ void s390_memory_init(ram_addr_t mem_size)
     MemoryRegion *ram = g_new(MemoryRegion, 1);
 
     /* allocate RAM for core */
-    memory_region_init_ram(ram, NULL, "s390.ram", mem_size, &error_fatal);
-    vmstate_register_ram_global(ram);
+    memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
     memory_region_add_subregion(sysmem, 0, ram);
 
     /* Initialize storage key device */

From 4c292a009700755a1e6b234063ef3f2db235aaae Mon Sep 17 00:00:00 2001
From: Dominik Dingel <dingel@linux.vnet.ibm.com>
Date: Tue, 11 Aug 2015 11:12:12 +0200
Subject: [PATCH 06/15] s390x/kvm: don't enable CMMA when hugetlbfs will be
 used

On hugetlbfs CMMA will not be useful as every ESSA instruction will trap.
So don't offer CMMA to guests with a hugepages backing.

Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 target-s390x/kvm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index c3be180de2..75a0e5d1c3 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -258,7 +258,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
     cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
 
-    kvm_s390_enable_cmma(s);
+    if (!mem_path) {
+        kvm_s390_enable_cmma(s);
+    }
 
     if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
         || !kvm_check_extension(s, KVM_CAP_S390_COW)) {

From 38150be860434de9d9c76cef71ff5c6b6112ee8f Mon Sep 17 00:00:00 2001
From: Maxim Samoylov <max7255@linux.vnet.ibm.com>
Date: Mon, 12 Oct 2015 17:50:20 +0200
Subject: [PATCH 07/15] pc-bios/s390-ccw: Always adjust virtio sector count

Let's always adjust the sector number to be read using the current
virtio block size value.

This prepares for the implementation of IPL from ISO-9660 media.

Signed-off-by: Maxim Samoylov <max7255@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 pc-bios/s390-ccw/virtio.h | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index c23466b8db..76c42f119d 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -199,14 +199,9 @@ extern int virtio_read_many(ulong sector, void *load_addr, int sec_num);
 
 #define VIRTIO_SECTOR_SIZE 512
 
-static inline ulong virtio_eckd_sector_adjust(ulong sector)
-{
-     return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE);
-}
-
 static inline ulong virtio_sector_adjust(ulong sector)
 {
-    return virtio_disk_is_eckd() ? virtio_eckd_sector_adjust(sector) : sector;
+    return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE);
 }
 
 #endif /* VIRTIO_H */

From 866cac91e06219f473a2900eefef0d1cf242b136 Mon Sep 17 00:00:00 2001
From: Maxim Samoylov <max7255@linux.vnet.ibm.com>
Date: Mon, 12 Oct 2015 17:50:20 +0200
Subject: [PATCH 08/15] pc-bios/s390-ccw: ISO-9660 El Torito boot
 implementation

This patch enables boot from media formatted according to
ISO-9660 and El Torito bootable CD specification.

We try to boot from device as ISO-9660 media when SCSI IPL failed.

The first boot catalog entry with bootable flag is used.

ISO-9660 media with default 2048-bytes sector size only is supported.

Signed-off-by: Maxim Samoylov <max7255@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 pc-bios/s390-ccw/bootmap.c | 107 +++++++++++++++++++++
 pc-bios/s390-ccw/bootmap.h | 191 +++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/virtio.c  |   7 ++
 pc-bios/s390-ccw/virtio.h  |   1 +
 4 files changed, 306 insertions(+)

diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index b678d5ebb8..7c8dce154a 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -444,6 +444,107 @@ static void ipl_scsi(void)
     zipl_run(prog_table_entry); /* no return */
 }
 
+/***********************************************************************
+ * IPL El Torito ISO9660 image or DVD
+ */
+
+static bool is_iso_bc_entry_compatible(IsoBcSection *s)
+{
+    return true;
+}
+
+static void load_iso_bc_entry(IsoBcSection *load)
+{
+    IsoBcSection s = *load;
+    /*
+     * According to spec, extent for each file
+     * is padded and ISO_SECTOR_SIZE bytes aligned
+     */
+    uint32_t blks_to_load = bswap16(s.sector_count) >> ET_SECTOR_SHIFT;
+
+    read_iso_boot_image(bswap32(s.load_rba),
+                        (void *)((uint64_t)bswap16(s.load_segment)),
+                        blks_to_load);
+
+    /* Trying to get PSW at zero address */
+    if (*((uint64_t *)0) & IPL_PSW_MASK) {
+        jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
+    }
+
+    /* Try default linux start address */
+    jump_to_IPL_code(KERN_IMAGE_START);
+}
+
+static uint32_t find_iso_bc(void)
+{
+    IsoVolDesc *vd = (IsoVolDesc *)sec;
+    uint32_t block_num = ISO_PRIMARY_VD_SECTOR;
+
+    if (virtio_read_many(block_num++, sec, 1)) {
+        /* If primary vd cannot be read, there is no boot catalog */
+        return 0;
+    }
+
+    while (is_iso_vd_valid(vd) && vd->type != VOL_DESC_TERMINATOR) {
+        if (vd->type == VOL_DESC_TYPE_BOOT) {
+            IsoVdElTorito *et = &vd->vd.boot;
+
+            if (!_memcmp(&et->el_torito[0], el_torito_magic, 32)) {
+                return bswap32(et->bc_offset);
+            }
+        }
+        read_iso_sector(block_num++, sec,
+                        "Failed to read ISO volume descriptor");
+    }
+
+    return 0;
+}
+
+static IsoBcSection *find_iso_bc_entry(void)
+{
+    IsoBcEntry *e = (IsoBcEntry *)sec;
+    uint32_t offset = find_iso_bc();
+    int i;
+
+    if (!offset) {
+        return NULL;
+    }
+
+    read_iso_sector(offset, sec, "Failed to read El Torito boot catalog");
+
+    if (!is_iso_bc_valid(e)) {
+        /* The validation entry is mandatory */
+        virtio_panic("No valid boot catalog found!\n");
+        return NULL;
+    }
+
+    /*
+     * Each entry has 32 bytes size, so one sector cannot contain > 64 entries.
+     * We consider only boot catalogs with no more than 64 entries.
+     */
+    for (i = 1; i < ISO_BC_ENTRY_PER_SECTOR; i++) {
+        if (e[i].id == ISO_BC_BOOTABLE_SECTION) {
+            if (is_iso_bc_entry_compatible(&e[i].body.sect)) {
+                return &e[i].body.sect;
+            }
+        }
+    }
+
+    virtio_panic("No suitable boot entry found on ISO-9660 media!\n");
+
+    return NULL;
+}
+
+static void ipl_iso_el_torito(void)
+{
+    IsoBcSection *s = find_iso_bc_entry();
+
+    if (s) {
+        load_iso_bc_entry(s);
+        /* no return */
+    }
+}
+
 /***********************************************************************
  * IPL starts here
  */
@@ -463,6 +564,12 @@ void zipl_load(void)
         ipl_scsi(); /* no return */
     }
 
+    /* Check if we can boot as ISO media */
+    if (virtio_guessed_disk_nature()) {
+        virtio_assume_iso9660();
+    }
+    ipl_iso_el_torito();
+
     /* We have failed to follow the SCSI scheme, so */
     if (virtio_guessed_disk_nature()) {
         sclp_print("Using guessed DASD geometry.\n");
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index ab132e3579..4f6f767584 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -341,4 +341,195 @@ static inline bool magic_match(const void *data, const void *magic)
     return *((uint32_t *)data) == *((uint32_t *)magic);
 }
 
+static inline int _memcmp(const void *s1, const void *s2, size_t n)
+{
+    int i;
+    const uint8_t *p1 = s1, *p2 = s2;
+
+    for (i = 0; i < n; i++) {
+        if (p1[i] != p2[i]) {
+            return p1[i] > p2[i] ? 1 : -1;
+        }
+    }
+
+    return 0;
+}
+
+/* from include/qemu/bswap.h */
+
+/* El Torito is always little-endian */
+static inline uint16_t bswap16(uint16_t x)
+{
+    return ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
+}
+
+static inline uint32_t bswap32(uint32_t x)
+{
+    return ((x & 0x000000ffU) << 24) | ((x & 0x0000ff00U) <<  8) |
+           ((x & 0x00ff0000U) >>  8) | ((x & 0xff000000U) >> 24);
+}
+
+static inline uint64_t bswap64(uint64_t x)
+{
+    return ((x & 0x00000000000000ffULL) << 56) |
+           ((x & 0x000000000000ff00ULL) << 40) |
+           ((x & 0x0000000000ff0000ULL) << 24) |
+           ((x & 0x00000000ff000000ULL) <<  8) |
+           ((x & 0x000000ff00000000ULL) >>  8) |
+           ((x & 0x0000ff0000000000ULL) >> 24) |
+           ((x & 0x00ff000000000000ULL) >> 40) |
+           ((x & 0xff00000000000000ULL) >> 56);
+}
+
+#define ISO_SECTOR_SIZE 2048
+/* El Torito specifies boot image size in 512 byte blocks */
+#define ET_SECTOR_SHIFT 2
+#define KERN_IMAGE_START 0x010000UL
+#define PSW_MASK_64 0x0000000100000000ULL
+#define PSW_MASK_32 0x0000000080000000ULL
+#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
+
+#define ISO_PRIMARY_VD_SECTOR 16
+
+static inline void read_iso_sector(uint32_t block_offset, void *buf,
+                                   const char *errmsg)
+{
+    IPL_assert(virtio_read_many(block_offset, buf, 1) == 0, errmsg);
+}
+
+static inline void read_iso_boot_image(uint32_t block_offset, void *load_addr,
+                                       uint32_t blks_to_load)
+{
+    IPL_assert(virtio_read_many(block_offset, load_addr, blks_to_load) == 0,
+               "Failed to read boot image!");
+}
+
+const uint8_t el_torito_magic[] = "EL TORITO SPECIFICATION"
+                                  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+
+typedef struct IsoDirHdr {
+    uint8_t dr_len;
+    uint8_t ear_len;
+    uint64_t ext_loc;
+    uint64_t data_len;
+    uint8_t recording_datetime[7];
+    uint8_t file_flags;
+    uint8_t file_unit_size;
+    uint8_t gap_size;
+    uint32_t vol_seqnum;
+    uint8_t fileid_len;
+} __attribute__((packed)) IsoDirHdr;
+
+typedef struct IsoVdElTorito {
+    uint8_t el_torito[32]; /* must contain el_torito_magic value */
+    uint8_t unused0[32];
+    uint32_t bc_offset;
+    uint8_t unused1[1974];
+} __attribute__((packed)) IsoVdElTorito;
+
+typedef struct IsoVdPrimary {
+    uint8_t unused1;
+    uint8_t sys_id[32];
+    uint8_t vol_id[32];
+    uint8_t unused2[8];
+    uint64_t vol_space_size;
+    uint8_t unused3[32];
+    uint32_t vol_set_size;
+    uint32_t vol_seqnum;
+    uint32_t log_block_size;
+    uint64_t path_table_size;
+    uint32_t l_path_table;
+    uint32_t opt_l_path_table;
+    uint32_t m_path_table;
+    uint32_t opt_m_path_table;
+    IsoDirHdr rootdir;
+    uint8_t root_null;
+    uint8_t reserved2[1858];
+} __attribute__((packed)) IsoVdPrimary;
+
+typedef struct IsoVolDesc {
+    uint8_t type;
+    uint8_t ident[5];
+    uint8_t version;
+    union {
+        IsoVdElTorito boot;
+        IsoVdPrimary primary;
+    } vd;
+} __attribute__((packed)) IsoVolDesc;
+
+const uint8_t vol_desc_magic[] = "CD001";
+#define VOL_DESC_TYPE_BOOT 0
+#define VOL_DESC_TYPE_PRIMARY 1
+#define VOL_DESC_TYPE_SUPPLEMENT 2
+#define VOL_DESC_TYPE_PARTITION 3
+#define VOL_DESC_TERMINATOR 255
+
+static inline bool is_iso_vd_valid(IsoVolDesc *vd)
+{
+    return !_memcmp(&vd->ident[0], vol_desc_magic, 5) &&
+           vd->version == 0x1 &&
+           vd->type <= VOL_DESC_TYPE_PARTITION;
+}
+
+typedef struct IsoBcValid {
+    uint8_t platform_id;
+    uint16_t reserved;
+    uint8_t id[24];
+    uint16_t checksum;
+    uint8_t key[2];
+} __attribute__((packed)) IsoBcValid;
+
+typedef struct IsoBcSection {
+    uint8_t boot_type;
+    uint16_t load_segment;
+    uint8_t sys_type;
+    uint8_t unused;
+    uint16_t sector_count;
+    uint32_t load_rba;
+    uint8_t selection[20];
+} __attribute__((packed)) IsoBcSection;
+
+typedef struct IsoBcHdr {
+    uint8_t platform_id;
+    uint16_t sect_num;
+    uint8_t id[28];
+} __attribute__((packed)) IsoBcHdr;
+
+typedef struct IsoBcEntry {
+    uint8_t id;
+    union {
+        IsoBcValid valid; /* id == 0x01 */
+        IsoBcSection sect; /* id == 0x88 || id == 0x0 */
+        IsoBcHdr hdr; /* id == 0x90 || id == 0x91 */
+    } body;
+} __attribute__((packed)) IsoBcEntry;
+
+#define ISO_BC_ENTRY_PER_SECTOR (ISO_SECTOR_SIZE / sizeof(IsoBcEntry))
+#define ISO_BC_HDR_VALIDATION 0x01
+#define ISO_BC_BOOTABLE_SECTION 0x88
+#define ISO_BC_MAGIC_55 0x55
+#define ISO_BC_MAGIC_AA 0xaa
+#define ISO_BC_PLATFORM_X86 0x0
+#define ISO_BC_PLATFORM_PPC 0x1
+#define ISO_BC_PLATFORM_MAC 0x2
+
+static inline bool is_iso_bc_valid(IsoBcEntry *e)
+{
+    IsoBcValid *v = &e->body.valid;
+
+    if (e->id != ISO_BC_HDR_VALIDATION) {
+        return false;
+    }
+
+    if (v->platform_id != ISO_BC_PLATFORM_X86 &&
+        v->platform_id != ISO_BC_PLATFORM_PPC &&
+        v->platform_id != ISO_BC_PLATFORM_MAC) {
+        return false;
+    }
+
+    return v->key[0] == ISO_BC_MAGIC_55 &&
+           v->key[1] == ISO_BC_MAGIC_AA &&
+           v->reserved == 0x0;
+}
+
 #endif /* _PC_BIOS_S390_CCW_BOOTMAP_H */
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 57ff1b07ee..87aed38a95 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -278,6 +278,13 @@ void virtio_assume_scsi(void)
     blk_cfg.physical_block_exp = 0;
 }
 
+void virtio_assume_iso9660(void)
+{
+    guessed_disk_nature = true;
+    blk_cfg.blk_size = 2048;
+    blk_cfg.physical_block_exp = 0;
+}
+
 void virtio_assume_eckd(void)
 {
     guessed_disk_nature = true;
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 76c42f119d..afa01a885b 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -187,6 +187,7 @@ typedef struct VirtioBlkConfig {
 bool virtio_guessed_disk_nature(void);
 void virtio_assume_scsi(void);
 void virtio_assume_eckd(void);
+void virtio_assume_iso9660(void);
 
 extern bool virtio_disk_is_scsi(void);
 extern bool virtio_disk_is_eckd(void);

From ba21f0cca8165c5b284274edd12dc955cf4fb248 Mon Sep 17 00:00:00 2001
From: Maxim Samoylov <max7255@linux.vnet.ibm.com>
Date: Mon, 12 Oct 2015 17:50:20 +0200
Subject: [PATCH 09/15] pc-bios/s390-ccw: El Torito s390x boot entry check

Boot entry is considered compatible if boot image is Linux kernel
with matching S390 Linux magic string.

Empty boot images with sector_count == 0 are considered broken.

Signed-off-by: Maxim Samoylov <max7255@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 pc-bios/s390-ccw/bootmap.c | 11 ++++++++++-
 pc-bios/s390-ccw/bootmap.h |  8 ++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 7c8dce154a..82cca9c9e8 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -450,7 +450,16 @@ static void ipl_scsi(void)
 
 static bool is_iso_bc_entry_compatible(IsoBcSection *s)
 {
-    return true;
+    uint8_t *magic_sec = (uint8_t *)(sec + ISO_SECTOR_SIZE);
+
+    if (s->unused || !s->sector_count) {
+        return false;
+    }
+    read_iso_sector(bswap32(s->load_rba), magic_sec,
+                    "Failed to read image sector 0");
+
+    /* Checking bytes 8 - 32 for S390 Linux magic */
+    return !_memcmp(magic_sec + 8, linux_s390_magic, 24);
 }
 
 static void load_iso_bc_entry(IsoBcSection *load)
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index 4f6f767584..cc77fd753c 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -495,6 +495,14 @@ typedef struct IsoBcHdr {
     uint8_t id[28];
 } __attribute__((packed)) IsoBcHdr;
 
+/*
+ * Match two CCWs located after PSW and eight filler bytes.
+ * From libmagic and arch/s390/kernel/head.S.
+ */
+const uint8_t linux_s390_magic[] = "\x02\x00\x00\x18\x60\x00\x00\x50\x02\x00"
+                                   "\x00\x68\x60\x00\x00\x50\x40\x40\x40\x40"
+                                   "\x40\x40\x40\x40";
+
 typedef struct IsoBcEntry {
     uint8_t id;
     union {

From 869648e87eeb998cc0ede230f3b7aabfdf0eb2dd Mon Sep 17 00:00:00 2001
From: Maxim Samoylov <max7255@linux.vnet.ibm.com>
Date: Mon, 12 Oct 2015 17:50:20 +0200
Subject: [PATCH 10/15] pc-bios/s390-ccw: El Torito 16-bit boot image size
 field workaround

Because of El Torito spec flaw boot image size needs to be verified.

Boot catalog entry size field has 16-bit width, and specifies size
in 512-byte units.

Thus, boot image size cannot exceed 32M.

We actually search for the file to get the file size.

This is done by scanning the ISO directory tree for the ISO block number
and reading the file size from the directory entry.

Signed-off-by: Maxim Samoylov <max7255@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 pc-bios/s390-ccw/bootmap.c | 90 ++++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/bootmap.h |  7 +++
 2 files changed, 97 insertions(+)

diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 82cca9c9e8..415508b279 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -462,6 +462,87 @@ static bool is_iso_bc_entry_compatible(IsoBcSection *s)
     return !_memcmp(magic_sec + 8, linux_s390_magic, 24);
 }
 
+/* Location of the current sector of the directory */
+static uint32_t sec_loc[ISO9660_MAX_DIR_DEPTH];
+/* Offset in the current sector of the directory */
+static uint32_t sec_offset[ISO9660_MAX_DIR_DEPTH];
+/* Remained directory space in bytes */
+static uint32_t dir_rem[ISO9660_MAX_DIR_DEPTH];
+
+static inline uint32_t iso_get_file_size(uint32_t load_rba)
+{
+    IsoVolDesc *vd = (IsoVolDesc *)sec;
+    IsoDirHdr *cur_record = &vd->vd.primary.rootdir;
+    uint8_t *temp = sec + ISO_SECTOR_SIZE;
+    int level = 0;
+
+    read_iso_sector(ISO_PRIMARY_VD_SECTOR, sec,
+                    "Failed to read ISO primary descriptor");
+    sec_loc[0] = iso_733_to_u32(cur_record->ext_loc);
+    dir_rem[0] = 0;
+    sec_offset[0] = 0;
+
+    while (level >= 0) {
+        IPL_assert(sec_offset[level] <= ISO_SECTOR_SIZE,
+                   "Directory tree structure violation");
+
+        cur_record = (IsoDirHdr *)(temp + sec_offset[level]);
+
+        if (sec_offset[level] == 0) {
+            read_iso_sector(sec_loc[level], temp,
+                            "Failed to read ISO directory");
+            if (dir_rem[level] == 0) {
+                /* Skip self and parent records */
+                dir_rem[level] = iso_733_to_u32(cur_record->data_len) -
+                                 cur_record->dr_len;
+                sec_offset[level] += cur_record->dr_len;
+
+                cur_record = (IsoDirHdr *)(temp + sec_offset[level]);
+                dir_rem[level] -= cur_record->dr_len;
+                sec_offset[level] += cur_record->dr_len;
+                continue;
+            }
+        }
+
+        if (!cur_record->dr_len || sec_offset[level] == ISO_SECTOR_SIZE) {
+            /* Zero-padding and/or the end of current sector */
+            dir_rem[level] -= ISO_SECTOR_SIZE - sec_offset[level];
+            sec_offset[level] = 0;
+            sec_loc[level]++;
+        } else {
+            /* The directory record is valid */
+            if (load_rba == iso_733_to_u32(cur_record->ext_loc)) {
+                return iso_733_to_u32(cur_record->data_len);
+            }
+
+            dir_rem[level] -= cur_record->dr_len;
+            sec_offset[level] += cur_record->dr_len;
+
+            if (cur_record->file_flags & 0x2) {
+                /* Subdirectory */
+                if (level == ISO9660_MAX_DIR_DEPTH - 1) {
+                    sclp_print("ISO-9660 directory depth limit exceeded\n");
+                } else {
+                    level++;
+                    sec_loc[level] = iso_733_to_u32(cur_record->ext_loc);
+                    sec_offset[level] = 0;
+                    dir_rem[level] = 0;
+                    continue;
+                }
+            }
+        }
+
+        if (dir_rem[level] == 0) {
+            /* Nothing remaining */
+            level--;
+            read_iso_sector(sec_loc[level], temp,
+                            "Failed to read ISO directory");
+        }
+    }
+
+    return 0;
+}
+
 static void load_iso_bc_entry(IsoBcSection *load)
 {
     IsoBcSection s = *load;
@@ -470,6 +551,15 @@ static void load_iso_bc_entry(IsoBcSection *load)
      * is padded and ISO_SECTOR_SIZE bytes aligned
      */
     uint32_t blks_to_load = bswap16(s.sector_count) >> ET_SECTOR_SHIFT;
+    uint32_t real_size = iso_get_file_size(bswap32(s.load_rba));
+
+    if (real_size) {
+        /* Round up blocks to load */
+        blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE;
+        sclp_print("ISO boot image size verified\n");
+    } else {
+        sclp_print("ISO boot image size could not be verified\n");
+    }
 
     read_iso_boot_image(bswap32(s.load_rba),
                         (void *)((uint64_t)bswap16(s.load_segment)),
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index cc77fd753c..f98765b841 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -381,6 +381,11 @@ static inline uint64_t bswap64(uint64_t x)
            ((x & 0xff00000000000000ULL) >> 56);
 }
 
+static inline uint32_t iso_733_to_u32(uint64_t x)
+{
+    return (uint32_t)x;
+}
+
 #define ISO_SECTOR_SIZE 2048
 /* El Torito specifies boot image size in 512 byte blocks */
 #define ET_SECTOR_SHIFT 2
@@ -407,6 +412,8 @@ static inline void read_iso_boot_image(uint32_t block_offset, void *load_addr,
 const uint8_t el_torito_magic[] = "EL TORITO SPECIFICATION"
                                   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 
+#define ISO9660_MAX_DIR_DEPTH 8
+
 typedef struct IsoDirHdr {
     uint8_t dr_len;
     uint8_t ear_len;

From 81a93ee64d78a1933998ff1b95f06b6d67db46fd Mon Sep 17 00:00:00 2001
From: Cornelia Huck <cornelia.huck@de.ibm.com>
Date: Thu, 5 Nov 2015 13:47:38 +0100
Subject: [PATCH 11/15] pc-bios/s390-ccw: rebuild image

Contains:
  pc-bios/s390-ccw: Always adjust virtio sector count
  pc-bios/s390-ccw: ISO-9660 El Torito boot implementation
  pc-bios/s390-ccw: El Torito s390x boot entry check
  pc-bios/s390-ccw: El Torito 16-bit boot image size field workaround

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 pc-bios/s390-ccw.img | Bin 13856 -> 17760 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index 0c540a10cf2a662889f5fbd08a7580395a7577d0..e0d9452945668fa74402c2caf942fc6eec1a9701 100644
GIT binary patch
literal 17760
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
aKAs>BpXvB##qS6-Pnij5A2DFbqyGtKI58~%

literal 13856
zcmds8dwf*&v7db;yLk{#LaNI{JwU(!vTQ;`zy})=5D;|bA)!{uYayvgHYN*#^-|QR
zpr|nwYg^k!BpwPrVthesC9Sj{P^=L}XhC@_SlUG0ASzdobH6j^oXsZcZ9n(kzwY64
z&isD!o0;Ft{AT9&J15JJr_P#Yx7#RoIp|!pO+<p<#G5duSo(gNKuP4M{*-}!BJKpi
z6L7}W2ii^<XbX}XeFtu*fwxcic1Y(K_!wlp__pRVhx-C=wt=yr!d>QLU2%;y08Q=#
zZFz#Qy<_5q&yLQ&;xp+@w~^S#wpsQ~Hwf%~AZ3}17Ic<}j|F=8vb&7&zR;Fx;4MhZ
zcO7sp1OIP774XdgwW;TK`o$C&v(GlRs<L!!Rr&ZlZ+*y{Bf~5s6Sw24Yv$7h-q(Nr
z!1R)Pn$FBh-+yDR_ijgvL1jqdwdafDfG?|W>S6iY82pxJUpsk?_==AUmdSWocQ>91
z>hiTFj_F*5{aSzCwP)&-+nXZ48(ehDzSplj(C?;EcfN(O|Mr4l(-BtO3i${`i)l|n
zahw1f@M%WhZ^W0;$pqerZ#!B&mpg{1Ui6oyTl7?HQm<k-07+=hoA{VHFqjqv%S*x~
zv}jRjef^^Pa7kSlsG4$GR#_LW3@xfHsi`cZvQSO^((2%%`m(CpMU^#Ss;jJ7vZ$mk
zSYpaCf!|{`%(%1W@vFV@mfimB-uPnb+!igOtVmSP)^BM)MwE17`#z%KuXDR!QP)25
z>bGw{pXmJEowG@y)UM1i-t_rf@1`sA)#!%p7h>d3OiN8&*{D7%w~qnlRpActGj$p8
zxwMkouD`WIue7&?{zDD(<hMcwOMh~!lSX%)&$6|Nx-N2mCUlFtM(BHKrS><nweQC~
z4(%P>NA-_H*8M`WMcR)@yUit6dz9#z;`U<La$}?xAWJ)`-`~y)I<l=zp-uw9@JH>@
zL}`tck@SdS+d^5=9<keHYgI_vo*s@zzP31AXL%w-vTYTFT9>0wA9xw>d?@M{KNst_
zz}DTk@6xsqX^-i8%d=z?FQ}dwU4wj+X};J$pe?V1+J=&UwVwueO{X-+N<35al@HrG
z60|U-YriF%_LP29!>UI7-3mFkX3|j1bcmd;le`jxzhs}J7ItOpowTy60lUM>h|-Zr
z>$*Jpk>X|Gw0)D4?P7ff?>jb&UL^`Bw8gO2<?8%2T5H+CvfWr&UDvPIPGWs=MHIyR
zxx5~`p4gp2q>`(<^SNjM{y(i3!|L@y|1SG=S7W;my#LsG9&KWde*1T)@B#&V<P0>E
zTjXD(4ItZH=?-_h4;tMiblV^?O3sJ^loRrQ9i5I<>p&VFG-qjI-jqi=*CQtTN&B9N
zuhC8qcMfGt=O#Q;BR;UK5=`oJrP01Ml_ud{KTqj!NBoUM53fPQN7P0qH4e<wM(g_4
z!SuvdHw`m==B81Y`#5{MGZgiiI<#n~KZ!<E8018J?|{vhu?ESV8AG+O?K!r*U;Q3O
zD=CEjPu5YZ6L5((Al<EvR6f!sDm(I9Th&Nwv>g(Qi8i0fPmfamP~7996j7px(TEyt
z#nTtvh-Uzl@J8S~YSb<uJEV=$78<eJue#lj`R<JPqs^3+KR>!-w>N;9MLKv|p{2GJ
z{XyMsk;;;4RS!AY)0?+x1N_vqNhNJGV(mQr4CHJ9g%7hkd5(wz@r|8Buv4WXvfxkc
zYO>|O6#WufHIs8UW(W`{zXT32T`3r?(iGK41)~*$KHRoxmyvy|N>jD4zL&M(wcdP3
zWHfYgitlE_cMX)uI;HMpjB5%!u+bQGT`u_Fab%rsgAbuqG3?rEr}Rh$+XdcmJ51fY
zsC^Zl^Tf96WEPGu(tZQ$en$GX0$(yR>%7i%*was&fsu)%<fj)a`STQ7w+WVn$;}pO
zm+GfbQ9==)3LUY=3yc+K9*MU@+E~Pklj^`>=v~eDM5$Y;cT4+_=)FkvzTVKA*Ms%u
zsEO%*E_$Q1`$>^i_$fSpQqKi$p!Pdb0N3Nr25vpp1?vZIs#qs@NBUX$icj4-gz~iw
zXS-y^Y?=KDY0sASFQh$CG)ezPJT;vC8{*0aOR~+lQCm4e*x#Aj>2w9N)sj<k0J*@j
zQoazmA(5LX?MlHPXRfagYA4UGk^T`GyFus_Y0nq@dqVdntlA;{zsT5C(%viWd}+4}
z-7AoHqx63(W8<X#vb4uY`)Q$j5_I`Jx!Uht)Qbt6k(*|=H{*E~N6Dr_Bgc%`ZzXtH
zVxQw>(|DGdlpwh*Rcq5FBDo!FFlcKM4Q$%fOxor+j`Nwr-6b6Vfv83P6e#MYzfbSz
zhfIB(rM{7_O-Bvq)yvYhq5}G(8_+{;cMihYsUKE^vo0qv0X1c~qGAl$FY`8F-aA?A
zou6t0ROD)pz8n=SeW&=?y_q$j_1bbG>=R2mALSU2G-6ISC`XF48_lS_6B+Y_w$i3+
z4f?y0=EekiSghDHV7--xDG7{8SSjAUP1?)3os2z4*Ux+cF4SA$+F?}PNOK43gHdl0
zkL$HUdRsUS3HL&gR4nbeg5NEYc5cgWbV2h~o#%?iQtgnJq>UtZetJO3pBu}~8pOU$
zyGTF9tHCmMmSZh9Qc`>ki}~ex(e6U7E&4K<@fR|?<ZH@sX{QPP0nwxZ(O4?|du5EI
z{Ta8NUrBp~(A9$Onj)N!v{7V(uiFA>n=9#)_3y73>))WKBMwqw-Q(uC)K^64DXjMp
zKi0ebB)nNN&)>nTl&#IgjxE&}atnFp#4lNYqsAo5PUC!0bU_9|uV<w_M)b<Unz*n>
z+=jCh#$2Chn;=c$THZDXRm4LBrH8Z9*=Rv?qtsqk_q^r~_dK=3{k`>CmOgSFH9Fxh
z!#l?~rt};ue$HHh7It{Z{?J%qeHeUk4(pKgvFNi{^toEv#ezS`x}AO>bJk1$uQE1A
z=*CKWmf+tMx<7($8s`Y)mJ9w5LNiI|7fU-&@Gl7cCeY2pxkb)jLQ{gAFA_Sny^(0+
zY~B+#&g2~0DD`DyVc%U3k!Ise+IT7Rxe|Lko^&T;9H&LHj5<D-*~2pX&0JfOZr|f*
z{DDH&DkW72&tc&a3myA~=ljBQ9agE*$Q;-CJ^7X-mD=%V;X>|X)^_2VEL`KUE~T*<
z3{6^vc7)JMtxA$CKdmx;qeJ-0*;Zb)_{sr$?QE~Mjd>FvjI%dcq{%rfIaAvI!P4Ak
zSlU;gu@{pE7AdP}A$ES~BWFSPr$SjF`lLx)^2mKyxb_u+cA>Hgab?7@d#}(0gkH{p
zj+rtG_I}LL-X4H%OSuN%gw@O^oD?T?PK@-&Kx2W;Pg8KdGHbz?O%#2Kxsy(a)Zwsp
zw6w$zNnO$&2<#}9e&#cr?mXDd9x_gLh@IH^GWm7HP5_i`niuYGgcggTa|wDjz&B);
zKV!b<nv$c>HhH7ZG)<0T=fMl_KV?kbjO<4_DztQ*zV!k{xi)hM`2AXgtq|}8;N>`h
z5;&h}8AQG*O7v;GYdxLc9Ni$2{>0Wlb&{=T%aiZzYk70L<;J=%70!)@jnL*v(IzC=
zUvm4YH@+q2<sA0Z@0luLZBGoiWku|Fhz!Xj`;WNo`ilMcpWWJPctdNTaqZ2(oki>u
zGz!z!bv9IvF#Qsd%I`0C044$kf#>>Oh`8@(#C^gOi2E>IB${oNHOJWiYcm{cqhf7-
z&Giu{4W8jGYX<!@(P)@hm5aRJE`6>P6GT5_C58+3N};+?@V^qh*MV-Q^dFP4bfFs}
z?G(Y^Cv<nj={cM8Q-2nm?+C?@nA#>MAopo$e<Jv5;Vc(R8}tW2|CZp(gysOZ-BR~#
z?+bpu(9aSNHR!j1ez)MIZra2y_bbBtn&7Vx`aJP$gFZh-KTc?#7MjbYEt%j#^~OpK
zmKABxCo+9gZuDu?)?H0G0(T(pe;l1)ywfCIE$5_KqL!CA!&_e9*l&^g((=rAMNUgI
z&*%*GL{4I-=pc35{iw8WV%-uyV0})#$LpDRjO%gBo#v`Gki?(86;i^84h5dtvwKAJ
z3A`n+^tGN0ZJ@5tS2`3ei$=*@59a%$uVa54ig?e6P=}lPp{3%^VQS7PKWSI%dd4v9
zULWTx(QVkR@^KzXZc>dA>2J`#LgqaodM3-vx9)MQBB|sH469LP%+sM&Gh1Y5bexQ{
zx|Su-KiE?DLTN|D>Qb?Kp-5g(q}I|xRb*c#nCr~m7)X{{{q<{1e@61vJym!wiv+rH
zM(F%;H(cS8oyUEy%+SV9`&g_jb{lZriPlE;3tNl!1EMcRzWxb%9q8GZ?(4Oz2Qad?
zxa8DLYa{9^1t$?7(T0~<uH)`F>%a%=Zj%^mmv)%j2{;$&`j`KVtz)KO|0xt@76mxv
z+@5eisNWUo{5~^-eX!vnoJpq0T5KozMzdk%9#;p6mo5^0mI>X>;K;)1dl=r*qxp(5
z#9Ysj`98c|UPQ?}-v*p55oKc#<@;EQ4^>I;hOJUJ5`HO~$$sVfp|lmz@*&ae9?%_R
zF9GhwcaDx|g^?TX8S6;poh~0bWMFQaCudOZI@U3at;$byV6Zlc(zt3LxWMm2d`;3%
z0lERdY9hZqV_effe==Gr+IC9i_t63y-jQtq(gtC^@%mRq*bmxN%EZ?ob+t-^S+7i+
z=zw>4bnq2~XWIXF%|mILn-cwqaQt(#{FwBU`Uk89>Lz@<{~hc<gZ(P>%qAybGN3=8
zDjwXaxHEApMQVU&9)g*Dt9_W+N7R42_2mUM!u+;#c8liLb=KXp-qRXUy79Hkld(6Y
zJFh!0U+t#0Je9v?wXSZZ!P*vR*4lkRTdv^5qA9*^Kj@|h{N07xDE(AG?Y{icRoxT)
zf$k~5=QXYBp42u@=xH@R1ZD7!a^BuW(dK9~a<thqu<a5VRaPq)O-EHewT_~{!MgNg
z&9HB5!JBm^sh!VtKL&rDT$dW%2&&IT?~{5rZ21L$N7Amd@p-5XH-D9U1UK(i9{AaV
zGr1q$J{NI-w>1UtH(T#T+?`89r~6tH@n&PAe*Rp=8BtrElo|2i1ELdHyk~g=Eep=-
zk@aw27QVXljLMgWz{5Vb$)oh}_~$68MgCUSI@9<fVMz4n`_c?*LpIv@>NZ_b(@@)N
zen6b3oZJpDv>}GVlmaT~4=TG!Wfyy$uCp8sC*Fu45-5|u^GW}Y9AiheX%isDhZynL
z@f}djY$DYYqmlZ5<e45C#h^)5`!ikBIckQ`22j;s6RAJlHkR`O*?`H8G_KQ?46M)~
zL@mFQ4l#5&(g5FjsIdq!xJLES0yW?S9jZLm_CkYh-DIUd^6MD1W=aK=$OA+$X&2Zz
z8=Yv|AlG(Y#yka?#5*+Wv6A!T$XwAT5K;Zi?ek}@@u_6$ma^^~KWmlVqtyZ*H0a-3
z1MNyD6{!CHpv=L}Gf2Bq<{idd^N=+>>wqEfjiC+vDBARAykUcOrJKjnv@6*s`Z0{B
zLeB_bj#L{DeGhOy`a=Ns8t*XL>9dD`kuy7D^C!3)0!lYlh{^!*&W3NQ516}UE79Q(
zBF+2_EZ^5nyrzf$fp1ibw$P~eXICQ{*$4jC%r$<6rB1}V;B=vU4|*1A3vIId7;k5X
z-+-J8A;AW`o##5cq%EOaVXq#36<-5Yau$(4JECxQEL2eC!c>uuZ-D`dHlsc`BJd3|
z2&dP(vJ&Vn!nsel;y4=g&H!`rcWnhqIRmPnD^x0DP?g+8sz2MveNRT)C8$tCsc+tg
zDbdJqayHqzFGT(~B74>D3-Pt`q3&Wr1>lp+;cHC$RoJg81iuxM`#zPD@U3?}yk4e_
zvgvXC8`u`$pLe;~3;cGjk4Np0@8TR)-NSKKDwbGkAP-{>5AGe$nirA6-|rEjou78Y
zKKOa45&MS|&78nn5`6m`UPt}ocq%jUPxOg=j{30vcWCxL&w1!b?>UVbjNCr-9(XgT
z(aPgPyU_1%_I=>x`Y!qB>+y-gK8OS`%-Uw~cTUtk-t&gL&a#h;F{Y9+(DaPMKL@S-
z()kBOa52{ZC?bgV>Qce+b(-xxvtQyi1K&=XTSkz+K<yyx20He<3p)><;4iJ>DUO5q
zKI{rWvB!9KIv(WMJzlB}PzY5h_T^ghILWX0I8Sl_?SOW`#I{A`i;JHyx%Sxd?5G$G
z<kGV74L3HU<wN89Ay#=hf1N)xroDqGItsfke=Q!z)(5CK6B!2BL7p~5zI=-~Q^k4f
z8SPi1FMu)^r?D46B^i6>Cb7KHGa4g9Ihzh4!w7F5@Jc|&9>uqrmv92EB~o12bDrQc
z_#u1eeZ1@7FB<$cuNH$&?f!H0fYL~;QKYs}!A{Il`(wT*^R;Gtg(n5?FdozdPqVY-
zyeP7)QKc+DHFFEQgr5}lj}25RdWzt=C3vp#(anbR=#!K+9eM?*(H&@Q%mxHi^f}o0
zJnMe?1axm8zeIDb*l`}O&%q|tf+4-u$ITVejx{Uxu-^hoaVD}BXA}7Qxa2GN9Gh6u
ziETZ8I#_M_>GZ2SmtMp29nT2eX5_=-CTH{&q0fN_UIDe7bWgVk^-Ds%S*RZY^)rZ7
z<6BWPw499iZsL3fEa)7EBV#IBcSqD_*>##_*BQWjKniq4CTk;g9sGw_-%gx1D3#^g
zuJ%0N@-h+6^3^f^yB%U_BqU7$#5*0%-I>}D(oq%8?Je7oii-R^sIzez9&Je%z2!uE
zVgmI32!D&jbxlY${*pYVwCZNHJh-f~ET}FHEv+dZl5C8YR8^L%6(x1$YI$WnlZ1n1
z;b6HpnWmLgRt3w|a7e8Rm6WU3&Q%xJg{pgKlPP(KIwLSktqX>i*45Oj5D5$wl+@IO
z!oY&50*_!FUI#!Y^KnD1E?I)VYEOxctKk*3L7_3Gst+!y4%UR##i9Yxg1S)65*3)b
z73#8*s-;1;YiiNd0t07o8pN!w%seG9XRcZjR(;FA-{&Io<>ZdbyJY;O6DF3FmX!w=
z<Afcj^Xw^ediAG-V9o53T6Jz&U1e>UM6%3b=~oI%$|{!D+^m*Xh01PL>nm>y67^uG
z7F=DZmXw#*8NB#&ez>w`X$k(oUt=h13Mvbg2Teh}<j=3Uxh8aLjan}Xn2r#i6%@|G
zI>u`c|K>tySqLi%^9_Y^dVF7x<>h%RYk2J}Qm?E=kM=w)OJ$LV7WXE{3e=1dyUd_s
zb^bM1yr$QOs_>%*byi7fu&PJZTsrptyWK=HYOvA>O^Fp1(=Ri~tAt!M{Z^X#V4Yz!
zU4QMYxl`v{aRXi{;iFlFv#4P9TvC?>>+0D7y}V{v?&IiLQdd%{mhzfc)+`QriI&#L
zoJa-8KwcQpDBdw;;n0#lw@|IDS2^$(hw9i@y>RR)UISw^TmjOOy0VIY!|UOSpqf+9
z>BLLw{Wh&>em#B<qRuUtI|Ct75v&eE%c*sB(1XK>#{zXB*j260D=DoC($wnO@QOY-
zL&lP&!TNewD)uZ1hN^?eIY`^Nm)9hI^$d^Y((CUX!N|LN{*GtzC{;`=E2&Xyf^ZIs
zMQv@cMje%G>L?Lo=%{ALh1)2;MqZ5C*z3aYZuDpz#`qnM@%tLxW|t8Q7e_|PWV`2A
z-v8yL#_?aCJ^J<$vHp;(Q6n$&ju{(6Ts(Zym6Kz=;z`5&7hN&bYZR9y6_w`54{xrj
zt_juNQfE=thnFt9b@__htbQMuKc%2>>a?q-&oJ>bubwsgnrj2s&9Ug_&YOSzf}(}r
zH~KwQ&FG6mmQjMh<tBtfjh|aFREQ?z8eX&+?kfl_ttyu&UJ|s5hne8lU#FsQEv{U$
zv`#7)*PZXC?nBx`d23x|IH=;6PT{5XoNg7N`Y`WBGsa%4O3adNkmEA!kvOf8s_Xl2
zM|*>=A2<q_rRyI&0$2t3G++bZF2L=8hX4=g`iFkl=LFmic(JY@!4b&*16}{99B{3!
zA8!VH5xeqZfS~{6MVt;m|7jKAU_kuB#gV7$(ba(9>s|#I25bZbe>c-_0K|NbS8?{J
z0DMo^Kg$N}()E*Dh@6>#nBR%{KMw%T0)%{LIUwwD-VV4H@DV`R<$PM#zbFLU1=tFB
z6yK#VUqU9~9UM2=Zkt24<!QD-spmACO9gs@zWXsBJx$YAr>;r4FZuqYweAO84<<g8
zFfFa!ZZA)M`!8?pdh?B)JJOnMQ&N`i*!jkryWaZC+vu@WxmZ5*I-mk(2*!8}27sP|
zA57CMnK23;e_Yr9+5xzmrp3>Eierl9z6yQ-!v=2P%EAqQ?LPxpOw%4pcrft+*IM`e
zN%tieLT4tCi|NjQKM$~>H{F_)nLU&j!#i1^gTEZ`L%h5-DXUZO?RQVw%(T{FhEP12
zex9x$N(KFi@1j56OAn5-2<)^^`X>F%v>gU5^tE9fj~xZw7k%kwrgc~nnGW_Je-ZN!
z>`TY`&P<cp;XfPf@7xHTx6rf)tlv@sZ_m_q{PqhQO3W(pE601+D&XGeEw?c3xFbf%
z{ILIH_U|cPxBHUUq@d0CD&&I`ZS!}K!ozsj|1q!EP{9}v#$)|Iaicq`5B^2qIX+hR
z!6UvuLEKY&93Fbuk0S5#VDE#y_2%_MOc=UjK1V9@@^SE@Uc@fU<G}hyvHrBy;E#(A
zvCC12an^rejLX3P0C~))KK63H<1b3z#IFTD3jFoVWL`Y~2FUTDf0Ly@G+;mS#d>eY
zcrDsL6pZme96AmFza4geXz>|&V8v}=+CD34WPP2m|FbaIU;ZZjH9Z*-H_89Ars-2V
z`;tQX+0PC8?E6eRjlGT>RzK0eJ3QvN6*u{2pW~h{Yy5jgH}*7h&Z(Lhj&;7K8vwtb
zG%n!};ZJC0zbD&F#QzPL{2gMf-}xpK8w3ET?^hKROj5Jw&YwF~orTwp<s;QR?*#8S
zHP@Gu=Nq4Usd~ebva&IGizbXItt+W1tH5D#S*09}b8~Wi<MVF(Rte+0c^2ciZ!qRu
zk~{IzaW~Sn^|cGGBJ$Q()Q9WBC8gxWua<*#wdBPCIp|$dv(#I<w6dyvOl3JqucD;B
zg1qG`YU)>18!%i)-nw8_2_wlH4lWO)ACezSdxI5=7UMJ<TvUNqs#s6>N~-Z@>0J^6
zwLy#DRg<?YRLw7xv4)qu;=ML7ul_qc`aeK(ELpp%nYGsM&Mg@G{}GmWi=O-aaa%Rs
z;y2^WZp9mFWv|PsF^uFIY{oxX{E{cAuO_65I2z`0^8**d5s2R}qz48AT6twbx*T|G
z4koeqx$VPk<&(*8<(&nk?sHC><1v2Dp9#3Fys`NA0mo<)l9jgxy2sz#_v5zwVe(sf
zYeC7|Z_}UWpNZRA53_DK*<ZLUc>XS<AA82z9{|?kH|HP9HsP{h;)_N<_KfE*0=5tT
zcm02o7{6sNBNl&?f8;5H(t=K2qxdU+evT2-ZfhN^dNbDK5%nw@###Id+ADBd`kU+M
z2a2!Qw6TVPkMXmdmAL!zoAf@5FWz1j5#Mh>-_pmNKfpA&e0c(F?E-opN>7t$4La8R
y)_mr;$xrm7c!oH7=4*=U_vL@i<cs$mqpbND@@>UGkHuZSm&{H}9Fm(BKm8Yc`(^0>


From ff8de0757fc13407c81f002e936031ddc13057e4 Mon Sep 17 00:00:00 2001
From: David Hildenbrand <dahi@linux.vnet.ibm.com>
Date: Tue, 21 Jul 2015 08:32:07 +0200
Subject: [PATCH 12/15] qdev: provide qdev_reset_all_fn()

For TYPE_DEVICE, the dc->reset() function is not called on system resets
yet. Until that is changed, we have to manually register a reset handler.
Let's provide qdev_reset_all_fn(), that can directly be used - just like
the reset handler that is already available for qbus.

Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/core/qdev.c         | 5 +++++
 include/hw/qdev-core.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 4ab04aa31e..b3ad467754 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -325,6 +325,11 @@ void qdev_reset_all(DeviceState *dev)
     qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
 }
 
+void qdev_reset_all_fn(void *opaque)
+{
+    qdev_reset_all(DEVICE(opaque));
+}
+
 void qbus_reset_all(BusState *bus)
 {
     qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 8057aedaa6..e6dbde42c4 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -337,6 +337,7 @@ int qdev_walk_children(DeviceState *dev,
                        void *opaque);
 
 void qdev_reset_all(DeviceState *dev);
+void qdev_reset_all_fn(void *opaque);
 
 /**
  * @qbus_reset_all:

From 04fccf106e22c4b861398cf2146f5a5b5f18d01e Mon Sep 17 00:00:00 2001
From: David Hildenbrand <dahi@linux.vnet.ibm.com>
Date: Thu, 8 Oct 2015 12:32:13 +0200
Subject: [PATCH 13/15] s390x/ipl: clean up qom definitions and turn into
 TYPE_DEVICE

Let's move the qom definitions of the ipl device into ipl.h, replace
"s390-ipl" by a proper type define, turn it into a TYPE_DEVICE
and remove the unneeded class definition.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/ipl.c         | 52 +++++-------------------------------------
 hw/s390x/ipl.h         | 25 ++++++++++++++++++++
 hw/s390x/s390-virtio.c | 10 ++++----
 3 files changed, 36 insertions(+), 51 deletions(-)

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 5f7f34900a..c75071d0fc 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -15,7 +15,6 @@
 #include "cpu.h"
 #include "elf.h"
 #include "hw/loader.h"
-#include "hw/sysbus.h"
 #include "hw/s390x/virtio-ccw.h"
 #include "hw/s390x/css.h"
 #include "ipl.h"
@@ -29,44 +28,6 @@
 #define ZIPL_IMAGE_START                0x009000UL
 #define IPL_PSW_MASK                    (PSW_MASK_32 | PSW_MASK_64)
 
-#define TYPE_S390_IPL "s390-ipl"
-#define S390_IPL(obj) \
-    OBJECT_CHECK(S390IPLState, (obj), TYPE_S390_IPL)
-#if 0
-#define S390_IPL_CLASS(klass) \
-    OBJECT_CLASS_CHECK(S390IPLState, (klass), TYPE_S390_IPL)
-#define S390_IPL_GET_CLASS(obj) \
-    OBJECT_GET_CLASS(S390IPLState, (obj), TYPE_S390_IPL)
-#endif
-
-typedef struct S390IPLClass {
-    /*< private >*/
-    SysBusDeviceClass parent_class;
-    /*< public >*/
-
-    void (*parent_reset) (SysBusDevice *dev);
-} S390IPLClass;
-
-typedef struct S390IPLState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    uint64_t start_addr;
-    uint64_t bios_start_addr;
-    bool enforce_bios;
-    IplParameterBlock iplb;
-    bool iplb_valid;
-    bool reipl_requested;
-
-    /*< public >*/
-    char *kernel;
-    char *initrd;
-    char *cmdline;
-    char *firmware;
-    uint8_t cssid;
-    uint8_t ssid;
-    uint16_t devno;
-} S390IPLState;
-
 static const VMStateDescription vmstate_iplb = {
     .name = "ipl/iplb",
     .version_id = 0,
@@ -110,7 +71,7 @@ static uint64_t bios_translate_addr(void *opaque, uint64_t srcaddr)
     return srcaddr + dstaddr;
 }
 
-static int s390_ipl_init(SysBusDevice *dev)
+static void s390_ipl_realize(DeviceState *dev, Error **errp)
 {
     S390IPLState *ipl = S390_IPL(dev);
     uint64_t pentry = KERN_IMAGE_START;
@@ -165,7 +126,7 @@ static int s390_ipl_init(SysBusDevice *dev)
         }
         if (kernel_size < 0) {
             fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
-            return -1;
+            exit(1);
         }
         /*
          * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
@@ -205,7 +166,7 @@ static int s390_ipl_init(SysBusDevice *dev)
             stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);
         }
     }
-    return 0;
+    qemu_register_reset(qdev_reset_all_fn, dev);
 }
 
 static Property s390_ipl_properties[] = {
@@ -308,9 +269,8 @@ static void s390_ipl_reset(DeviceState *dev)
 static void s390_ipl_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = s390_ipl_init;
+    dc->realize = s390_ipl_realize;
     dc->props = s390_ipl_properties;
     dc->reset = s390_ipl_reset;
     dc->vmsd = &vmstate_ipl;
@@ -319,8 +279,8 @@ static void s390_ipl_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo s390_ipl_info = {
     .class_init = s390_ipl_class_init,
-    .parent = TYPE_SYS_BUS_DEVICE,
-    .name  = "s390-ipl",
+    .parent = TYPE_DEVICE,
+    .name  = TYPE_S390_IPL,
     .instance_size  = sizeof(S390IPLState),
 };
 
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 7f2b4033d4..6b48ed7b93 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -12,6 +12,7 @@
 #ifndef HW_S390_IPL_H
 #define HW_S390_IPL_H
 
+#include "hw/qdev.h"
 #include "cpu.h"
 
 typedef struct IplParameterBlock {
@@ -25,4 +26,28 @@ void s390_ipl_prepare_cpu(S390CPU *cpu);
 IplParameterBlock *s390_ipl_get_iplb(void);
 void s390_reipl_request(void);
 
+#define TYPE_S390_IPL "s390-ipl"
+#define S390_IPL(obj) OBJECT_CHECK(S390IPLState, (obj), TYPE_S390_IPL)
+
+struct S390IPLState {
+    /*< private >*/
+    DeviceState parent_obj;
+    uint64_t start_addr;
+    uint64_t bios_start_addr;
+    bool enforce_bios;
+    IplParameterBlock iplb;
+    bool iplb_valid;
+    bool reipl_requested;
+
+    /*< public >*/
+    char *kernel;
+    char *initrd;
+    char *cmdline;
+    char *firmware;
+    uint8_t cssid;
+    uint8_t ssid;
+    uint16_t devno;
+};
+typedef struct S390IPLState S390IPLState;
+
 #endif
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index cbde9772e5..cebebb1c0a 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -31,7 +31,6 @@
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "hw/virtio/virtio.h"
-#include "hw/sysbus.h"
 #include "sysemu/kvm.h"
 #include "exec/address-spaces.h"
 
@@ -151,9 +150,9 @@ void s390_init_ipl_dev(const char *kernel_filename,
                        const char *firmware,
                        bool enforce_bios)
 {
-    DeviceState *dev;
+    Object *new = object_new(TYPE_S390_IPL);
+    DeviceState *dev = DEVICE(new);
 
-    dev  = qdev_create(NULL, "s390-ipl");
     if (kernel_filename) {
         qdev_prop_set_string(dev, "kernel", kernel_filename);
     }
@@ -163,8 +162,9 @@ void s390_init_ipl_dev(const char *kernel_filename,
     qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
     qdev_prop_set_string(dev, "firmware", firmware);
     qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
-    object_property_add_child(qdev_get_machine(), "s390-ipl",
-                              OBJECT(dev), NULL);
+    object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
+                              new, NULL);
+    object_unref(new);
     qdev_init_nofail(dev);
 }
 

From 8f04e88e2cd792e348eb54983ce1a485d5db4f27 Mon Sep 17 00:00:00 2001
From: David Hildenbrand <dahi@linux.vnet.ibm.com>
Date: Thu, 8 Oct 2015 12:33:28 +0200
Subject: [PATCH 14/15] s390x/ipl: switch error reporting to error_setg

Now that we can report errors in the realize function, let's replace
the fprintf's and hw_error's with error_setg.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/ipl.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index c75071d0fc..b91fcc6e79 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -76,6 +76,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
     S390IPLState *ipl = S390_IPL(dev);
     uint64_t pentry = KERN_IMAGE_START;
     int kernel_size;
+    Error *l_err = NULL;
 
     int bios_size;
     char *bios_filename;
@@ -93,7 +94,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
 
         bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (bios_filename == NULL) {
-            hw_error("could not find stage1 bootloader\n");
+            error_setg(&l_err, "could not find stage1 bootloader\n");
+            goto error;
         }
 
         bios_size = load_elf(bios_filename, bios_translate_addr, &fwbase,
@@ -111,7 +113,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
         g_free(bios_filename);
 
         if (bios_size == -1) {
-            hw_error("could not load bootloader '%s'\n", bios_name);
+            error_setg(&l_err, "could not load bootloader '%s'\n", bios_name);
+            goto error;
         }
 
         /* default boot target is the bios */
@@ -125,8 +128,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
             kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
         }
         if (kernel_size < 0) {
-            fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
-            exit(1);
+            error_setg(&l_err, "could not load kernel '%s'\n", ipl->kernel);
+            goto error;
         }
         /*
          * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
@@ -153,9 +156,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
             initrd_size = load_image_targphys(ipl->initrd, initrd_offset,
                                               ram_size - initrd_offset);
             if (initrd_size == -1) {
-                fprintf(stderr, "qemu: could not load initrd '%s'\n",
-                        ipl->initrd);
-                exit(1);
+                error_setg(&l_err, "could not load initrd '%s'\n", ipl->initrd);
+                goto error;
             }
 
             /*
@@ -167,6 +169,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
         }
     }
     qemu_register_reset(qdev_reset_all_fn, dev);
+error:
+    error_propagate(errp, l_err);
 }
 
 static Property s390_ipl_properties[] = {

From 3c4c694c7ce2d21c0cf17a27cc60c91b6725ce48 Mon Sep 17 00:00:00 2001
From: Christian Borntraeger <borntraeger@de.ibm.com>
Date: Fri, 6 Nov 2015 13:07:25 +0100
Subject: [PATCH 15/15] s390: deprecate the non-ccw machine in 2.5

The non-ccw machine for s390 (s390-virtio) is not very well maintained
and caused several issues in the past:
- aliases like virtio-blk did not work for s390
- virtio refactoring failed due to long standing bugs (e.g.see
commit cb927b8a "s390-virtio: Accommodate guests using virtqueues too early")
- some features like memory hotplug will cause trouble due to virtio storage
  being above guest memory
- the boot loader bios no longer seems to work. the source code of that
  loader is also no longer maintained

2.4 changed the default to the ccw machine, let's deprecate the old
machine for 2.5.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Message-Id: <1446811645-25565-1-git-send-email-borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/s390x/s390-virtio.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index cebebb1c0a..51dc0a8aaf 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -268,6 +268,10 @@ static void s390_init(MachineState *machine)
     hwaddr virtio_region_len;
     hwaddr virtio_region_start;
 
+    error_printf("WARNING\n"
+                 "The s390-virtio machine (non-ccw) is deprecated.\n"
+                 "It will be removed in 2.6. Please use s390-ccw-virtio\n");
+
     if (machine->ram_slots) {
         error_report("Memory hotplug not supported by the selected machine.");
         exit(EXIT_FAILURE);
@@ -334,7 +338,7 @@ static void s390_machine_class_init(ObjectClass *oc, void *data)
     NMIClass *nc = NMI_CLASS(oc);
 
     mc->alias = "s390";
-    mc->desc = "VirtIO based S390 machine";
+    mc->desc = "VirtIO based S390 machine (deprecated)";
     mc->init = s390_init;
     mc->reset = s390_machine_reset;
     mc->block_default_type = IF_VIRTIO;