s390/ipl: rely on diag308 store to get ipl info
authorVasily Gorbik <gor@linux.ibm.com>
Tue, 3 Apr 2018 14:03:08 +0000 (16:03 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 10 Apr 2018 05:38:59 +0000 (07:38 +0200)
For both ccw and fcp boot retrieve ipl info from ipl block received via
diag308 store. Old scsi ipl parm block handling and cio_get_iplinfo are
removed. Ipl type is deducted from ipl block (if valid).

Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/boot/compressed/misc.c
arch/s390/include/asm/cio.h
arch/s390/include/asm/ipl.h
arch/s390/kernel/early.c
arch/s390/kernel/ipl.c
drivers/s390/cio/cio.c

index 63838a1..511b2cc 100644 (file)
@@ -119,34 +119,12 @@ static void error(char *x)
        asm volatile("lpsw %0" : : "Q" (psw));
 }
 
-/*
- * Safe guard the ipl parameter block against a memory area that will be
- * overwritten. The validity check for the ipl parameter block is complex
- * (see cio_get_iplinfo and ipl_save_parameters) but if the pointer to
- * the ipl parameter block intersects with the passed memory area we can
- * safely assume that we can read from that memory. In that case just copy
- * the memory to IPL_PARMBLOCK_ORIGIN even if there is no ipl parameter
- * block.
- */
-static void check_ipl_parmblock(void *start, unsigned long size)
-{
-       void *src, *dst;
-
-       src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
-       if (src + PAGE_SIZE <= start || src >= start + size)
-               return;
-       dst = (void *) IPL_PARMBLOCK_ORIGIN;
-       memmove(dst, src, PAGE_SIZE);
-       S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
-}
-
 unsigned long decompress_kernel(void)
 {
        void *output, *kernel_end;
 
        output = (void *) ALIGN((unsigned long) _end + HEAP_SIZE, PAGE_SIZE);
        kernel_end = output + SZ__bss_start;
-       check_ipl_parmblock((void *) 0, (unsigned long) kernel_end);
 
 #ifdef CONFIG_BLK_DEV_INITRD
        /*
@@ -156,7 +134,6 @@ unsigned long decompress_kernel(void)
         * current bss section..
         */
        if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) {
-               check_ipl_parmblock(kernel_end, INITRD_SIZE);
                memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE);
                INITRD_START = (unsigned long) kernel_end;
        }
index 847a042..80c1179 100644 (file)
@@ -330,14 +330,6 @@ extern void css_schedule_reprobe(void);
 
 extern void reipl_ccw_dev(struct ccw_dev_id *id);
 
-struct cio_iplinfo {
-       u8 ssid;
-       u16 devno;
-       int is_qdio;
-};
-
-extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo);
-
 /* Function from drivers/s390/cio/chsc.c */
 int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta);
 int chsc_sstpi(void *page, void *result, size_t size);
index 284acf8..eb10df9 100644 (file)
@@ -15,8 +15,6 @@
 
 #define NSS_NAME_SIZE  8
 
-#define IPL_PARMBLOCK_ORIGIN   0x2000
-
 #define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \
                              sizeof(struct ipl_block_fcp))
 
@@ -92,8 +90,7 @@ void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
 extern void do_reipl(void);
 extern void do_halt(void);
 extern void do_poff(void);
-extern void ipl_verify_parameters(void);
-extern void ipl_update_parameters(void);
+extern void ipl_store_parameters(void);
 extern size_t append_ipl_vmparm(char *, size_t);
 extern size_t append_ipl_scpdata(char *, size_t);
 
index b00b515..32daa0f 100644 (file)
@@ -342,16 +342,6 @@ static __init void memmove_early(void *dst, const void *src, size_t n)
        S390_lowcore.program_new_psw = old;
 }
 
-static __init noinline void ipl_save_parameters(void)
-{
-       void *src, *dst;
-
-       src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
-       dst = (void *) IPL_PARMBLOCK_ORIGIN;
-       memmove_early(dst, src, PAGE_SIZE);
-       S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
-}
-
 static __init noinline void rescue_initrd(void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -421,10 +411,8 @@ static void __init setup_boot_command_line(void)
 void __init startup_init(void)
 {
        reset_tod_clock();
-       ipl_save_parameters();
        rescue_initrd();
        clear_bss_section();
-       ipl_verify_parameters();
        time_early_init();
        init_kernel_storage_key();
        lockdep_off();
@@ -432,7 +420,7 @@ void __init startup_init(void)
        setup_facility_list();
        detect_machine_type();
        setup_arch_string();
-       ipl_update_parameters();
+       ipl_store_parameters();
        setup_boot_command_line();
        detect_diag9c();
        detect_diag44();
index ffecd7c..44c3025 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/smp.h>
 #include <asm/setup.h>
 #include <asm/cpcmd.h>
-#include <asm/cio.h>
 #include <asm/ebcdic.h>
 #include <asm/reset.h>
 #include <asm/sclp.h>
@@ -119,16 +118,6 @@ static char *dump_type_str(enum dump_type type)
        }
 }
 
-enum {
-       IPL_DEVNO_VALID         = 1,
-       IPL_PARMBLOCK_VALID     = 2,
-};
-
-/*
- * IPL validity flags
- */
-static u32 ipl_flags;
-
 enum ipl_method {
        REIPL_METHOD_CCW_CIO,
        REIPL_METHOD_CCW_DIAG,
@@ -150,6 +139,7 @@ enum dump_method {
        DUMP_METHOD_FCP_DIAG,
 };
 
+static int ipl_block_valid;
 static int diag308_set_works;
 
 static struct ipl_parameter_block ipl_block;
@@ -280,17 +270,19 @@ static void make_attrs_ro(struct attribute **attrs)
 
 static __init enum ipl_type get_ipl_type(void)
 {
-       if (!(ipl_flags & IPL_DEVNO_VALID))
+       if (!ipl_block_valid)
                return IPL_TYPE_UNKNOWN;
-       if (!(ipl_flags & IPL_PARMBLOCK_VALID))
+
+       switch (ipl_block.hdr.pbt) {
+       case DIAG308_IPL_TYPE_CCW:
                return IPL_TYPE_CCW;
-       if (ipl_block.hdr.version > IPL_MAX_SUPPORTED_VERSION)
-               return IPL_TYPE_UNKNOWN;
-       if (ipl_block.hdr.pbt != DIAG308_IPL_TYPE_FCP)
-               return IPL_TYPE_UNKNOWN;
-       if (ipl_block.ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP)
-               return IPL_TYPE_FCP_DUMP;
-       return IPL_TYPE_FCP;
+       case DIAG308_IPL_TYPE_FCP:
+               if (ipl_block.ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP)
+                       return IPL_TYPE_FCP_DUMP;
+               else
+                       return IPL_TYPE_FCP;
+       }
+       return IPL_TYPE_UNKNOWN;
 }
 
 struct ipl_info ipl_info;
@@ -1949,30 +1941,15 @@ void __init setup_ipl(void)
        atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
 }
 
-void __init ipl_update_parameters(void)
+void __init ipl_store_parameters(void)
 {
        int rc;
 
        rc = diag308(DIAG308_STORE, &ipl_block);
        if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG))
                diag308_set_works = 1;
-       if (rc != DIAG308_RC_OK && (ipl_flags & IPL_PARMBLOCK_VALID))
-               memcpy(&ipl_block, (void *)IPL_PARMBLOCK_ORIGIN, PAGE_SIZE);
-}
-
-void __init ipl_verify_parameters(void)
-{
-       struct cio_iplinfo iplinfo;
-
-       if (cio_get_iplinfo(&iplinfo))
-               return;
-
-       ipl_block.ipl_info.ccw.ssid = iplinfo.ssid;
-       ipl_block.ipl_info.ccw.devno = iplinfo.devno;
-       ipl_flags |= IPL_DEVNO_VALID;
-       if (!iplinfo.is_qdio)
-               return;
-       ipl_flags |= IPL_PARMBLOCK_VALID;
+       if (rc == DIAG308_RC_OK && ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION)
+               ipl_block_valid = 1;
 }
 
 static LIST_HEAD(rcall);
index 6886b3d..28d4ee8 100644 (file)
@@ -990,39 +990,6 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
        do_reipl_asm(*((__u32*)&schid));
 }
 
-int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
-{
-       static struct chsc_sda_area sda_area __initdata;
-       struct subchannel_id schid;
-       struct schib schib;
-
-       schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
-       if (!schid.one)
-               return -ENODEV;
-
-       if (schid.ssid) {
-               /*
-                * Firmware should have already enabled MSS but whoever started
-                * the kernel might have initiated a channel subsystem reset.
-                * Ensure that MSS is enabled.
-                */
-               memset(&sda_area, 0, sizeof(sda_area));
-               if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS))
-                       return -ENODEV;
-       }
-       if (stsch(schid, &schib))
-               return -ENODEV;
-       if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
-               return -ENODEV;
-       if (!schib.pmcw.dnv)
-               return -ENODEV;
-
-       iplinfo->ssid = schid.ssid;
-       iplinfo->devno = schib.pmcw.dev;
-       iplinfo->is_qdio = schib.pmcw.qf;
-       return 0;
-}
-
 /**
  * cio_tm_start_key - perform start function
  * @sch: subchannel on which to perform the start function