public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Nico Boehr <nrb@linux.ibm.com>
To: thuth@redhat.com, pbonzini@redhat.com, andrew.jones@linux.dev
Cc: kvm@vger.kernel.org, frankja@linux.ibm.com,
	imbrenda@linux.ibm.com,
	Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Subject: [kvm-unit-tests GIT PULL 16/26] s390x: topology: Rewrite topology list test
Date: Fri, 10 Nov 2023 14:52:25 +0100	[thread overview]
Message-ID: <20231110135348.245156-17-nrb@linux.ibm.com> (raw)
In-Reply-To: <20231110135348.245156-1-nrb@linux.ibm.com>

From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>

Rewrite recursion with separate functions for checking containers,
containers containing CPUs and CPUs.
This improves comprehension and allows for more tests.
We now also test for ordering of CPU TLEs and number of child entries.

Acked-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Link: https://lore.kernel.org/r/20231030160349.458764-9-nsg@linux.ibm.com
Signed-off-by: Nico Boehr <nrb@linux.ibm.com>
---
 lib/s390x/stsi.h |  36 +++++----
 s390x/topology.c | 202 ++++++++++++++++++++++++++++++-----------------
 2 files changed, 149 insertions(+), 89 deletions(-)

diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
index 1e9d095..f2290ca 100644
--- a/lib/s390x/stsi.h
+++ b/lib/s390x/stsi.h
@@ -30,15 +30,18 @@ struct sysinfo_3_2_2 {
 };
 
 #define CPUS_TLE_RES_BITS 0x00fffffff8000000UL
-struct topology_cpu {
-	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;
+union topology_cpu {
+	uint64_t raw[2];
+	struct {
+		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;
+	};
 };
 
 enum topology_polarization {
@@ -53,16 +56,19 @@ enum cpu_type {
 };
 
 #define CONTAINER_TLE_RES_BITS 0x00ffffffffffff00UL
-struct topology_container {
-	uint8_t nl;
-	uint8_t reserved[6];
-	uint8_t id;
+union topology_container {
+	uint64_t raw;
+	struct {
+		uint8_t nl;
+		uint8_t reserved[6];
+		uint8_t id;
+	};
 };
 
 union topology_entry {
 	uint8_t nl;
-	struct topology_cpu cpu;
-	struct topology_container container;
+	union topology_cpu cpu;
+	union topology_container container;
 };
 
 #define CPU_TOPOLOGY_MAX_LEVEL 6
diff --git a/s390x/topology.c b/s390x/topology.c
index df158ae..01021eb 100644
--- a/s390x/topology.c
+++ b/s390x/topology.c
@@ -2,7 +2,7 @@
 /*
  * CPU Topology
  *
- * Copyright IBM Corp. 2022
+ * Copyright IBM Corp. 2022, 2023
  *
  * Authors:
  *  Pierre Morel <pmorel@linux.ibm.com>
@@ -23,7 +23,6 @@ static uint8_t pagebuf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
 
 static int max_nested_lvl;
 static int number_of_cpus;
-static int cpus_in_masks;
 static int max_cpus;
 
 /*
@@ -238,108 +237,163 @@ done:
 }
 
 /**
- * check_tle:
- * @tc: pointer to first TLE
+ * stsi_get_sysib:
+ * @info: pointer to the STSI info structure
+ * @sel2: the selector giving the topology level to check
  *
- * Recursively check the containers TLEs until we
- * find a CPU TLE.
+ * Fill the sysinfo_15_1_x info structure and check the
+ * SYSIB header.
+ *
+ * Returns instruction validity.
  */
-static uint8_t *check_tle(void *tc)
+static int stsi_get_sysib(struct sysinfo_15_1_x *info, int sel2)
 {
-	struct topology_container *container = tc;
-	struct topology_cpu *cpus;
-	int n;
+	int ret;
 
-	if (container->nl) {
-		report_info("NL: %d id: %d", container->nl, container->id);
+	report_prefix_pushf("SYSIB");
 
-		report(!(*(uint64_t *)tc & CONTAINER_TLE_RES_BITS),
-		       "reserved bits %016lx",
-		       *(uint64_t *)tc & CONTAINER_TLE_RES_BITS);
+	ret = stsi(info, 15, 1, sel2);
 
-		return check_tle(tc + sizeof(*container));
+	if (max_nested_lvl >= sel2) {
+		report(!ret, "Valid instruction");
+	} else {
+		report(ret, "Invalid instruction");
 	}
 
-	report_info("NL: %d", container->nl);
-	cpus = tc;
+	report_prefix_pop();
 
-	report(!(*(uint64_t *)tc & CPUS_TLE_RES_BITS), "reserved bits %016lx",
-	       *(uint64_t *)tc & CPUS_TLE_RES_BITS);
+	return ret;
+}
 
-	report(cpus->type == CPU_TYPE_IFL, "type IFL");
+static int check_cpu(union topology_cpu *cpu,
+		     union topology_container *parent)
+{
+	report_prefix_pushf("%d:%d:%d:%d", cpu->d, cpu->pp, cpu->type, cpu->origin);
 
-	report_info("origin: %d", cpus->origin);
-	report_info("mask: %016lx", cpus->mask);
-	report_info("dedicated: %d entitlement: %d", cpus->d, cpus->pp);
+	report(!(cpu->raw[0] & CPUS_TLE_RES_BITS), "reserved bits %016lx",
+	       cpu->raw[0] & CPUS_TLE_RES_BITS);
 
-	n = __builtin_popcountl(cpus->mask);
-	report(n <= expected_topo_lvl[0], "CPUs per mask: %d out of max %d",
-	       n, expected_topo_lvl[0]);
-	cpus_in_masks += n;
+	report(cpu->type == CPU_TYPE_IFL, "type IFL");
 
-	if (!cpus->d)
-		report_skip("Not dedicated");
-	else
-		report(cpus->pp == POLARIZATION_VERTICAL_HIGH ||
-		       cpus->pp == POLARIZATION_HORIZONTAL,
+	if (cpu->d)
+		report(cpu->pp == POLARIZATION_VERTICAL_HIGH ||
+		       cpu->pp == POLARIZATION_HORIZONTAL,
 		       "Dedicated CPUs are either horizontally polarized or have high entitlement");
+	else
+		report_skip("Not dedicated");
+
+	report_prefix_pop();
 
-	return tc + sizeof(*cpus);
+	return __builtin_popcountl(cpu->mask);
 }
 
-/**
- * stsi_check_tle_coherency:
- * @info: Pointer to the stsi information
- *
- * 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)
+static union topology_container *check_child_cpus(struct sysinfo_15_1_x *info,
+						  union topology_container *cont,
+						  union topology_cpu *child,
+						  unsigned int *cpus_in_masks)
 {
-	void *tc, *end;
+	void *last = ((void *)info) + info->length;
+	union topology_cpu *prev_cpu = NULL;
+	bool correct_ordering = true;
+	unsigned int cpus = 0;
+	int i;
 
-	report_prefix_push("TLE");
-	cpus_in_masks = 0;
+	for (i = 0; (void *)&child[i] < last && child[i].nl == 0; prev_cpu = &child[i++]) {
+		cpus += check_cpu(&child[i], cont);
+		if (prev_cpu) {
+			if (prev_cpu->type > child[i].type) {
+				report_info("Incorrect ordering wrt type for child %d", i);
+				correct_ordering = false;
+			}
+			if (prev_cpu->type < child[i].type)
+				continue;
+			if (prev_cpu->pp < child[i].pp) {
+				report_info("Incorrect ordering wrt polarization for child %d", i);
+				correct_ordering = false;
+			}
+			if (prev_cpu->pp > child[i].pp)
+				continue;
+			if (!prev_cpu->d && child[i].d) {
+				report_info("Incorrect ordering wrt dedication for child %d", i);
+				correct_ordering = false;
+			}
+			if (prev_cpu->d && !child[i].d)
+				continue;
+			if (prev_cpu->origin > child[i].origin) {
+				report_info("Incorrect ordering wrt origin for child %d", i);
+				correct_ordering = false;
+			}
+		}
+	}
+	report(correct_ordering, "children correctly ordered");
+	report(cpus <= expected_topo_lvl[0], "%d children <= max of %d",
+	       cpus, expected_topo_lvl[0]);
+	*cpus_in_masks += cpus;
 
-	tc = info->tle;
-	end = (void *)info + info->length;
+	return (union topology_container *)&child[i];
+}
 
-	while (tc < end)
-		tc = check_tle(tc);
+static union topology_container *check_container(struct sysinfo_15_1_x *info,
+						 union topology_container *cont,
+						 union topology_entry *child,
+						 unsigned int *cpus_in_masks);
 
-	report(cpus_in_masks == number_of_cpus, "CPUs in mask %d",
-	       cpus_in_masks);
+static union topology_container *check_child_containers(struct sysinfo_15_1_x *info,
+							union topology_container *cont,
+							union topology_container *child,
+							unsigned int *cpus_in_masks)
+{
+	void *last = ((void *)info) + info->length;
+	union topology_container *entry;
+	int i;
 
-	report_prefix_pop();
+	for (i = 0, entry = child; (void *)entry < last && entry->nl == cont->nl - 1; i++) {
+		entry = check_container(info, entry, (union topology_entry *)(entry + 1),
+					cpus_in_masks);
+	}
+	if (max_nested_lvl == info->mnest)
+		report(i <= expected_topo_lvl[cont->nl - 1], "%d children <= max of %d",
+		       i, expected_topo_lvl[cont->nl - 1]);
+
+	return entry;
 }
 
-/**
- * stsi_get_sysib:
- * @info: pointer to the STSI info structure
- * @sel2: the selector giving the topology level to check
- *
- * Fill the sysinfo_15_1_x info structure and check the
- * SYSIB header.
- *
- * Returns instruction validity.
- */
-static int stsi_get_sysib(struct sysinfo_15_1_x *info, int sel2)
+static union topology_container *check_container(struct sysinfo_15_1_x *info,
+						 union topology_container *cont,
+						 union topology_entry *child,
+						 unsigned int *cpus_in_masks)
 {
-	int ret;
+	union topology_container *entry;
 
-	report_prefix_pushf("SYSIB");
+	report_prefix_pushf("%d", cont->id);
 
-	ret = stsi(info, 15, 1, sel2);
+	report(cont->nl - 1 == child->nl, "Level %d one above child level %d",
+	       cont->nl, child->nl);
+	report(!(cont->raw & CONTAINER_TLE_RES_BITS), "reserved bits %016lx",
+	       cont->raw & CONTAINER_TLE_RES_BITS);
 
-	if (max_nested_lvl >= sel2) {
-		report(!ret, "Valid instruction");
-	} else {
-		report(ret, "Invalid instruction");
-	}
+	if (cont->nl > 1)
+		entry = check_child_containers(info, cont, &child->container, cpus_in_masks);
+	else
+		entry = check_child_cpus(info, cont, &child->cpu, cpus_in_masks);
 
 	report_prefix_pop();
+	return entry;
+}
 
-	return ret;
+static void check_topology_list(struct sysinfo_15_1_x *info, int sel2)
+{
+	union topology_container dummy = { .nl = sel2, .id = 0 };
+	unsigned int cpus_in_masks = 0;
+
+	report_prefix_push("TLE");
+
+	check_container(info, &dummy, info->tle, &cpus_in_masks);
+	report(cpus_in_masks == number_of_cpus,
+	       "Number of CPUs %d equals  %d CPUs in masks",
+	       number_of_cpus, cpus_in_masks);
+
+	report_prefix_pop();
 }
 
 /**
@@ -372,7 +426,7 @@ static void check_sysinfo_15_1_x(struct sysinfo_15_1_x *info, int sel2)
 	}
 
 	stsi_check_header(info, sel2);
-	stsi_check_tle_coherency(info);
+	check_topology_list(info, sel2);
 
 vertical:
 	report_prefix_pop();
@@ -385,7 +439,7 @@ vertical:
 	}
 
 	stsi_check_header(info, sel2);
-	stsi_check_tle_coherency(info);
+	check_topology_list(info, sel2);
 	report_prefix_pop();
 
 end:
-- 
2.41.0


  parent reply	other threads:[~2023-11-10 13:54 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-10 13:52 [kvm-unit-tests GIT PULL 00/26] s390x: multiline unittests.cfg, sclp enhancements, topology fixes and improvements, sie without MSO/MSL, 2G guest alignment, bug fixes Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 01/26] s390x: spec_ex: load full register Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 02/26] s390x: run PV guests with confidential guest enabled Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 03/26] lib: s390x: hw: rework do_detect_host so we don't need allocation Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 04/26] lib: s390x: sclp: Add compat handling for HMC ASCII consoles Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 05/26] lib: s390x: sclp: Add line mode input handling Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 06/26] s390x: spec_ex-sie: refactor to use snippet API Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 07/26] s390x: sie: ensure guests are aligned to 2GB Nico Boehr
2023-11-22 11:06   ` Thomas Huth
2023-11-23  9:24     ` Nina Schoetterl-Glausch
2023-11-23 13:03       ` Thomas Huth
2023-11-23 14:16       ` Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 08/26] s390x: mvpg-sie: fix virtual-physical address confusion Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 09/26] s390x: topology: Introduce enums for polarization & cpu type Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 10/26] s390x: topology: Fix report message Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 11/26] s390x: topology: Use function parameter in stsi_get_sysib Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 12/26] s390x: topology: Fix parsing loop Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 13/26] s390x: topology: Make some report messages unique Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 14/26] s390x: topology: Refine stsi header test Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 15/26] s390x: topology: Rename topology_core to topology_cpu Nico Boehr
2023-11-10 13:52 ` Nico Boehr [this message]
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 17/26] scripts: Implement multiline strings for extra_params Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 18/26] s390x: topology: Add complex topology test Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 19/26] lib: s390x: introduce bitfield for PSW mask Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 20/26] s390x: add function to set DAT mode for all interrupts Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 21/26] s390x: sie: switch to home space mode before entering SIE Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 22/26] s390x: lib: don't forward PSW when handling exception in SIE Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 23/26] s390x: lib: sie: don't reenter SIE on pgm int Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 24/26] s390x: add test source dir to include paths Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 25/26] s390x: add a test for SIE without MSO/MSL Nico Boehr
2023-11-10 13:52 ` [kvm-unit-tests GIT PULL 26/26] lib: s390x: interrupt: remove TEID_ASCE defines Nico Boehr
2023-11-10 15:25 ` [kvm-unit-tests GIT PULL 00/26] s390x: multiline unittests.cfg, sclp enhancements, topology fixes and improvements, sie without MSO/MSL, 2G guest alignment, bug fixes Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231110135348.245156-17-nrb@linux.ibm.com \
    --to=nrb@linux.ibm.com \
    --cc=andrew.jones@linux.dev \
    --cc=frankja@linux.ibm.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=nsg@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox