pc-bios/s390-ccw: Remove panics from DASD IPL path
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>
This commit is contained in:
parent
facd91ac1a
commit
1d5c7f078e
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user