aboutsummaryrefslogtreecommitdiff
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorAlexander Egorenkov2020-10-10 03:34:25 +0200
committerHeiko Carstens2021-07-27 09:39:13 +0200
commit0029b4d19491cd83cfb85de0fa9ac1e175409377 (patch)
tree68604b1541e9aa5d142e994d6b70556b4acb3b7f /drivers/s390/char
parent6040b3f45f394ef3a9fabd68282de92cc271328e (diff)
s390/sclp: use only one sclp early buffer to send commands
A buffer that can be used for communication with SCLP is required to lie below 2GB memory address. Therefore, both sclp_info_sccb and sclp_early_sccb must fulfill this requirement if passed directly to the sclp_early_cmd() function. Instead, use only sclp_early_sccb for communication with SCLP. This allows the buffer sclp_info_sccb to be placed anywhere in the memory address space and, therefore, simplifies the process of making the decompressor relocatable later on, one thing less to relocate. And make sure that the length of the new unified early SCLP buffer is no less than the length of the removed sclp_info_sccb buffer which might be larger than the length of the sclp_early_sccb buffer. Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Reviewed-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/sclp_early_core.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c
index b7329af076a0..80ba6523e76e 100644
--- a/drivers/s390/char/sclp_early_core.c
+++ b/drivers/s390/char/sclp_early_core.c
@@ -235,11 +235,20 @@ void sclp_early_printk(const char *str)
__sclp_early_printk(str, strlen(str));
}
+/*
+ * We can't pass sclp_info_sccb to sclp_early_cmd() here directly,
+ * because it might not fulfil the requiremets for a SCLP communication buffer:
+ * - lie below 2G in memory
+ * - be page-aligned
+ * Therefore, we use the buffer sclp_early_sccb (which fulfils all those
+ * requirements) temporarily for communication and copy a received response
+ * back into the buffer sclp_info_sccb upon successful completion.
+ */
int __init sclp_early_read_info(void)
{
int i;
int length = test_facility(140) ? EXT_SCCB_READ_SCP : PAGE_SIZE;
- struct read_info_sccb *sccb = &sclp_info_sccb;
+ struct read_info_sccb *sccb = (struct read_info_sccb *)sclp_early_sccb;
sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
SCLP_CMDW_READ_SCP_INFO};
@@ -251,6 +260,7 @@ int __init sclp_early_read_info(void)
if (sclp_early_cmd(commands[i], sccb))
break;
if (sccb->header.response_code == 0x10) {
+ memcpy(&sclp_info_sccb, sccb, length);
sclp_info_sccb_valid = 1;
return 0;
}