From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43090) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XNI4L-0006VD-1u for qemu-devel@nongnu.org; Fri, 29 Aug 2014 05:02:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XNI4A-0006Lz-6L for qemu-devel@nongnu.org; Fri, 29 Aug 2014 05:02:05 -0400 Received: from e06smtp13.uk.ibm.com ([195.75.94.109]:59121) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XNI49-0006Ld-Tp for qemu-devel@nongnu.org; Fri, 29 Aug 2014 05:01:54 -0400 Received: from /spool/local by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 29 Aug 2014 10:01:52 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by d06dlp02.portsmouth.uk.ibm.com (Postfix) with ESMTP id 2F77E2190023 for ; Fri, 29 Aug 2014 10:01:31 +0100 (BST) Received: from d06av09.portsmouth.uk.ibm.com (d06av09.portsmouth.uk.ibm.com [9.149.37.250]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id s7T91ngc44957736 for ; Fri, 29 Aug 2014 09:01:49 GMT Received: from d06av09.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av09.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s7T91nGC009695 for ; Fri, 29 Aug 2014 03:01:49 -0600 From: Jens Freimann Date: Fri, 29 Aug 2014 11:01:40 +0200 Message-Id: <1409302902-57391-6-git-send-email-jfrei@linux.vnet.ibm.com> In-Reply-To: <1409302902-57391-1-git-send-email-jfrei@linux.vnet.ibm.com> References: <1409302902-57391-1-git-send-email-jfrei@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 5/7] pc-bios/s390-ccw: IPL from DASD with format variations List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Christian Borntraeger , Alexander Graf , Cornelia Huck Cc: "Eugene (jno) Dvurechenski" , Jens Freimann , qemu-devel@nongnu.org From: "Eugene (jno) Dvurechenski" There are two known cases of DASD format where signatures are incomplete or absent: 1. result of (ECKD_LDL_UNLABELED) 2. CDL with zero keys in IPL1 and IPL2 records Now the code attempts to 1. find zIPL and use SCSI layout 2. find IPL1 and use CDL layout 3. find CMS1 and use LDL layout 3. find LNX1 and use LDL layout 4. find zIPL and use unlabeled LDL layout 5. find zIPL and use CDL layout 6. die in this sequence. Signed-off-by: Eugene (jno) Dvurechenski Acked-by: Cornelia Huck Acked-by: Christian Borntraeger Reviewed-by: David Hildenbrand Signed-off-by: Jens Freimann --- pc-bios/s390-ccw/bootmap.c | 52 ++++++++++++++++++++++++++-------------------- pc-bios/s390-ccw/bootmap.h | 2 +- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index d4c579c..aa1cf80 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -222,7 +222,6 @@ static void ipl_eckd_cdl(void) memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(1, ipl2, "Cannot read IPL2 record at block 1"); - IPL_assert(magic_match(ipl2, IPL2_MAGIC), "No IPL2 record"); mbr = &ipl2->u.x.mbr; IPL_assert(magic_match(mbr, ZIPL_MAGIC), "No zIPL section in IPL2 record."); @@ -246,12 +245,10 @@ static void ipl_eckd_cdl(void) /* no return */ } -static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) +static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) { LDL_VTOC *vlbl = (void *)sec; /* already read, 3rd block */ char msg[4] = { '?', '.', '\n', '\0' }; - block_number_t block_nr; - BootInfo *bip; sclp_print((mode == ECKD_CMS) ? "CMS" : "LDL"); sclp_print(" version "); @@ -271,12 +268,27 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) } sclp_print(msg); print_volser(vlbl->volser); +} + +static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) +{ + block_number_t block_nr; + BootInfo *bip = (void *)(sec + 0x70); /* BootInfo is MBR for LDL */ + + if (mode != ECKD_LDL_UNLABELED) { + print_eckd_ldl_msg(mode); + } /* DO NOT read BootMap pointer (only one, xECKD) at block #2 */ memset(sec, FREE_SPACE_FILLER, sizeof(sec)); - read_block(0, sec, "Cannot read block 0"); - bip = (void *)(sec + 0x70); /* "boot info" is "eckd mbr" for LDL */ + read_block(0, sec, "Cannot read block 0 to grab boot info."); + if (mode == ECKD_LDL_UNLABELED) { + if (!magic_match(bip->magic, ZIPL_MAGIC)) { + return; /* not applicable layout */ + } + sclp_print("unlabeled LDL.\n"); + } verify_boot_info(bip); block_nr = eckd_block_num((void *)&(bip->bp.ipl.bm_ptr.eckd.bptr)); @@ -284,19 +296,6 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) /* no return */ } -static void ipl_eckd(ECKD_IPL_mode_t mode) -{ - switch (mode) { - case ECKD_CDL: - ipl_eckd_cdl(); /* no return */ - case ECKD_CMS: - case ECKD_LDL: - ipl_eckd_ldl(mode); /* no return */ - default: - virtio_panic("\n! Unknown ECKD IPL mode !\n"); - } -} - static void print_eckd_msg(void) { char msg[] = "Using ECKD scheme (block size *****), "; @@ -471,7 +470,7 @@ void zipl_load(void) } print_eckd_msg(); if (magic_match(mbr->magic, IPL1_MAGIC)) { - ipl_eckd(ECKD_CDL); /* no return */ + ipl_eckd_cdl(); /* no return */ } /* LDL/CMS? */ @@ -479,11 +478,18 @@ void zipl_load(void) read_block(2, vlbl, "Cannot read block 2"); if (magic_match(vlbl->magic, CMS1_MAGIC)) { - ipl_eckd(ECKD_CMS); /* no return */ + ipl_eckd_ldl(ECKD_CMS); /* no return */ } if (magic_match(vlbl->magic, LNX1_MAGIC)) { - ipl_eckd(ECKD_LDL); /* no return */ + ipl_eckd_ldl(ECKD_LDL); /* no return */ } - virtio_panic("\n* invalid MBR magic *\n"); + ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */ + /* + * Ok, it is not a LDL by any means. + * It still might be a CDL with zero record keys for IPL1 and IPL2 + */ + ipl_eckd_cdl(); + + virtio_panic("\n* this can never happen *\n"); } diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 30ef22f..6a4823d 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -257,9 +257,9 @@ typedef struct IplVolumeLabel { typedef enum { ECKD_NO_IPL, - ECKD_CDL, ECKD_CMS, ECKD_LDL, + ECKD_LDL_UNLABELED, } ECKD_IPL_mode_t; /* utility code below */ -- 1.8.5.5