xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] libx86: Work around GCC bug with ebx output constrants
@ 2018-11-19 13:11 Andrew Cooper
  2018-11-19 13:29 ` Andrew Cooper
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Andrew Cooper @ 2018-11-19 13:11 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, Roger Pau Monné

Some versions of GCC can't compile cpuid.c, and fail with the rather cryptic:

  In file included from lib/x86/cpuid.c:3:0:
  lib/x86/cpuid.c: In function ‘x86_cpuid_policy_fill_native’:
  include/xen/lib/x86/cpuid.h:25:5: error: inconsistent operand constraints in an ‘asm’
       asm ( "cpuid"
       ^

In practice, this is a collision between the output constraint and the GOT
which is held in %ebx when compiling with -fPIC for libraries.

This affects at least GCC 4.9 as shipped in Debian Jessie, but experimentally
is fixed in GCC 6 and later.  Curiously, it only affects 32-bit builds.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
---
 xen/include/xen/lib/x86/cpuid.h | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/xen/include/xen/lib/x86/cpuid.h b/xen/include/xen/lib/x86/cpuid.h
index 266c910..77f63d5 100644
--- a/xen/include/xen/lib/x86/cpuid.h
+++ b/xen/include/xen/lib/x86/cpuid.h
@@ -20,21 +20,48 @@ struct cpuid_leaf
     uint32_t a, b, c, d;
 };
 
+/*
+ * Some versions of GCC are unable to cope with preserving the GOT (held in
+ * %ebx) around an asm() with an %ebx output constraint, and produce a rather
+ * cryptic error:
+ *    error: inconsistent operand constraints in an ‘asm’
+ *
+ * Experimentally, 64-bit builds work correctly, and 32-bit builds on GCC 6 or
+ * later work correctly.
+ *
+ * To work around the issue, use a separate register to hold the the ebx
+ * output, and xchg twice to leave %ebx preserved around the asm() statement.
+ */
+#if __PIC__ && __i386__ && __GNUC__ < 6 && !__clang__
+#define XCHG_BX "xchg %%ebx, %k[bx];"
+#define BX_CON [bx] "=&r"
+#else
+#define XCHG_BX ""
+#define BX_CON "=b"
+#endif
+
 static inline void cpuid_leaf(uint32_t leaf, struct cpuid_leaf *l)
 {
-    asm ( "cpuid"
-          : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
+    asm ( XCHG_BX
+          "cpuid;"
+          XCHG_BX
+          : "=a" (l->a), BX_CON (l->b), "=c" (l->c), "=d" (l->d)
           : "a" (leaf) );
 }
 
 static inline void cpuid_count_leaf(
     uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *l)
 {
-    asm ( "cpuid"
-          : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
+    asm ( XCHG_BX
+          "cpuid;"
+          XCHG_BX
+          : "=a" (l->a), BX_CON (l->b), "=c" (l->c), "=d" (l->d)
           : "a" (leaf), "c" (subleaf) );
 }
 
+#undef BX_CON
+#undef XCHG
+
 #define CPUID_GUEST_NR_BASIC      (0xdu + 1)
 #define CPUID_GUEST_NR_FEAT       (0u + 1)
 #define CPUID_GUEST_NR_CACHE      (5u + 1)
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-11-19 15:30 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-19 13:11 [PATCH] libx86: Work around GCC bug with ebx output constrants Andrew Cooper
2018-11-19 13:29 ` Andrew Cooper
2018-11-19 14:52   ` Mihai Donțu
2018-11-19 15:00     ` Andrew Cooper
2018-11-19 13:51 ` Jan Beulich
2018-11-19 14:08   ` Andrew Cooper
2018-11-19 14:21     ` Jan Beulich
2018-11-19 14:23     ` Jan Beulich
2018-11-19 14:24       ` Andrew Cooper
2018-11-19 14:33   ` Andrew Cooper
2018-11-19 14:38     ` Jan Beulich
2018-11-19 14:45 ` [PATCH v2] " Andrew Cooper
2018-11-19 15:14   ` Jan Beulich
2018-11-19 15:19     ` Andrew Cooper
2018-11-19 15:30       ` Jan Beulich
2018-11-19 15:13 ` [PATCH v3] libx86: Work around GCC being unable to spill the PIC hard register Andrew Cooper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).