From c778ff571489adc577f9b7395940281aa3af4b6a Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Tue, 6 Dec 2016 14:52:37 +0800 Subject: [PATCH] qemu: packaging target {x86_64,arm}-softmmu and friends 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 --- utils/qemu/Makefile | 191 ++++++++++++++++-- utils/qemu/files/bridge.conf | 1 + .../0001-allow-disable-fortify-source.patch | 11 + ...setting-language-type-for-_asm-files.patch | 11 + .../0003-disable-avx2_opt-with-musl.patch | 14 ++ ...4-pixman-fix-detection-of-mips-dspr2.patch | 10 + .../0005-pixman-arm-neon-assembler-fix.patch | 17 ++ .../0006-libvixl-cxx-macro-isnan.patch | 55 +++++ 8 files changed, 292 insertions(+), 18 deletions(-) create mode 100644 utils/qemu/files/bridge.conf create mode 100644 utils/qemu/patches/0001-allow-disable-fortify-source.patch create mode 100644 utils/qemu/patches/0002-setting-language-type-for-_asm-files.patch create mode 100644 utils/qemu/patches/0003-disable-avx2_opt-with-musl.patch create mode 100644 utils/qemu/patches/0004-pixman-fix-detection-of-mips-dspr2.patch create mode 100644 utils/qemu/patches/0005-pixman-arm-neon-assembler-fix.patch create mode 100644 utils/qemu/patches/0006-libvixl-cxx-macro-isnan.patch diff --git a/utils/qemu/Makefile b/utils/qemu/Makefile index 15fa72b17c..c512dec32d 100644 --- a/utils/qemu/Makefile +++ b/utils/qemu/Makefile @@ -18,6 +18,7 @@ PKG_LICENSE_FILES:=LICENSE tcg/LICENSE PKG_MAINTAINER:=Yousong Zhou 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)) + +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 Build/Compile - $(if $(CONFIG_PACKAGE_qemu-ga),$(call Build/Compile/Default,qemu-ga)) -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 + $(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 index 0000000000..545a1639dc --- /dev/null +++ b/utils/qemu/files/bridge.conf @@ -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 index 0000000000..ef6813aa3a --- /dev/null +++ b/utils/qemu/patches/0001-allow-disable-fortify-source.patch @@ -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 index 0000000000..ea6d49de2e --- /dev/null +++ b/utils/qemu/patches/0002-setting-language-type-for-_asm-files.patch @@ -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 index 0000000000..c52cb4c7a5 --- /dev/null +++ b/utils/qemu/patches/0003-disable-avx2_opt-with-musl.patch @@ -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 index 0000000000..05e34e098e --- /dev/null +++ b/utils/qemu/patches/0004-pixman-fix-detection-of-mips-dspr2.patch @@ -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 index 0000000000..93c967a0cf --- /dev/null +++ b/utils/qemu/patches/0005-pixman-arm-neon-assembler-fix.patch @@ -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 +- + #ifndef PIXMAN_PRIVATE_H + #define PIXMAN_PRIVATE_H + +@@ -17,6 +15,8 @@ + + #ifndef __ASSEMBLER__ + ++#include ++ + #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 index 0000000000..0dae8ce5cb --- /dev/null +++ b/utils/qemu/patches/0006-libvixl-cxx-macro-isnan.patch @@ -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 + 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); + } +