[PATCH kvm-unit-tests] x86: add tests for MSR_IA32_TSX_CTRL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 lib/x86/msr.h       | 14 +++++++++++++
 lib/x86/processor.h |  2 ++
 x86/Makefile.common |  2 +-
 x86/tsx-ctrl.c      | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 x86/vmexit.c        | 12 +++++++++++
 5 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 x86/tsx-ctrl.c

diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index abf0d93..8dca964 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -221,6 +221,20 @@
 #define MSR_IA32_UCODE_WRITE		0x00000079
 #define MSR_IA32_UCODE_REV		0x0000008b
 
+#define MSR_IA32_ARCH_CAPABILITIES	0x0000010a
+#define ARCH_CAP_RDCL_NO		(1ULL << 0)
+#define ARCH_CAP_IBRS_ALL		(1ULL << 1)
+#define ARCH_CAP_SKIP_VMENTRY_L1DFLUSH	(1ULL << 3)
+#define ARCH_CAP_SSB_NO			(1ULL << 4)
+#define ARCH_CAP_MDS_NO			(1ULL << 5)
+#define ARCH_CAP_PSCHANGE_MC_NO		(1ULL << 6)
+#define ARCH_CAP_TSX_CTRL_MSR		(1ULL << 7)
+#define ARCH_CAP_TAA_NO			(1ULL << 8)
+
+#define MSR_IA32_TSX_CTRL		0x00000122
+#define TSX_CTRL_RTM_DISABLE		(1ULL << 0)
+#define TSX_CTRL_CPUID_CLEAR		(1ULL << 1)
+
 #define MSR_IA32_PERF_STATUS		0x00000198
 #define MSR_IA32_PERF_CTL		0x00000199
 
diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 3f461dc..7057180 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -137,6 +137,7 @@ static inline u8 cpuid_maxphyaddr(void)
 #define	X86_FEATURE_XMM			(CPUID(0x1, 0, EDX, 25))
 #define	X86_FEATURE_XMM2		(CPUID(0x1, 0, EDX, 26))
 #define	X86_FEATURE_TSC_ADJUST		(CPUID(0x7, 0, EBX, 1))
+#define	X86_FEATURE_HLE			(CPUID(0x7, 0, EBX, 4))
 #define	X86_FEATURE_INVPCID_SINGLE	(CPUID(0x7, 0, EBX, 7))
 #define	X86_FEATURE_INVPCID		(CPUID(0x7, 0, EBX, 10))
 #define	X86_FEATURE_RTM			(CPUID(0x7, 0, EBX, 11))
@@ -149,6 +150,7 @@ static inline u8 cpuid_maxphyaddr(void)
 #define	X86_FEATURE_LA57		(CPUID(0x7, 0, ECX, 16))
 #define	X86_FEATURE_RDPID		(CPUID(0x7, 0, ECX, 22))
 #define	X86_FEATURE_SPEC_CTRL		(CPUID(0x7, 0, EDX, 26))
+#define	X86_FEATURE_ARCH_CAPABILITIES	(CPUID(0x7, 0, EDX, 29))
 #define	X86_FEATURE_NX			(CPUID(0x80000001, 0, EDX, 20))
 #define	X86_FEATURE_RDPRU		(CPUID(0x80000008, 0, EBX, 4))
 
diff --git a/x86/Makefile.common b/x86/Makefile.common
index e612dbe..b157154 100644
--- a/x86/Makefile.common
+++ b/x86/Makefile.common
@@ -58,7 +58,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
                $(TEST_DIR)/init.flat $(TEST_DIR)/smap.flat \
                $(TEST_DIR)/hyperv_synic.flat $(TEST_DIR)/hyperv_stimer.flat \
                $(TEST_DIR)/hyperv_connections.flat \
-               $(TEST_DIR)/umip.flat
+               $(TEST_DIR)/umip.flat $(TEST_DIR)/tsx-ctrl.flat
 
 ifdef API
 tests-api = api/api-sample api/dirty-log api/dirty-log-perf
diff --git a/x86/tsx-ctrl.c b/x86/tsx-ctrl.c
new file mode 100644
index 0000000..f482cb5
--- /dev/null
+++ b/x86/tsx-ctrl.c
@@ -0,0 +1,60 @@
+/* TSX tests */
+
+#include "libcflat.h"
+#include "processor.h"
+#include "msr.h"
+
+static bool try_transaction(void)
+{
+    unsigned x;
+    int i;
+
+    for (i = 0; i < 100; i++) {
+        x = 0;
+        /*
+         * The value before the transaction is important, so make the
+         * operand input/output.
+         */
+        asm volatile("xbegin 2f; movb $1, %0; xend; 2:" : "+m" (x) : : "eax");
+        if (x) {
+            return true;
+        }
+    }
+    return false;
+}
+
+int main(int ac, char **av)
+{
+    if (!this_cpu_has(X86_FEATURE_RTM)) {
+        report_skip("TSX not available");
+	return 0;
+    }
+    if (!this_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) {
+        report_skip("ARCH_CAPABILITIES not available");
+	return 0;
+    }
+    if (!(rdmsr(MSR_IA32_ARCH_CAPABILITIES) & ARCH_CAP_TSX_CTRL_MSR)) {
+        report_skip("TSX_CTRL not available");
+	return 0;
+    }
+
+    report("TSX_CTRL should be 0", rdmsr(MSR_IA32_TSX_CTRL) == 0);
+    report("Transactions do not abort", try_transaction());
+
+    wrmsr(MSR_IA32_TSX_CTRL, TSX_CTRL_CPUID_CLEAR);
+    report("TSX_CTRL hides RTM", !this_cpu_has(X86_FEATURE_RTM));
+    report("TSX_CTRL hides HLE", !this_cpu_has(X86_FEATURE_HLE));
+
+    /* Microcode might hide HLE unconditionally */
+    wrmsr(MSR_IA32_TSX_CTRL, 0);
+    report("TSX_CTRL=0 unhides RTM", this_cpu_has(X86_FEATURE_RTM));
+
+    wrmsr(MSR_IA32_TSX_CTRL, TSX_CTRL_RTM_DISABLE);
+    report("TSX_CTRL causes transactions to abort", !try_transaction());
+
+    wrmsr(MSR_IA32_TSX_CTRL, 0);
+    report("TSX_CTRL=0 causes transactions to succeed", try_transaction());
+
+    return report_summary();
+}
+
diff --git a/x86/vmexit.c b/x86/vmexit.c
index 81b743b..acdcbdc 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -434,6 +434,17 @@ static void tscdeadline(void)
 	while (x == 0) barrier();
 }
 
+static void wr_tsx_ctrl_msr(void)
+{
+	wrmsr(MSR_IA32_TSX_CTRL, 0);
+}
+
+static int has_tsx_ctrl(void)
+{
+    return this_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)
+	    && (rdmsr(MSR_IA32_ARCH_CAPABILITIES) & ARCH_CAP_TSX_CTRL_MSR);
+}
+
 static void wr_ibrs_msr(void)
 {
 	wrmsr(MSR_IA32_SPEC_CTRL, 1);
@@ -478,6 +489,7 @@ static struct test tests[] = {
 	{ ipi_halt, "ipi_halt", is_smp, .parallel = 0, },
 	{ ple_round_robin, "ple_round_robin", .parallel = 1 },
 	{ wr_kernel_gs_base, "wr_kernel_gs_base", .parallel = 1 },
+	{ wr_tsx_ctrl_msr, "wr_tsx_ctrl_msr", has_tsx_ctrl, .parallel = 1, },
 	{ wr_ibrs_msr, "wr_ibrs_msr", has_spec_ctrl, .parallel = 1 },
 	{ wr_ibpb_msr, "wr_ibpb_msr", has_ibpb, .parallel = 1 },
 	{ wr_tsc_adjust_msr, "wr_tsc_adjust_msr", .parallel = 1 },
-- 
1.8.3.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux