summaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/sysinfo.h2
-rw-r--r--arch/s390/kernel/early.c27
-rw-r--r--arch/s390/kernel/sysinfo.c12
-rw-r--r--arch/s390/kernel/topology.c10
4 files changed, 31 insertions, 20 deletions
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h
index 12e5256adca3..04e6e9774708 100644
--- a/arch/s390/include/asm/sysinfo.h
+++ b/arch/s390/include/asm/sysinfo.h
@@ -118,6 +118,8 @@ struct sysinfo_3_2_2 {
char reserved_544[3552];
};
+extern int topology_max_mnest;
+
#define TOPOLOGY_CPU_BITS 64
#define TOPOLOGY_NR_MAG 6
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 1345ba452c83..f4bcdc01bfc8 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -215,26 +215,44 @@ static noinline __init void init_kernel_storage_key(void)
PAGE_DEFAULT_KEY, 0);
}
-static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
+static __initdata char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE);
static noinline __init void detect_machine_type(void)
{
+ struct sysinfo_3_2_2 *vmms = (struct sysinfo_3_2_2 *)&sysinfo_page;
+
/* Check current-configuration-level */
if ((stsi(NULL, 0, 0, 0) >> 28) <= 2) {
S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR;
return;
}
/* Get virtual-machine cpu information. */
- if (stsi(&vmms, 3, 2, 2) == -ENOSYS || !vmms.count)
+ if (stsi(vmms, 3, 2, 2) == -ENOSYS || !vmms->count)
return;
/* Running under KVM? If not we assume z/VM */
- if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3))
+ if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3))
S390_lowcore.machine_flags |= MACHINE_FLAG_KVM;
else
S390_lowcore.machine_flags |= MACHINE_FLAG_VM;
}
+static __init void setup_topology(void)
+{
+#ifdef CONFIG_64BIT
+ int max_mnest;
+
+ if (!test_facility(11))
+ return;
+ S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
+ for (max_mnest = 6; max_mnest > 1; max_mnest--) {
+ if (stsi(&sysinfo_page, 15, 1, max_mnest) != -ENOSYS)
+ break;
+ }
+ topology_max_mnest = max_mnest;
+#endif
+}
+
static void early_pgm_check_handler(void)
{
unsigned long addr;
@@ -364,8 +382,6 @@ static __init void detect_machine_facilities(void)
S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
if (test_facility(8))
S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
- if (test_facility(11))
- S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
if (test_facility(27))
S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
if (test_facility(40))
@@ -467,6 +483,7 @@ void __init startup_init(void)
detect_diag44();
detect_machine_facilities();
setup_hpage();
+ setup_topology();
sclp_facilities_detect();
detect_memory_layout(memory_chunk);
#ifdef CONFIG_DYNAMIC_FTRACE
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c
index 2249b0cf80ef..2af4ee67fe52 100644
--- a/arch/s390/kernel/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -22,6 +22,8 @@
#include <math-emu/soft-fp.h>
#include <math-emu/single.h>
+int topology_max_mnest;
+
static inline int stsi_0(void)
{
int rc = stsi(NULL, 0, 0, 0);
@@ -95,15 +97,7 @@ static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info)
seq_putc(m, '\n');
if (!MACHINE_HAS_TOPOLOGY)
return;
- if (max_mnest) {
- stsi(info, 15, 1, max_mnest);
- } else {
- for (max_mnest = 6; max_mnest > 1; max_mnest--) {
- rc = stsi(info, 15, 1, max_mnest);
- if (rc != -ENOSYS)
- break;
- }
- }
+ stsi(info, 15, 1, topology_max_mnest);
seq_printf(m, "CPU Topology HW: ");
for (i = 0; i < TOPOLOGY_NR_MAG; i++)
seq_printf(m, " %d", info->mag[i]);
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index fc957f2eef7c..80ca4ba759f6 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -251,12 +251,10 @@ static void update_cpu_core_map(void)
void store_topology(struct sysinfo_15_1_x *info)
{
- int rc;
-
- rc = stsi(info, 15, 1, 3);
- if (rc != -ENOSYS)
- return;
- stsi(info, 15, 1, 2);
+ if (topology_max_mnest >= 3)
+ stsi(info, 15, 1, 3);
+ else
+ stsi(info, 15, 1, 2);
}
int arch_update_cpu_topology(void)
OpenPOWER on IntegriCloud