@@ -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
@@ -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
new file mode 100644
@@ -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();
+}
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