All of lore.kernel.org
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH v4 0/4] S390x: CPU Topology Information
@ 2022-02-08 13:27 Pierre Morel
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 1/4] s390x: lib: Add SCLP toplogy nested level Pierre Morel
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-08 13:27 UTC (permalink / raw)
  To: linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david, nrb

Hi,

new version of the series with corrections.

When facility 11 is available inside the S390x architecture, 2 new
instructions are available: PTF and STSI with function code 15.

Let's check their availability in QEMU/KVM and their coherence
with the CPU topology provided to the QEMU -smp parameter and as
argument for the test.

To run these tests successfully you will need both the Linux and the
QEMU patches, at least the following or newer patches:

    https://lkml.org/lkml/2021/8/3/201

    https://lists.nongnu.org/archive/html/qemu-s390x/2021-07/msg00165.html

Then if you have the text you can run directly the unit test or directly
start QEMU with:

# ./s390x-run s390x/topology.elf \
	-smp 5,drawers=2,books=3,sockets=4,cores=4,maxcpus=96 \
	-append "-d 2 -b 3 -s 4 -c 4 -m 96"

If you do not have the patches you can still use the test but only with
the first two topology levels like in:

# ./s390x-run s390x/topology.elf \
	-smp 5,sockets=24,cores=4,maxcpus=96 \
	-append "-s 24 -c 4 -m 96"

Of course the declaration of the number of socket and core must be
coherent.

Regards,
Pierre

Pierre Morel (4):
  s390x: lib: Add SCLP toplogy nested level
  s390x: stsi: Define vm_is_kvm to be used in different tests
  s390x: topology: Check the Perform Topology Function
  s390x: topology: Checking Configuration Topology Information

 lib/s390x/sclp.c    |   6 +
 lib/s390x/sclp.h    |   4 +-
 lib/s390x/stsi.h    |  76 ++++++++++
 lib/s390x/vm.c      |  56 ++++++-
 lib/s390x/vm.h      |   3 +
 s390x/Makefile      |   1 +
 s390x/stsi.c        |  23 +--
 s390x/topology.c    | 346 ++++++++++++++++++++++++++++++++++++++++++++
 s390x/unittests.cfg |   4 +
 9 files changed, 495 insertions(+), 24 deletions(-)
 create mode 100644 lib/s390x/stsi.h
 create mode 100644 s390x/topology.c

-- 
2.27.0

Changelog:

From V2:

- Copyrights modifications, assert for allocation failures
  (Claudio)

- adding a vm_is_lpar and modification of vm_is_kvm
  (Janosh)

- Check if the test in running in KVM
  (Janosch)

- patch on "Simplify stsi_get_fc and move it to library"
  pushed separatly

- replace named level with abstracted topology levels
  to get rid of a possible naming controversy
  (Pierre)

- Better checks and new checks for STSI(15,1,x)
  (Pierre)

From V1:

- Simplify the stsi_get_fc function when pushing it into lib
  (Janosch)

- Simplify PTF inline assembly as PTF instruction does not use RRE
  second argument
  (Claudio)

- Rename Test global name
  (Claudio, Janosch)

- readibility, naming for PTF_REQ_* and removed unused globals
  (Janosch)

- skipping tests which could fail when run on LPAR
  (Janosh)

- Missing prefix_pop
  (Janosch)


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [kvm-unit-tests PATCH v4 1/4] s390x: lib: Add SCLP toplogy nested level
  2022-02-08 13:27 [kvm-unit-tests PATCH v4 0/4] S390x: CPU Topology Information Pierre Morel
@ 2022-02-08 13:27 ` Pierre Morel
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests Pierre Morel
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-08 13:27 UTC (permalink / raw)
  To: linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david, nrb

The maximum CPU Topology nested level is available with the SCLP
READ_INFO command inside the byte at offset 15 of the ReadInfo
structure.

Let's return this information to check the number of topology nested
information available with the STSI 15.1.x instruction.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
---
 lib/s390x/sclp.c | 6 ++++++
 lib/s390x/sclp.h | 4 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/lib/s390x/sclp.c b/lib/s390x/sclp.c
index 33985eb4..e15b3b2c 100644
--- a/lib/s390x/sclp.c
+++ b/lib/s390x/sclp.c
@@ -128,6 +128,12 @@ int sclp_get_cpu_num(void)
 	return read_info->entries_cpu;
 }
 
+int sclp_get_stsi_parm(void)
+{
+	assert(read_info);
+	return read_info->stsi_parm;
+}
+
 CPUEntry *sclp_get_cpu_entries(void)
 {
 	assert(read_info);
diff --git a/lib/s390x/sclp.h b/lib/s390x/sclp.h
index fead007a..541eb441 100644
--- a/lib/s390x/sclp.h
+++ b/lib/s390x/sclp.h
@@ -146,7 +146,8 @@ typedef struct ReadInfo {
 	SCCBHeader h;
 	uint16_t rnmax;
 	uint8_t rnsize;
-	uint8_t  _reserved1[16 - 11];       /* 11-15 */
+	uint8_t  _reserved1[15 - 11];       /* 11-14 */
+	uint8_t stsi_parm;
 	uint16_t entries_cpu;               /* 16-17 */
 	uint16_t offset_cpu;                /* 18-19 */
 	uint8_t  _reserved2[24 - 20];       /* 20-23 */
@@ -323,6 +324,7 @@ void sclp_console_setup(void);
 void sclp_print(const char *str);
 void sclp_read_info(void);
 int sclp_get_cpu_num(void);
+int sclp_get_stsi_parm(void);
 CPUEntry *sclp_get_cpu_entries(void);
 void sclp_facilities_setup(void);
 int sclp_service_call(unsigned int command, void *sccb);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests
  2022-02-08 13:27 [kvm-unit-tests PATCH v4 0/4] S390x: CPU Topology Information Pierre Morel
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 1/4] s390x: lib: Add SCLP toplogy nested level Pierre Morel
@ 2022-02-08 13:27 ` Pierre Morel
  2022-02-08 15:31   ` Janosch Frank
                     ` (2 more replies)
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function Pierre Morel
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 4/4] s390x: topology: Checking Configuration Topology Information Pierre Morel
  3 siblings, 3 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-08 13:27 UTC (permalink / raw)
  To: linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david, nrb

We need in several tests to check if the VM we are running in
is KVM.
Let's add the test.

To check the VM type we use the STSI 3.2.2 instruction, let's
define it's response structure in a central header.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
---
 lib/s390x/stsi.h | 32 +++++++++++++++++++++++++++
 lib/s390x/vm.c   | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
 lib/s390x/vm.h   |  3 +++
 s390x/stsi.c     | 23 ++------------------
 4 files changed, 91 insertions(+), 23 deletions(-)
 create mode 100644 lib/s390x/stsi.h

diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
new file mode 100644
index 00000000..9b40664f
--- /dev/null
+++ b/lib/s390x/stsi.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Structures used to Store System Information
+ *
+ * Copyright IBM Corp. 2022
+ */
+
+#ifndef _S390X_STSI_H_
+#define _S390X_STSI_H_
+
+struct sysinfo_3_2_2 {
+	uint8_t reserved[31];
+	uint8_t count;
+	struct {
+		uint8_t reserved2[4];
+		uint16_t total_cpus;
+		uint16_t conf_cpus;
+		uint16_t standby_cpus;
+		uint16_t reserved_cpus;
+		uint8_t name[8];
+		uint32_t caf;
+		uint8_t cpi[16];
+		uint8_t reserved5[3];
+		uint8_t ext_name_encoding;
+		uint32_t reserved3;
+		uint8_t uuid[16];
+	} vm[8];
+	uint8_t reserved4[1504];
+	uint8_t ext_names[8][256];
+};
+
+#endif  /* _S390X_STSI_H_ */
diff --git a/lib/s390x/vm.c b/lib/s390x/vm.c
index a5b92863..38886b76 100644
--- a/lib/s390x/vm.c
+++ b/lib/s390x/vm.c
@@ -12,6 +12,7 @@
 #include <alloc_page.h>
 #include <asm/arch_def.h>
 #include "vm.h"
+#include "stsi.h"
 
 /**
  * Detect whether we are running with TCG (instead of KVM)
@@ -26,9 +27,13 @@ bool vm_is_tcg(void)
 	if (initialized)
 		return is_tcg;
 
-	buf = alloc_page();
-	if (!buf)
+	if (!vm_is_vm()) {
+		initialized = true;
 		return false;
+	}
+
+	buf = alloc_page();
+	assert(buf);
 
 	if (stsi(buf, 1, 1, 1))
 		goto out;
@@ -43,3 +48,50 @@ out:
 	free_page(buf);
 	return is_tcg;
 }
+
+/**
+ * Detect whether we are running with KVM
+ */
+
+bool vm_is_kvm(void)
+{
+	/* EBCDIC for "KVM/" */
+	const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
+	static bool initialized;
+	static bool is_kvm;
+	struct sysinfo_3_2_2 *stsi_322;
+
+	if (initialized)
+		return is_kvm;
+
+	if (!vm_is_vm() || vm_is_tcg()) {
+		initialized = true;
+		return is_kvm;
+	}
+
+	stsi_322 = alloc_page();
+	assert(stsi_322);
+
+	if (stsi(stsi_322, 3, 2, 2))
+		goto out;
+
+	/*
+	 * If the manufacturer string is "KVM/" in EBCDIC, then we
+	 * are on KVM.
+	 */
+	is_kvm = !memcmp(&stsi_322->vm[0].cpi, kvm_ebcdic, sizeof(kvm_ebcdic));
+	initialized = true;
+out:
+	free_page(stsi_322);
+	return is_kvm;
+}
+
+bool vm_is_lpar(void)
+{
+	return stsi_get_fc() == 2;
+}
+
+bool vm_is_vm(void)
+{
+	return stsi_get_fc() == 3;
+}
diff --git a/lib/s390x/vm.h b/lib/s390x/vm.h
index 7abba0cc..3aaf76af 100644
--- a/lib/s390x/vm.h
+++ b/lib/s390x/vm.h
@@ -9,5 +9,8 @@
 #define _S390X_VM_H_
 
 bool vm_is_tcg(void);
+bool vm_is_kvm(void);
+bool vm_is_vm(void);
+bool vm_is_lpar(void);
 
 #endif  /* _S390X_VM_H_ */
diff --git a/s390x/stsi.c b/s390x/stsi.c
index 391f8849..1ed045e2 100644
--- a/s390x/stsi.c
+++ b/s390x/stsi.c
@@ -13,27 +13,8 @@
 #include <asm/asm-offsets.h>
 #include <asm/interrupt.h>
 #include <smp.h>
+#include "stsi.h"
 
-struct stsi_322 {
-	uint8_t reserved[31];
-	uint8_t count;
-	struct {
-		uint8_t reserved2[4];
-		uint16_t total_cpus;
-		uint16_t conf_cpus;
-		uint16_t standby_cpus;
-		uint16_t reserved_cpus;
-		uint8_t name[8];
-		uint32_t caf;
-		uint8_t cpi[16];
-		uint8_t reserved5[3];
-		uint8_t ext_name_encoding;
-		uint32_t reserved3;
-		uint8_t uuid[16];
-	} vm[8];
-	uint8_t reserved4[1504];
-	uint8_t ext_names[8][256];
-};
 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
 
 static void test_specs(void)
@@ -91,7 +72,7 @@ static void test_3_2_2(void)
 	/* EBCDIC for "KVM/" */
 	const uint8_t cpi_kvm[] = { 0xd2, 0xe5, 0xd4, 0x61 };
 	const char vm_name_ext[] = "kvm-unit-test";
-	struct stsi_322 *data = (void *)pagebuf;
+	struct sysinfo_3_2_2 *data = (void *)pagebuf;
 
 	report_prefix_push("3.2.2");
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function
  2022-02-08 13:27 [kvm-unit-tests PATCH v4 0/4] S390x: CPU Topology Information Pierre Morel
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 1/4] s390x: lib: Add SCLP toplogy nested level Pierre Morel
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests Pierre Morel
@ 2022-02-08 13:27 ` Pierre Morel
  2022-02-09 11:37   ` Nico Boehr
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 4/4] s390x: topology: Checking Configuration Topology Information Pierre Morel
  3 siblings, 1 reply; 19+ messages in thread
From: Pierre Morel @ 2022-02-08 13:27 UTC (permalink / raw)
  To: linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david, nrb

We check the PTF instruction.

- We do not expect to support vertical polarization.

- We do not expect the Modified Topology Change Report to be
pending or not at the moment the first PTF instruction with
PTF_CHECK function code is done as some code already did run
a polarization change may have occur.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
---
 s390x/Makefile      |   1 +
 s390x/topology.c    | 115 ++++++++++++++++++++++++++++++++++++++++++++
 s390x/unittests.cfg |   3 ++
 3 files changed, 119 insertions(+)
 create mode 100644 s390x/topology.c

diff --git a/s390x/Makefile b/s390x/Makefile
index 53b0fe04..d833d6a3 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -26,6 +26,7 @@ tests += $(TEST_DIR)/edat.elf
 tests += $(TEST_DIR)/mvpg-sie.elf
 tests += $(TEST_DIR)/spec_ex-sie.elf
 tests += $(TEST_DIR)/firq.elf
+tests += $(TEST_DIR)/topology.elf
 
 pv-tests += $(TEST_DIR)/pv-diags.elf
 
diff --git a/s390x/topology.c b/s390x/topology.c
new file mode 100644
index 00000000..a1f9ce51
--- /dev/null
+++ b/s390x/topology.c
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * CPU Topology
+ *
+ * Copyright IBM Corp. 2022
+ *
+ * Authors:
+ *  Pierre Morel <pmorel@linux.ibm.com>
+ */
+
+#include <libcflat.h>
+#include <asm/page.h>
+#include <asm/asm-offsets.h>
+#include <asm/interrupt.h>
+#include <asm/facility.h>
+#include <smp.h>
+#include <sclp.h>
+#include <s390x/vm.h>
+
+#define PTF_REQ_HORIZONTAL	0
+#define PTF_REQ_VERTICAL	1
+#define PTF_REQ_CHECK		2
+
+#define PTF_ERR_NO_REASON	0
+#define PTF_ERR_ALRDY_POLARIZED	1
+#define PTF_ERR_IN_PROGRESS	2
+
+static int ptf(unsigned long fc, unsigned long *rc)
+{
+	int cc;
+
+	asm volatile(
+		"       .insn   rre,0xb9a20000,%1,0\n"
+		"       ipm     %0\n"
+		"       srl     %0,28\n"
+		: "=d" (cc), "+d" (fc)
+		: "d" (fc)
+		: "cc");
+
+	*rc = fc >> 8;
+	return cc;
+}
+
+static void test_ptf(void)
+{
+	unsigned long rc;
+	int cc;
+
+	report_prefix_push("Topology Report pending");
+	/*
+	 * At this moment the topology may already have changed
+	 * since the VM has been started.
+	 * However, we can test if a second PTF instruction
+	 * reports that the topology did not change since the
+	 * preceding PFT instruction.
+	 */
+	ptf(PTF_REQ_CHECK, &rc);
+	cc = ptf(PTF_REQ_CHECK, &rc);
+	report(cc == 0, "PTF check should clear topology report");
+
+	report_prefix_pop();
+
+	report_prefix_push("Topology polarisation check");
+	/*
+	 * We can not assume the state of the polarization for
+	 * any Virtual Machine but KVM.
+	 * Let's skip the polarisation tests for other VMs.
+	 */
+	if (!vm_is_kvm()) {
+		report_skip("Topology polarisation check is done for KVM only");
+		goto end;
+	}
+
+	cc = ptf(PTF_REQ_HORIZONTAL, &rc);
+	report(cc == 2 && rc == PTF_ERR_ALRDY_POLARIZED,
+	       "KVM always provides horizontal polarization");
+
+	cc = ptf(PTF_REQ_VERTICAL, &rc);
+	report(cc == 2 && rc == PTF_ERR_NO_REASON,
+	       "KVM doesn't support vertical polarization.");
+
+end:
+	report_prefix_pop();
+}
+
+static struct {
+	const char *name;
+	void (*func)(void);
+} tests[] = {
+	{ "PTF", test_ptf},
+	{ NULL, NULL }
+};
+
+int main(int argc, char *argv[])
+{
+	int i;
+
+	report_prefix_push("CPU Topology");
+
+	if (!test_facility(11)) {
+		report_skip("Topology facility not present");
+		goto end;
+	}
+
+	report_info("Machine level %ld", stsi_get_fc());
+
+	for (i = 0; tests[i].name; i++) {
+		report_prefix_push(tests[i].name);
+		tests[i].func();
+		report_prefix_pop();
+	}
+end:
+	report_prefix_pop();
+	return report_summary();
+}
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index 054560c2..e2d3e6a5 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -122,3 +122,6 @@ extra_params = -smp 1,maxcpus=3 -cpu qemu -device qemu-s390x-cpu,core-id=1 -devi
 file = firq.elf
 timeout = 20
 extra_params = -smp 1,maxcpus=3 -cpu qemu -device qemu-s390x-cpu,core-id=2 -device qemu-s390x-cpu,core-id=1
+
+[topology]
+file = topology.elf
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [kvm-unit-tests PATCH v4 4/4] s390x: topology: Checking Configuration Topology Information
  2022-02-08 13:27 [kvm-unit-tests PATCH v4 0/4] S390x: CPU Topology Information Pierre Morel
                   ` (2 preceding siblings ...)
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function Pierre Morel
@ 2022-02-08 13:27 ` Pierre Morel
  3 siblings, 0 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-08 13:27 UTC (permalink / raw)
  To: linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david, nrb

STSI with function code 15 is used to store the CPU configuration
topology.

We check :
- if the topology stored is coherent between the QEMU -smp
  parameters and kernel parameters.
- the number of CPUs
- the maximum number of CPUs
- the number of containers of each levels for every STSI(15.1.x)
  instruction allowed by the machine.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
---
 lib/s390x/stsi.h    |  44 +++++++++
 s390x/topology.c    | 231 ++++++++++++++++++++++++++++++++++++++++++++
 s390x/unittests.cfg |   1 +
 3 files changed, 276 insertions(+)

diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
index 9b40664f..cec487f7 100644
--- a/lib/s390x/stsi.h
+++ b/lib/s390x/stsi.h
@@ -29,4 +29,48 @@ struct sysinfo_3_2_2 {
 	uint8_t ext_names[8][256];
 };
 
+struct topology_core {
+	uint8_t nl;
+	uint8_t reserved1[3];
+	uint8_t reserved4:5;
+	uint8_t d:1;
+	uint8_t pp:2;
+	uint8_t type;
+	uint16_t origin;
+	uint64_t mask;
+};
+
+struct topology_container {
+	uint8_t nl;
+	uint8_t reserved[6];
+	uint8_t id;
+};
+
+union topology_entry {
+	uint8_t nl;
+	struct topology_core cpu;
+	struct topology_container container;
+};
+
+#define CPU_TOPOLOGY_MAX_LEVEL 6
+struct sysinfo_15_1_x {
+	uint8_t reserved0[2];
+	uint16_t length;
+	uint8_t mag[CPU_TOPOLOGY_MAX_LEVEL];
+	uint8_t reserved0a;
+	uint8_t mnest;
+	uint8_t reserved0c[4];
+	union topology_entry tle[0];
+};
+
+static inline int cpus_in_tle_mask(uint64_t val)
+{
+	int i, n;
+
+	for (i = 0, n = 0; i < 64; i++, val >>= 1)
+		if (val & 0x01)
+			n++;
+	return n;
+}
+
 #endif  /* _S390X_STSI_H_ */
diff --git a/s390x/topology.c b/s390x/topology.c
index a1f9ce51..5115eed7 100644
--- a/s390x/topology.c
+++ b/s390x/topology.c
@@ -16,6 +16,15 @@
 #include <smp.h>
 #include <sclp.h>
 #include <s390x/vm.h>
+#include <s390x/stsi.h>
+
+static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
+
+static int max_nested_lvl;
+static int number_of_cpus;
+static int max_cpus = 1;
+static int arch_topo_lvl[CPU_TOPOLOGY_MAX_LEVEL];	/* Topology level defined by architecture */
+static int stsi_nested_lvl[CPU_TOPOLOGY_MAX_LEVEL];	/* Topology nested level reported in STSI */
 
 #define PTF_REQ_HORIZONTAL	0
 #define PTF_REQ_VERTICAL	1
@@ -83,11 +92,230 @@ end:
 	report_prefix_pop();
 }
 
+/*
+ * stsi_check_maxcpus
+ * @info: Pointer to the stsi information
+ *
+ * The product of the numbers of containers per level
+ * is the maximum number of CPU allowed by the machine.
+ */
+static void stsi_check_maxcpus(struct sysinfo_15_1_x *info)
+{
+	int n, i;
+
+	report_prefix_push("maximum cpus");
+
+	for (i = 0, n = 1; i < CPU_TOPOLOGY_MAX_LEVEL; i++) {
+		report_info("Mag%d: %d", CPU_TOPOLOGY_MAX_LEVEL - i, info->mag[i]);
+		n *= info->mag[i] ? info->mag[i] : 1;
+	}
+	report(n == max_cpus, "Maximum CPUs %d expected %d", n, max_cpus);
+
+	report_prefix_pop();
+}
+
+/*
+ * stsi_check_tle_coherency
+ * @info: Pointer to the stsi information
+ * @sel2: Topology level to check.
+ *
+ * We verify that we get the expected number of Topology List Entry
+ * containers for a specific level.
+ */
+static void stsi_check_tle_coherency(struct sysinfo_15_1_x *info, int sel2)
+{
+	struct topology_container *tc, *end;
+	struct topology_core *cpus;
+	int n = 0;
+	int i;
+
+	report_prefix_push("TLE coherency");
+
+	tc = &info->tle[0].container;
+	end = (struct topology_container *)((unsigned long)info + info->length);
+
+	for (i = 0; i < CPU_TOPOLOGY_MAX_LEVEL; i++)
+		stsi_nested_lvl[i] = 0;
+
+	while (tc < end) {
+		if (tc->nl > 5) {
+			report_abort("Unexpected TL Entry: tle->nl: %d", tc->nl);
+			return;
+		}
+		if (tc->nl == 0) {
+			cpus = (struct topology_core *)tc;
+			n += cpus_in_tle_mask(cpus->mask);
+			report_info("cpu type %02x  d: %d pp: %d", cpus->type, cpus->d, cpus->pp);
+			report_info("origin : %04x mask %016lx", cpus->origin, cpus->mask);
+		}
+
+		stsi_nested_lvl[tc->nl]++;
+		report_info("level %d: lvl: %d id: %d cnt: %d",
+			    tc->nl, tc->nl, tc->id, stsi_nested_lvl[tc->nl]);
+
+		/* trick: CPU TLEs are twice the size of containers TLE */
+		if (tc->nl == 0)
+			tc++;
+		tc++;
+	}
+	report(n == number_of_cpus, "Number of CPUs  : %d expect %d", n, number_of_cpus);
+	/*
+	 * For KVM we accept
+	 * - only 1 type of CPU
+	 * - only horizontal topology
+	 * - only dedicated CPUs
+	 * This leads to expect the number of entries of level 0 CPU
+	 * Topology Level Entry (TLE) to be:
+	 * 1 + (number_of_cpus - 1)  / arch_topo_lvl[0]
+	 *
+	 * For z/VM or LPAR this number can only be greater if different
+	 * polarity, CPU types because there may be a nested level 0 CPU TLE
+	 * for each of the CPU/polarity/sharing types in a level 1 container TLE.
+	 */
+	n =  (number_of_cpus - 1)  / arch_topo_lvl[0];
+	report(stsi_nested_lvl[0] >=  n + 1,
+	       "CPU Type TLE    : %d expect %d", stsi_nested_lvl[0], n + 1);
+
+	/* For each level found in STSI */
+	for (i = 1; i < CPU_TOPOLOGY_MAX_LEVEL; i++) {
+		/*
+		 * For non QEMU/KVM hypervisor the concatenation of the levels
+		 * above level 1 are architecture dependent.
+		 * Skip these checks.
+		 */
+		if (!vm_is_kvm() && sel2 != 2)
+			continue;
+
+		/* For QEMU/KVM we expect a simple calculation */
+		if (sel2 > i) {
+			report(stsi_nested_lvl[i] ==  n + 1,
+			       "Container TLE  %d: %d expect %d", i, stsi_nested_lvl[i], n + 1);
+			n /= arch_topo_lvl[i];
+		}
+	}
+
+	report_prefix_pop();
+}
+
+/*
+ * check_sysinfo_15_1_x
+ * @info: pointer to the STSI info structure
+ * @sel2: the selector giving the topology level to check
+ *
+ * Check if the validity of the STSI instruction and then
+ * calls specific checks on the information buffer.
+ */
+static void check_sysinfo_15_1_x(struct sysinfo_15_1_x *info, int sel2)
+{
+	int ret;
+
+	report_prefix_pushf("15_1_%d", sel2);
+
+	ret = stsi(pagebuf, 15, 1, sel2);
+	if (max_nested_lvl >= sel2)
+		report(!ret, "Valid stsi instruction");
+	else
+		report(ret, "Invalid stsi instruction");
+	if (ret)
+		goto end;
+
+	stsi_check_maxcpus(info);
+	stsi_check_tle_coherency(info, sel2);
+
+end:
+	report_prefix_pop();
+}
+
+/*
+ * test_stsi
+ *
+ * Retrieves the maximum nested topology level supported by the architecture
+ * and the number of CPUs.
+ * Calls the checking for the STSI instruction in sel2 reverse level order
+ * from 6 (CPU_TOPOLOGY_MAX_LEVEL) to 2 to have the most interesting level,
+ * the one triggering a topology-change-report-pending condition, level 2,
+ * at the end of the report.
+ *
+ */
+static void test_stsi(void)
+{
+	int sel2;
+
+	max_nested_lvl = sclp_get_stsi_parm();
+	/* If the STSI parm is 0, the Maximum Nesting for STSI is 2 */
+	if (!max_nested_lvl)
+		max_nested_lvl = 2;
+	report_info("SCLP maximum nested level : %d", max_nested_lvl);
+
+	number_of_cpus = sclp_get_cpu_num();
+	report_info("SCLP number of CPU: %d", number_of_cpus);
+
+	/* STSI selector 2 can takes values between 2 and 6 */
+	for (sel2 = 6; sel2 >= 2; sel2--)
+		check_sysinfo_15_1_x((struct sysinfo_15_1_x *)pagebuf, sel2);
+}
+
+/*
+ * parse_topology_args
+ * @argc: number of arguments
+ * @argv: argument array
+ *
+ * This function initialize the architecture topology levels
+ * which should be the same as the one provided by the hypervisor.
+ *
+ * We use the current names found in IBM/Z literature, Linux and QEMU:
+ * cores, sockets/packages, books, drawers and nodes to facilitate the
+ * human machine interface but store the result in a machine abstract
+ * array of architecture topology levels.
+ * Note that when QEMU uses socket as a name for the topology level 1
+ * Linux uses package or physical_package.
+ */
+static void parse_topology_args(int argc, char **argv)
+{
+	int i;
+
+	for (i = 1; i < argc; i++) {
+		if (!strcmp("-c", argv[i])) {
+			i++;
+			if (i >= argc)
+				report_abort("-c (cores) needs a parameter");
+			arch_topo_lvl[0] = atol(argv[i]);
+		} else if (!strcmp("-s", argv[i])) {
+			i++;
+			if (i >= argc)
+				report_abort("-s (sockets) needs a parameter");
+			arch_topo_lvl[1] = atol(argv[i]);
+		} else if (!strcmp("-b", argv[i])) {
+			i++;
+			if (i >= argc)
+				report_abort("-b (books) needs a parameter");
+			arch_topo_lvl[2] = atol(argv[i]);
+		} else if (!strcmp("-d", argv[i])) {
+			i++;
+			if (i >= argc)
+				report_abort("-d (drawers) needs a parameter");
+			arch_topo_lvl[3] = atol(argv[i]);
+		} else if (!strcmp("-n", argv[i])) {
+			i++;
+			if (i >= argc)
+				report_abort("-n (nodes) needs a parameter");
+			arch_topo_lvl[4] = atol(argv[i]);
+		}
+	}
+
+	for (i = 0; i < CPU_TOPOLOGY_MAX_LEVEL; i++) {
+		if (!arch_topo_lvl[i])
+			arch_topo_lvl[i] = 1;
+		max_cpus *= arch_topo_lvl[i];
+	}
+}
+
 static struct {
 	const char *name;
 	void (*func)(void);
 } tests[] = {
 	{ "PTF", test_ptf},
+	{ "STSI", test_stsi},
 	{ NULL, NULL }
 };
 
@@ -97,6 +325,8 @@ int main(int argc, char *argv[])
 
 	report_prefix_push("CPU Topology");
 
+	parse_topology_args(argc, argv);
+
 	if (!test_facility(11)) {
 		report_skip("Topology facility not present");
 		goto end;
@@ -109,6 +339,7 @@ int main(int argc, char *argv[])
 		tests[i].func();
 		report_prefix_pop();
 	}
+
 end:
 	report_prefix_pop();
 	return report_summary();
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index e2d3e6a5..bc19b5b6 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -125,3 +125,4 @@ extra_params = -smp 1,maxcpus=3 -cpu qemu -device qemu-s390x-cpu,core-id=2 -devi
 
 [topology]
 file = topology.elf
+extra_params=-smp 5,drawers=2,books=3,sockets=4,cores=4,maxcpus=16 -append "-d 2 -b 3 -s 4 -c 4"
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests Pierre Morel
@ 2022-02-08 15:31   ` Janosch Frank
  2022-02-08 15:43     ` Nico Boehr
  2022-02-14  9:18     ` Pierre Morel
  2022-02-08 15:35   ` Nico Boehr
  2022-02-15 11:18   ` Claudio Imbrenda
  2 siblings, 2 replies; 19+ messages in thread
From: Janosch Frank @ 2022-02-08 15:31 UTC (permalink / raw)
  To: Pierre Morel, linux-s390; +Cc: thuth, kvm, cohuck, imbrenda, david, nrb

On 2/8/22 14:27, Pierre Morel wrote:
> We need in several tests to check if the VM we are running in
> is KVM.
> Let's add the test.

Several tests are in need of a way to check on which hypervisor and 
virtualization level they are running on to be able to fence certain 
tests. This patch adds functions that return true if a vm is running 
under KVM, LPAR or generally as a level 2 guest.

> 
> To check the VM type we use the STSI 3.2.2 instruction, let's

To check if we're running under KVM we...

> define it's response structure in a central header.

Since we already have a stsi test that defines the 3.2.2 structure let's 
move the struct from the test into a new library header.

> 
> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
> ---
>   lib/s390x/stsi.h | 32 +++++++++++++++++++++++++++
>   lib/s390x/vm.c   | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
>   lib/s390x/vm.h   |  3 +++
>   s390x/stsi.c     | 23 ++------------------
>   4 files changed, 91 insertions(+), 23 deletions(-)
>   create mode 100644 lib/s390x/stsi.h
> 
> diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
> new file mode 100644
> index 00000000..9b40664f
> --- /dev/null
> +++ b/lib/s390x/stsi.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Structures used to Store System Information
> + *
> + * Copyright IBM Corp. 2022
> + */
> +
> +#ifndef _S390X_STSI_H_
> +#define _S390X_STSI_H_
> +
> +struct sysinfo_3_2_2 {

Any particular reason why you renamed this?

> +	uint8_t reserved[31];
> +	uint8_t count;
> +	struct {
> +		uint8_t reserved2[4];
> +		uint16_t total_cpus;
> +		uint16_t conf_cpus;
> +		uint16_t standby_cpus;
> +		uint16_t reserved_cpus;
> +		uint8_t name[8];
> +		uint32_t caf;
> +		uint8_t cpi[16];
> +		uint8_t reserved5[3];
> +		uint8_t ext_name_encoding;
> +		uint32_t reserved3;
> +		uint8_t uuid[16];
> +	} vm[8];
> +	uint8_t reserved4[1504];
> +	uint8_t ext_names[8][256];
> +};
> +
> +#endif  /* _S390X_STSI_H_ */
> diff --git a/lib/s390x/vm.c b/lib/s390x/vm.c
> index a5b92863..38886b76 100644
> --- a/lib/s390x/vm.c
> +++ b/lib/s390x/vm.c
> @@ -12,6 +12,7 @@
>   #include <alloc_page.h>
>   #include <asm/arch_def.h>
>   #include "vm.h"
> +#include "stsi.h"
>   
>   /**
>    * Detect whether we are running with TCG (instead of KVM)
> @@ -26,9 +27,13 @@ bool vm_is_tcg(void)
>   	if (initialized)
>   		return is_tcg;
>   
> -	buf = alloc_page();
> -	if (!buf)
> +	if (!vm_is_vm()) {
> +		initialized = true;
>   		return false;
> +	}
> +
> +	buf = alloc_page();
> +	assert(buf);
>   
>   	if (stsi(buf, 1, 1, 1))
>   		goto out;
> @@ -43,3 +48,50 @@ out:
>   	free_page(buf);
>   	return is_tcg;
>   }
> +
> +/**
> + * Detect whether we are running with KVM
> + */
> +
> +bool vm_is_kvm(void)
> +{
> +	/* EBCDIC for "KVM/" */
> +	const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
> +	static bool initialized;
> +	static bool is_kvm;
> +	struct sysinfo_3_2_2 *stsi_322;
> +
> +	if (initialized)
> +		return is_kvm;
> +
> +	if (!vm_is_vm() || vm_is_tcg()) {
> +		initialized = true;
> +		return is_kvm;
> +	}
> +
> +	stsi_322 = alloc_page();
> +	assert(stsi_322);
> +
> +	if (stsi(stsi_322, 3, 2, 2))
> +		goto out;
> +
> +	/*
> +	 * If the manufacturer string is "KVM/" in EBCDIC, then we
> +	 * are on KVM.
> +	 */
> +	is_kvm = !memcmp(&stsi_322->vm[0].cpi, kvm_ebcdic, sizeof(kvm_ebcdic));
> +	initialized = true;
> +out:
> +	free_page(stsi_322);
> +	return is_kvm;
> +}
> +
> +bool vm_is_lpar(void)
> +{
> +	return stsi_get_fc() == 2;
> +}
> +
> +bool vm_is_vm(void)
> +{
> +	return stsi_get_fc() == 3;

This would be true when running under z/VM, no?

I.e. what you're testing here is that we're a level 2 guest and hence 
the naming could be improved.

Also: what if we're under VSIE where we would be > 3?

> +}
> diff --git a/lib/s390x/vm.h b/lib/s390x/vm.h
> index 7abba0cc..3aaf76af 100644
> --- a/lib/s390x/vm.h
> +++ b/lib/s390x/vm.h
> @@ -9,5 +9,8 @@
>   #define _S390X_VM_H_
>   
>   bool vm_is_tcg(void);
> +bool vm_is_kvm(void);
> +bool vm_is_vm(void);
> +bool vm_is_lpar(void);
>   
>   #endif  /* _S390X_VM_H_ */
> diff --git a/s390x/stsi.c b/s390x/stsi.c
> index 391f8849..1ed045e2 100644
> --- a/s390x/stsi.c
> +++ b/s390x/stsi.c
> @@ -13,27 +13,8 @@
>   #include <asm/asm-offsets.h>
>   #include <asm/interrupt.h>
>   #include <smp.h>
> +#include "stsi.h"

#include <stsi.h>

We're not in the lib.

>   
> -struct stsi_322 {
> -	uint8_t reserved[31];
> -	uint8_t count;
> -	struct {
> -		uint8_t reserved2[4];
> -		uint16_t total_cpus;
> -		uint16_t conf_cpus;
> -		uint16_t standby_cpus;
> -		uint16_t reserved_cpus;
> -		uint8_t name[8];
> -		uint32_t caf;
> -		uint8_t cpi[16];
> -		uint8_t reserved5[3];
> -		uint8_t ext_name_encoding;
> -		uint32_t reserved3;
> -		uint8_t uuid[16];
> -	} vm[8];
> -	uint8_t reserved4[1504];
> -	uint8_t ext_names[8][256];
> -};
>   static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
>   
>   static void test_specs(void)
> @@ -91,7 +72,7 @@ static void test_3_2_2(void)
>   	/* EBCDIC for "KVM/" */
>   	const uint8_t cpi_kvm[] = { 0xd2, 0xe5, 0xd4, 0x61 };
>   	const char vm_name_ext[] = "kvm-unit-test";
> -	struct stsi_322 *data = (void *)pagebuf;
> +	struct sysinfo_3_2_2 *data = (void *)pagebuf;
>   
>   	report_prefix_push("3.2.2");
>   


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests Pierre Morel
  2022-02-08 15:31   ` Janosch Frank
@ 2022-02-08 15:35   ` Nico Boehr
  2022-02-14  7:55     ` Pierre Morel
  2022-02-15 11:18   ` Claudio Imbrenda
  2 siblings, 1 reply; 19+ messages in thread
From: Nico Boehr @ 2022-02-08 15:35 UTC (permalink / raw)
  To: Pierre Morel, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david

On Tue, 2022-02-08 at 14:27 +0100, Pierre Morel wrote:
> We need in several tests to check if the VM we are running in
> is KVM.
> Let's add the test.
> 
> To check the VM type we use the STSI 3.2.2 instruction, let's
> define it's response structure in a central header.
> 
> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>

> ---
>  lib/s390x/stsi.h | 32 +++++++++++++++++++++++++++
>  lib/s390x/vm.c   | 56
> ++++++++++++++++++++++++++++++++++++++++++++++--
>  lib/s390x/vm.h   |  3 +++
>  s390x/stsi.c     | 23 ++------------------
>  4 files changed, 91 insertions(+), 23 deletions(-)
>  create mode 100644 lib/s390x/stsi.h
> 
> diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
> new file mode 100644
> index 00000000..9b40664f
> --- /dev/null
> +++ b/lib/s390x/stsi.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */

This was taken from stsi.c which is GPL 2 only, so this probably should
be as well.

> diff --git a/lib/s390x/vm.c b/lib/s390x/vm.c
> index a5b92863..38886b76 100644
> --- a/lib/s390x/vm.c
> +++ b/lib/s390x/vm.c
> @@ -12,6 +12,7 @@
>  #include <alloc_page.h>
>  #include <asm/arch_def.h>
>  #include "vm.h"
> +#include "stsi.h"
>  
>  /**
>   * Detect whether we are running with TCG (instead of KVM)
> @@ -26,9 +27,13 @@ bool vm_is_tcg(void)
>         if (initialized)
>                 return is_tcg;
>  
> -       buf = alloc_page();
> -       if (!buf)
> +       if (!vm_is_vm()) {
> +               initialized = true;
>                 return false;
> diff --git a/lib/s390x/vm.c b/lib/s390x/vm.c
> index a5b92863..38886b76 100644
> --- a/lib/s390x/vm.c
> +++ b/lib/s390x/vm.c
> @@ -12,6 +12,7 @@
>  #include <alloc_page.h>
>  #include <asm/arch_def.h>
>  #include "vm.h"
> +#include "stsi.h"
>  
>  /**
>   * Detect whether we are running with TCG (instead of KVM)
> @@ -26,9 +27,13 @@ bool vm_is_tcg(void)
>         if (initialized)
>                 return is_tcg;
>  
> -       buf = alloc_page();
> -       if (!buf)
> +       if (!vm_is_vm()) {
> +               initialized = true;
>                 return false;

I would personally prefer return is_tcg here to make it obvious we're
relying on the previous initalization to false for subsequent calls.

> +       }
> +
> +       buf = alloc_page();
> +       assert(buf);
>  
>         if (stsi(buf, 1, 1, 1))
>                 goto out;
> @@ -43,3 +48,50 @@ out:
>         free_page(buf);
>         return is_tcg;
>  }
> +
> +/**
> + * Detect whether we are running with KVM
> + */
> +

No newline here.

> +bool vm_is_kvm(void)
> +{
> +       /* EBCDIC for "KVM/" */
> +       const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
> +       static bool initialized;
> +       static bool is_kvm;

Might make sense to initizalize these to false to make it consistent
with vm_is_tcg().

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests
  2022-02-08 15:31   ` Janosch Frank
@ 2022-02-08 15:43     ` Nico Boehr
  2022-02-14  8:01       ` Pierre Morel
  2022-02-14  9:18     ` Pierre Morel
  1 sibling, 1 reply; 19+ messages in thread
From: Nico Boehr @ 2022-02-08 15:43 UTC (permalink / raw)
  To: Janosch Frank, Pierre Morel, linux-s390
  Cc: thuth, kvm, cohuck, imbrenda, david

On Tue, 2022-02-08 at 16:31 +0100, Janosch Frank wrote:
> > diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
> > new file mode 100644
> > index 00000000..9b40664f
> > --- /dev/null
> > +++ b/lib/s390x/stsi.h
> > @@ -0,0 +1,32 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Structures used to Store System Information
> > + *
> > + * Copyright IBM Corp. 2022
> > + */
> > +
> > +#ifndef _S390X_STSI_H_
> > +#define _S390X_STSI_H_
> > +
> > +struct sysinfo_3_2_2 {
> 
> Any particular reason why you renamed this?

Stumbled across this as well. I think this makes it consistent with
Linux' arch/s390/include/asm/sysinfo.h.

The PoP, on the other hand, calls it SYSIB, so this at least resolves
the inconsistency between kvm-unit-tests and Linux.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function Pierre Morel
@ 2022-02-09 11:37   ` Nico Boehr
  2022-02-14  9:21     ` Pierre Morel
                       ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Nico Boehr @ 2022-02-09 11:37 UTC (permalink / raw)
  To: Pierre Morel, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david

On Tue, 2022-02-08 at 14:27 +0100, Pierre Morel wrote:
> We check the PTF instruction.

You could test some very basic things as well:

- you get a privileged pgm int in problem state,
- reserved bits in first operand cause specification pgm int,
- reserved FC values result in a specification pgm int,
- second operand is ignored.

> 
> - We do not expect to support vertical polarization.
> 
> - We do not expect the Modified Topology Change Report to be
[...]

Forgive me if I'm missing something, but why _Modified_ Topology Change
Report?

> diff --git a/s390x/topology.c b/s390x/topology.c
> new file mode 100644
> index 00000000..a1f9ce51
> --- /dev/null
> +++ b/s390x/topology.c

[...]

> +static int ptf(unsigned long fc, unsigned long *rc)
> +{
> +       int cc;
> +
> +       asm volatile(
> +               "       .insn   rre,0xb9a20000,%1,0\n"
> +               "       ipm     %0\n"
> +               "       srl     %0,28\n"
> +               : "=d" (cc), "+d" (fc)
> +               : "d" (fc)

Why list fc here again?



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests
  2022-02-08 15:35   ` Nico Boehr
@ 2022-02-14  7:55     ` Pierre Morel
  0 siblings, 0 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-14  7:55 UTC (permalink / raw)
  To: Nico Boehr, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david



On 2/8/22 16:35, Nico Boehr wrote:
> On Tue, 2022-02-08 at 14:27 +0100, Pierre Morel wrote:
>> We need in several tests to check if the VM we are running in
>> is KVM.
>> Let's add the test.
>>
>> To check the VM type we use the STSI 3.2.2 instruction, let's
>> define it's response structure in a central header.
>>
>> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
> 
>> ---
>>   lib/s390x/stsi.h | 32 +++++++++++++++++++++++++++
>>   lib/s390x/vm.c   | 56
>> ++++++++++++++++++++++++++++++++++++++++++++++--
>>   lib/s390x/vm.h   |  3 +++
>>   s390x/stsi.c     | 23 ++------------------
>>   4 files changed, 91 insertions(+), 23 deletions(-)
>>   create mode 100644 lib/s390x/stsi.h
>>
>> diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
>> new file mode 100644
>> index 00000000..9b40664f
>> --- /dev/null
>> +++ b/lib/s390x/stsi.h
>> @@ -0,0 +1,32 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> 
> This was taken from stsi.c which is GPL 2 only, so this probably should
> be as well.
> 
>> diff --git a/lib/s390x/vm.c b/lib/s390x/vm.c
>> index a5b92863..38886b76 100644
>> --- a/lib/s390x/vm.c
>> +++ b/lib/s390x/vm.c
>> @@ -12,6 +12,7 @@
>>   #include <alloc_page.h>
>>   #include <asm/arch_def.h>
>>   #include "vm.h"
>> +#include "stsi.h"
>>   
>>   /**
>>    * Detect whether we are running with TCG (instead of KVM)
>> @@ -26,9 +27,13 @@ bool vm_is_tcg(void)
>>          if (initialized)
>>                  return is_tcg;
>>   
>> -       buf = alloc_page();
>> -       if (!buf)
>> +       if (!vm_is_vm()) {
>> +               initialized = true;
>>                  return false;
>> diff --git a/lib/s390x/vm.c b/lib/s390x/vm.c
>> index a5b92863..38886b76 100644
>> --- a/lib/s390x/vm.c
>> +++ b/lib/s390x/vm.c
>> @@ -12,6 +12,7 @@
>>   #include <alloc_page.h>
>>   #include <asm/arch_def.h>
>>   #include "vm.h"
>> +#include "stsi.h"
>>   
>>   /**
>>    * Detect whether we are running with TCG (instead of KVM)
>> @@ -26,9 +27,13 @@ bool vm_is_tcg(void)
>>          if (initialized)
>>                  return is_tcg;
>>   
>> -       buf = alloc_page();
>> -       if (!buf)
>> +       if (!vm_is_vm()) {
>> +               initialized = true;
>>                  return false;
> 
> I would personally prefer return is_tcg here to make it obvious we're
> relying on the previous initalization to false for subsequent calls.

OK

> 
>> +       }
>> +
>> +       buf = alloc_page();
>> +       assert(buf);
>>   
>>          if (stsi(buf, 1, 1, 1))
>>                  goto out;
>> @@ -43,3 +48,50 @@ out:
>>          free_page(buf);
>>          return is_tcg;
>>   }
>> +
>> +/**
>> + * Detect whether we are running with KVM
>> + */
>> +
> 
> No newline here.

ok

> 
>> +bool vm_is_kvm(void)
>> +{
>> +       /* EBCDIC for "KVM/" */
>> +       const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
>> +       static bool initialized;
>> +       static bool is_kvm;
> 
> Might make sense to initizalize these to false to make it consistent
> with vm_is_tcg().
> 

OK

-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests
  2022-02-08 15:43     ` Nico Boehr
@ 2022-02-14  8:01       ` Pierre Morel
  0 siblings, 0 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-14  8:01 UTC (permalink / raw)
  To: Nico Boehr, Janosch Frank, linux-s390; +Cc: thuth, kvm, cohuck, imbrenda, david



On 2/8/22 16:43, Nico Boehr wrote:
> On Tue, 2022-02-08 at 16:31 +0100, Janosch Frank wrote:
>>> diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
>>> new file mode 100644
>>> index 00000000..9b40664f
>>> --- /dev/null
>>> +++ b/lib/s390x/stsi.h
>>> @@ -0,0 +1,32 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>> +/*
>>> + * Structures used to Store System Information
>>> + *
>>> + * Copyright IBM Corp. 2022
>>> + */
>>> +
>>> +#ifndef _S390X_STSI_H_
>>> +#define _S390X_STSI_H_
>>> +
>>> +struct sysinfo_3_2_2 {
>>
>> Any particular reason why you renamed this?
> 
> Stumbled across this as well. I think this makes it consistent with
> Linux' arch/s390/include/asm/sysinfo.h.
> 
> The PoP, on the other hand, calls it SYSIB, so this at least resolves
> the inconsistency between kvm-unit-tests and Linux.
> 

In fact I do not know why I renamed it probably because I coded the next 
patches first and used sysinfo in it.
QEMU calls these structures SysIB so for me we do as you want.

-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests
  2022-02-08 15:31   ` Janosch Frank
  2022-02-08 15:43     ` Nico Boehr
@ 2022-02-14  9:18     ` Pierre Morel
  1 sibling, 0 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-14  9:18 UTC (permalink / raw)
  To: Janosch Frank, linux-s390; +Cc: thuth, kvm, cohuck, imbrenda, david, nrb



On 2/8/22 16:31, Janosch Frank wrote:
> On 2/8/22 14:27, Pierre Morel wrote:
>> We need in several tests to check if the VM we are running in
>> is KVM.
>> Let's add the test.
> 
> Several tests are in need of a way to check on which hypervisor and 
> virtualization level they are running on to be able to fence certain 
> tests. This patch adds functions that return true if a vm is running 
> under KVM, LPAR or generally as a level 2 guest.
> 
>>
>> To check the VM type we use the STSI 3.2.2 instruction, let's
> 
> To check if we're running under KVM we...

OK

> 
>> define it's response structure in a central header.
> 
> Since we already have a stsi test that defines the 3.2.2 structure let's 
> move the struct from the test into a new library header.

OK

> 
>>
>> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
>> ---
>>   lib/s390x/stsi.h | 32 +++++++++++++++++++++++++++
>>   lib/s390x/vm.c   | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
>>   lib/s390x/vm.h   |  3 +++
>>   s390x/stsi.c     | 23 ++------------------
>>   4 files changed, 91 insertions(+), 23 deletions(-)
>>   create mode 100644 lib/s390x/stsi.h
>>
>> diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
>> new file mode 100644
>> index 00000000..9b40664f
>> --- /dev/null
>> +++ b/lib/s390x/stsi.h
>> @@ -0,0 +1,32 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * Structures used to Store System Information
>> + *
>> + * Copyright IBM Corp. 2022
>> + */
>> +
>> +#ifndef _S390X_STSI_H_
>> +#define _S390X_STSI_H_
>> +
>> +struct sysinfo_3_2_2 {
> 
> Any particular reason why you renamed this?

In addition to what I answered to Nico:
I found stsi_3_2_2 better to describe a function calling STSI(3,2,2) 
than the result of the STSI(3,2,2) instruction, the SYStem Information 
Block.


> 
>> +    uint8_t reserved[31];
>> +    uint8_t count;
>> +    struct {
>> +        uint8_t reserved2[4];
>> +        uint16_t total_cpus;
>> +        uint16_t conf_cpus;
>> +        uint16_t standby_cpus;
>> +        uint16_t reserved_cpus;
>> +        uint8_t name[8];
>> +        uint32_t caf;
>> +        uint8_t cpi[16];
>> +        uint8_t reserved5[3];
>> +        uint8_t ext_name_encoding;
>> +        uint32_t reserved3;
>> +        uint8_t uuid[16];
>> +    } vm[8];
>> +    uint8_t reserved4[1504];
>> +    uint8_t ext_names[8][256];
>> +};
>> +
>> +#endif  /* _S390X_STSI_H_ */
>> diff --git a/lib/s390x/vm.c b/lib/s390x/vm.c
>> index a5b92863..38886b76 100644
>> --- a/lib/s390x/vm.c
>> +++ b/lib/s390x/vm.c
>> @@ -12,6 +12,7 @@
>>   #include <alloc_page.h>
>>   #include <asm/arch_def.h>
>>   #include "vm.h"
>> +#include "stsi.h"
>>   /**
>>    * Detect whether we are running with TCG (instead of KVM)
>> @@ -26,9 +27,13 @@ bool vm_is_tcg(void)
>>       if (initialized)
>>           return is_tcg;
>> -    buf = alloc_page();
>> -    if (!buf)
>> +    if (!vm_is_vm()) {
>> +        initialized = true;
>>           return false;
>> +    }
>> +
>> +    buf = alloc_page();
>> +    assert(buf);
>>       if (stsi(buf, 1, 1, 1))
>>           goto out;
>> @@ -43,3 +48,50 @@ out:
>>       free_page(buf);
>>       return is_tcg;
>>   }
>> +
>> +/**
>> + * Detect whether we are running with KVM
>> + */
>> +
>> +bool vm_is_kvm(void)
>> +{
>> +    /* EBCDIC for "KVM/" */
>> +    const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
>> +    static bool initialized;
>> +    static bool is_kvm;
>> +    struct sysinfo_3_2_2 *stsi_322;
>> +
>> +    if (initialized)
>> +        return is_kvm;
>> +
>> +    if (!vm_is_vm() || vm_is_tcg()) {
>> +        initialized = true;
>> +        return is_kvm;
>> +    }
>> +
>> +    stsi_322 = alloc_page();
>> +    assert(stsi_322);
>> +
>> +    if (stsi(stsi_322, 3, 2, 2))
>> +        goto out;
>> +
>> +    /*
>> +     * If the manufacturer string is "KVM/" in EBCDIC, then we
>> +     * are on KVM.
>> +     */
>> +    is_kvm = !memcmp(&stsi_322->vm[0].cpi, kvm_ebcdic, 
>> sizeof(kvm_ebcdic));
>> +    initialized = true;
>> +out:
>> +    free_page(stsi_322);
>> +    return is_kvm;
>> +}
>> +
>> +bool vm_is_lpar(void)
>> +{
>> +    return stsi_get_fc() == 2;
>> +}
>> +
>> +bool vm_is_vm(void)
>> +{
>> +    return stsi_get_fc() == 3;
> 
> This would be true when running under z/VM, no?

yes

> 
> I.e. what you're testing here is that we're a level 2 guest and hence 
> the naming could be improved.

STSI(0,x,x) used by stsi_get_fc() returns the current configuration 
level number which can be one of: basic machine (1), LPAR(2) or VM(3)

by the way stsi_get_fc() should probably better be named 
stsi_get_cfglevel() or something like that.

> 
> Also: what if we're under VSIE where we would be > 3?

No other configuration level is defined in the architecture than (1,2,3)

> 
>> +}
>> diff --git a/lib/s390x/vm.h b/lib/s390x/vm.h
>> index 7abba0cc..3aaf76af 100644
>> --- a/lib/s390x/vm.h
>> +++ b/lib/s390x/vm.h
>> @@ -9,5 +9,8 @@
>>   #define _S390X_VM_H_
>>   bool vm_is_tcg(void);
>> +bool vm_is_kvm(void);
>> +bool vm_is_vm(void);
>> +bool vm_is_lpar(void);
>>   #endif  /* _S390X_VM_H_ */
>> diff --git a/s390x/stsi.c b/s390x/stsi.c
>> index 391f8849..1ed045e2 100644
>> --- a/s390x/stsi.c
>> +++ b/s390x/stsi.c
>> @@ -13,27 +13,8 @@
>>   #include <asm/asm-offsets.h>
>>   #include <asm/interrupt.h>
>>   #include <smp.h>
>> +#include "stsi.h"
> 
> #include <stsi.h>
> 
> We're not in the lib.

OK

> 
>> -struct stsi_322 {
>> -    uint8_t reserved[31];
>> -    uint8_t count;
>> -    struct {
>> -        uint8_t reserved2[4];
>> -        uint16_t total_cpus;
>> -        uint16_t conf_cpus;
>> -        uint16_t standby_cpus;
>> -        uint16_t reserved_cpus;
>> -        uint8_t name[8];
>> -        uint32_t caf;
>> -        uint8_t cpi[16];
>> -        uint8_t reserved5[3];
>> -        uint8_t ext_name_encoding;
>> -        uint32_t reserved3;
>> -        uint8_t uuid[16];
>> -    } vm[8];
>> -    uint8_t reserved4[1504];
>> -    uint8_t ext_names[8][256];
>> -};
>>   static uint8_t pagebuf[PAGE_SIZE * 2] 
>> __attribute__((aligned(PAGE_SIZE * 2)));
>>   static void test_specs(void)
>> @@ -91,7 +72,7 @@ static void test_3_2_2(void)
>>       /* EBCDIC for "KVM/" */
>>       const uint8_t cpi_kvm[] = { 0xd2, 0xe5, 0xd4, 0x61 };
>>       const char vm_name_ext[] = "kvm-unit-test";
>> -    struct stsi_322 *data = (void *)pagebuf;
>> +    struct sysinfo_3_2_2 *data = (void *)pagebuf;
>>       report_prefix_push("3.2.2");
> 

Thanks for the review,
Pierre

-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function
  2022-02-09 11:37   ` Nico Boehr
@ 2022-02-14  9:21     ` Pierre Morel
  2022-02-15  8:29     ` Pierre Morel
  2022-02-15  8:50     ` Pierre Morel
  2 siblings, 0 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-14  9:21 UTC (permalink / raw)
  To: Nico Boehr, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david



On 2/9/22 12:37, Nico Boehr wrote:
> On Tue, 2022-02-08 at 14:27 +0100, Pierre Morel wrote:
>> We check the PTF instruction.
> 
> You could test some very basic things as well:
> 
> - you get a privileged pgm int in problem state,
> - reserved bits in first operand cause specification pgm int,
> - reserved FC values result in a specification pgm int,
> - second operand is ignored.

right, I will add these, I was more focused on the functionalities

> 
>>
>> - We do not expect to support vertical polarization.
>>
>> - We do not expect the Modified Topology Change Report to be
> [...]
> 
> Forgive me if I'm missing something, but why _Modified_ Topology Change
> Report?
> 
>> diff --git a/s390x/topology.c b/s390x/topology.c
>> new file mode 100644
>> index 00000000..a1f9ce51
>> --- /dev/null
>> +++ b/s390x/topology.c
> 
> [...]
> 
>> +static int ptf(unsigned long fc, unsigned long *rc)
>> +{
>> +       int cc;
>> +
>> +       asm volatile(
>> +               "       .insn   rre,0xb9a20000,%1,0\n"
>> +               "       ipm     %0\n"
>> +               "       srl     %0,28\n"
>> +               : "=d" (cc), "+d" (fc)
>> +               : "d" (fc)
> 
> Why list fc here again?
> 
> 

No reason, I suppress it.

Thanks for the review
pierre


-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function
  2022-02-09 11:37   ` Nico Boehr
  2022-02-14  9:21     ` Pierre Morel
@ 2022-02-15  8:29     ` Pierre Morel
  2022-02-15  8:50     ` Pierre Morel
  2 siblings, 0 replies; 19+ messages in thread
From: Pierre Morel @ 2022-02-15  8:29 UTC (permalink / raw)
  To: Nico Boehr, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david



On 2/9/22 12:37, Nico Boehr wrote:
> On Tue, 2022-02-08 at 14:27 +0100, Pierre Morel wrote:
>> We check the PTF instruction.
> 
> You could test some very basic things as well:
> 
> - you get a privileged pgm int in problem state,
> - reserved bits in first operand cause specification pgm int,
> - reserved FC values result in a specification pgm int,
> - second operand is ignored.
> 
>>
>> - We do not expect to support vertical polarization.
>>
>> - We do not expect the Modified Topology Change Report to be
> [...]
> 
> Forgive me if I'm missing something, but why _Modified_ Topology Change
> Report?

This does only exist in my mind the real name is indeed only Topology 
change report.

> 
>> diff --git a/s390x/topology.c b/s390x/topology.c
>> new file mode 100644
>> index 00000000..a1f9ce51
>> --- /dev/null
>> +++ b/s390x/topology.c
> 
> [...]
> 
>> +static int ptf(unsigned long fc, unsigned long *rc)
>> +{
>> +       int cc;
>> +
>> +       asm volatile(
>> +               "       .insn   rre,0xb9a20000,%1,0\n"
>> +               "       ipm     %0\n"
>> +               "       srl     %0,28\n"
>> +               : "=d" (cc), "+d" (fc)
>> +               : "d" (fc)
> 
> Why list fc here again?
> 
> 

-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function
  2022-02-09 11:37   ` Nico Boehr
  2022-02-14  9:21     ` Pierre Morel
  2022-02-15  8:29     ` Pierre Morel
@ 2022-02-15  8:50     ` Pierre Morel
  2022-02-15  9:21       ` Pierre Morel
  2 siblings, 1 reply; 19+ messages in thread
From: Pierre Morel @ 2022-02-15  8:50 UTC (permalink / raw)
  To: Nico Boehr, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david



On 2/9/22 12:37, Nico Boehr wrote:
> On Tue, 2022-02-08 at 14:27 +0100, Pierre Morel wrote:
>> We check the PTF instruction.
> 
> You could test some very basic things as well:
> 
> - you get a privileged pgm int in problem state,
> - reserved bits in first operand cause specification pgm int,
> - reserved FC values result in a specification pgm int,
> - second operand is ignored.

Which second operand?

> 
>>
>> - We do not expect to support vertical polarization.
>>
>> - We do not expect the Modified Topology Change Report to be
> [...]
> 
> Forgive me if I'm missing something, but why _Modified_ Topology Change
> Report?
> 
>> diff --git a/s390x/topology.c b/s390x/topology.c
>> new file mode 100644
>> index 00000000..a1f9ce51
>> --- /dev/null
>> +++ b/s390x/topology.c
> 
> [...]
> 
>> +static int ptf(unsigned long fc, unsigned long *rc)
>> +{
>> +       int cc;
>> +
>> +       asm volatile(
>> +               "       .insn   rre,0xb9a20000,%1,0\n"
>> +               "       ipm     %0\n"
>> +               "       srl     %0,28\n"
>> +               : "=d" (cc), "+d" (fc)
>> +               : "d" (fc)
> 
> Why list fc here again?
> 
> 

-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function
  2022-02-15  8:50     ` Pierre Morel
@ 2022-02-15  9:21       ` Pierre Morel
  2022-02-15  9:44         ` Pierre Morel
  0 siblings, 1 reply; 19+ messages in thread
From: Pierre Morel @ 2022-02-15  9:21 UTC (permalink / raw)
  To: Nico Boehr, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david



On 2/15/22 09:50, Pierre Morel wrote:
> 
> 
> On 2/9/22 12:37, Nico Boehr wrote:
>> On Tue, 2022-02-08 at 14:27 +0100, Pierre Morel wrote:
>>> We check the PTF instruction.
>>
>> You could test some very basic things as well:
>>
>> - you get a privileged pgm int in problem state,
>> - reserved bits in first operand cause specification pgm int,
>> - reserved FC values result in a specification pgm int,
>> - second operand is ignored.
> 
> Which second operand?

Sorry got it
> 
>>
>>>
>>> - We do not expect to support vertical polarization.
>>>
>>> - We do not expect the Modified Topology Change Report to be
>> [...]
>>
>> Forgive me if I'm missing something, but why _Modified_ Topology Change
>> Report?
>>
>>> diff --git a/s390x/topology.c b/s390x/topology.c
>>> new file mode 100644
>>> index 00000000..a1f9ce51
>>> --- /dev/null
>>> +++ b/s390x/topology.c
>>
>> [...]
>>
>>> +static int ptf(unsigned long fc, unsigned long *rc)
>>> +{
>>> +       int cc;
>>> +
>>> +       asm volatile(
>>> +               "       .insn   rre,0xb9a20000,%1,0\n"
>>> +               "       ipm     %0\n"
>>> +               "       srl     %0,28\n"
>>> +               : "=d" (cc), "+d" (fc)
>>> +               : "d" (fc)
>>
>> Why list fc here again?
>>
>>
> 

-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function
  2022-02-15  9:21       ` Pierre Morel
@ 2022-02-15  9:44         ` Pierre Morel
  2022-02-15 10:28           ` Nico Boehr
  0 siblings, 1 reply; 19+ messages in thread
From: Pierre Morel @ 2022-02-15  9:44 UTC (permalink / raw)
  To: Nico Boehr, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david



On 2/15/22 10:21, Pierre Morel wrote:
> 
> 
> On 2/15/22 09:50, Pierre Morel wrote:
>>
>>
>> On 2/9/22 12:37, Nico Boehr wrote:
>>> On Tue, 2022-02-08 at 14:27 +0100, Pierre Morel wrote:
>>>> We check the PTF instruction.
>>>
>>> You could test some very basic things as well:
>>>
>>> - you get a privileged pgm int in problem state,
>>> - reserved bits in first operand cause specification pgm int,
>>> - reserved FC values result in a specification pgm int,
>>> - second operand is ignored.
>>
>> Which second operand?
> 
> Sorry got it

I was a little fast in my answer, twice.
If the second operand is ignored, how would you like to check something 
like that?
We can check that the result of the instruction is identical for the 
known effects the user can check what ever we put in there but how can 
we know if it is really ignored?



>>
>>>
>>>>
>>>> - We do not expect to support vertical polarization.
>>>>
>>>> - We do not expect the Modified Topology Change Report to be
>>> [...]
>>>
>>> Forgive me if I'm missing something, but why _Modified_ Topology Change
>>> Report?
>>>
>>>> diff --git a/s390x/topology.c b/s390x/topology.c
>>>> new file mode 100644
>>>> index 00000000..a1f9ce51
>>>> --- /dev/null
>>>> +++ b/s390x/topology.c
>>>
>>> [...]
>>>
>>>> +static int ptf(unsigned long fc, unsigned long *rc)
>>>> +{
>>>> +       int cc;
>>>> +
>>>> +       asm volatile(
>>>> +               "       .insn   rre,0xb9a20000,%1,0\n"
>>>> +               "       ipm     %0\n"
>>>> +               "       srl     %0,28\n"
>>>> +               : "=d" (cc), "+d" (fc)
>>>> +               : "d" (fc)
>>>
>>> Why list fc here again?
>>>
>>>
>>
> 

-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function
  2022-02-15  9:44         ` Pierre Morel
@ 2022-02-15 10:28           ` Nico Boehr
  0 siblings, 0 replies; 19+ messages in thread
From: Nico Boehr @ 2022-02-15 10:28 UTC (permalink / raw)
  To: Pierre Morel, linux-s390; +Cc: frankja, thuth, kvm, cohuck, imbrenda, david

On Tue, 2022-02-15 at 10:44 +0100, Pierre Morel wrote:
> > > > - second operand is ignored.
> > > 
> > > Which second operand?
> > 
> > Sorry got it
> 
> I was a little fast in my answer, twice.
> If the second operand is ignored, how would you like to check
> something 
> like that?
> We can check that the result of the instruction is identical for the 
> known effects the user can check what ever we put in there but how
> can 
> we know if it is really ignored?

Yes, there is no 100% guarantee. If you think there is no value or it's
too difficult to test for the value it adds, it is fine for me if you
leave it out.

Your suggestion sounds fine, though.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests
  2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests Pierre Morel
  2022-02-08 15:31   ` Janosch Frank
  2022-02-08 15:35   ` Nico Boehr
@ 2022-02-15 11:18   ` Claudio Imbrenda
  2 siblings, 0 replies; 19+ messages in thread
From: Claudio Imbrenda @ 2022-02-15 11:18 UTC (permalink / raw)
  To: Pierre Morel; +Cc: linux-s390, frankja, thuth, kvm, cohuck, david, nrb

On Tue,  8 Feb 2022 14:27:07 +0100
Pierre Morel <pmorel@linux.ibm.com> wrote:

> We need in several tests to check if the VM we are running in
> is KVM.
> Let's add the test.
> 
> To check the VM type we use the STSI 3.2.2 instruction, let's
> define it's response structure in a central header.
> 
> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
> ---
>  lib/s390x/stsi.h | 32 +++++++++++++++++++++++++++
>  lib/s390x/vm.c   | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
>  lib/s390x/vm.h   |  3 +++
>  s390x/stsi.c     | 23 ++------------------
>  4 files changed, 91 insertions(+), 23 deletions(-)
>  create mode 100644 lib/s390x/stsi.h
> 
> diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
> new file mode 100644
> index 00000000..9b40664f
> --- /dev/null
> +++ b/lib/s390x/stsi.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Structures used to Store System Information
> + *
> + * Copyright IBM Corp. 2022
> + */
> +
> +#ifndef _S390X_STSI_H_
> +#define _S390X_STSI_H_
> +
> +struct sysinfo_3_2_2 {
> +	uint8_t reserved[31];
> +	uint8_t count;
> +	struct {
> +		uint8_t reserved2[4];
> +		uint16_t total_cpus;
> +		uint16_t conf_cpus;
> +		uint16_t standby_cpus;
> +		uint16_t reserved_cpus;
> +		uint8_t name[8];
> +		uint32_t caf;
> +		uint8_t cpi[16];
> +		uint8_t reserved5[3];
> +		uint8_t ext_name_encoding;
> +		uint32_t reserved3;
> +		uint8_t uuid[16];
> +	} vm[8];
> +	uint8_t reserved4[1504];
> +	uint8_t ext_names[8][256];
> +};
> +
> +#endif  /* _S390X_STSI_H_ */
> diff --git a/lib/s390x/vm.c b/lib/s390x/vm.c
> index a5b92863..38886b76 100644
> --- a/lib/s390x/vm.c
> +++ b/lib/s390x/vm.c
> @@ -12,6 +12,7 @@
>  #include <alloc_page.h>
>  #include <asm/arch_def.h>
>  #include "vm.h"
> +#include "stsi.h"
>  
>  /**
>   * Detect whether we are running with TCG (instead of KVM)
> @@ -26,9 +27,13 @@ bool vm_is_tcg(void)
>  	if (initialized)
>  		return is_tcg;
>  
> -	buf = alloc_page();
> -	if (!buf)
> +	if (!vm_is_vm()) {
> +		initialized = true;
>  		return false;
> +	}
> +
> +	buf = alloc_page();
> +	assert(buf);
>  
>  	if (stsi(buf, 1, 1, 1))
>  		goto out;
> @@ -43,3 +48,50 @@ out:
>  	free_page(buf);
>  	return is_tcg;
>  }
> +
> +/**
> + * Detect whether we are running with KVM
> + */
> +
> +bool vm_is_kvm(void)

I think this is too messy

I think a cleaner approach would be to have one "detect_environment"
function to call stsi and find out which environment we are running on.

then the various vm_is_* would just be something like

bool vm_is_kvm(void)
{
	return detect_environment() == VM_IS_KVM;
}

obviously the detect_environment function would call stsi only once and
then cache the result.

bonus, we could make that function public too, so e.g. a testcase could
do a switch, instead of having to do a series of nested ifs

> +{
> +	/* EBCDIC for "KVM/" */
> +	const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
> +	static bool initialized;
> +	static bool is_kvm;
> +	struct sysinfo_3_2_2 *stsi_322;
> +
> +	if (initialized)
> +		return is_kvm;
> +
> +	if (!vm_is_vm() || vm_is_tcg()) {
> +		initialized = true;
> +		return is_kvm;
> +	}
> +
> +	stsi_322 = alloc_page();
> +	assert(stsi_322);
> +
> +	if (stsi(stsi_322, 3, 2, 2))
> +		goto out;
> +
> +	/*
> +	 * If the manufacturer string is "KVM/" in EBCDIC, then we
> +	 * are on KVM.
> +	 */
> +	is_kvm = !memcmp(&stsi_322->vm[0].cpi, kvm_ebcdic, sizeof(kvm_ebcdic));
> +	initialized = true;
> +out:
> +	free_page(stsi_322);
> +	return is_kvm;
> +}
> +
> +bool vm_is_lpar(void)
> +{
> +	return stsi_get_fc() == 2;
> +}
> +
> +bool vm_is_vm(void)

is it enough to call it vm? maybe zvm? I don't have a strong opinion,
though

> +{
> +	return stsi_get_fc() == 3;
> +}
> diff --git a/lib/s390x/vm.h b/lib/s390x/vm.h
> index 7abba0cc..3aaf76af 100644
> --- a/lib/s390x/vm.h
> +++ b/lib/s390x/vm.h
> @@ -9,5 +9,8 @@
>  #define _S390X_VM_H_
>  
>  bool vm_is_tcg(void);
> +bool vm_is_kvm(void);
> +bool vm_is_vm(void);
> +bool vm_is_lpar(void);
>  
>  #endif  /* _S390X_VM_H_ */
> diff --git a/s390x/stsi.c b/s390x/stsi.c
> index 391f8849..1ed045e2 100644
> --- a/s390x/stsi.c
> +++ b/s390x/stsi.c
> @@ -13,27 +13,8 @@
>  #include <asm/asm-offsets.h>
>  #include <asm/interrupt.h>
>  #include <smp.h>
> +#include "stsi.h"
>  
> -struct stsi_322 {
> -	uint8_t reserved[31];
> -	uint8_t count;
> -	struct {
> -		uint8_t reserved2[4];
> -		uint16_t total_cpus;
> -		uint16_t conf_cpus;
> -		uint16_t standby_cpus;
> -		uint16_t reserved_cpus;
> -		uint8_t name[8];
> -		uint32_t caf;
> -		uint8_t cpi[16];
> -		uint8_t reserved5[3];
> -		uint8_t ext_name_encoding;
> -		uint32_t reserved3;
> -		uint8_t uuid[16];
> -	} vm[8];
> -	uint8_t reserved4[1504];
> -	uint8_t ext_names[8][256];
> -};
>  static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
>  
>  static void test_specs(void)
> @@ -91,7 +72,7 @@ static void test_3_2_2(void)
>  	/* EBCDIC for "KVM/" */
>  	const uint8_t cpi_kvm[] = { 0xd2, 0xe5, 0xd4, 0x61 };
>  	const char vm_name_ext[] = "kvm-unit-test";
> -	struct stsi_322 *data = (void *)pagebuf;
> +	struct sysinfo_3_2_2 *data = (void *)pagebuf;
>  
>  	report_prefix_push("3.2.2");
>  


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2022-02-15 11:18 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-08 13:27 [kvm-unit-tests PATCH v4 0/4] S390x: CPU Topology Information Pierre Morel
2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 1/4] s390x: lib: Add SCLP toplogy nested level Pierre Morel
2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 2/4] s390x: stsi: Define vm_is_kvm to be used in different tests Pierre Morel
2022-02-08 15:31   ` Janosch Frank
2022-02-08 15:43     ` Nico Boehr
2022-02-14  8:01       ` Pierre Morel
2022-02-14  9:18     ` Pierre Morel
2022-02-08 15:35   ` Nico Boehr
2022-02-14  7:55     ` Pierre Morel
2022-02-15 11:18   ` Claudio Imbrenda
2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 3/4] s390x: topology: Check the Perform Topology Function Pierre Morel
2022-02-09 11:37   ` Nico Boehr
2022-02-14  9:21     ` Pierre Morel
2022-02-15  8:29     ` Pierre Morel
2022-02-15  8:50     ` Pierre Morel
2022-02-15  9:21       ` Pierre Morel
2022-02-15  9:44         ` Pierre Morel
2022-02-15 10:28           ` Nico Boehr
2022-02-08 13:27 ` [kvm-unit-tests PATCH v4 4/4] s390x: topology: Checking Configuration Topology Information Pierre Morel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.