]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
Fix asm constraints for push/pop instructions
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 17 Feb 2020 09:48:26 +0000 (09:48 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 17 Feb 2020 13:45:49 +0000 (13:45 +0000)
There are several issues with 64bit builds.  Correct the types/constraints to
prohibit encoding 32bit registers, and immediates which can't be represented
as a 32bit signed extended number.

Introduce asm_checks() in selftest as a build-time check for constraint corner
cases, to be extended as needed.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/include/arch/lib.h
tests/selftest/main.c

index 0259c2ed7525c348c11fc735ae951e99d41573be..4046b9c67d92fad2d7bb9ff508015e69187dc233 100644 (file)
@@ -175,7 +175,7 @@ static inline unsigned int read_ss(void)
     return ss;
 }
 
-static inline void write_cs(unsigned int cs)
+static inline void write_cs(unsigned long cs)
 {
     asm volatile ("push %0;"
                   "push $1f;"
@@ -183,7 +183,7 @@ static inline void write_cs(unsigned int cs)
                   "rex64 "
 #endif
                   "lret; 1:"
-                  :: "qI" (cs));
+                  :: "rme" (cs));
 }
 
 static inline void write_ds(unsigned int ds)
@@ -211,18 +211,18 @@ static inline void write_ss(unsigned int ss)
     asm volatile ("mov %0, %%ss" :: "rm" (ss));
 }
 
-static inline unsigned int read_flags(void)
+static inline unsigned long read_flags(void)
 {
-    unsigned int flags;
+    unsigned long flags;
 
     asm volatile ("pushf; pop %0" : "=rm" (flags));
 
     return flags;
 }
 
-static inline void write_flags(unsigned int flags)
+static inline void write_flags(unsigned long flags)
 {
-    asm volatile ("push %0; popf" :: "irm" (flags));
+    asm volatile ("push %0; popf" :: "rme" (flags));
 }
 
 static inline unsigned long read_cr0(void)
index a376df38c12018688c3ab26049dab60d298076de..c2f6e727fd3080660a4ec8fb1c404f7ca47a15f3 100644 (file)
@@ -375,6 +375,28 @@ void test_main(void)
     xtf_success(NULL);
 }
 
+/*
+ * Inline assembly checks.
+ *
+ * Needs to be written out into an object file to cause build failures.
+ * Nothing executes the resulting code.
+ *
+ * - push/pop %reg need to use unsigned long types to avoid trying to allocate
+ *   32bit registers, which aren't encodable in 64bit.
+ * - push $imm can't encode 64bit integers (only 32bit sign extended)
+ */
+static void __used asm_checks(void)
+{
+    read_flags();
+
+#ifdef __x86_64__
+    unsigned long tmp = 0xdead0000c0deULL;
+
+    write_flags(tmp);
+    write_cs(tmp);
+#endif
+}
+
 /*
  * Local variables:
  * mode: C