qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC] Bring in all the Linux headers we depend on in QEMU


From: Anthony Liguori
Subject: [Qemu-devel] [RFC] Bring in all the Linux headers we depend on in QEMU
Date: Sun, 03 May 2009 16:37:27 -0500
User-agent: Thunderbird 2.0.0.21 (X11/20090320)

Sorry this explanation is long winded, but this is a messy situation.

In Linux, there isn't a very consistent policy about userspace kernel header inclusion. On a typical Linux system, you're likely to find kernel headers in three places.

glibc headers (/usr/include/{linux,asm})

These headers are installed by glibc. They very often are based on much older kernel versions that the kernel you have in your distribution. For software that depends on these headers, very often this means that your software detects features being missing that are present on your kernel. Furthermore, glibc only installs the headers it needs so very often certain headers have dependencies that aren't met. A classic example is linux/compiler.h and the broken usbdevice_fs.h header that depends on it. There are still distributions today that QEMU doesn't compile on because of this.

Today, most of QEMU's code depends on these headers.

/lib/modules/$(uname -r)/build

These are the kernel headers that are installed as part of your kernel. In general, this is a pretty good place to find the headers that are associated with the kernel version you're actually running on. However, these headers are part of the kernel build tree and are not always guaranteed to be includable from userspace.

<random kernel tree>

Developers, in particular, like to point things at their random kernel trees. In general though, relying on a full kernel source tree being available isn't a good idea. Kernel headers change dramatically across versions too so it's very likely that we would need to have a lot of #ifdefs dependent on kernel versions, or some of the uglier work arounds we have in usb-linux.c.

I think the best way to avoid #ifdefs and dependencies on broken/incomplete glibc headers is to include all of the Linux headers we need within QEMU. The attached patch does just this.

I think there's room for discussion about whether we really want to do this. We could potentially depend on some more common glibc headers (like asm/types.h) while bringing in less reliable headers (if_tun.h/virtio*). Including them all seems like the most robust solution to me though.

Comments?

Regards,

Anthony Liguori
>From b42aa57e94fc6b05897271b0816fa34d70670c9a Mon Sep 17 00:00:00 2001
From: Anthony Liguori <address@hidden>
Date: Sat, 2 May 2009 15:45:24 -0500
Subject: [PATCH] Import Linux headers into QEMU

These are the headers from Linux 2.6.29 that have been modified to work under
QEMU.  This includes the necessary scripts to generate the headers from the
original Linux source tree.

I've not included the headers in this patch as they are quite big and would make
review more difficult.  I've included headers for all host architectures QEMU
currently supports but I've only tested x86.

Signed-off-by: Anthony Liguori <address@hidden>
---
 Makefile.target |    3 --
 configure       |   37 ++++++++++---------
 linux/Makefile  |  108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 linux/README    |   19 ++++++++++
 linux/fixup.sed |   19 ++++++++++
 usb-linux.c     |    1 -
 6 files changed, 165 insertions(+), 22 deletions(-)
 create mode 100644 linux/Makefile
 create mode 100644 linux/README
 create mode 100644 linux/fixup.sed

diff --git a/Makefile.target b/Makefile.target
index f735105..474245a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -124,9 +124,6 @@ CFLAGS+=-I/opt/SUNWspro/prod/include/cc
 endif
 endif
 
-kvm.o: CFLAGS+=$(KVM_CFLAGS)
-kvm-all.o: CFLAGS+=$(KVM_CFLAGS)
-
 all: $(PROGS)
 
 #########################################################
diff --git a/configure b/configure
index 82fb60a..379a2a6 100755
--- a/configure
+++ b/configure
@@ -1081,6 +1081,23 @@ EOF
   fi
 fi
 
+# Linux kernel headers CFLAGS
+if test -z "$kerneldir" ; then
+    linux_cflags="-I$source_path/linux"
+else
+    linux_cflags="-I$kerneldir/include"
+    if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) \
+       -a -d "$kerneldir/arch/x86/include" ; then
+       linux_cflags="$linux_cflags -I$kerneldir/arch/x86/include"
+    elif test "$cpu" = "ppc" -a -d "$kerneldir/arch/powerpc/include" ; then
+       linux_cflags="$linux_cflags -I$kerneldir/arch/powerpc/include"
+    elif test -d "$kerneldir/arch/$cpu/include" ; then
+       linux_cflags="$linux_cflags -I$kerneldir/arch/$cpu/include"
+    fi
+fi
+
+OS_CFLAGS="$OS_CFLAGS $linux_cflags"
+
 ##########################################
 # kvm probe
 if test "$kvm" = "yes" ; then
@@ -1100,27 +1117,14 @@ if test "$kvm" = "yes" ; then
 #endif
 int main(void) { return 0; }
 EOF
-  if test "$kerneldir" != "" ; then
-      kvm_cflags=-I"$kerneldir"/include
-      if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) \
-         -a -d "$kerneldir/arch/x86/include" ; then
-            kvm_cflags="$kvm_cflags -I$kerneldir/arch/x86/include"
-       elif test "$cpu" = "ppc" -a -d "$kerneldir/arch/powerpc/include" ; then
-           kvm_cflags="$kvm_cflags -I$kerneldir/arch/powerpc/include"
-        elif test -d "$kerneldir/arch/$cpu/include" ; then
-            kvm_cflags="$kvm_cflags -I$kerneldir/arch/$cpu/include"
-      fi
-  else
-      kvm_cflags=""
-  fi
-  if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $kvm_cflags $TMPC \
+  if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $TMPC \
       > /dev/null 2>/dev/null ; then
     :
   else
     kvm="no";
     if [ -x "`which awk 2>/dev/null`" ] && \
        [ -x "`which grep 2>/dev/null`" ]; then
-      kvmerr=`LANG=C $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $kvm_cflags $TMPC 
2>&1 \
+      kvmerr=`LANG=C $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $TMPC 2>&1 \
        | grep "error: " \
        | awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'`
       if test "$kvmerr" != "" ; then
@@ -1817,7 +1821,6 @@ case "$target_cpu" in
     fi
     if test "$kvm" = "yes" ; then
       echo "CONFIG_KVM=yes" >> $config_mak
-      echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
       echo "#define CONFIG_KVM 1" >> $config_h
     fi
     if test "$xen" = "yes" -a "$target_softmmu" = "yes";
@@ -1838,7 +1841,6 @@ case "$target_cpu" in
     fi
     if test "$kvm" = "yes" ; then
       echo "CONFIG_KVM=yes" >> $config_mak
-      echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
       echo "#define CONFIG_KVM 1" >> $config_h
     fi
     if test "$xen" = "yes" -a "$target_softmmu" = "yes"
@@ -1906,7 +1908,6 @@ case "$target_cpu" in
     echo "#define TARGET_PPCEMB 1" >> $config_h
     if test "$kvm" = "yes" ; then
       echo "CONFIG_KVM=yes" >> $config_mak
-      echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
       echo "#define CONFIG_KVM 1" >> $config_h
     fi
     gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml"
diff --git a/linux/Makefile b/linux/Makefile
new file mode 100644
index 0000000..68a5844
--- /dev/null
+++ b/linux/Makefile
@@ -0,0 +1,108 @@
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+
+# Basic types/annotations that Linux headers use
+CORE_HDRS=linux/types.h linux/posix_types.h linux/stddef.h linux/compiler.h
+CORE_HDRS+=linux/byteorder/little_endian.h linux/byteorder/big_endian.h
+CORE_HDRS+=linux/swab.h linux/ioctl.h
+
+CORE_HDRS+=asm-generic/int-ll64.h asm-generic/int-l64.h asm-generic/ioctl.h
+
+CORE_HDRS+=asm-x86/types.h asm-x86/posix_types.h
+CORE_HDRS+=asm-x86/posix_types_32.h asm-x86/posix_types_64.h
+CORE_HDRS+=asm-x86/byteorder.h asm-x86/swab.h asm-x86/ioctl.h
+
+CORE_HDRS+=asm-powerpc/types.h asm-powerpc/posix_types.h
+CORE_HDRS+=asm-powerpc/byteorder.h asm-powerpc/swab.h asm-powerpc/ioctl.h
+
+CORE_HDRS+=asm-sparc/types.h asm-sparc/posix_types.h
+CORE_HDRS+=asm-sparc/byteorder.h asm-sparc/swab.h asm-sparc/ioctl.h
+CORE_HDRS+=asm-sparc/asi.h 
+
+CORE_HDRS+=asm-arm/types.h asm-arm/posix_types.h
+CORE_HDRS+=asm-arm/byteorder.h asm-arm/swab.h asm-arm/ioctl.h
+
+CORE_HDRS+=asm-parisc/types.h asm-parisc/posix_types.h
+CORE_HDRS+=asm-parisc/byteorder.h asm-parisc/swab.h asm-parisc/ioctl.h
+
+# Kernel Virtual Machine interface
+KVM_HDRS=linux/kvm.h linux/kvm_para.h
+KVM_HDRS+=asm-x86/kvm.h asm-x86/kvm_para.h
+KVM_HDRS+=asm-powerpc/kvm.h asm-powerpc/kvm_para.h
+
+# VirtIO paravirtual IO framework
+VIRTIO_HDRS=linux/virtio_config.h linux/virtio_net.h linux/virtio_blk.h
+VIRTIO_HDRS+=linux/virtio_console.h linux/virtio_balloon.h
+
+# tun/tap interfaces
+TUN_HDRS=linux/if_tun.h linux/if_ether.h
+
+# timers
+TIMER_HDRS=linux/rtc.h linux/hpet.h
+
+# USB pass through
+USB_HDRS=linux/usbdevice_fs.h linux/magic.h
+
+# IDE/FD
+DISK_HDRS=linux/cdrom.h linux/fd.h
+
+# Parallel port
+PPORT_HDRS=linux/ppdev.h linux/parport.h
+
+sync: sync-kvm sync-virtio sync-tun sync-timer sync-usb sync-disk sync-pport
+
+sync-core: $(CORE_HDRS)
+
+sync-kvm: sync-core $(KVM_HDRS)
+
+sync-virtio: sync-core $(VIRTIO_HDRS)
+
+sync-tun: sync-core $(TUN_HDRS)
+
+sync-timer: sync-core $(TIMER_HDRS)
+
+sync-usb: sync-core $(USB_HDRS)
+
+sync-disk: sync-core $(DISK_HDRS)
+
+sync-pport: sync-core $(PPORT_HDRS)
+
+clean:
+       @$(RM) -r linux asm-x86 asm-powerpc asm-generic asm-sparc asm-arm \
+                 asm-parisc
+
+linux/%: $(KERNELDIR)/include/linux/%
+       @mkdir -p $(shell dirname $@)
+       @echo "  IMPORT    $@"
+       @sed -f fixup.sed $< > $@
+
+asm-generic/%: $(KERNELDIR)/include/asm-generic/%
+       @mkdir -p $(shell dirname $@)
+       @echo "  IMPORT    $@"
+       @sed -f fixup.sed $< > $@
+
+asm-x86/%: $(KERNELDIR)/arch/x86/include/asm/%
+       @mkdir -p $(shell dirname $@)
+       @echo "  IMPORT    $@"
+       @sed -f fixup.sed $< > $@
+
+asm-powerpc/%: $(KERNELDIR)/arch/powerpc/include/asm/%
+       @mkdir -p $(shell dirname $@)
+       @echo "  IMPORT    $@"
+       @sed -f fixup.sed $< > $@
+
+asm-sparc/%: $(KERNELDIR)/arch/sparc/include/asm/%
+       @mkdir -p $(shell dirname $@)
+       @echo "  IMPORT    $@"
+       @sed -f fixup.sed $< > $@
+
+asm-arm/%: $(KERNELDIR)/arch/arm/include/asm/%
+       @mkdir -p $(shell dirname $@)
+       @echo "  IMPORT    $@"
+       @sed -f fixup.sed $< > $@
+
+asm-parisc/%: $(KERNELDIR)/arch/parisc/include/asm/%
+       @mkdir -p $(shell dirname $@)
+       @echo "  IMPORT    $@"
+       @sed -f fixup.sed $< > $@
+
+.PHONY: clean
diff --git a/linux/README b/linux/README
new file mode 100644
index 0000000..e29d39b
--- /dev/null
+++ b/linux/README
@@ -0,0 +1,19 @@
+This directory contains a snapshot of Linux kernel headers.  The included
+Makefile was used to import these headers into QEMU.
+
+This process is intended for use by the QEMU maintainers.  It is not intended
+to work against arbitrary kernel versions nor is the intention for end-users to
+use this to update the included headers.
+
+If a contributor needs a newer kernel header for a feature implemented
+by a particular patch, please run the appropriate make sync-* command and
+send the results of that command as a separate patch.  Also make sure to update
+this file to reflect the kernel version used.
+
+While it is okay for development versions of QEMU to contain headers from
+non-release versions of the Linux kernel, any official release of QEMU must use
+headers from a released version of the Linux kernel to ensure ABI 
compatibility.
+
+Kernel versions used:
+
+git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git 
v2.6.30-rc4
diff --git a/linux/fixup.sed b/linux/fixup.sed
new file mode 100644
index 0000000..c0ad124
--- /dev/null
+++ b/linux/fixup.sed
@@ -0,0 +1,19 @@
+# Header file fix ups.  This is tailored for importing the kvm linux headers
+
+# Expand asm/ includes to avoid having to do symlink trickery
+s:^#include <asm/\(.*\)>:                              \
+#if defined(__x86_64__) || defined(__i386__)            \
+#include "asm-x86/\1"                                   \
+#elif defined(__powerpc__)                              \
+#include "asm-powerpc/\1"                               \
+#elif defined(__sparc__)                                \
+#include "asm-sparc/\1"                                 \
+#elif defined(__hppa__)                                 \
+#include "asm-parisc/\1"                                \
+#elif defined(__arm__)                                  \
+#include "asm-arm/\1"                                   \
+#else                                                   \
+#error Using Linux headers on unknown architecture      \
+#endif                                                  \
+:g
+s:^#include <linux/\(.*\)>:#include "linux/\1":g
diff --git a/usb-linux.c b/usb-linux.c
index 70d7a1c..1392579 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -39,7 +39,6 @@
 #include <signal.h>
 
 #include <linux/usbdevice_fs.h>
-#include <linux/version.h>
 #include "hw/usb.h"
 
 /* We redefine it to avoid version problems */
-- 
1.6.0.6


reply via email to

[Prev in Thread] Current Thread [Next in Thread]