x86: make hypervisor build with gcc11

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: 722f59d38c
master date: 2021-05-27 14:40:29 +0200
This commit is contained in:
Jan Beulich committed 2021-08-25 15:43:57 +02:00
1 parent 7dadebd8d2
commit bd52c7e902
5 files changed
+16 -3

No files matched your search

+7
View File
@@ -2,6 +2,13 @@
#include <sys/mman.h>
/* 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
+1 -1
View File
@@ -644,7 +644,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]); \
+1 -1
View File
@@ -80,7 +80,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))
+6
View File
@@ -99,6 +99,12 @@
__asm__ ("" : "=r"(__ptr) : "0"(ptr)); \
(typeof(ptr)) (__ptr + (off)); })
#if __GNUC__ >= 11 /* 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
+1 -1
View 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);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.