Skip to content

Commit

Permalink
s390/ipl: rely on diag308 store to get ipl info
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Vasily Gorbik authored and Martin Schwidefsky committed Apr 10, 2018
1 parent 283abed commit d08091a
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 119 deletions.
23 changes: 0 additions & 23 deletions arch/s390/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
/*
Expand All @@ -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;
}
Expand Down
8 changes: 0 additions & 8 deletions arch/s390/include/asm/cio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 1 addition & 4 deletions arch/s390/include/asm/ipl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down Expand Up @@ -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);

Expand Down
14 changes: 1 addition & 13 deletions arch/s390/kernel/early.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -421,18 +411,16 @@ 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();
setup_lowcore_early();
setup_facility_list();
detect_machine_type();
setup_arch_string();
ipl_update_parameters();
ipl_store_parameters();
setup_boot_command_line();
detect_diag9c();
detect_diag44();
Expand Down
53 changes: 15 additions & 38 deletions arch/s390/kernel/ipl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
33 changes: 0 additions & 33 deletions drivers/s390/cio/cio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d08091a

Please sign in to comment.