new file mode 100644
@@ -0,0 +1,46 @@
+/*
+ * Functions to retrieve VM-specific information
+ *
+ * Copyright (c) 2020 Red Hat Inc
+ *
+ * Authors:
+ * Thomas Huth <thuth@redhat.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include <libcflat.h>
+#include <alloc_page.h>
+#include <asm/arch_def.h>
+#include "vm.h"
+
+/**
+ * Detect whether we are running with TCG (instead of KVM)
+ */
+bool vm_is_tcg(void)
+{
+ const char qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
+ static bool initialized = false;
+ static bool is_tcg = false;
+ uint8_t *buf;
+
+ if (initialized)
+ return is_tcg;
+
+ 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)
+ */
+ is_tcg = !memcmp(&buf[32], qemu_ebcdic, sizeof(qemu_ebcdic));
+ initialized = true;
+out:
+ free_page(buf);
+ return is_tcg;
+}
new file mode 100644
@@ -0,0 +1,14 @@
+/*
+ * Functions to retrieve VM-specific information
+ *
+ * Copyright (c) 2020 Red Hat Inc
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef S390X_VM_H
+#define S390X_VM_H
+
+bool vm_is_tcg(void);
+
+#endif /* S390X_VM_H */
@@ -51,6 +51,7 @@ cflatobjs += lib/s390x/sclp-console.o
cflatobjs += lib/s390x/interrupt.o
cflatobjs += lib/s390x/mmu.o
cflatobjs += lib/s390x/smp.o
+cflatobjs += lib/s390x/vm.o
OBJDIRS += lib/s390x
@@ -11,14 +11,19 @@
*/
#include <asm/facility.h>
+#include <vm.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 },
@@ -46,11 +51,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 && vm_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();