From 08ab919d0dccc4ed6fb12231b20758cef112bd26 Mon Sep 17 00:00:00 2001 From: Sumanth Korikkar Date: Sat, 7 Nov 2020 22:55:51 -0600 Subject: s390/sclp: use memblock for early read cpu info sclp early read cpu info is used to detect the number of configured cpus, which is utilized by smp_detect_cpus() in early startup. * For read cpu info, the sccb block should be below 2gb. * smp_detect_cpus() utilizes read cpu info early, but after memblock initialization. Thus use memblock_allow_low() instead. * Avoid copy of sclp_core_info structure. * sclp_early_init_core_info(), sclp_early_core_info and sclp_early_core_info_valid initdata are no longer required. * smp_get_core_info() is called only once during early stage. Hence for early sclp_get_core_info(), directly call read cpu command. No need to maintain sclp_early_core_info_valid. Signed-off-by: Sumanth Korikkar Reviewed-by: Vasily Gorbik Signed-off-by: Heiko Carstens --- drivers/s390/char/sclp_early.c | 50 +++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index cc5e84b80c69..62e0d35ea1a7 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -9,9 +9,11 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include +#include #include "sclp_sdias.h" #include "sclp.h" @@ -107,29 +109,34 @@ void __init sclp_early_get_ipl_info(struct sclp_ipl_info *info) *info = sclp_ipl_info; } -static struct sclp_core_info sclp_early_core_info __initdata; -static int sclp_early_core_info_valid __initdata; - -static void __init sclp_early_init_core_info(struct read_cpu_info_sccb *sccb) -{ - if (!SCLP_HAS_CPU_INFO) - return; - memset(sccb, 0, sizeof(*sccb)); - sccb->header.length = sizeof(*sccb); - if (sclp_early_cmd(SCLP_CMDW_READ_CPU_INFO, sccb)) - return; - if (sccb->header.response_code != 0x0010) - return; - sclp_fill_core_info(&sclp_early_core_info, sccb); - sclp_early_core_info_valid = 1; -} - int __init sclp_early_get_core_info(struct sclp_core_info *info) { - if (!sclp_early_core_info_valid) - return -EIO; - *info = sclp_early_core_info; - return 0; + struct read_cpu_info_sccb *sccb; + int length = PAGE_SIZE; + int rc = 0; + + if (!SCLP_HAS_CPU_INFO) + return -EOPNOTSUPP; + + sccb = memblock_alloc_low(length, PAGE_SIZE); + if (!sccb) + return -ENOMEM; + + memset(sccb, 0, length); + sccb->header.length = length; + sccb->header.control_mask[2] = 0x80; + if (sclp_early_cmd(SCLP_CMDW_READ_CPU_INFO, sccb)) { + rc = -EIO; + goto out; + } + if (sccb->header.response_code != 0x0010) { + rc = -EIO; + goto out; + } + sclp_fill_core_info(info, sccb); +out: + memblock_free_early((unsigned long)sccb, length); + return rc; } static void __init sclp_early_console_detect(struct init_sccb *sccb) @@ -149,7 +156,6 @@ void __init sclp_early_detect(void) void *sccb = sclp_early_sccb; sclp_early_facilities_detect(sccb); - sclp_early_init_core_info(sccb); /* * Turn off SCLP event notifications. Also save remote masks in the -- cgit v1.2.3