From d6fbf061e79a3d37e30c1b1e97c773e583c2176a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 18 Jan 2012 10:04:48 +0100 Subject: [PATCH] kvm tools: Fix build breakage with GCC 4.7 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * Pekka Enberg wrote: > >In file included from virtio/net.c:3:0: > >include/kvm/virtio.h: In function ‘virt_queue__available’: > >include/kvm/virtio.h:42:2: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] > It's tools/kvm/include/kvm/virtio.h: > > static inline bool virt_queue__available(struct virt_queue *vq) > { > if (!vq->vring.avail) > return 0; > > vring_avail_event(&vq->vring) = vq->last_avail_idx; > return vq->vring.avail->idx != vq->last_avail_idx; > } > > and include/linux/virtio_ring.h: > > #define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num]) > > I'm not sure what GCC thinks is wrong there... i suspect the contrast might be from casting a 'struct vring_used_elem's 'id' field to type '__u16 *' and dereferencing it might break GCC alias optimizations, as it makes two uses of the 'num' field - one the regular 32-bit usage, the other this weird 16-bit usage. I think the only sane way to solve this is to do what the kernel does, to turn off strict aliasing. The patch below does this and resolves the build bug. Note: i also switched optimization from -Os to -O2 - the latter is generally the better option for performance critical code. -Os sometimes produces really weird code. The other build problem is that it appears the default GCC regparm model changed, which highlighted this prototype bug: x86/bios/e820.c:32:15: error: conflicting types for ‘e820_query_map’ In file included from x86/bios/e820.c:1:0: include/kvm/e820.h:10:6: note: previous declaration of ‘e820_query_map’ was here and there are similar problems with other BIOS prototypes. Resolved via the other bits in the patch below. Signed-off-by: Ingo Molnar Signed-off-by: Pekka Enberg --- tools/kvm/Makefile | 2 +- tools/kvm/include/kvm/e820.h | 3 ++- tools/kvm/x86/include/kvm/bios.h | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 1aef516f27d2..ccf10fb80368 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -196,7 +196,7 @@ DEFINES += -DKVMTOOLS_VERSION='"$(KVMTOOLS_VERSION)"' DEFINES += -DBUILD_ARCH='"$(ARCH)"' KVM_INCLUDE := include -CFLAGS += $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I$(KINCL_PATH)/include -I$(KINCL_PATH)/arch/$(ARCH)/include/ -Os -g +CFLAGS += $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I$(KINCL_PATH)/include -I$(KINCL_PATH)/arch/$(ARCH)/include/ -O2 -fno-strict-aliasing -g ifneq ($(WERROR),0) WARNINGS += -Werror diff --git a/tools/kvm/include/kvm/e820.h b/tools/kvm/include/kvm/e820.h index d23c1779dc30..15f62cc660ef 100644 --- a/tools/kvm/include/kvm/e820.h +++ b/tools/kvm/include/kvm/e820.h @@ -2,11 +2,12 @@ #define KVM_E820_H #include +#include #define SMAP 0x534d4150 /* ASCII "SMAP" */ struct biosregs; -void e820_query_map(struct biosregs *regs); +extern bioscall void e820_query_map(struct biosregs *regs); #endif /* KVM_E820_H */ diff --git a/tools/kvm/x86/include/kvm/bios.h b/tools/kvm/x86/include/kvm/bios.h index c12fba731f25..de569bc108a8 100644 --- a/tools/kvm/x86/include/kvm/bios.h +++ b/tools/kvm/x86/include/kvm/bios.h @@ -80,8 +80,8 @@ struct biosregs { u32 eflags; }; -void int10_handler(struct biosregs *regs); -void int15_handler(struct biosregs *regs); +extern bioscall void int10_handler(struct biosregs *regs); +extern bioscall void int15_handler(struct biosregs *regs); #endif -- 2.39.5