qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC] Bring in all the Linux headers we depend on in QEMU
@ 2009-05-03 21:37 Anthony Liguori
  2009-05-04  6:51 ` Stefan Weil
                   ` (3 more replies)
  0 siblings, 4 replies; 25+ messages in thread
From: Anthony Liguori @ 2009-05-03 21:37 UTC (permalink / raw)
  To: qemu-devel@nongnu.org, kvm-devel, Avi Kivity

[-- Attachment #1: Type: text/plain, Size: 2230 bytes --]

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

[-- Attachment #2: 0001-Import-Linux-headers-into-QEMU.patch --]
[-- Type: text/x-patch, Size: 10288 bytes --]

>From b42aa57e94fc6b05897271b0816fa34d70670c9a Mon Sep 17 00:00:00 2001
From: Anthony Liguori <aliguori@us.ibm.com>
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 <aliguori@us.ibm.com>
---
 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


^ permalink raw reply related	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2009-05-04 14:27 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-03 21:37 [Qemu-devel] [RFC] Bring in all the Linux headers we depend on in QEMU Anthony Liguori
2009-05-04  6:51 ` Stefan Weil
2009-05-04  8:17   ` Edgar E. Iglesias
2009-05-04 13:15     ` Anthony Liguori
2009-05-04 13:44       ` Edgar E. Iglesias
2009-05-04 13:13   ` Anthony Liguori
2009-05-04 13:28     ` Avi Kivity
2009-05-04 13:30       ` Anthony Liguori
2009-05-04 14:01     ` Christoph Hellwig
2009-05-04 14:27     ` Lennart Sorensen
2009-05-04  7:52 ` Avi Kivity
2009-05-04  9:35   ` Paul Brook
2009-05-04 13:14   ` Anthony Liguori
2009-05-04  9:08 ` [Qemu-devel] " Avi Kivity
2009-05-04 12:42   ` Mark McLoughlin
2009-05-04 13:01     ` Arnd Bergmann
2009-05-04 13:25       ` Anthony Liguori
2009-05-04 13:26     ` Avi Kivity
2009-05-04 13:24   ` Anthony Liguori
2009-05-04 13:40     ` Avi Kivity
2009-05-04 11:29 ` Arnd Bergmann
2009-05-04 13:21   ` Anthony Liguori
2009-05-04 13:38     ` Avi Kivity
2009-05-04 14:04       ` Christoph Hellwig
2009-05-04 14:18     ` Arnd Bergmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).