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 <sumanthk@linux.ibm.com>
Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
Sumanth Korikkar 2020-11-07 22:55:51 -06:00 committed by Heiko Carstens
parent da78693e6e
commit 08ab919d0d

View file

@ -9,9 +9,11 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/errno.h>
#include <linux/memblock.h>
#include <asm/ctl_reg.h>
#include <asm/sclp.h>
#include <asm/ipl.h>
#include <asm/setup.h>
#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