qemu: packaging target {x86_64,arm}-softmmu and friends
authorYousong Zhou <yszhou4tech@gmail.com>
Tue, 6 Dec 2016 06:52:37 +0000 (14:52 +0800)
committerYousong Zhou <yszhou4tech@gmail.com>
Mon, 12 Dec 2016 03:32:22 +0000 (21:32 -0600)
At the moment, only build these softmmu emulators for x86_64 and sunxi
target.  The decision was made for the following reasons

 - It seems that interests of virtualization with qemu are mostly from
   x86, and ARM recently.
 - x86, sunxi boards/boxes capable of running qemu with accel=kvm are more
   widely available
 - Not all host, target combinations of qemu works, or even compiles
 - Extra maintenance work and server resources

Test results are as the following

 - Nested vmx works: lede-qemu-x86_64-kvm on lede-qemu-x86_64-kvm
 - KVM on Cubieboard2 works
 - tcg with malta works: lede-qemu-malta-tcg on lede-qemu-malta-tcg.
   But it's too slow to be useful thus not included in this version
 - mips64 host does not compile

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
utils/qemu/Makefile
utils/qemu/files/bridge.conf [new file with mode: 0644]
utils/qemu/patches/0001-allow-disable-fortify-source.patch [new file with mode: 0644]
utils/qemu/patches/0002-setting-language-type-for-_asm-files.patch [new file with mode: 0644]
utils/qemu/patches/0003-disable-avx2_opt-with-musl.patch [new file with mode: 0644]
utils/qemu/patches/0004-pixman-fix-detection-of-mips-dspr2.patch [new file with mode: 0644]
utils/qemu/patches/0005-pixman-arm-neon-assembler-fix.patch [new file with mode: 0644]
utils/qemu/patches/0006-libvixl-cxx-macro-isnan.patch [new file with mode: 0644]

index 15fa72b17c1372f0e7ffc36f54314f18bdea9994..c512dec32d89a2e61e2e4f045d292bc2701e469e 100644 (file)
@@ -18,6 +18,7 @@ PKG_LICENSE_FILES:=LICENSE tcg/LICENSE
 PKG_MAINTAINER:=Yousong Zhou <yszhou4tech@gmail.com>
 
 PKG_INSTALL:=1
+PKG_USE_MIPS16:=0
 
 include $(INCLUDE_DIR)/uclibc++.mk
 include $(INCLUDE_DIR)/package.mk
@@ -27,15 +28,100 @@ define Package/qemu-ga
   CATEGORY:=Utilities
   TITLE:=QEMU Guest Agent
   URL:=http://www.qemu.org
-  DEPENDS:=+glib2 +libpthread $(CXX_DEPENDS) +librt
+  DEPENDS:= +glib2 $(CXX_DEPENDS)
 endef
 
 define Package/qemu-ga/description
-This package contains the QEMU Guest Agent daemon
+  This package contains the QEMU Guest Agent daemon
+endef
+
+define Package/qemu-ga/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qemu-ga $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/qemu-ga.init $(1)/etc/init.d/qemu-ga
+       $(INSTALL_DIR) $(1)/etc/hotplug.d/virtio-ports
+       $(INSTALL_BIN) ./files/virtio-ports.hotplug $(1)/etc/hotplug.d/virtio-ports/qemu-ga
+endef
+
+define Package/qemu-blobs
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=QEMU blobs of BIOS, VGA BIOS and keymaps
+  URL:=http://www.qemu.org
+  DEPENDS:=
+endef
+
+define Package/qemu-blobs/install
+       $(INSTALL_DIR) $(1)/usr/share/qemu
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/qemu/* $(1)/usr/share/qemu
+endef
+
+define Package/qemu-bridge-helper
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=QEMU bridge helper
+  URL:=http://www.qemu.org
+  DEPENDS:=+glib2 $(CXX_DEPENDS)
+endef
+
+define Package/qemu-bridge-helper/install
+       $(INSTALL_DIR) $(1)/usr/lib/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/qemu-bridge-helper $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/etc/qemu
+       $(INSTALL_DATA) ./files/bridge.conf $(1)/etc/qemu
 endef
 
 PKG_CONFIG_DEPENDS += CONFIG_PACKAGE_qemu-ga
 
+# Naming rules used in qemu Makefile.target
+define qemu-prog_
+  $(if $(filter %-softmmu,$(1)), \
+    $(patsubst %-softmmu,qemu-system-%,$(1)), \
+    $(error unknown qemu target $(1)) \
+  )
+endef
+qemu-prog = $(strip $(call qemu-prog_,$(1)))
+
+# Why libfdt was enabled for all softmmu targets:  according to qemu's
+# configure script, libfdt is only strictly required for the following targets
+# and is optional for others.  But libfdt support will be built into other
+# targets when any single target enabled it.
+#
+#      aarch64%-softmmu arm%-softmmu ppc%-softmmu microblaze%-softmmu
+#
+define qemu-target
+  PKG_CONFIG_DEPENDS += CONFIG_PACKAGE_qemu-$(1)
+
+  define Package/qemu-$(1)
+    SECTION:=utils
+    CATEGORY:=Utilities
+    TITLE:=QEMU target $(1)
+    URL:=http://www.qemu.org
+    DEPENDS:= +glib2 +libpthread +zlib $(CXX_DEPENDS) \
+       $(if $(filter %-softmmu,$(1)),+libncurses +libfdt +qemu-blobs) \
+       @(TARGET_x86_64||TARGET_sunxi)
+  endef
+
+  define Package/qemu-$(1)/description
+    This package contains the QEMU target $(1)
+  endef
+
+  define Package/qemu-$(1)/install
+       $(INSTALL_DIR) $$(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(call qemu-prog,$(1)) $$(1)/usr/bin
+  endef
+
+endef
+
+QEMU_TARGET_LIST :=    \
+       x86_64-softmmu  \
+       arm-softmmu     \
+
+$(foreach target,$(QEMU_TARGET_LIST), \
+  $(eval $(call qemu-target,$(target))) \
+)
+
 # QEMU configure script does not recognize these options
 CONFIGURE_ARGS:=$(filter-out   \
        --target=%              \
@@ -47,36 +133,105 @@ CONFIGURE_ARGS:=$(filter-out      \
        --disable-nls           \
        , $(CONFIGURE_ARGS))
 
-# Building qemu-ga alone does not require zlib, pixman
-#
-# --disable-tools to disable building pixman which will fail at the moment on
-#  octeon mips64 target.
+# Tell build system of qemu to not add _FORTIFY_SOURCE options and let the base
+# build system decide flavor of fortify_source to use
 CONFIGURE_ARGS +=                      \
        --cross-prefix=$(TARGET_CROSS)  \
        --host-cc="$(HOSTCC)"           \
-       --target-list=''                \
+       --disable-fortify-source        \
+       --disable-stack-protector       \
+
+CONFIGURE_ARGS +=                      \
+       --audio-drv-list=''             \
+       --disable-debug-info            \
+       --disable-modules               \
+       --disable-sdl                   \
+       --disable-qom-cast-debug        \
+       --disable-virtfs                \
+       --disable-vnc                   \
+       --disable-debug-tcg             \
+       --disable-sparse                \
+       --disable-strip                 \
+       --disable-vnc-sasl              \
+       --disable-vnc-jpeg              \
+       --disable-vnc-png               \
+       --disable-uuid                  \
+       --disable-vde                   \
+       --disable-netmap                \
+       --disable-xen                   \
+       --disable-xen-pci-passthrough   \
+       --disable-xen-pv-domain-build   \
+       --disable-brlapi                \
+       --disable-bluez                 \
+       --disable-tcg-interpreter       \
+       --disable-cap-ng                \
+       --disable-spice                 \
+       --disable-libiscsi              \
+       --disable-libnfs                \
+       --disable-cocoa                 \
+       --disable-bsd-user              \
+       --disable-curl                  \
+       --disable-linux-aio             \
+       --disable-attr                  \
        --disable-docs                  \
+       --disable-opengl                \
+       --disable-rbd                   \
+       --disable-xfsctl                \
+       --disable-smartcard             \
+       --disable-libusb                \
+       --disable-usb-redir             \
        --disable-zlib-test             \
+       --disable-lzo                   \
+       --disable-snappy                \
+       --disable-bzip2                 \
+       --disable-guest-agent-msi       \
        --disable-tools                 \
-       --without-pixman                \
+       --disable-seccomp               \
+       --disable-glusterfs             \
+       --disable-archipelago           \
+       --disable-gtk                   \
+       --disable-gnutls                \
+       --disable-nettle                \
+       --disable-gcrypt                \
+       --disable-rdma                  \
+       --disable-vte                   \
+       --disable-virglrenderer         \
+       --disable-tpm                   \
+       --disable-libssh2               \
+       --disable-vhdx                  \
+       --disable-numa                  \
+       --disable-tcmalloc              \
+       --disable-jemalloc              \
+       --disable-strip                 \
+       --disable-werror                \
+
+QEMU_CONFIGURE_TARGET_LIST := $(foreach target,$(QEMU_TARGET_LIST),$(if $(CONFIG_PACKAGE_qemu-$(target)),$(target)))
+CONFIGURE_ARGS += --target-list='$(QEMU_CONFIGURE_TARGET_LIST)'
 
 ifneq ($(CONFIG_PACKAGE_qemu-ga),)
 CONFIGURE_ARGS += --enable-guest-agent
 endif
 
+TARGET_LDFLAGS += -Wl,--as-needed
 MAKE_VARS += V=s
+# ARCH is special in qemu's build system, e.g. ARCH mips64 will be translated
+# there to mips and stored in config-host.mak
+MAKE_FLAGS:=$(filter-out       \
+       ARCH=%                  \
+       ,$(MAKE_FLAGS))
 
-define Build/Compile
-       $(if $(CONFIG_PACKAGE_qemu-ga),$(call Build/Compile/Default,qemu-ga))
-endef
+QEMU_MAKE_TARGETS := \
+       $(if $(CONFIG_PACKAGE_qemu-ga),qemu-ga) \
+       $(if $(CONFIG_PACKAGE_qemu-bridge-helper),qemu-bridge-helper) \
+       $(foreach target,$(QEMU_TARGET_LIST),$(if $(CONFIG_PACKAGE_qemu-$(target)),subdir-$(target))) \
 
-define Package/qemu-ga/install
-       $(INSTALL_DIR) $(1)/usr/bin
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qemu-ga $(1)/usr/bin
-       $(INSTALL_DIR) $(1)/etc/init.d
-       $(INSTALL_BIN) ./files/qemu-ga.init $(1)/etc/init.d/qemu-ga
-       $(INSTALL_DIR) $(1)/etc/hotplug.d/virtio-ports
-       $(INSTALL_BIN) ./files/virtio-ports.hotplug $(1)/etc/hotplug.d/virtio-ports/qemu-ga
+define Build/Compile
+       $(if $(strip $(QEMU_MAKE_TARGETS)),$(call Build/Compile/Default,$(QEMU_MAKE_TARGETS)))
 endef
 
 $(eval $(call BuildPackage,qemu-ga))
+$(eval $(call BuildPackage,qemu-bridge-helper))
+$(eval $(call BuildPackage,qemu-blobs))
+$(foreach target,$(QEMU_TARGET_LIST), \
+  $(eval $(call BuildPackage,qemu-$(target))) \
+)
diff --git a/utils/qemu/files/bridge.conf b/utils/qemu/files/bridge.conf
new file mode 100644 (file)
index 0000000..545a163
--- /dev/null
@@ -0,0 +1 @@
+allow all
diff --git a/utils/qemu/patches/0001-allow-disable-fortify-source.patch b/utils/qemu/patches/0001-allow-disable-fortify-source.patch
new file mode 100644 (file)
index 0000000..ef6813a
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/configure.orig   2016-11-22 11:53:25.739180380 +0800
++++ b/configure        2016-11-22 11:53:55.183189596 +0800
+@@ -1147,6 +1147,8 @@ for opt do
+   ;;
+   --enable-jemalloc) jemalloc="yes"
+   ;;
++  --disable-fortify-source) fortify_source="no"
++  ;;
+   *)
+       echo "ERROR: unknown option $opt"
+       echo "Try '$0 --help' for more information"
diff --git a/utils/qemu/patches/0002-setting-language-type-for-_asm-files.patch b/utils/qemu/patches/0002-setting-language-type-for-_asm-files.patch
new file mode 100644 (file)
index 0000000..ea6d49d
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/rules.mak.orig   2016-11-22 13:30:40.933006727 +0800
++++ b/rules.mak        2016-11-22 13:30:47.229008698 +0800
+@@ -70,7 +70,7 @@ LINK = $(call quiet-command, $(LINKPROG)
+       $(call quiet-command,$(CPP) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -o $@ $<,"  CPP   $(TARGET_DIR)$@")
+ %.o: %.asm
+-      $(call quiet-command,$(AS) $(ASFLAGS) -o $@ $<,"  AS    $(TARGET_DIR)$@")
++      $(call quiet-command,$(AS) $(ASFLAGS) -o $@ -x assembler $<,"  AS    $(TARGET_DIR)$@")
+ %.o: %.cc
+       $(call quiet-command,$(CXX) $(QEMU_INCLUDES) $(QEMU_CXXFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o $@ $<,"  CXX   $(TARGET_DIR)$@")
diff --git a/utils/qemu/patches/0003-disable-avx2_opt-with-musl.patch b/utils/qemu/patches/0003-disable-avx2_opt-with-musl.patch
new file mode 100644 (file)
index 0000000..c52cb4c
--- /dev/null
@@ -0,0 +1,14 @@
+--- a/configure.orig   2016-11-22 17:35:12.069598617 +0800
++++ b/configure        2016-11-22 18:24:01.042515353 +0800
+@@ -1789,7 +1789,10 @@ static void foo(void) __attribute__((ifu
+ int main(void) { foo(); return 0; }
+ EOF
+ if compile_prog "-mavx2" "" ; then
+-    if readelf --syms $TMPE |grep "IFUNC.*foo" >/dev/null 2>&1; then
++    if readelf --program-headers $TMPE | grep -iq 'Requesting program interpreter: .*ld-musl'; then
++        # ifunc support is not available with dynamic linker of musl
++        avx2_opt="no"
++    elif readelf --syms $TMPE |grep "IFUNC.*foo" >/dev/null 2>&1; then
+         avx2_opt="yes"
+     fi
+ fi
diff --git a/utils/qemu/patches/0004-pixman-fix-detection-of-mips-dspr2.patch b/utils/qemu/patches/0004-pixman-fix-detection-of-mips-dspr2.patch
new file mode 100644 (file)
index 0000000..05e34e0
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/pixman/configure.ac.orig 2016-11-22 20:44:21.205150763 +0800
++++ b/pixman/configure.ac      2016-11-22 20:44:55.505161500 +0800
+@@ -720,7 +720,6 @@ dnl Check if assembler is gas compatible
+ have_mips_dspr2=no
+ AC_MSG_CHECKING(whether to use MIPS DSPr2 assembler)
+ xserver_save_CFLAGS=$CFLAGS
+-CFLAGS="-mdspr2 $CFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+ #if !(defined(__mips__) &&  __mips_isa_rev >= 2)
diff --git a/utils/qemu/patches/0005-pixman-arm-neon-assembler-fix.patch b/utils/qemu/patches/0005-pixman-arm-neon-assembler-fix.patch
new file mode 100644 (file)
index 0000000..93c967a
--- /dev/null
@@ -0,0 +1,17 @@
+--- a/pixman/pixman/pixman-private.h.orig      2016-11-22 22:10:33.574769654 +0800
++++ b/pixman/pixman/pixman-private.h   2016-11-22 22:10:47.638774056 +0800
+@@ -1,5 +1,3 @@
+-#include <float.h>
+-
+ #ifndef PIXMAN_PRIVATE_H
+ #define PIXMAN_PRIVATE_H
+@@ -17,6 +15,8 @@
+ #ifndef __ASSEMBLER__
++#include <float.h>
++
+ #ifndef PACKAGE
+ #  error config.h must be included before pixman-private.h
+ #endif
diff --git a/utils/qemu/patches/0006-libvixl-cxx-macro-isnan.patch b/utils/qemu/patches/0006-libvixl-cxx-macro-isnan.patch
new file mode 100644 (file)
index 0000000..0dae8ce
--- /dev/null
@@ -0,0 +1,55 @@
+--- a/disas/libvixl/vixl/utils.h.orig  2016-11-22 22:36:20.691253883 +0800
++++ b/disas/libvixl/vixl/utils.h       2016-11-22 22:55:44.639618185 +0800
+@@ -118,11 +118,17 @@ double double_pack(uint64_t sign, uint64
+ // An fpclassify() function for 16-bit half-precision floats.
+ int float16classify(float16 value);
++#ifdef isnan
++#define isnan_ isnan
++#else
++#define isnan_ std::isnan
++#endif
++
+ // NaN tests.
+ inline bool IsSignallingNaN(double num) {
+   const uint64_t kFP64QuietNaNMask = UINT64_C(0x0008000000000000);
+   uint64_t raw = double_to_rawbits(num);
+-  if (std::isnan(num) && ((raw & kFP64QuietNaNMask) == 0)) {
++  if (isnan_(num) && ((raw & kFP64QuietNaNMask) == 0)) {
+     return true;
+   }
+   return false;
+@@ -132,7 +138,7 @@ inline bool IsSignallingNaN(double num)
+ inline bool IsSignallingNaN(float num) {
+   const uint32_t kFP32QuietNaNMask = 0x00400000;
+   uint32_t raw = float_to_rawbits(num);
+-  if (std::isnan(num) && ((raw & kFP32QuietNaNMask) == 0)) {
++  if (isnan_(num) && ((raw & kFP32QuietNaNMask) == 0)) {
+     return true;
+   }
+   return false;
+@@ -148,21 +154,21 @@ inline bool IsSignallingNaN(float16 num)
+ template <typename T>
+ inline bool IsQuietNaN(T num) {
+-  return std::isnan(num) && !IsSignallingNaN(num);
++  return isnan_(num) && !IsSignallingNaN(num);
+ }
+ // Convert the NaN in 'num' to a quiet NaN.
+ inline double ToQuietNaN(double num) {
+   const uint64_t kFP64QuietNaNMask = UINT64_C(0x0008000000000000);
+-  VIXL_ASSERT(std::isnan(num));
++  VIXL_ASSERT(isnan_(num));
+   return rawbits_to_double(double_to_rawbits(num) | kFP64QuietNaNMask);
+ }
+ inline float ToQuietNaN(float num) {
+   const uint32_t kFP32QuietNaNMask = 0x00400000;
+-  VIXL_ASSERT(std::isnan(num));
++  VIXL_ASSERT(isnan_(num));
+   return rawbits_to_float(float_to_rawbits(num) | kFP32QuietNaNMask);
+ }