From 4f6a1eb886961f1f9da2d553c4b0e5ef69cd3801 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 28 Jul 2020 13:24:11 +0200 Subject: [PATCH 01/16] pc-bios/s390-ccw/Makefile: Compile with -std=gnu99, -fwrapv and -fno-common The main QEMU code is compiled with -std=gnu99, -fwrapv and -fno-common. We should use the same flags for the s390-ccw bios, too, to avoid that we get different behavior with different compiler versions that changed their default settings in the course of time (it happened at least with -std=... and -fno-common in the past already). While we're at it, also group the other flags here in a little bit nicer fashion: Move the two "-m" flags out of the "-f" area and specify them on a separate line. Reviewed-by: Claudio Imbrenda Acked-by: Cornelia Huck Acked-by: Janosch Frank Message-Id: <20200806105349.632-2-thuth@redhat.com> Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile index 3eb785048a..29fd9019b8 100644 --- a/pc-bios/s390-ccw/Makefile +++ b/pc-bios/s390-ccw/Makefile @@ -30,10 +30,11 @@ 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 dasd-ipl.o QEMU_CFLAGS := -Wall $(filter -W%, $(QEMU_CFLAGS)) -QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float -QEMU_CFLAGS += -march=z900 -fPIE -fno-strict-aliasing -QEMU_CFLAGS += -fno-asynchronous-unwind-tables +QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE +QEMU_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables QEMU_CFLAGS += $(call cc-option, $(QEMU_CFLAGS), -fno-stack-protector) +QEMU_CFLAGS += -msoft-float -march=z900 +QEMU_CFLAGS += -std=gnu99 LDFLAGS += -Wl,-pie -nostdlib build-all: s390-ccw.img s390-netboot.img From d1f060a8b515a0b1d14c38f2c8f86ab54e79c3dc Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 28 Jul 2020 10:35:53 +0200 Subject: [PATCH 02/16] pc-bios/s390-ccw: Move ipl-related code from main() into a separate function Let's move this part of the code into a separate function to be able to use it from multiple spots later. Reviewed-by: Claudio Imbrenda Reviewed-by: Cornelia Huck Reviewed-by: Janosch Frank Message-Id: <20200806105349.632-3-thuth@redhat.com> Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/main.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index 146a50760b..9b64eb0c24 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -223,14 +223,8 @@ static void virtio_setup(void) } } -int main(void) +static void ipl_boot_device(void) { - sclp_setup(); - css_setup(); - boot_setup(); - find_boot_device(); - enable_subchannel(blk_schid); - switch (cutype) { case CU_TYPE_DASD_3990: case CU_TYPE_DASD_2107: @@ -242,8 +236,18 @@ int main(void) break; default: print_int("Attempting to boot from unexpected device type", cutype); - panic(""); + panic("\nBoot failed.\n"); } +} + +int main(void) +{ + sclp_setup(); + css_setup(); + boot_setup(); + find_boot_device(); + enable_subchannel(blk_schid); + ipl_boot_device(); panic("Failed to load OS from hard disk\n"); return 0; /* make compiler happy */ From f3180b0266386b31deb7bb83fcaea68af7d1bcee Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 5 Aug 2020 17:41:08 +0200 Subject: [PATCH 03/16] pc-bios/s390-ccw: Introduce ENODEV define and remove guards of others Remove the "#ifndef E..." guards from the defines here - the header guard S390_CCW_H at the top of the file should avoid double definition, and if the error code is defined in a different file already, we're in trouble anyway, then it's better to see the error at compile time instead of hunting weird behavior during runtime later. Also define ENODEV - we will use this in a later patch. Message-Id: <20200806105349.632-4-thuth@redhat.com> Reviewed-by: Cornelia Huck Reviewed-by: Janosch Frank Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/s390-ccw.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index 36b884cced..dbc4c64851 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -27,12 +27,10 @@ typedef unsigned long long __u64; #define false 0 #define PAGE_SIZE 4096 -#ifndef EIO #define EIO 1 -#endif -#ifndef EBUSY #define EBUSY 2 -#endif +#define ENODEV 3 + #ifndef NULL #define NULL 0 #endif From d2cf4af1f4af02f6f2d5827d9a06c31690084d3b Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 28 Jul 2020 15:50:31 +0200 Subject: [PATCH 04/16] pc-bios/s390-ccw: Move the inner logic of find_subch() to a separate function Move the code to a separate function to be able to re-use it from a different spot later. Reviewed-by: Claudio Imbrenda Message-Id: <20200806105349.632-5-thuth@redhat.com> Reviewed-by: Cornelia Huck Reviewed-by: Janosch Frank Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/main.c | 99 ++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 42 deletions(-) diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index 9b64eb0c24..0d2aabbc58 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -51,6 +51,60 @@ unsigned int get_loadparm_index(void) return atoui(loadparm_str); } +static int is_dev_possibly_bootable(int dev_no, int sch_no) +{ + bool is_virtio; + Schib schib; + int r; + + blk_schid.sch_no = sch_no; + r = stsch_err(blk_schid, &schib); + if (r == 3 || r == -EIO) { + return -ENODEV; + } + if (!schib.pmcw.dnv) { + return false; + } + + enable_subchannel(blk_schid); + cutype = cu_type(blk_schid); + + /* + * Note: we always have to run virtio_is_supported() here to make + * sure that the vdev.senseid data gets pre-initialized correctly + */ + is_virtio = virtio_is_supported(blk_schid); + + /* No specific devno given, just return whether the device is possibly bootable */ + if (dev_no < 0) { + switch (cutype) { + case CU_TYPE_VIRTIO: + if (is_virtio) { + /* + * Skip net devices since no IPLB is created and therefore + * no network bootloader has been loaded + */ + if (virtio_get_device_type() != VIRTIO_ID_NET) { + return true; + } + } + return false; + case CU_TYPE_DASD_3990: + case CU_TYPE_DASD_2107: + return true; + default: + return false; + } + } + + /* Caller asked for a specific devno */ + if (schib.pmcw.dev == dev_no) { + return true; + } + + return false; +} + /* * Find the subchannel connected to the given device (dev_no) and fill in the * subchannel information block (schib) with the connected subchannel's info. @@ -62,53 +116,14 @@ unsigned int get_loadparm_index(void) */ static bool find_subch(int dev_no) { - Schib schib; int i, r; - bool is_virtio; for (i = 0; i < 0x10000; i++) { - blk_schid.sch_no = i; - r = stsch_err(blk_schid, &schib); - if ((r == 3) || (r == -EIO)) { + r = is_dev_possibly_bootable(dev_no, i); + if (r < 0) { break; } - if (!schib.pmcw.dnv) { - continue; - } - - enable_subchannel(blk_schid); - cutype = cu_type(blk_schid); - - /* - * Note: we always have to run virtio_is_supported() here to make - * sure that the vdev.senseid data gets pre-initialized correctly - */ - is_virtio = virtio_is_supported(blk_schid); - - /* No specific devno given, just return 1st possibly bootable device */ - if (dev_no < 0) { - switch (cutype) { - case CU_TYPE_VIRTIO: - if (is_virtio) { - /* - * Skip net devices since no IPLB is created and therefore - * no network bootloader has been loaded - */ - if (virtio_get_device_type() != VIRTIO_ID_NET) { - return true; - } - } - continue; - case CU_TYPE_DASD_3990: - case CU_TYPE_DASD_2107: - return true; - default: - continue; - } - } - - /* Caller asked for a specific devno */ - if (schib.pmcw.dev == dev_no) { + if (r == true) { return true; } } From 605751b5a5334e187761b0b8a8266a216897bf70 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 28 Jul 2020 14:30:14 +0200 Subject: [PATCH 05/16] pc-bios/s390-ccw: Do not bail out early if not finding a SCSI disk In case the user did not specify a boot device, we want to continue looking for other devices if there are no valid SCSI disks on a virtio- scsi controller. As a first step, do not panic in this case and let the control flow carry the error to the upper functions instead. Message-Id: <20200806105349.632-6-thuth@redhat.com> Reviewed-by: Cornelia Huck Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/main.c | 14 ++++++++++---- pc-bios/s390-ccw/s390-ccw.h | 2 +- pc-bios/s390-ccw/virtio-blkdev.c | 7 +++++-- pc-bios/s390-ccw/virtio-scsi.c | 28 ++++++++++++++++++++-------- pc-bios/s390-ccw/virtio-scsi.h | 2 +- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index 0d2aabbc58..7bdd12ab2e 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -218,7 +218,7 @@ static void find_boot_device(void) IPL_assert(found, "Boot device not found\n"); } -static void virtio_setup(void) +static int virtio_setup(void) { VDev *vdev = virtio_get_device(); QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS; @@ -233,9 +233,14 @@ static void virtio_setup(void) sclp_print("Network boot device detected\n"); vdev->netboot_start_addr = qipl.netboot_start_addr; } else { - virtio_blk_setup_device(blk_schid); + int ret = virtio_blk_setup_device(blk_schid); + if (ret) { + return ret; + } IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected"); } + + return 0; } static void ipl_boot_device(void) @@ -246,8 +251,9 @@ static void ipl_boot_device(void) dasd_ipl(blk_schid, cutype); /* no return */ break; case CU_TYPE_VIRTIO: - virtio_setup(); - zipl_load(); /* no return */ + if (virtio_setup() == 0) { + zipl_load(); /* no return */ + } break; default: print_int("Attempting to boot from unexpected device type", cutype); diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index dbc4c64851..9b86c120b4 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -69,7 +69,7 @@ int sclp_read(char *str, size_t count); unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, ulong subchan_id, void *load_addr); bool virtio_is_supported(SubChannelId schid); -void virtio_blk_setup_device(SubChannelId schid); +int virtio_blk_setup_device(SubChannelId schid); int virtio_read(ulong sector, void *load_addr); /* bootmap.c */ diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c index 11c56261ca..7d35050292 100644 --- a/pc-bios/s390-ccw/virtio-blkdev.c +++ b/pc-bios/s390-ccw/virtio-blkdev.c @@ -263,9 +263,10 @@ uint64_t virtio_get_blocks(void) return 0; } -void virtio_blk_setup_device(SubChannelId schid) +int virtio_blk_setup_device(SubChannelId schid) { VDev *vdev = virtio_get_device(); + int ret = 0; vdev->schid = schid; virtio_setup_ccw(vdev); @@ -288,9 +289,11 @@ void virtio_blk_setup_device(SubChannelId schid) "Config: CDB size mismatch"); sclp_print("Using virtio-scsi.\n"); - virtio_scsi_setup(vdev); + ret = virtio_scsi_setup(vdev); break; default: panic("\n! No IPL device available !\n"); } + + return ret; } diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c index eddfb8a7ad..2c8d0f3097 100644 --- a/pc-bios/s390-ccw/virtio-scsi.c +++ b/pc-bios/s390-ccw/virtio-scsi.c @@ -194,7 +194,12 @@ static bool scsi_read_capacity(VDev *vdev, /* virtio-scsi routines */ -static void virtio_scsi_locate_device(VDev *vdev) +/* + * Tries to locate a SCSI device and and adds the information for the found + * device to the vdev->scsi_device structure. + * Returns 0 if SCSI device could be located, or a error code < 0 otherwise + */ +static int virtio_scsi_locate_device(VDev *vdev) { const uint16_t channel = 0; /* again, it's what QEMU does */ uint16_t target; @@ -220,7 +225,7 @@ static void virtio_scsi_locate_device(VDev *vdev) IPL_check(sdev->channel == 0, "non-zero channel requested"); IPL_check(sdev->target <= vdev->config.scsi.max_target, "target# high"); IPL_check(sdev->lun <= vdev->config.scsi.max_lun, "LUN# high"); - return; + return 0; } for (target = 0; target <= vdev->config.scsi.max_target; target++) { @@ -247,18 +252,20 @@ static void virtio_scsi_locate_device(VDev *vdev) */ sdev->lun = r->lun[0].v16[0]; /* it's returned this way */ debug_print_int("Have to use LUN", sdev->lun); - return; /* we have to use this device */ + return 0; /* we have to use this device */ } for (i = 0; i < luns; i++) { if (r->lun[i].v64) { /* Look for non-zero LUN - we have where to choose from */ sdev->lun = r->lun[i].v16[0]; debug_print_int("Will use LUN", sdev->lun); - return; /* we have found a device */ + return 0; /* we have found a device */ } } } - panic("\n! Cannot locate virtio-scsi device !\n"); + + sclp_print("Warning: Could not locate a usable virtio-scsi device\n"); + return -ENODEV; } int virtio_scsi_read_many(VDev *vdev, @@ -322,17 +329,20 @@ static void scsi_parse_capacity_report(void *data, } } -void virtio_scsi_setup(VDev *vdev) +int virtio_scsi_setup(VDev *vdev) { int retry_test_unit_ready = 3; uint8_t data[256]; uint32_t data_size = sizeof(data); ScsiInquiryEvpdPages *evpd = &scsi_inquiry_evpd_pages_response; ScsiInquiryEvpdBl *evpd_bl = &scsi_inquiry_evpd_bl_response; - int i; + int i, ret; vdev->scsi_device = &default_scsi_device; - virtio_scsi_locate_device(vdev); + ret = virtio_scsi_locate_device(vdev); + if (ret < 0) { + return ret; + } /* We have to "ping" the device before it becomes readable */ while (!scsi_test_unit_ready(vdev)) { @@ -417,4 +427,6 @@ void virtio_scsi_setup(VDev *vdev) } scsi_parse_capacity_report(data, &vdev->scsi_last_block, (uint32_t *) &vdev->scsi_block_size); + + return 0; } diff --git a/pc-bios/s390-ccw/virtio-scsi.h b/pc-bios/s390-ccw/virtio-scsi.h index 4c4f4bbc31..4b14c2c2f9 100644 --- a/pc-bios/s390-ccw/virtio-scsi.h +++ b/pc-bios/s390-ccw/virtio-scsi.h @@ -67,7 +67,7 @@ static inline bool virtio_scsi_response_ok(const VirtioScsiCmdResp *r) return r->response == VIRTIO_SCSI_S_OK && r->status == CDB_STATUS_GOOD; } -void virtio_scsi_setup(VDev *vdev); +int virtio_scsi_setup(VDev *vdev); int virtio_scsi_read_many(VDev *vdev, ulong sector, void *load_addr, int sec_num); From 869d0e2f593dd37297c366203f006b9acd1b7b45 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 28 Jul 2020 16:29:03 +0200 Subject: [PATCH 06/16] pc-bios/s390-ccw: Scan through all devices if no boot device specified If no boot device has been specified (via "bootindex=..."), the s390-ccw bios scans through all devices to find a bootable device. But so far, it stops at the very first block device (including virtio-scsi controllers without attached devices) that it finds, no matter whether it is bootable or not. That leads to some weird situatation where it is e.g. possible to boot via: qemu-system-s390x -hda /path/to/disk.qcow2 but not if there is e.g. a virtio-scsi controller specified before: qemu-system-s390x -device virtio-scsi -hda /path/to/disk.qcow2 While using "bootindex=..." is clearly the preferred way of booting on s390x, we still can make the life for the users at least a little bit easier if we look at all available devices to find a bootable one. Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1846975 Reviewed-by: Cornelia Huck Message-Id: <20200806105349.632-7-thuth@redhat.com> Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/main.c | 46 +++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index 7bdd12ab2e..9b581074a1 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -182,20 +182,8 @@ static void boot_setup(void) static void find_boot_device(void) { VDev *vdev = virtio_get_device(); - int ssid; bool found; - if (!have_iplb) { - for (ssid = 0; ssid < 0x3; ssid++) { - blk_schid.ssid = ssid; - found = find_subch(-1); - if (found) { - return; - } - } - panic("Could not find a suitable boot device (none specified)\n"); - } - switch (iplb.pbt) { case S390_IPL_TYPE_CCW: debug_print_int("device no. ", iplb.ccw.devno); @@ -261,14 +249,42 @@ static void ipl_boot_device(void) } } +/* + * No boot device has been specified, so we have to scan through the + * channels to find one. + */ +static void probe_boot_device(void) +{ + int ssid, sch_no, ret; + + for (ssid = 0; ssid < 0x3; ssid++) { + blk_schid.ssid = ssid; + for (sch_no = 0; sch_no < 0x10000; sch_no++) { + ret = is_dev_possibly_bootable(-1, sch_no); + if (ret < 0) { + break; + } + if (ret == true) { + ipl_boot_device(); /* Only returns if unsuccessful */ + } + } + } + + sclp_print("Could not find a suitable boot device (none specified)\n"); +} + int main(void) { sclp_setup(); css_setup(); boot_setup(); - find_boot_device(); - enable_subchannel(blk_schid); - ipl_boot_device(); + if (have_iplb) { + find_boot_device(); + enable_subchannel(blk_schid); + ipl_boot_device(); + } else { + probe_boot_device(); + } panic("Failed to load OS from hard disk\n"); return 0; /* make compiler happy */ From 5dc739f343cd06ecb9b058294564ce7504856f3f Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 28 Jul 2020 18:14:50 +0200 Subject: [PATCH 07/16] pc-bios/s390-ccw: Allow booting in case the first virtio-blk disk is bad If you try to boot with two virtio-blk disks (without bootindex), and only the second one is bootable, the s390-ccw bios currently stops at the first disk and does not continue booting from the second one. This is annoying - and all other major QEMU firmwares succeed to boot from the second disk in this case, so we should do the same in the s390-ccw bios, too. Reviewed-by: Cornelia Huck Message-Id: <20200806105349.632-8-thuth@redhat.com> Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/bootmap.c | 34 +++++++++++++++++++++++----------- pc-bios/s390-ccw/main.c | 2 +- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 97205674e5..0ef6b851f3 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -289,11 +289,18 @@ static void ipl_eckd_cdl(void) read_block(1, ipl2, "Cannot read IPL2 record at block 1"); mbr = &ipl2->mbr; - IPL_assert(magic_match(mbr, ZIPL_MAGIC), "No zIPL section in IPL2 record."); - IPL_assert(block_size_ok(mbr->blockptr.xeckd.bptr.size), - "Bad block size in zIPL section of IPL2 record."); - IPL_assert(mbr->dev_type == DEV_TYPE_ECKD, - "Non-ECKD device type in zIPL section of IPL2 record."); + if (!magic_match(mbr, ZIPL_MAGIC)) { + sclp_print("No zIPL section in IPL2 record.\n"); + return; + } + if (!block_size_ok(mbr->blockptr.xeckd.bptr.size)) { + sclp_print("Bad block size in zIPL section of IPL2 record.\n"); + return; + } + if (!mbr->dev_type == DEV_TYPE_ECKD) { + sclp_print("Non-ECKD device type in zIPL section of IPL2 record.\n"); + return; + } /* save pointer to Boot Map Table */ bmt_block_nr = eckd_block_num(&mbr->blockptr.xeckd.bptr.chs); @@ -303,10 +310,14 @@ static void ipl_eckd_cdl(void) memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(2, vlbl, "Cannot read Volume Label at block 2"); - IPL_assert(magic_match(vlbl->key, VOL1_MAGIC), - "Invalid magic of volume label block"); - IPL_assert(magic_match(vlbl->f.key, VOL1_MAGIC), - "Invalid magic of volser block"); + if (!magic_match(vlbl->key, VOL1_MAGIC)) { + sclp_print("Invalid magic of volume label block.\n"); + return; + } + if (!magic_match(vlbl->f.key, VOL1_MAGIC)) { + sclp_print("Invalid magic of volser block.\n"); + return; + } print_volser(vlbl->f.volser); run_eckd_boot_script(bmt_block_nr, s1b_block_nr); @@ -398,7 +409,8 @@ static void ipl_eckd(void) read_block(0, mbr, "Cannot read block 0 on DASD"); if (magic_match(mbr->magic, IPL1_MAGIC)) { - ipl_eckd_cdl(); /* no return */ + ipl_eckd_cdl(); /* only returns in case of error */ + return; } /* LDL/CMS? */ @@ -825,5 +837,5 @@ void zipl_load(void) panic("\n! Unknown IPL device type !\n"); } - panic("\n* this can never happen *\n"); + sclp_print("zIPL load failed.\n"); } diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index 9b581074a1..fc17e6ab83 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -240,7 +240,7 @@ static void ipl_boot_device(void) break; case CU_TYPE_VIRTIO: if (virtio_setup() == 0) { - zipl_load(); /* no return */ + zipl_load(); /* Only returns in case of errors */ } break; default: From 49d4388ec03fd8c7701b907a4e11c437a28f8572 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 6 Aug 2020 11:41:51 +0200 Subject: [PATCH 08/16] pc-bios/s390-ccw/main: Remove superfluous call to enable_subchannel() enable_subchannel() is already done during is_dev_possibly_bootable() (which is called from find_boot_device() -> find_subch()), so there is no need to do this again in the main() function. Message-Id: <20200806105349.632-9-thuth@redhat.com> Reviewed-by: Cornelia Huck Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index fc17e6ab83..43c792cf95 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -280,7 +280,6 @@ int main(void) boot_setup(); if (have_iplb) { find_boot_device(); - enable_subchannel(blk_schid); ipl_boot_device(); } else { probe_boot_device(); From 5f97ba0c74ccace0a4014460de9751ff3c6f454a Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Thu, 24 Sep 2020 10:59:24 +0200 Subject: [PATCH 09/16] pc-bios/s390-ccw: fix off-by-one error This error takes effect when the magic value "zIPL" is located at the end of a block. For example if s2_cur_blk = 0x7fe18000 and the magic value "zIPL" is located at 0x7fe18ffc - 0x7fe18fff. Fixes: ba831b25262a ("s390-ccw: read stage2 boot loader data to find menu") Reviewed-by: Collin Walling Signed-off-by: Marc Hartmayer Message-Id: <20200924085926.21709-2-mhartmay@linux.ibm.com> Reviewed-by: Thomas Huth [thuth: Use "<= ... - 4" instead of "< ... - 3"] Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/bootmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 0ef6b851f3..767bb612db 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -163,7 +163,7 @@ static bool find_zipl_boot_menu_banner(int *offset) int i; /* Menu banner starts with "zIPL" */ - for (i = 0; i < virtio_get_block_size() - 4; i++) { + for (i = 0; i <= virtio_get_block_size() - 4; i++) { if (magic_match(s2_cur_blk + i, ZIPL_MAGIC_EBCDIC)) { *offset = i; return true; From 468184ec9024f4f7b55247f70ec57554e8a500d7 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Thu, 24 Sep 2020 10:59:25 +0200 Subject: [PATCH 10/16] pc-bios/s390-ccw: break loop if a null block number is reached Break the loop if `cur_block_nr` is a null block number because this means that the end of chunk is reached. In this case we will try to boot the default entry. Fixes: ba831b25262a ("s390-ccw: read stage2 boot loader data to find menu") Reviewed-by: Collin Walling Signed-off-by: Marc Hartmayer Message-Id: <20200924085926.21709-3-mhartmay@linux.ibm.com> Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/bootmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 767bb612db..942fba3fa7 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -192,7 +192,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) for (i = 0; i < STAGE2_BLK_CNT_MAX; i++) { cur_block_nr = eckd_block_num(&s1b->seek[i].chs); - if (!cur_block_nr) { + if (!cur_block_nr || is_null_block_number(cur_block_nr)) { break; } From 4906a4e41c29b65ad350736e0a989e5cf3387baf Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Tue, 6 Oct 2020 05:42:46 -0400 Subject: [PATCH 11/16] pc-bios: s390x: Fix bootmap.c zipl component entry data handling The two main types of zipl component entries are execute and load/data. The last member of the component entry struct therefore denotes either a PSW or an address. Let's make this a bit more clear by introducing a union and cleaning up the code that uses that struct member. The execute type component entries written by zipl contain short PSWs, not addresses. Let's mask them and only pass the address part to jump_to_IPL_code(uint64_t address) because it expects an address as visible by the name of the argument. Signed-off-by: Janosch Frank Reviewed-by: Thomas Huth Message-Id: <20201006094249.50640-2-frankja@linux.ibm.com> Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/bootmap.c | 5 +++-- pc-bios/s390-ccw/bootmap.h | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 942fba3fa7..73471801de 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -10,6 +10,7 @@ #include "libc.h" #include "s390-ccw.h" +#include "s390-arch.h" #include "bootmap.h" #include "virtio.h" #include "bswap.h" @@ -448,7 +449,7 @@ static void zipl_load_segment(ComponentEntry *entry) char *blk_no = &err_msg[30]; /* where to print blockno in (those ZZs) */ blockno = entry->data.blockno; - address = entry->load_address; + address = entry->compdat.load_addr; debug_print_int("loading segment at block", blockno); debug_print_int("addr", address); @@ -526,7 +527,7 @@ static void zipl_run(ScsiBlockPtr *pte) IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry"); /* should not return */ - jump_to_IPL_code(entry->load_address); + jump_to_IPL_code(entry->compdat.load_psw & PSW_MASK_SHORT_ADDR); } static void ipl_scsi(void) diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 12a0166aae..3946aa3f8d 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -64,11 +64,16 @@ typedef struct BootMapTable { BootMapPointer entry[]; } __attribute__ ((packed)) BootMapTable; +typedef union ComponentEntryData { + uint64_t load_psw; + uint64_t load_addr; +} ComponentEntryData; + typedef struct ComponentEntry { ScsiBlockPtr data; uint8_t pad[7]; uint8_t component_type; - uint64_t load_address; + ComponentEntryData compdat; } __attribute((packed)) ComponentEntry; typedef struct ComponentHeader { From 26e0b96fa9c303194fe159037d69d9ec30355d07 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Tue, 6 Oct 2020 05:42:47 -0400 Subject: [PATCH 12/16] pc-bios: s390x: Save PSW rework We don't need to save the ipl_continue variable in lowcore and have it limited to 32 bits because of the lowcore layout. Let's move it to a new 64 bit variable and get rid of the reset info struct. Signed-off-by: Janosch Frank Reviewed-by: Thomas Huth Message-Id: <20201006094249.50640-3-frankja@linux.ibm.com> Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/jump2ipl.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c index 767012bf0c..b6aad32def 100644 --- a/pc-bios/s390-ccw/jump2ipl.c +++ b/pc-bios/s390-ccw/jump2ipl.c @@ -13,20 +13,17 @@ #define KERN_IMAGE_START 0x010000UL #define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_64) -typedef struct ResetInfo { - uint64_t ipl_psw; - uint32_t ipl_continue; -} ResetInfo; +static uint64_t *reset_psw = 0, save_psw, ipl_continue; -static ResetInfo save; - -static void jump_to_IPL_2(void) +static void jump_to_IPL_addr(void) { - ResetInfo *current = 0; + __attribute__((noreturn)) void (*ipl)(void) = (void *)ipl_continue; - void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue; - *current = save; - ipl(); /* should not return */ + /* Restore reset PSW */ + *reset_psw = save_psw; + + ipl(); + /* should not return */ } void jump_to_IPL_code(uint64_t address) @@ -46,15 +43,11 @@ void jump_to_IPL_code(uint64_t address) * content of non-BIOS memory after we loaded the guest, so we * save the original content and restore it in jump_to_IPL_2. */ - ResetInfo *current = 0; - - save = *current; - - current->ipl_psw = (uint64_t) &jump_to_IPL_2; - current->ipl_psw |= RESET_PSW_MASK; - current->ipl_continue = address & PSW_MASK_SHORT_ADDR; - - debug_print_int("set IPL addr to", current->ipl_continue); + save_psw = *reset_psw; + *reset_psw = (uint64_t) &jump_to_IPL_addr; + *reset_psw |= RESET_PSW_MASK; + ipl_continue = address; + debug_print_int("set IPL addr to", ipl_continue); /* Ensure the guest output starts fresh */ sclp_print("\n"); From 42ab98e7d71b834f4f8e2471f60b1c737b9543f3 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Tue, 6 Oct 2020 05:42:48 -0400 Subject: [PATCH 13/16] pc-bios: s390x: Use reset PSW if avaliable If a blob provides a reset PSW then we should use it instead of branching to the PSW address and using our own mask. Signed-off-by: Janosch Frank Reviewed-by: Thomas Huth Message-Id: <20201006094249.50640-4-frankja@linux.ibm.com> [thuth: Use Elvis operator to shorten long line] Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/bootmap.c | 6 ++++-- pc-bios/s390-ccw/jump2ipl.c | 26 +++++++++++++++++++------- pc-bios/s390-ccw/s390-ccw.h | 1 + 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 73471801de..44df7d16af 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -273,7 +273,8 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr, IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC, "Unknown script entry type"); - jump_to_IPL_code(bms->entry[i].address.load_address); /* no return */ + write_reset_psw(bms->entry[i].address.load_address); /* no return */ + jump_to_IPL_code(0); /* no return */ } static void ipl_eckd_cdl(void) @@ -527,7 +528,8 @@ static void zipl_run(ScsiBlockPtr *pte) IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry"); /* should not return */ - jump_to_IPL_code(entry->compdat.load_psw & PSW_MASK_SHORT_ADDR); + write_reset_psw(entry->compdat.load_psw); + jump_to_IPL_code(0); } static void ipl_scsi(void) diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c index b6aad32def..fbae45b03c 100644 --- a/pc-bios/s390-ccw/jump2ipl.c +++ b/pc-bios/s390-ccw/jump2ipl.c @@ -12,15 +12,21 @@ #define KERN_IMAGE_START 0x010000UL #define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_64) +#define RESET_PSW ((uint64_t)&jump_to_IPL_addr | RESET_PSW_MASK) static uint64_t *reset_psw = 0, save_psw, ipl_continue; +void write_reset_psw(uint64_t psw) +{ + *reset_psw = psw; +} + static void jump_to_IPL_addr(void) { __attribute__((noreturn)) void (*ipl)(void) = (void *)ipl_continue; /* Restore reset PSW */ - *reset_psw = save_psw; + write_reset_psw(save_psw); ipl(); /* should not return */ @@ -43,11 +49,12 @@ void jump_to_IPL_code(uint64_t address) * content of non-BIOS memory after we loaded the guest, so we * save the original content and restore it in jump_to_IPL_2. */ - save_psw = *reset_psw; - *reset_psw = (uint64_t) &jump_to_IPL_addr; - *reset_psw |= RESET_PSW_MASK; - ipl_continue = address; - debug_print_int("set IPL addr to", ipl_continue); + if (address) { + save_psw = *reset_psw; + write_reset_psw(RESET_PSW); + ipl_continue = address; + } + debug_print_int("set IPL addr to", address ?: *reset_psw & PSW_MASK_SHORT_ADDR); /* Ensure the guest output starts fresh */ sclp_print("\n"); @@ -77,7 +84,12 @@ void jump_to_low_kernel(void) /* Trying to get PSW at zero address */ if (*((uint64_t *)0) & RESET_PSW_MASK) { - jump_to_IPL_code((*((uint64_t *)0)) & PSW_MASK_SHORT_ADDR); + /* + * Surely nobody will try running directly from lowcore, so + * let's use 0 as an indication that we want to load the reset + * psw at 0x0 and not jump to the entry. + */ + jump_to_IPL_code(0); } /* No other option left, so use the Linux kernel start address */ diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index 9b86c120b4..6cd92669e9 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -76,6 +76,7 @@ int virtio_read(ulong sector, void *load_addr); void zipl_load(void); /* jump2ipl.c */ +void write_reset_psw(uint64_t psw); void jump_to_IPL_code(uint64_t address); void jump_to_low_kernel(void); From 25f5adea5a10fe204e41d085dff6ea94aaf80a9f Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Tue, 6 Oct 2020 05:42:49 -0400 Subject: [PATCH 14/16] pc-bios: s390x: Go into disabled wait when encountering a PGM exception Let's setup a PGM PSW, so we won't load 0s when a program exception happens. Instead we'll load a disabled wait PSW. Signed-off-by: Janosch Frank Reviewed-by: Christian Borntraeger Reviewed-by: Thomas Huth Message-Id: <20201006094249.50640-5-frankja@linux.ibm.com> Signed-off-by: Thomas Huth --- pc-bios/s390-ccw/start.S | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S index ce519300a1..4d5ad21653 100644 --- a/pc-bios/s390-ccw/start.S +++ b/pc-bios/s390-ccw/start.S @@ -34,7 +34,10 @@ remainder: larl %r2,memsetxc ex %r3,0(%r2) done: - j main /* And call C */ + /* set up a pgm exception disabled wait psw */ + larl %r2, disabled_wait_psw + mvc 0x01d0(16), 0(%r2) + j main /* And call C */ memsetxc: xc 0(1,%r1),0(%r1) From 6e05891c31012fccb071cc173ba0f31b09167bba Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 6 Oct 2020 12:43:03 +0200 Subject: [PATCH 15/16] pc-bios/s390: Update the s390-ccw bios binaries Make sure that the binaries match the current state of the sources. Signed-off-by: Thomas Huth --- pc-bios/s390-ccw.img | Bin 42608 -> 42608 bytes pc-bios/s390-netboot.img | Bin 67232 -> 67232 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img index 3074686a8c7448d943aa62f810d88d3e92865ef3..5b57ea2837680ca6f6e98e7703b89818fd8fb316 100644 GIT binary patch delta 21824 zcmexxhUvo@rU`OPtQiv(wsB2A!2kx+PfUCu?s);sW>|+tGh2YgnF|fTG=l($Vq#!m zU;{B280Mj=Uw2`$1LJf>3{i+`MyM%_29tjN2x1acWBERSGd_Aqc@5K&!f{{LsE0t2I% z(PIUHJcfx51`Z4$GZ?#tl$N*DGh~A~XF)!);|H<%AA?ASnag)DFdS%LU$H2I} zg+XNbEC$Bq%l>~@zKelz`922b*aO~ z|Cg6Ah)?EWlW>SI5Rd?SDknz|2|x25MU5s00kq1_hcUqOU$tDvAhD}Ng1|0?rGRy54n3uOOBrUi5|9^Q4L)=8h4=b0KFz_zdU|@Lc@X>>T zWv2*(((Cyj6&P69zwBgTSQMeK0USN5dN7ui>VXLi3~TBf6eci4DAYrwMP@Hw2R2gV zvBHN{3=_q*1eBI*{r}&gz#xxl@MD1q3=9*O%UKvLZ(-nDE@wGmc?$#Eaydozj<%E>L>-zZDdaLNk_2FffWM3MzrjTmI$$n&le*|1SUXe+7Fz`)gPTB$P1&%j{64$M&oS@rKGJ3A;6SAT$L_b?D( zkPu$}`@g|bF$M;xj|-tbjsW|(g(2j%F@pgEFG!#DIWU{&vB8H03@VrSKkO1JZs1{fY@oovFyRuzhn*WHUyPHPe3(_X-ntm% zB;G@g3LkcXS$o0mZveBmgB_X+vM#t4Y#lF{_kYv?g$GEN z;GX4@3}<$-Fl+)91Szh|H5p_a9Ss;RF*q;?Fn~)F_5VLXX0DFiUoS7fu)Ku96s&Ox zG~>yFB!hinmME$SDJ?Jge-@-hK?)St4B%|UwE@j?1qKGIcOX@~(I692@*WEaurRPZ z7T7p}L1p=u|Ie3OFa&@KI#9-3t#}}SfuY{&%yLZz4#$TM40{b9fSe)>aUlcua!UqK z5eE(lfy>Lk{NLbg7{CC|=oSnLU}FLp7_2s;>i<6%s$U7@grwJx1;7QJ90L<1;ev{Y z|J@+D6#34;ha z(w(&MvBCug2F1q$0u1#GEX!3GxC0afL>@bQ6kuR^eg7i|I3_`XIU8(g9mqI#_Sf$} z6fmfO3|Q3)Ht;C}gTfn#uAO2GO0VC8^s|3?z5YW0Qf_$4z#zX7R6c+_CZFQruz^X! zWT_ng|4su29+Ant+&=Xf*~juONHI?sEc@^Tf~>W@1{U=OIqEMXJNxVW4+an)+66BE z{hk358jc1Z!AVp0HYn9Fx?W|z!0?e_c?qM*RECc%%S#xY91A`wJQgSrXP6+NxLoW1 zzsU=DWa6x5KUOGUU|_kV_u(R>dG*ISPDu|5)I|1_l*S5L(`Rtngt6gUaIx z1riJ_jtL)jJQnz{fLSU>||ju1L>VC#Typ&un**Z z*=Ufv7$$%XX934P3&hBsObklPTNt!K`SxMO@|6t#_X}^}THeACvXg}&a=9l1!()RD z91JXAQyiA-|Njpz##$IcC!gZgXH1*?i&wio`>_JZVIVbJOv^PHz+u6~xcs*u!()dJ z1q>|UP-9{L;%KlzV7VlNz*LZPOa8A|4sr4?uv=J`fBEkL3UdokRmZ?>3SwK%0h!9J z4`SPF0kgq{=I{F;5sT#@k$P?gM}-d;K}>FGkg&}HFk2K9X}?c{L@XwQMR-7LOK|Su zW&^Qpy20WMV3pfIB9;Ll_P^<1b_tk05zMv%v%zf{OD{0H6_iF_=YOa-U{G1^$-ub$ z_kRaalss6wT$2IZ#F4%O4tM3{5e$N$5Pq-#R5@8WIxhII>k{jST@x6VTQE3-vh{LJ z23AMM4UBsY9Y6&FqyePPz%!L`1KaWz2A~JMTqGhuO^D?d46Y!H zLB*2Ip5>Yh3XY8%*!LPXFf1?m{{UK^=sjMr!JR=4R#?EnAQuZN7hvvt`~ajuS`h5Koy#p4K&?myke?r4U#`g@ z;TQ-ig9AW*J_q$PH>fffEnI$tfoply|NqOs{6FXn3Y9PaUq4n@F!`*2Y}Nv%0D%u% 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
m1Nel*zm?}ZRtN?DL{RdATDu5S~ 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 b1(uo%LV5F{G=s(Dh^2K*Ngb1KES&)Wy_LU5 diff --git a/pc-bios/s390-netboot.img b/pc-bios/s390-netboot.img index d9c319604b1b37660cc085c62915b25b9abd7abd..3dfce693f595a39daa5b22c75823818eb8062303 100644 GIT binary patch delta 27217 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 R2P Date: Thu, 6 Aug 2020 12:16:13 +0200 Subject: [PATCH 16/16] tests/qtest/cdrom: Add more s390x-related boot tests Let's add two new tests: 1) Booting with "bootindex" is the architected default behavior on the s390x target, so we should have at least one test that is using the "bootindex" property. 2) The s390-ccw bios used to fail when other unbootable devices have been specified before the bootable device (without "bootindex"). Now that the s390-ccw bios is a little bit smarter here, we should test this scenario, too, to avoid regressions. Message-Id: <20200806105349.632-10-thuth@redhat.com> Reviewed-by: Cornelia Huck Acked-by: Janosch Frank Signed-off-by: Thomas Huth --- tests/qtest/cdrom-test.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c index e9afab693c..eef242dc80 100644 --- a/tests/qtest/cdrom-test.c +++ b/tests/qtest/cdrom-test.c @@ -163,6 +163,18 @@ static void add_s390x_tests(void) qtest_add_data_func("cdrom/boot/virtio-scsi", "-device virtio-scsi -device scsi-cd,drive=cdr " "-blockdev file,node-name=cdr,filename=", test_cdboot); + qtest_add_data_func("cdrom/boot/with-bootindex", + "-device virtio-serial -device virtio-scsi " + "-device virtio-blk,drive=d1 " + "-drive driver=null-co,read-zeroes=on,if=none,id=d1 " + "-device virtio-blk,drive=d2,bootindex=1 " + "-drive if=none,id=d2,media=cdrom,file=", test_cdboot); + qtest_add_data_func("cdrom/boot/without-bootindex", + "-device virtio-scsi -device virtio-serial " + "-device x-terminal3270 -device virtio-blk,drive=d1 " + "-drive driver=null-co,read-zeroes=on,if=none,id=d1 " + "-device virtio-blk,drive=d2 " + "-drive if=none,id=d2,media=cdrom,file=", test_cdboot); } int main(int argc, char **argv)