Skip to contentSkip to conversation

s390x/cpumodel: The missing DFP facility on TCG is expected

PATCH Superseded Thomas Huth 4 participants 6 messages Jul 7, 2020 – Jul 8, 2020 KVM

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 s390x/cpumodel: The missing DFP facility on TCG is expected

When running the kvm-unit-tests with TCG on s390x, the cpumodel test always reports the error about the missing DFP (decimal floating point) facility. This is kind of expected, since DFP is not required for running Linux and thus nobody is really interested in implementing this facility in TCG. Thus let's mark this as an expected error instead, so that we can run the kvm-unit-tests also with TCG without getting test failures that we do not care about.

---
v2:
- Rewrote the logic, introduced expected_tcg_fail flag
- Use manufacturer string instead of VM name to detect TCG

 s390x/cpumodel.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)
s390x/cpumodel.c +43 -6
index 5d232c6..190ceb2 100644
@@ -11,14 +11,19 @@
  */
 
 #include <asm/facility.h>
+#include <alloc_page.h>
 
-static int dep[][2] = {
+static struct {
+	int facility;
+	int implied;
+	bool expected_tcg_fail;
+} dep[] = {
 	/* from SA22-7832-11 4-98 facility indications */
 	{   4,   3 },
 	{   5,   3 },
 	{   5,   4 },
 	{  19,  18 },
-	{  37,  42 },
+	{  37,  42, true },  /* TCG does not have DFP and won't get it soon */
 	{  43,  42 },
 	{  73,  49 },
 	{ 134, 129 },
@@ -38,6 +43,36 @@ static int dep[][2] = {
 	{ 155,  77 },
 };
 
+/*
+ * A hack to detect TCG (instead of KVM): QEMU uses "TCGguest" as guest
+ * name by default when we are running with TCG (otherwise it's "KVMguest")
+ */
+static bool is_tcg(void)
+{
+	const char qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
+	bool ret = false;
+	uint8_t *buf;
+
+	buf = alloc_page();
+	if (!buf)
+		return false;
+
+	if (stsi(buf, 1, 1, 1)) {
+		goto out;
+	}
+
+	/*
+	 * If the manufacturer string is "QEMU" in EBCDIC, then we are on TCG
+	 * (otherwise the string is "IBM" in EBCDIC)
+	 */
+	if (!memcmp(&buf[32], qemu_ebcdic, sizeof(qemu_ebcdic)))
+		ret =  true;
+out:
+	free_page(buf);
+	return ret;
+}
+
+
 int main(void)
 {
 	int i;
@@ -46,11 +81,13 @@ int main(void)
 
 	report_prefix_push("dependency");
 	for (i = 0; i < ARRAY_SIZE(dep); i++) {
-		if (test_facility(dep[i][0])) {
-			report(test_facility(dep[i][1]), "%d implies %d",
-				dep[i][0], dep[i][1]);
+		if (test_facility(dep[i].facility)) {
+			report_xfail(dep[i].expected_tcg_fail && is_tcg(),
+				     test_facility(dep[i].implied),
+				     "%d implies %d",
+				     dep[i].facility, dep[i].implied);
 		} else {
-			report_skip("facility %d not present", dep[i][0]);
+			report_skip("facility %d not present", dep[i].facility);
 		}
 	}
 	report_prefix_pop();
Signature · 1 line
2.18.1
#1 lore raw
Quoted 44 lines · Thomas Huth

When running the kvm-unit-tests with TCG on s390x, the cpumodel test always reports the error about the missing DFP (decimal floating point) facility. This is kind of expected, since DFP is not required for running Linux and thus nobody is really interested in implementing this facility in TCG. Thus let's mark this as an expected error instead, so that we can run the kvm-unit-tests also with TCG without getting test failures that we do not care about.

---
v2:
- Rewrote the logic, introduced expected_tcg_fail flag
- Use manufacturer string instead of VM name to detect TCG

 s390x/cpumodel.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)
s390x/cpumodel.c +7 -2
index 5d232c6..190ceb2 100644
@@ -11,14 +11,19 @@
  */
 
 #include <asm/facility.h>
+#include <alloc_page.h>
 
-static int dep[][2] = {
+static struct {
+	int facility;
+	int implied;
+	bool expected_tcg_fail;
+} dep[] = {
 	/* from SA22-7832-11 4-98 facility indications */
 	{   4,   3 },
 	{   5,   3 },
 	{   5,   4 },
 	{  19,  18 },
-	{  37,  42 },
+	{  37,  42, true },  /* TCG does not have DFP and won't get it soon */
 	{  43,  42 },
 	{  73,  49 },
 	{ 134, 129 },

s390x/cpumodel.c static int dep[][2] = { · line 48

Quoted 6 lines
s390x/cpumodel.c +3 -0
@@ -38,6 +43,36 @@ static int dep[][2] = {
 	{ 155,  77 },
 };
 
+/*
+ * A hack to detect TCG (instead of KVM): QEMU uses "TCGguest" as guest
+ * name by default when we are running with TCG (otherwise it's "KVMguest")

I forgot to update the comment, it rather should read: "A hack to detect TCG (instead of KVM): Check the manufacturer string which differs between TCG and KVM." (or something similar)

Thomas

#2 lore raw
In reply to Thomas Huth
Quoted 16 lines · On Tue, 7 Jul 2020 12:42:05 +0200 Thomas Huth <[email protected]> wrote:

When running the kvm-unit-tests with TCG on s390x, the cpumodel test always reports the error about the missing DFP (decimal floating point) facility. This is kind of expected, since DFP is not required for running Linux and thus nobody is really interested in implementing this facility in TCG. Thus let's mark this as an expected error instead, so that we can run the kvm-unit-tests also with TCG without getting test failures that we do not care about.

---
v2:
- Rewrote the logic, introduced expected_tcg_fail flag
- Use manufacturer string instead of VM name to detect TCG

 s390x/cpumodel.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)

(...)

s390x/cpumodel.c static int dep[][2] = { · line 62

Quoted 13 lines
s390x/cpumodel.c +13 -0
+static bool is_tcg(void)
+{
+	const char qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
+	bool ret = false;
+	uint8_t *buf;
+
+	buf = alloc_page();
+	if (!buf)
+		return false;
+
+	if (stsi(buf, 1, 1, 1)) {
+		goto out;
+	}

This does an alloc_page() and a stsi() every time you call it...

Quoted 17 lines
s390x/cpumodel.c +13 -0
+
+	/*
+	 * If the manufacturer string is "QEMU" in EBCDIC, then we are on TCG
+	 * (otherwise the string is "IBM" in EBCDIC)
+	 */
+	if (!memcmp(&buf[32], qemu_ebcdic, sizeof(qemu_ebcdic)))
+		ret =  true;
+out:
+	free_page(buf);
+	return ret;
+}
+
+
 int main(void)
 {
 	int i;

s390x/cpumodel.c int main(void) · line 82

Quoted 2 lines
s390x/cpumodel.c +0 -0
@@ -46,11 +81,13 @@ int main(void)
 
 	report_prefix_push("dependency");

...so maybe cache the value for is_tcg() here instead of checking multiple times in the loop?

(Or cache the value in is_tcg().)

Quoted 15 lines
s390x/cpumodel.c +6 -4
 	for (i = 0; i < ARRAY_SIZE(dep); i++) {
-		if (test_facility(dep[i][0])) {
-			report(test_facility(dep[i][1]), "%d implies %d",
-				dep[i][0], dep[i][1]);
+		if (test_facility(dep[i].facility)) {
+			report_xfail(dep[i].expected_tcg_fail && is_tcg(),
+				     test_facility(dep[i].implied),
+				     "%d implies %d",
+				     dep[i].facility, dep[i].implied);
 		} else {
-			report_skip("facility %d not present", dep[i][0]);
+			report_skip("facility %d not present", dep[i].facility);
 		}
 	}
 	report_prefix_pop();
#3 lore raw
Quoted 56 lines · Cornelia Huck
Quoted 16 lines · On Tue, 7 Jul 2020 12:42:05 +0200 Thomas Huth <[email protected]> wrote:

When running the kvm-unit-tests with TCG on s390x, the cpumodel test always reports the error about the missing DFP (decimal floating point) facility. This is kind of expected, since DFP is not required for running Linux and thus nobody is really interested in implementing this facility in TCG. Thus let's mark this as an expected error instead, so that we can run the kvm-unit-tests also with TCG without getting test failures that we do not care about.

---
v2:
- Rewrote the logic, introduced expected_tcg_fail flag
- Use manufacturer string instead of VM name to detect TCG

 s390x/cpumodel.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)

(...)

s390x/cpumodel.c static int dep[][2] = { · line 62

Quoted 13 lines
s390x/cpumodel.c +13 -0
+static bool is_tcg(void)
+{
+	const char qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
+	bool ret = false;
+	uint8_t *buf;
+
+	buf = alloc_page();
+	if (!buf)
+		return false;
+
+	if (stsi(buf, 1, 1, 1)) {
+		goto out;
+	}

This does an alloc_page() and a stsi() every time you call it...

Quoted 18 lines
s390x/cpumodel.c +13 -0
+
+	/*
+	 * If the manufacturer string is "QEMU" in EBCDIC, then we are on TCG
+	 * (otherwise the string is "IBM" in EBCDIC)
+	 */
+	if (!memcmp(&buf[32], qemu_ebcdic, sizeof(qemu_ebcdic)))
+		ret =  true;
+out:
+	free_page(buf);
+	return ret;
+}
+
+
 int main(void)
 {
 	int i;
@@ -46,11 +81,13 @@ int main(void)
 
Quoted 4 lines

s390x/cpumodel.c int main(void) · line 82

Quoted 1 line
s390x/cpumodel.c +0 -0
 	report_prefix_push("dependency");

...so maybe cache the value for is_tcg() here instead of checking multiple times in the loop?

Maybe move it to common code and do the detection early during boot? The n provide is_tcg() or sth. like that. Could be helpful in other context maybe.

Signature · 3 lines
Thanks,

David / dhildenb
#4 lore raw
Quoted 57 lines · David Hildenbrand
Quoted 56 lines · Cornelia Huck
Quoted 16 lines · On Tue, 7 Jul 2020 12:42:05 +0200 Thomas Huth <[email protected]> wrote:

When running the kvm-unit-tests with TCG on s390x, the cpumodel test always reports the error about the missing DFP (decimal floating point) facility. This is kind of expected, since DFP is not required for running Linux and thus nobody is really interested in implementing this facility in TCG. Thus let's mark this as an expected error instead, so that we can run the kvm-unit-tests also with TCG without getting test failures that we do not care about.

---
v2:
- Rewrote the logic, introduced expected_tcg_fail flag
- Use manufacturer string instead of VM name to detect TCG

 s390x/cpumodel.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)

(...)

s390x/cpumodel.c static int dep[][2] = { · line 62

Quoted 13 lines
s390x/cpumodel.c +13 -0
+static bool is_tcg(void)
+{
+	const char qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
+	bool ret = false;
+	uint8_t *buf;
+
+	buf = alloc_page();
+	if (!buf)
+		return false;
+
+	if (stsi(buf, 1, 1, 1)) {
+		goto out;
+	}

This does an alloc_page() and a stsi() every time you call it...

Quoted 18 lines
s390x/cpumodel.c +13 -0
+
+	/*
+	 * If the manufacturer string is "QEMU" in EBCDIC, then we are on TCG
+	 * (otherwise the string is "IBM" in EBCDIC)
+	 */
+	if (!memcmp(&buf[32], qemu_ebcdic, sizeof(qemu_ebcdic)))
+		ret =  true;
+out:
+	free_page(buf);
+	return ret;
+}
+
+
 int main(void)
 {
 	int i;
@@ -46,11 +81,13 @@ int main(void)
 
Quoted 9 lines
Quoted 4 lines

s390x/cpumodel.c int main(void) · line 82

Quoted 1 line
s390x/cpumodel.c +0 -0
 	report_prefix_push("dependency");

...so maybe cache the value for is_tcg() here instead of checking multiple times in the loop?

Maybe move it to common code and do the detection early during boot? The n provide is_tcg() or sth. like that. Could be helpful in other context maybe.

Well we also already have a check for zvm 6 with stsi 3.2.2 in skey.c I'm not completely convinced that I want to loose two pages and a few cycles on every startup for two separate test cases.

#5 lore raw
Quoted 63 lines · Janosch Frank
Quoted 62 lines · David Hildenbrand
Quoted 60 lines · Cornelia Huck
Quoted 16 lines · On Tue, 7 Jul 2020 12:42:05 +0200 Thomas Huth <[email protected]> wrote:

When running the kvm-unit-tests with TCG on s390x, the cpumodel test always reports the error about the missing DFP (decimal floating point) facility. This is kind of expected, since DFP is not required for running Linux and thus nobody is really interested in implementing this facility in TCG. Thus let's mark this as an expected error instead, so that we can run the kvm-unit-tests also with TCG without getting test failures that we do not care about.

---
v2:
- Rewrote the logic, introduced expected_tcg_fail flag
- Use manufacturer string instead of VM name to detect TCG

 s390x/cpumodel.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)

(...)

s390x/cpumodel.c static int dep[][2] = { · line 62

Quoted 13 lines
s390x/cpumodel.c +13 -0
+static bool is_tcg(void)
+{
+	const char qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
+	bool ret = false;
+	uint8_t *buf;
+
+	buf = alloc_page();
+	if (!buf)
+		return false;
+
+	if (stsi(buf, 1, 1, 1)) {
+		goto out;
+	}

This does an alloc_page() and a stsi() every time you call it...

Quoted 17 lines
s390x/cpumodel.c +13 -0
+
+	/*
+	 * If the manufacturer string is "QEMU" in EBCDIC, then we are on TCG
+	 * (otherwise the string is "IBM" in EBCDIC)
+	 */
+	if (!memcmp(&buf[32], qemu_ebcdic, sizeof(qemu_ebcdic)))
+		ret =  true;
+out:
+	free_page(buf);
+	return ret;
+}
+
+
 int main(void)
 {
 	int i;

s390x/cpumodel.c int main(void) · line 82

Quoted 2 lines
s390x/cpumodel.c +0 -0
@@ -46,11 +81,13 @@ int main(void)
 
 	report_prefix_push("dependency");

...so maybe cache the value for is_tcg() here instead of checking multiple times in the loop?

Quoted 8 lines
Quoted 4 lines

Maybe move it to common code and do the detection early during boot? The n provide is_tcg() or sth. like that. Could be helpful in other context maybe.

Well we also already have a check for zvm 6 with stsi 3.2.2 in skey.c I'm not completely convinced that I want to loose two pages and a few cycles on every startup for two separate test cases.

It certainly does not make sense to run the stsi calls during each and every startup ... but I can move the is_tcg() function to the library and make it a little bit smarter. I'll prepare a v3...

Thomas