x86: make hypervisor build with gcc11
authorJan Beulich <jbeulich@suse.com>
Fri, 4 Jun 2021 12:56:19 +0000 (14:56 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 4 Jun 2021 12:56:19 +0000 (14:56 +0200)
Gcc 11 looks to make incorrect assumptions about valid ranges that
pointers may be used for addressing when they are derived from e.g. a
plain constant. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100680.

Utilize RELOC_HIDE() to work around the issue, which for x86 manifests
in at least
- mpparse.c:efi_check_config(),
- tboot.c:tboot_probe(),
- tboot.c:tboot_gen_frametable_integrity(),
- x86_emulate.c:x86_emulate() (at -O2 only).
The last case is particularly odd not just because it only triggers at
higher optimization levels, but also because it only affects one of at
least three similar constructs. Various "note" diagnostics claim the
valid index range to be [0, 2⁶³-1].

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Jason Andryuk <jandryuk@gmail.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
master commit: 722f59d38c710a940ab05e542a83020eb5546dea
master date: 2021-05-27 14:40:29 +0200

tools/tests/x86_emulator/x86-emulate.c
xen/arch/x86/x86_emulate/x86_emulate.c
xen/include/asm-x86/fixmap.h
xen/include/xen/compiler.h
xen/include/xen/pdx.h

index 572989078a64d53a7850d8c456040189a185ed3d..c32d9a55b49fca5888ef3fa2cb40251ac410a8d4 100644 (file)
@@ -8,6 +8,13 @@
 
 #define ERR_PTR(val) NULL
 
+/* See gcc bug 100680, but here don't bother making this version dependent. */
+#define gcc11_wrap(x) ({                  \
+    unsigned long x_;                     \
+    __asm__ ( "" : "=g" (x_) : "0" (x) ); \
+    (typeof(x))x_;                        \
+})
+
 #define cpu_has_amd_erratum(nr) 0
 #define cpu_has_mpx false
 #define read_bndcfgu() 0
index 8ef66d824db1780e75764904a3add40ff9ffe2a3..16d164904cee1fce8b9ea8f436f38ac2b38287c3 100644 (file)
@@ -725,7 +725,7 @@ union vex {
 #define copy_VEX(ptr, vex) ({ \
     if ( !mode_64bit() ) \
         (vex).reg |= 8; \
-    (ptr)[0 - PFX_BYTES] = ext < ext_8f08 ? 0xc4 : 0x8f; \
+    gcc11_wrap(ptr)[0 - PFX_BYTES] = ext < ext_8f08 ? 0xc4 : 0x8f; \
     (ptr)[1 - PFX_BYTES] = (vex).raw[0]; \
     (ptr)[2 - PFX_BYTES] = (vex).raw[1]; \
     container_of((ptr) + 1 - PFX_BYTES, typeof(vex), raw[0]); \
index 8330097a74bc0a08ec6cebcd63da695f4f9c4657..22afb92ff05a7c7586f06cc429c95eb0237cff22 100644 (file)
@@ -79,7 +79,7 @@ extern void __set_fixmap(
 
 #define clear_fixmap(idx) __set_fixmap(idx, 0, 0)
 
-#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __fix_to_virt(x) gcc11_wrap(FIXADDR_TOP - ((x) << PAGE_SHIFT))
 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
 
 #define fix_to_virt(x)   ((void *)__fix_to_virt(x))
index c0e0ee9f27be1807bb2112576c68f36ae04e7753..eb819fab46ec5d642b92737e6aa8bad6057d7e15 100644 (file)
     __asm__ ("" : "=r"(__ptr) : "0"(ptr));      \
     (typeof(ptr)) (__ptr + (off)); })
 
+#if CONFIG_GCC_VERSION >= 110000 /* See gcc bug 100680. */
+# define gcc11_wrap(x) RELOC_HIDE(x, 0)
+#else
+# define gcc11_wrap(x) (x)
+#endif
+
 #ifdef __GCC_ASM_FLAG_OUTPUTS__
 # define ASM_FLAG_OUT(yes, no) yes
 #else
index 770fadc06cce3511df17de3ffdba8b9f89852e0d..9fcfb0ce52d6edd5681265439cee8bc2ed6c3808 100644 (file)
@@ -19,7 +19,7 @@ extern u64 pdx_region_mask(u64 base, u64 len);
 extern void set_pdx_range(unsigned long smfn, unsigned long emfn);
 
 #define page_to_pdx(pg)  ((pg) - frame_table)
-#define pdx_to_page(pdx) (frame_table + (pdx))
+#define pdx_to_page(pdx) gcc11_wrap(frame_table + (pdx))
 
 bool __mfn_valid(unsigned long mfn);