diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2018-04-03 17:03:08 +0300 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-04-10 08:38:59 +0300 |
commit | d08091ac9654383422350ce829caf467b3e9a8b1 (patch) | |
tree | 6d5b94617b0423412917b26eb22be9b8752221e9 | |
parent | 283abedb1bd67e22f05fe4e79e1722bd7c7ed3be (diff) | |
download | linux-d08091ac9654383422350ce829caf467b3e9a8b1.tar.xz |
s390/ipl: rely on diag308 store to get ipl info
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>
-rw-r--r-- | arch/s390/boot/compressed/misc.c | 23 | ||||
-rw-r--r-- | arch/s390/include/asm/cio.h | 8 | ||||
-rw-r--r-- | arch/s390/include/asm/ipl.h | 5 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 14 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 53 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 33 |
6 files changed, 17 insertions, 119 deletions
diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c index 63838a17e56a..511b2cc9b91a 100644 --- a/arch/s390/boot/compressed/misc.c +++ b/arch/s390/boot/compressed/misc.c @@ -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; } diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 847a04262b9c..80c1179bc666 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -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); diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 284acf81d0ad..eb10df9ef607 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -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); diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index b00b515baa53..32daa0f84325 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -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(); diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index ffecd7cf34b6..44c3025ddaaf 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -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); diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 6886b3d34cf8..28d4ee865a1c 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -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 |