[kvm-unit-tests PATCH 04/10] x86: Use "safe" helpers to implement unsafe CRs accessors

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

 



Use the "safe" helpers to read and write CR0, CR3, and CR4, so that an
unexpected fault results in a detailed message instead of an generic
"unexpected fault" explosion.

Do not give RDMSR/WRMSR the same treatment.  KUT's exception fixup uses
per-CPU data and thus needs a stable GS.base.  Various tests modify
MSR_GS_BASE and routing them through the safe variants will cause
fireworks when trying to clear/read the exception vector with a garbage
GS.base.

Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
 lib/x86/desc.c      |  8 --------
 lib/x86/desc.h      |  1 -
 lib/x86/processor.h | 45 ++++++++++++++++++++++++++++++++++++++++++---
 x86/pcid.c          |  8 --------
 4 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/lib/x86/desc.c b/lib/x86/desc.c
index ff9bd6b7..7620dc81 100644
--- a/lib/x86/desc.c
+++ b/lib/x86/desc.c
@@ -299,14 +299,6 @@ unsigned exception_vector(void)
 	return this_cpu_read_exception_vector();
 }
 
-int write_cr4_safe(unsigned long val)
-{
-	asm volatile(ASM_TRY("1f")
-		"mov %0,%%cr4\n\t"
-		"1:": : "r" (val));
-	return exception_vector();
-}
-
 unsigned exception_error_code(void)
 {
 	return this_cpu_read_exception_error_code();
diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index 0bd44445..ac843c35 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -213,7 +213,6 @@ extern tss64_t tss[];
 extern gdt_entry_t gdt[];
 
 unsigned exception_vector(void);
-int write_cr4_safe(unsigned long val);
 unsigned exception_error_code(void);
 bool exception_rflags_rf(void);
 void set_idt_entry(int vec, void *addr, int dpl);
diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index e169aac8..bc6c8d94 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -341,6 +341,12 @@ static inline void set_iopl(int iopl)
 	write_rflags(flags);
 }
 
+/*
+ * Don't use the safe variants for rdmsr() or wrmsr().  The exception fixup
+ * infrastructure uses per-CPU data and thus consumes GS.base.  Various tests
+ * temporarily modify MSR_GS_BASE and will explode when trying to determine
+ * whether or not RDMSR/WRMSR faulted.
+ */
 static inline u64 rdmsr(u32 index)
 {
 	u32 a, d;
@@ -381,9 +387,20 @@ static inline uint64_t rdpmc(uint32_t index)
 	return a | ((uint64_t)d << 32);
 }
 
+static inline int write_cr0_safe(ulong val)
+{
+	asm volatile(ASM_TRY("1f")
+		     "mov %0,%%cr0\n\t"
+		     "1:": : "r" (val));
+	return exception_vector();
+}
+
 static inline void write_cr0(ulong val)
 {
-	asm volatile ("mov %0, %%cr0" : : "r"(val) : "memory");
+	int vector = write_cr0_safe(val);
+
+	assert_msg(!vector, "Unexpected fault '%d' writing CR0 = %lx",
+		   vector, val);
 }
 
 static inline ulong read_cr0(void)
@@ -405,9 +422,20 @@ static inline ulong read_cr2(void)
 	return val;
 }
 
+static inline int write_cr3_safe(ulong val)
+{
+	asm volatile(ASM_TRY("1f")
+		     "mov %0,%%cr3\n\t"
+		     "1:": : "r" (val));
+	return exception_vector();
+}
+
 static inline void write_cr3(ulong val)
 {
-	asm volatile ("mov %0, %%cr3" : : "r"(val) : "memory");
+	int vector = write_cr3_safe(val);
+
+	assert_msg(!vector, "Unexpected fault '%d' writing CR3 = %lx",
+		   vector, val);
 }
 
 static inline ulong read_cr3(void)
@@ -422,9 +450,20 @@ static inline void update_cr3(void *cr3)
 	write_cr3((ulong)cr3);
 }
 
+static inline int write_cr4_safe(ulong val)
+{
+	asm volatile(ASM_TRY("1f")
+		     "mov %0,%%cr4\n\t"
+		     "1:": : "r" (val));
+	return exception_vector();
+}
+
 static inline void write_cr4(ulong val)
 {
-	asm volatile ("mov %0, %%cr4" : : "r"(val) : "memory");
+	int vector = write_cr4_safe(val);
+
+	assert_msg(!vector, "Unexpected fault '%d' writing CR4 = %lx",
+		   vector, val);
 }
 
 static inline ulong read_cr4(void)
diff --git a/x86/pcid.c b/x86/pcid.c
index 5e08f576..4dfc6fd0 100644
--- a/x86/pcid.c
+++ b/x86/pcid.c
@@ -10,14 +10,6 @@ struct invpcid_desc {
     u64 addr : 64;
 };
 
-static int write_cr0_safe(unsigned long val)
-{
-    asm volatile(ASM_TRY("1f")
-                 "mov %0, %%cr0\n\t"
-                 "1:": : "r" (val));
-    return exception_vector();
-}
-
 static int invpcid_safe(unsigned long type, void *desc)
 {
     asm volatile (ASM_TRY("1f")
-- 
2.36.1.255.ge46751e96f-goog




[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