[PATCH kvm-unit-tests] x86: use asm volatile for flags and segment register read/writes

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

 



The effects of a move from or to these registers is not entirely described
by the asm's operands.  Therefore, it may happen that the compiler
moves the asm around in ways that break tests.

In one case, the compiler marked read_ss() as pure and thus subjected
it to common subexpression elimination:

    u16 ss = read_ss();

    // check for null segment load
    *mem = 0;
    asm volatile("mov %0, %%ss" : : "m"(*mem));
    report("mov null, %%ss", read_ss() == 0);

This caused a spurious failure of the test.

Reported-by: Lucas Meneguel Rodrigues <lmr@xxxxxxxxxxxx>
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 lib/x86/processor.h | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 1816807..95cea1a 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -61,7 +61,7 @@ static inline u16 read_cs(void)
 {
     unsigned val;
 
-    asm ("mov %%cs, %0" : "=mr"(val));
+    asm volatile ("mov %%cs, %0" : "=mr"(val));
     return val;
 }
 
@@ -69,7 +69,7 @@ static inline u16 read_ds(void)
 {
     unsigned val;
 
-    asm ("mov %%ds, %0" : "=mr"(val));
+    asm volatile ("mov %%ds, %0" : "=mr"(val));
     return val;
 }
 
@@ -77,7 +77,7 @@ static inline u16 read_es(void)
 {
     unsigned val;
 
-    asm ("mov %%es, %0" : "=mr"(val));
+    asm volatile ("mov %%es, %0" : "=mr"(val));
     return val;
 }
 
@@ -85,7 +85,7 @@ static inline u16 read_ss(void)
 {
     unsigned val;
 
-    asm ("mov %%ss, %0" : "=mr"(val));
+    asm volatile ("mov %%ss, %0" : "=mr"(val));
     return val;
 }
 
@@ -93,7 +93,7 @@ static inline u16 read_fs(void)
 {
     unsigned val;
 
-    asm ("mov %%fs, %0" : "=mr"(val));
+    asm volatile ("mov %%fs, %0" : "=mr"(val));
     return val;
 }
 
@@ -101,45 +101,45 @@ static inline u16 read_gs(void)
 {
     unsigned val;
 
-    asm ("mov %%gs, %0" : "=mr"(val));
+    asm volatile ("mov %%gs, %0" : "=mr"(val));
     return val;
 }
 
 static inline unsigned long read_rflags(void)
 {
 	unsigned long f;
-	asm ("pushf; pop %0\n\t" : "=rm"(f));
+	asm volatile ("pushf; pop %0\n\t" : "=rm"(f));
 	return f;
 }
 
 static inline void write_ds(unsigned val)
 {
-    asm ("mov %0, %%ds" : : "rm"(val) : "memory");
+    asm volatile ("mov %0, %%ds" : : "rm"(val) : "memory");
 }
 
 static inline void write_es(unsigned val)
 {
-    asm ("mov %0, %%es" : : "rm"(val) : "memory");
+    asm volatile ("mov %0, %%es" : : "rm"(val) : "memory");
 }
 
 static inline void write_ss(unsigned val)
 {
-    asm ("mov %0, %%ss" : : "rm"(val) : "memory");
+    asm volatile ("mov %0, %%ss" : : "rm"(val) : "memory");
 }
 
 static inline void write_fs(unsigned val)
 {
-    asm ("mov %0, %%fs" : : "rm"(val) : "memory");
+    asm volatile ("mov %0, %%fs" : : "rm"(val) : "memory");
 }
 
 static inline void write_gs(unsigned val)
 {
-    asm ("mov %0, %%gs" : : "rm"(val) : "memory");
+    asm volatile ("mov %0, %%gs" : : "rm"(val) : "memory");
 }
 
 static inline void write_rflags(unsigned long f)
 {
-	asm ("push %0; popf\n\t" : : "rm"(f));
+    asm volatile ("push %0; popf\n\t" : : "rm"(f));
 }
 
 static inline u64 rdmsr(u32 index)
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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