diff mbox series

[kvm-unit-tests,v10,1/2] s390x: topology: Check the Perform Topology Function

Message ID 20230627082155.6375-2-pmorel@linux.ibm.com (mailing list archive)
State New, archived
Headers show
Series S390x: CPU Topology Information | expand

Commit Message

Pierre Morel June 27, 2023, 8:21 a.m. UTC
We check that the PTF instruction is working correctly when
the cpu topology facility is available.

For KVM only, we test changing of the polarity between horizontal
and vertical and that a reset set the horizontal polarity.

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

Comments

Nico Boehr June 29, 2023, 8:49 a.m. UTC | #1
Quoting Pierre Morel (2023-06-27 10:21:54)
[...]
> diff --git a/s390x/topology.c b/s390x/topology.c
> new file mode 100644
> index 0000000..7e1bbf9
> --- /dev/null
> +++ b/s390x/topology.c
> @@ -0,0 +1,190 @@
[...]
> +static void check_privilege(int fc)
> +{
> +       unsigned long rc;
> +       char buf[20];
> +
> +       snprintf(buf, sizeof(buf), "Privileged fc %d", fc);
> +       report_prefix_push(buf);

We have report_prefix_pushf (note the f at the end!) for this.

I can fix that up when picking in case there's no new version, though.
Pierre Morel June 29, 2023, 12:53 p.m. UTC | #2
On 6/29/23 10:49, Nico Boehr wrote:
> Quoting Pierre Morel (2023-06-27 10:21:54)
> [...]
>> diff --git a/s390x/topology.c b/s390x/topology.c
>> new file mode 100644
>> index 0000000..7e1bbf9
>> --- /dev/null
>> +++ b/s390x/topology.c
>> @@ -0,0 +1,190 @@
> [...]
>> +static void check_privilege(int fc)
>> +{
>> +       unsigned long rc;
>> +       char buf[20];
>> +
>> +       snprintf(buf, sizeof(buf), "Privileged fc %d", fc);
>> +       report_prefix_push(buf);
> We have report_prefix_pushf (note the f at the end!) for this.
>
> I can fix that up when picking in case there's no new version, though.


ohhh, perfect.

Yes please if you can, do it :)

Thanks

Pierre
Thomas Huth July 3, 2023, 8:42 a.m. UTC | #3
On 29/06/2023 10.49, Nico Boehr wrote:
> Quoting Pierre Morel (2023-06-27 10:21:54)
> [...]
>> diff --git a/s390x/topology.c b/s390x/topology.c
>> new file mode 100644
>> index 0000000..7e1bbf9
>> --- /dev/null
>> +++ b/s390x/topology.c
>> @@ -0,0 +1,190 @@
> [...]
>> +static void check_privilege(int fc)
>> +{
>> +       unsigned long rc;
>> +       char buf[20];
>> +
>> +       snprintf(buf, sizeof(buf), "Privileged fc %d", fc);
>> +       report_prefix_push(buf);
> 
> We have report_prefix_pushf (note the f at the end!) for this.
> 
> I can fix that up when picking in case there's no new version, though.

With that fixed:

Reviewed-by: Thomas Huth <thuth@redhat.com>
Pierre Morel July 12, 2023, 9:09 a.m. UTC | #4
On 7/3/23 10:42, Thomas Huth wrote:
> On 29/06/2023 10.49, Nico Boehr wrote:
>> Quoting Pierre Morel (2023-06-27 10:21:54)
>> [...]
>>> diff --git a/s390x/topology.c b/s390x/topology.c
>>> new file mode 100644
>>> index 0000000..7e1bbf9
>>> --- /dev/null
>>> +++ b/s390x/topology.c
>>> @@ -0,0 +1,190 @@
>> [...]
>>> +static void check_privilege(int fc)
>>> +{
>>> +       unsigned long rc;
>>> +       char buf[20];
>>> +
>>> +       snprintf(buf, sizeof(buf), "Privileged fc %d", fc);
>>> +       report_prefix_push(buf);
>>
>> We have report_prefix_pushf (note the f at the end!) for this.
>>
>> I can fix that up when picking in case there's no new version, though.
>
> With that fixed:
>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
>
Thanks both of you.

Regards,

Pierre
Pierre Morel July 12, 2023, 9:10 a.m. UTC | #5
On 7/3/23 10:42, Thomas Huth wrote:
> On 29/06/2023 10.49, Nico Boehr wrote:
>> Quoting Pierre Morel (2023-06-27 10:21:54)
>> [...]
>>> diff --git a/s390x/topology.c b/s390x/topology.c
>>> new file mode 100644
>>> index 0000000..7e1bbf9
>>> --- /dev/null
>>> +++ b/s390x/topology.c
>>> @@ -0,0 +1,190 @@
>> [...]
>>> +static void check_privilege(int fc)
>>> +{
>>> +       unsigned long rc;
>>> +       char buf[20];
>>> +
>>> +       snprintf(buf, sizeof(buf), "Privileged fc %d", fc);
>>> +       report_prefix_push(buf);
>>
>> We have report_prefix_pushf (note the f at the end!) for this.
>>
>> I can fix that up when picking in case there's no new version, though.
>
> With that fixed:
>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
>
Thanks both of you.

Regards,

Pierre
diff mbox series

Patch

diff --git a/s390x/Makefile b/s390x/Makefile
index a80db53..fe77b07 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -40,6 +40,7 @@  tests += $(TEST_DIR)/panic-loop-pgm.elf
 tests += $(TEST_DIR)/migration-sck.elf
 tests += $(TEST_DIR)/exittime.elf
 tests += $(TEST_DIR)/ex.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 0000000..7e1bbf9
--- /dev/null
+++ b/s390x/topology.c
@@ -0,0 +1,190 @@ 
+/* 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 <asm/barrier.h>
+#include <smp.h>
+#include <sclp.h>
+#include <s390x/hardware.h>
+
+#define PTF_REQ_HORIZONTAL	0
+#define PTF_REQ_VERTICAL	1
+#define PTF_CHECK		2
+
+#define PTF_ERR_NO_REASON	0
+#define PTF_ERR_ALRDY_POLARIZED	1
+#define PTF_ERR_IN_PROGRESS	2
+
+extern int diag308_load_reset(u64);
+
+static int ptf(unsigned long fc, unsigned long *rc)
+{
+	int cc;
+
+	asm volatile(
+		"	ptf	%1	\n"
+		"       ipm     %0	\n"
+		"       srl     %0,28	\n"
+		: "=d" (cc), "+d" (fc)
+		:
+		: "cc");
+
+	*rc = fc >> 8;
+	return cc;
+}
+
+static void check_privilege(int fc)
+{
+	unsigned long rc;
+	char buf[20];
+
+	snprintf(buf, sizeof(buf), "Privileged fc %d", fc);
+	report_prefix_push(buf);
+	enter_pstate();
+	expect_pgm_int();
+	ptf(fc, &rc);
+	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
+	report_prefix_pop();
+}
+
+static void check_specifications(void)
+{
+	unsigned long error = 0;
+	unsigned long ptf_bits;
+	unsigned long rc;
+	int i;
+
+	report_prefix_push("Specifications");
+
+	/* Function codes above 3 are undefined */
+	for (i = 4; i < 255; i++) {
+		expect_pgm_int();
+		ptf(i, &rc);
+		if (clear_pgm_int() != PGM_INT_CODE_SPECIFICATION) {
+			report_fail("FC %d did not yield specification exception", i);
+			error = 1;
+		}
+	}
+	report(!error, "Undefined function codes");
+
+	/* Reserved bits must be 0 */
+	for (i = 8, error = 0; i < 64; i++) {
+		ptf_bits = 0x01UL << i;
+		expect_pgm_int();
+		ptf(ptf_bits, &rc);
+		if (clear_pgm_int() != PGM_INT_CODE_SPECIFICATION) {
+			report_fail("Reserved bit %d did not yield specification exception", i);
+			error = 1;
+		}
+	}
+
+	report(!error, "Reserved bits");
+
+	report_prefix_pop();
+}
+
+static void check_polarization_change(void)
+{
+	unsigned long rc;
+	int cc;
+
+	report_prefix_push("Polarization change");
+
+	/* We expect a clean state through reset */
+	report(diag308_load_reset(1), "load normal reset done");
+
+	/*
+	 * Set vertical polarization to verify that RESET sets
+	 * horizontal polarization back.
+	 */
+	cc = ptf(PTF_REQ_VERTICAL, &rc);
+	report(cc == 0, "Set vertical polarization.");
+
+	report(diag308_load_reset(1), "load normal reset done");
+
+	cc = ptf(PTF_CHECK, &rc);
+	report(cc == 0, "Reset should clear topology report");
+
+	cc = ptf(PTF_REQ_HORIZONTAL, &rc);
+	report(cc == 2 && rc == PTF_ERR_ALRDY_POLARIZED,
+	       "After RESET polarization is horizontal");
+
+	/* Flip between vertical and horizontal polarization */
+	cc = ptf(PTF_REQ_VERTICAL, &rc);
+	report(cc == 0, "Change to vertical");
+
+	cc = ptf(PTF_CHECK, &rc);
+	report(cc == 1, "Should report");
+
+	cc = ptf(PTF_REQ_VERTICAL, &rc);
+	report(cc == 2 && rc == PTF_ERR_ALRDY_POLARIZED, "Double change to vertical");
+
+	cc = ptf(PTF_CHECK, &rc);
+	report(cc == 0, "Should not report");
+
+	cc = ptf(PTF_REQ_HORIZONTAL, &rc);
+	report(cc == 0, "Change to horizontal");
+
+	cc = ptf(PTF_CHECK, &rc);
+	report(cc == 1, "Should Report");
+
+	cc = ptf(PTF_REQ_HORIZONTAL, &rc);
+	report(cc == 2 && rc == PTF_ERR_ALRDY_POLARIZED, "Double change to horizontal");
+
+	cc = ptf(PTF_CHECK, &rc);
+	report(cc == 0, "Should not report");
+
+	report_prefix_pop();
+}
+
+static void test_ptf(void)
+{
+	check_privilege(PTF_REQ_HORIZONTAL);
+	check_privilege(PTF_REQ_VERTICAL);
+	check_privilege(PTF_CHECK);
+	check_specifications();
+	check_polarization_change();
+}
+
+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("Virtual 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 b61faf0..fc3666b 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -218,3 +218,6 @@  extra_params = -append '--parallel'
 
 [execute]
 file = ex.elf
+
+[topology]
+file = topology.elf