diff mbox series

[kvm-unit-tests] x86: Add test for split lock detection

Message ID 20190304110547.68324-1-xiaoyao.li@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series [kvm-unit-tests] x86: Add test for split lock detection | expand

Commit Message

Xiaoyao Li March 4, 2019, 11:05 a.m. UTC
Add x86/split_lock_detect.c and update lib/x86/msr.h to include
split lock detection related MSR definitions.

About split lock detection feature, ralated kernel patches:
https://lkml.org/lkml/2019/3/1/749
related qemu patches:
https://lists.gnu.org/archive/html/qemu-devel/2019-03/msg00507.html

Signed-off-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
---
 lib/x86/msr.h           |  6 ++++
 x86/Makefile.common     |  2 +-
 x86/split_lock_detect.c | 66 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 1 deletion(-)
 create mode 100644 x86/split_lock_detect.c

Comments

Paolo Bonzini March 4, 2019, 12:18 p.m. UTC | #1
On 04/03/19 12:05, Xiaoyao Li wrote:
> +
> +static void ac_handler(struct ex_regs *regs) {
> +	report("Caught #AC exception because of split locked accesses", true);

If split lock detection does not work, this would not fail.  You can
just set a boolean here, and in main pass it to "report".

Paolo

> +	/* disable split lock detection */
> +	wrmsr(MSR_TEST_CTL, rdmsr(MSR_TEST_CTL) & ~TEST_CTL_ENABLE_SPLIT_LOCK_DETECT);
Xiaoyao Li March 4, 2019, 12:30 p.m. UTC | #2
On Mon, 2019-03-04 at 13:18 +0100, Paolo Bonzini wrote:
> On 04/03/19 12:05, Xiaoyao Li wrote:
> > +
> > +static void ac_handler(struct ex_regs *regs) {
> > +	report("Caught #AC exception because of split locked accesses", true);
> 
> If split lock detection does not work, this would not fail.  You can
> just set a boolean here, and in main pass it to "report".
> 
> Paolo

Thanks for pointing out this. I'll correct it in next version.

> > +	/* disable split lock detection */
> > +	wrmsr(MSR_TEST_CTL, rdmsr(MSR_TEST_CTL) &
> > ~TEST_CTL_ENABLE_SPLIT_LOCK_DETECT);
> 
>
diff mbox series

Patch

diff --git a/lib/x86/msr.h b/lib/x86/msr.h
index abf0d93..42818e5 100644
--- a/lib/x86/msr.h
+++ b/lib/x86/msr.h
@@ -32,6 +32,9 @@ 
 #define EFER_FFXSR		(1<<_EFER_FFXSR)
 
 /* Intel MSRs. Some also available on other CPUs */
+#define MSR_TEST_CTL			0x00000033
+#define TEST_CTL_ENABLE_SPLIT_LOCK_DETECT	(1UL << 29)
+
 #define MSR_IA32_SPEC_CTRL              0x00000048
 #define MSR_IA32_PRED_CMD               0x00000049
 
@@ -39,6 +42,9 @@ 
 #define MSR_IA32_PERFCTR1		0x000000c2
 #define MSR_FSB_FREQ			0x000000cd
 
+#define MSR_IA32_CORE_CAPABILITY	0x000000cf
+#define CORE_CAP_SPLIT_LOCK_DETECT	(1UL << 5)
+
 #define MSR_MTRRcap			0x000000fe
 #define MSR_IA32_BBL_CR_CTL		0x00000119
 
diff --git a/x86/Makefile.common b/x86/Makefile.common
index e612dbe..209f495 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)/split_lock_detect.flat
 
 ifdef API
 tests-api = api/api-sample api/dirty-log api/dirty-log-perf
diff --git a/x86/split_lock_detect.c b/x86/split_lock_detect.c
new file mode 100644
index 0000000..2184e2c
--- /dev/null
+++ b/x86/split_lock_detect.c
@@ -0,0 +1,66 @@ 
+#include <libcflat.h>
+#include <alloc.h>
+#include <processor.h>
+#include <desc.h>
+
+#define CPUID_80000006_ECX_CACHE_LINE_SIZE      0x000000FF
+#define CPUID_7_EDX_CORE_CAPABILITY		(1 << 30)
+
+
+static inline u32 get_cache_line_size(void)
+{
+        return (cpuid(0x80000006).c & CPUID_80000006_ECX_CACHE_LINE_SIZE);
+}
+
+static void ac_handler(struct ex_regs *regs) {
+	report("Caught #AC exception because of split locked accesses", true);
+
+	/* disable split lock detection */
+	wrmsr(MSR_TEST_CTL, rdmsr(MSR_TEST_CTL) & ~TEST_CTL_ENABLE_SPLIT_LOCK_DETECT);
+}
+
+static void do_split_locked_testcase(u32 cache_line_size)
+{
+	unsigned char * buffer;
+	int * int_ptr;
+
+	/* alloc a cache_line_zise aligned memory */
+	buffer = (unsigned char *) memalign(cache_line_size, 2 * cache_line_size);
+
+	/* Increment the pointer by 63, making it misaligned */
+	int_ptr = (int *) (buffer + 63);
+
+	asm volatile(
+		"lock; addl $1,%0\n\t"
+		: "+m" (*int_ptr)
+		:
+		: "memory"
+		);
+}
+
+int main(void)
+{
+	if (!(cpuid(0x7).d & CPUID_7_EDX_CORE_CAPABILITY)) {
+		report("MSR_IA32_CORE_CAPABILITY is not available", false);
+		return report_summary();
+	} else {
+		printf("MSR_IA32_CORE_CAPABILITY is available\n");
+	}
+
+	if(!(rdmsr(MSR_IA32_CORE_CAPABILITY) & CORE_CAP_SPLIT_LOCK_DETECT)) {
+		report("Split Lock Detection feature is not available", false);
+		return report_summary();
+	} else {
+		printf("Split Lock Detection feature is available\n");
+	}
+
+	setup_idt();
+	handle_exception(AC_VECTOR, ac_handler);
+
+	/* enalbe split lock detection */
+	wrmsr(MSR_TEST_CTL, rdmsr(MSR_TEST_CTL) | TEST_CTL_ENABLE_SPLIT_LOCK_DETECT);
+
+	do_split_locked_testcase(get_cache_line_size());
+
+	return report_summary();
+}