178 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 8279e0d5e38b31b9fcd36ff38f0175163ac4ba28 Mon Sep 17 00:00:00 2001
 | |
| From: Jared Rossi <jrossi@linux.ibm.com>
 | |
| Date: Sat, 19 Oct 2024 21:29:44 -0400
 | |
| Subject: [PATCH 12/38] pc-bios/s390-ccw: Remove panics from DASD IPL path
 | |
| MIME-Version: 1.0
 | |
| Content-Type: text/plain; charset=UTF-8
 | |
| Content-Transfer-Encoding: 8bit
 | |
| 
 | |
| RH-Author: Thomas Huth <thuth@redhat.com>
 | |
| RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
 | |
| RH-Jira: RHEL-58153
 | |
| RH-Acked-by: Cédric Le Goater <clg@redhat.com>
 | |
| RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
 | |
| RH-Commit: [11/23] 10de76e1707b351835081f37ddf8ef1c2c00fe61 (thuth/qemu-kvm-cs9)
 | |
| 
 | |
| Remove panic-on-error from DASD IPL specific functions so that error recovery
 | |
| may be possible in the future.
 | |
| 
 | |
| Functions that would previously panic now provide a return code.
 | |
| 
 | |
| Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
 | |
| Reviewed-by: Thomas Huth <thuth@redhat.com>
 | |
| Message-ID: <20241020012953.1380075-11-jrossi@linux.ibm.com>
 | |
| Signed-off-by: Thomas Huth <thuth@redhat.com>
 | |
| (cherry picked from commit 1d5c7f078e938e6844f404429dd70bc52b39dac6)
 | |
| ---
 | |
|  pc-bios/s390-ccw/dasd-ipl.c | 66 ++++++++++++++++++++-----------------
 | |
|  pc-bios/s390-ccw/dasd-ipl.h |  2 +-
 | |
|  2 files changed, 37 insertions(+), 31 deletions(-)
 | |
| 
 | |
| diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c
 | |
| index ae751adec1..babece95ea 100644
 | |
| --- a/pc-bios/s390-ccw/dasd-ipl.c
 | |
| +++ b/pc-bios/s390-ccw/dasd-ipl.c
 | |
| @@ -111,38 +111,29 @@ static void make_readipl(void)
 | |
|      ccwIplRead->count = 0x18; /* Read 0x18 bytes of data */
 | |
|  }
 | |
|  
 | |
| -static void run_readipl(SubChannelId schid, uint16_t cutype)
 | |
| +static int run_readipl(SubChannelId schid, uint16_t cutype)
 | |
|  {
 | |
| -    if (do_cio(schid, cutype, 0x00, CCW_FMT0)) {
 | |
| -        panic("dasd-ipl: Failed to run Read IPL channel program\n");
 | |
| -    }
 | |
| +    return do_cio(schid, cutype, 0x00, CCW_FMT0);
 | |
|  }
 | |
|  
 | |
|  /*
 | |
|   * 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)
 | |
| +static bool 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");
 | |
| -    }
 | |
| +    return (ccwread->cmd_code == CCW_CMD_DASD_READ &&
 | |
| +            ccwtic->cmd_code == CCW_CMD_TIC);
 | |
|  }
 | |
|  
 | |
| -static void check_ipl2(uint32_t ipl2_addr)
 | |
| +static bool 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");
 | |
| -    }
 | |
| +    return (ipl2_addr != 0x00 && ccw->cmd_code != 0x00);
 | |
|  }
 | |
|  
 | |
|  static uint32_t read_ipl2_addr(void)
 | |
| @@ -188,52 +179,67 @@ static void ipl1_fixup(void)
 | |
|      ccwSearchTic->cda = ptr2u32(ccwSearchID);
 | |
|  }
 | |
|  
 | |
| -static void run_ipl1(SubChannelId schid, uint16_t cutype)
 | |
| +static int run_ipl1(SubChannelId schid, uint16_t cutype)
 | |
|   {
 | |
|      uint32_t startAddr = 0x08;
 | |
|  
 | |
| -    if (do_cio(schid, cutype, startAddr, CCW_FMT0)) {
 | |
| -        panic("dasd-ipl: Failed to run IPL1 channel program\n");
 | |
| -    }
 | |
| +    return do_cio(schid, cutype, startAddr, CCW_FMT0);
 | |
|  }
 | |
|  
 | |
| -static void run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr)
 | |
| +static int run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr)
 | |
|  {
 | |
| -    if (run_dynamic_ccw_program(schid, cutype, addr)) {
 | |
| -        panic("dasd-ipl: Failed to run IPL2 channel program\n");
 | |
| -    }
 | |
| +    return run_dynamic_ccw_program(schid, cutype, addr);
 | |
|  }
 | |
|  
 | |
|  /*
 | |
|   * Limitations in vfio-ccw support complicate the IPL process. Details can
 | |
|   * be found in docs/devel/s390-dasd-ipl.rst
 | |
|   */
 | |
| -void dasd_ipl(SubChannelId schid, uint16_t cutype)
 | |
| +int dasd_ipl(SubChannelId schid, uint16_t cutype)
 | |
|  {
 | |
|      PSWLegacy *pswl = (PSWLegacy *) 0x00;
 | |
|      uint32_t ipl2_addr;
 | |
|  
 | |
|      /* Construct Read IPL CCW and run it to read IPL1 from boot disk */
 | |
|      make_readipl();
 | |
| -    run_readipl(schid, cutype);
 | |
| +    if (run_readipl(schid, cutype)) {
 | |
| +        puts("Failed to run Read IPL channel program");
 | |
| +        return -EIO;
 | |
| +    }
 | |
| +
 | |
|      ipl2_addr = read_ipl2_addr();
 | |
| -    check_ipl1();
 | |
| +
 | |
| +    if (!check_ipl1()) {
 | |
| +        puts("IPL1 invalid for DASD-IPL");
 | |
| +        return -EINVAL;
 | |
| +    }
 | |
|  
 | |
|      /*
 | |
|       * Fixup IPL1 channel program to account for vfio-ccw limitations, then run
 | |
|       * it to read IPL2 channel program from boot disk.
 | |
|       */
 | |
|      ipl1_fixup();
 | |
| -    run_ipl1(schid, cutype);
 | |
| -    check_ipl2(ipl2_addr);
 | |
| +    if (run_ipl1(schid, cutype)) {
 | |
| +        puts("Failed to run IPL1 channel program");
 | |
| +        return -EIO;
 | |
| +    }
 | |
| +
 | |
| +    if (!check_ipl2(ipl2_addr)) {
 | |
| +        puts("IPL2 invalid for DASD-IPL");
 | |
| +        return -EINVAL;
 | |
| +    }
 | |
|  
 | |
|      /*
 | |
|       * Run IPL2 channel program to read operating system code from boot disk
 | |
|       */
 | |
| -    run_ipl2(schid, cutype, ipl2_addr);
 | |
| +    if (run_ipl2(schid, cutype, ipl2_addr)) {
 | |
| +        puts("Failed to run IPL2 channel program");
 | |
| +        return -EIO;
 | |
| +    }
 | |
|  
 | |
|      /* Transfer control to the guest operating system */
 | |
|      pswl->mask |= PSW_MASK_EAMODE;   /* Force z-mode */
 | |
|      pswl->addr |= PSW_MASK_BAMODE;   /* ...          */
 | |
|      jump_to_low_kernel();
 | |
| +    return -1;
 | |
|  }
 | |
| diff --git a/pc-bios/s390-ccw/dasd-ipl.h b/pc-bios/s390-ccw/dasd-ipl.h
 | |
| index c394828906..eb1898c84a 100644
 | |
| --- a/pc-bios/s390-ccw/dasd-ipl.h
 | |
| +++ b/pc-bios/s390-ccw/dasd-ipl.h
 | |
| @@ -11,6 +11,6 @@
 | |
|  #ifndef DASD_IPL_H
 | |
|  #define DASD_IPL_H
 | |
|  
 | |
| -void dasd_ipl(SubChannelId schid, uint16_t cutype);
 | |
| +int dasd_ipl(SubChannelId schid, uint16_t cutype);
 | |
|  
 | |
|  #endif /* DASD_IPL_H */
 | |
| -- 
 | |
| 2.39.3
 | |
| 
 |