diff options
Diffstat (limited to 'arch/s390/boot/ipl_parm.c')
| -rw-r--r-- | arch/s390/boot/ipl_parm.c | 54 | 
1 files changed, 33 insertions, 21 deletions
| diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c index 36beb56de021..3c49bde8aa5e 100644 --- a/arch/s390/boot/ipl_parm.c +++ b/arch/s390/boot/ipl_parm.c @@ -7,16 +7,19 @@  #include <asm/sections.h>  #include <asm/boot_data.h>  #include <asm/facility.h> +#include <asm/uv.h>  #include "boot.h"  char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; -struct ipl_parameter_block __bootdata(early_ipl_block); -int __bootdata(early_ipl_block_valid); +struct ipl_parameter_block __bootdata_preserved(ipl_block); +int __bootdata_preserved(ipl_block_valid);  unsigned long __bootdata(memory_end);  int __bootdata(memory_end_set);  int __bootdata(noexec_disabled); +int kaslr_enabled __section(.data); +  static inline int __diag308(unsigned long subcode, void *addr)  {  	register unsigned long _addr asm("0") = (unsigned long)addr; @@ -45,13 +48,15 @@ void store_ipl_parmblock(void)  {  	int rc; -	rc = __diag308(DIAG308_STORE, &early_ipl_block); +	uv_set_shared(__pa(&ipl_block)); +	rc = __diag308(DIAG308_STORE, &ipl_block); +	uv_remove_shared(__pa(&ipl_block));  	if (rc == DIAG308_RC_OK && -	    early_ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION) -		early_ipl_block_valid = 1; +	    ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION) +		ipl_block_valid = 1;  } -static size_t scpdata_length(const char *buf, size_t count) +static size_t scpdata_length(const u8 *buf, size_t count)  {  	while (count) {  		if (buf[count - 1] != '\0' && buf[count - 1] != ' ') @@ -68,26 +73,26 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,  	size_t i;  	int has_lowercase; -	count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data, -					     ipb->ipl_info.fcp.scp_data_len)); +	count = min(size - 1, scpdata_length(ipb->fcp.scp_data, +					     ipb->fcp.scp_data_len));  	if (!count)  		goto out;  	has_lowercase = 0;  	for (i = 0; i < count; i++) { -		if (!isascii(ipb->ipl_info.fcp.scp_data[i])) { +		if (!isascii(ipb->fcp.scp_data[i])) {  			count = 0;  			goto out;  		} -		if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i])) +		if (!has_lowercase && islower(ipb->fcp.scp_data[i]))  			has_lowercase = 1;  	}  	if (has_lowercase) -		memcpy(dest, ipb->ipl_info.fcp.scp_data, count); +		memcpy(dest, ipb->fcp.scp_data, count);  	else  		for (i = 0; i < count; i++) -			dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]); +			dest[i] = tolower(ipb->fcp.scp_data[i]);  out:  	dest[count] = '\0';  	return count; @@ -103,14 +108,14 @@ static void append_ipl_block_parm(void)  	delim = early_command_line + len;    /* '\0' character position */  	parm = early_command_line + len + 1; /* append right after '\0' */ -	switch (early_ipl_block.hdr.pbt) { -	case DIAG308_IPL_TYPE_CCW: +	switch (ipl_block.pb0_hdr.pbt) { +	case IPL_PBT_CCW:  		rc = ipl_block_get_ascii_vmparm( -			parm, COMMAND_LINE_SIZE - len - 1, &early_ipl_block); +			parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);  		break; -	case DIAG308_IPL_TYPE_FCP: +	case IPL_PBT_FCP:  		rc = ipl_block_get_ascii_scpdata( -			parm, COMMAND_LINE_SIZE - len - 1, &early_ipl_block); +			parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);  		break;  	}  	if (rc) { @@ -141,7 +146,7 @@ void setup_boot_command_line(void)  	strcpy(early_command_line, strim(COMMAND_LINE));  	/* append IPL PARM data to the boot command line */ -	if (early_ipl_block_valid) +	if (!is_prot_virt_guest() && ipl_block_valid)  		append_ipl_block_parm();  } @@ -211,6 +216,7 @@ void parse_boot_command_line(void)  	char *args;  	int rc; +	kaslr_enabled = IS_ENABLED(CONFIG_RANDOMIZE_BASE);  	args = strcpy(command_line_buf, early_command_line);  	while (*args) {  		args = next_arg(args, ¶m, &val); @@ -228,15 +234,21 @@ void parse_boot_command_line(void)  		if (!strcmp(param, "facilities"))  			modify_fac_list(val); + +		if (!strcmp(param, "nokaslr")) +			kaslr_enabled = 0;  	}  }  void setup_memory_end(void)  {  #ifdef CONFIG_CRASH_DUMP -	if (!OLDMEM_BASE && early_ipl_block_valid && -	    early_ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP && -	    early_ipl_block.ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP) { +	if (OLDMEM_BASE) { +		kaslr_enabled = 0; +	} else if (ipl_block_valid && +		   ipl_block.pb0_hdr.pbt == IPL_PBT_FCP && +		   ipl_block.fcp.opt == IPL_PB0_FCP_OPT_DUMP) { +		kaslr_enabled = 0;  		if (!sclp_early_get_hsa_size(&memory_end) && memory_end)  			memory_end_set = 1;  	} |