* Pekka Enberg <penberg@kernel.org> 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 <mingo@elte.hu>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
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
#define KVM_E820_H
#include <linux/types.h>
+#include <kvm/bios.h>
#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 */
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