diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .travis.yml | 6 | ||||
-rw-r--r-- | Kconfig.host | 33 | ||||
-rw-r--r-- | MAINTAINERS | 6 | ||||
-rw-r--r-- | Makefile | 113 | ||||
-rw-r--r-- | Makefile.objs | 1 | ||||
-rw-r--r-- | Makefile.target | 12 | ||||
-rwxr-xr-x | configure | 123 | ||||
-rw-r--r-- | default-configs/alpha-softmmu.mak | 26 | ||||
-rw-r--r-- | default-configs/arm-softmmu.mak | 18 | ||||
-rw-r--r-- | default-configs/cris-softmmu.mak | 6 | ||||
-rw-r--r-- | default-configs/hppa-softmmu.mak | 20 | ||||
-rw-r--r-- | default-configs/hyperv.mak | 2 | ||||
-rw-r--r-- | default-configs/i386-softmmu.mak | 93 | ||||
-rw-r--r-- | default-configs/lm32-softmmu.mak | 12 | ||||
-rw-r--r-- | default-configs/m68k-softmmu.mak | 4 | ||||
-rw-r--r-- | default-configs/microblaze-softmmu.mak | 12 | ||||
-rw-r--r-- | default-configs/mips-softmmu-common.mak | 10 | ||||
-rw-r--r-- | default-configs/mips64el-softmmu.mak | 2 | ||||
-rw-r--r-- | default-configs/moxie-softmmu.mak | 7 | ||||
-rw-r--r-- | default-configs/nios2-softmmu.mak | 6 | ||||
-rw-r--r-- | default-configs/or1k-softmmu.mak | 5 | ||||
-rw-r--r-- | default-configs/pci.mak | 51 | ||||
-rw-r--r-- | default-configs/ppc-softmmu.mak | 60 | ||||
-rw-r--r-- | default-configs/ppc64-softmmu.mak | 13 | ||||
-rw-r--r-- | default-configs/riscv32-softmmu.mak | 21 | ||||
-rw-r--r-- | default-configs/riscv64-softmmu.mak | 22 | ||||
-rw-r--r-- | default-configs/s390x-softmmu.mak | 23 | ||||
-rw-r--r-- | default-configs/sh4-softmmu.mak | 28 | ||||
-rw-r--r-- | default-configs/sh4eb-softmmu.mak | 22 | ||||
-rw-r--r-- | default-configs/sound.mak | 4 | ||||
-rw-r--r-- | default-configs/sparc-softmmu.mak | 24 | ||||
-rw-r--r-- | default-configs/sparc64-softmmu.mak | 25 | ||||
-rw-r--r-- | default-configs/unicore32-softmmu.mak | 6 | ||||
-rw-r--r-- | default-configs/usb.mak | 11 | ||||
-rw-r--r-- | default-configs/virtio.mak | 15 | ||||
-rw-r--r-- | default-configs/xtensa-softmmu.mak | 8 | ||||
-rw-r--r-- | default-configs/xtensaeb-softmmu.mak | 7 | ||||
-rw-r--r-- | docs/conf.py | 216 | ||||
-rw-r--r-- | docs/cpu-hotplug.rst | 2 | ||||
-rw-r--r-- | docs/devel/build-system.txt | 1 | ||||
-rw-r--r-- | docs/devel/conf.py | 15 | ||||
-rw-r--r-- | docs/devel/index.rst | 22 | ||||
-rw-r--r-- | docs/devel/kconfig.rst | 306 | ||||
-rw-r--r-- | docs/devel/memory.rst (renamed from docs/devel/memory.txt) | 132 | ||||
-rw-r--r-- | docs/devel/testing.rst | 42 | ||||
-rw-r--r-- | docs/index.rst | 15 | ||||
-rw-r--r-- | docs/interop/conf.py | 15 | ||||
-rw-r--r-- | docs/interop/index.rst | 18 | ||||
-rw-r--r-- | hw/9pfs/Kconfig | 4 | ||||
-rw-r--r-- | hw/9pfs/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/Kconfig | 73 | ||||
-rw-r--r-- | hw/Makefile.objs | 4 | ||||
-rw-r--r-- | hw/acpi/Kconfig | 29 | ||||
-rw-r--r-- | hw/adc/Kconfig | 2 | ||||
-rw-r--r-- | hw/alpha/Kconfig | 12 | ||||
-rw-r--r-- | hw/arm/Kconfig | 124 | ||||
-rw-r--r-- | hw/audio/Kconfig | 52 | ||||
-rw-r--r-- | hw/block/Kconfig | 39 | ||||
-rw-r--r-- | hw/block/Makefile.objs | 3 | ||||
-rw-r--r-- | hw/block/dataplane/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/bt/Kconfig | 2 | ||||
-rw-r--r-- | hw/char/Kconfig | 42 | ||||
-rw-r--r-- | hw/core/Kconfig | 11 | ||||
-rw-r--r-- | hw/cpu/Kconfig | 8 | ||||
-rw-r--r-- | hw/cris/Kconfig | 9 | ||||
-rw-r--r-- | hw/display/Kconfig | 108 | ||||
-rw-r--r-- | hw/display/Makefile.objs | 4 | ||||
-rw-r--r-- | hw/dma/Kconfig | 21 | ||||
-rw-r--r-- | hw/gpio/Kconfig | 9 | ||||
-rw-r--r-- | hw/hppa/Kconfig | 10 | ||||
-rw-r--r-- | hw/hyperv/Kconfig | 8 | ||||
-rw-r--r-- | hw/i2c/Kconfig | 27 | ||||
-rw-r--r-- | hw/i2c/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/i386/Kconfig | 99 | ||||
-rw-r--r-- | hw/i386/Makefile.objs | 5 | ||||
-rw-r--r-- | hw/ide/Kconfig | 54 | ||||
-rw-r--r-- | hw/input/Kconfig | 33 | ||||
-rw-r--r-- | hw/intc/Kconfig | 57 | ||||
-rw-r--r-- | hw/ipack/Kconfig | 4 | ||||
-rw-r--r-- | hw/ipmi/Kconfig | 22 | ||||
-rw-r--r-- | hw/isa/Kconfig | 53 | ||||
-rw-r--r-- | hw/lm32/Kconfig | 13 | ||||
-rw-r--r-- | hw/m68k/Kconfig | 9 | ||||
-rw-r--r-- | hw/mem/Kconfig | 11 | ||||
-rw-r--r-- | hw/microblaze/Kconfig | 20 | ||||
-rw-r--r-- | hw/mips/Kconfig | 21 | ||||
-rw-r--r-- | hw/misc/Kconfig | 118 | ||||
-rw-r--r-- | hw/misc/macio/Kconfig | 11 | ||||
-rw-r--r-- | hw/moxie/Kconfig | 3 | ||||
-rw-r--r-- | hw/net/Kconfig | 125 | ||||
-rw-r--r-- | hw/nios2/Kconfig | 8 | ||||
-rw-r--r-- | hw/nvram/Kconfig | 9 | ||||
-rw-r--r-- | hw/openrisc/Kconfig | 5 | ||||
-rw-r--r-- | hw/pci-bridge/Kconfig | 29 | ||||
-rw-r--r-- | hw/pci-host/Kconfig | 51 | ||||
-rw-r--r-- | hw/pci/Kconfig | 9 | ||||
-rw-r--r-- | hw/pci/Makefile.objs | 9 | ||||
-rw-r--r-- | hw/pcmcia/Kconfig | 2 | ||||
-rw-r--r-- | hw/ppc/Kconfig | 121 | ||||
-rw-r--r-- | hw/riscv/Kconfig | 33 | ||||
-rw-r--r-- | hw/s390x/Kconfig | 11 | ||||
-rw-r--r-- | hw/s390x/Makefile.objs | 4 | ||||
-rw-r--r-- | hw/scsi/Kconfig | 54 | ||||
-rw-r--r-- | hw/scsi/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/sd/Kconfig | 17 | ||||
-rw-r--r-- | hw/sh4/Kconfig | 23 | ||||
-rw-r--r-- | hw/smbios/Kconfig | 2 | ||||
-rw-r--r-- | hw/sparc/Kconfig | 26 | ||||
-rw-r--r-- | hw/sparc64/Kconfig | 19 | ||||
-rw-r--r-- | hw/ssi/Kconfig | 18 | ||||
-rw-r--r-- | hw/timer/Kconfig | 63 | ||||
-rw-r--r-- | hw/tpm/Kconfig | 24 | ||||
-rw-r--r-- | hw/tricore/Kconfig | 2 | ||||
-rw-r--r-- | hw/unicore32/Kconfig | 5 | ||||
-rw-r--r-- | hw/usb/Kconfig | 91 | ||||
-rw-r--r-- | hw/usb/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/vfio/Kconfig | 36 | ||||
-rw-r--r-- | hw/virtio/Kconfig | 31 | ||||
-rw-r--r-- | hw/virtio/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/watchdog/Kconfig | 16 | ||||
-rw-r--r-- | hw/xtensa/Kconfig | 8 | ||||
-rw-r--r-- | hw/xtensa/Makefile.objs | 2 | ||||
-rw-r--r-- | include/migration/qemu-file-types.h | 2 | ||||
-rw-r--r-- | linux-user/elfload.c | 37 | ||||
-rw-r--r-- | linux-user/fd-trans.c | 9 | ||||
-rw-r--r-- | linux-user/nios2/cpu_loop.c | 6 | ||||
-rw-r--r-- | linux-user/strace.c | 12 | ||||
-rw-r--r-- | linux-user/strace.list | 2 | ||||
-rw-r--r-- | linux-user/syscall.c | 53 | ||||
-rw-r--r-- | migration/qemu-file.h | 1 | ||||
-rw-r--r-- | net/Makefile.objs | 2 | ||||
-rw-r--r-- | net/slirp.c | 58 | ||||
-rw-r--r-- | python/qemu/__init__.py (renamed from scripts/qemu.py) | 12 | ||||
-rw-r--r-- | python/qemu/qmp.py (renamed from scripts/qmp/qmp.py) | 0 | ||||
-rw-r--r-- | python/qemu/qtest.py (renamed from scripts/qtest.py) | 5 | ||||
-rw-r--r-- | rules.mak | 2 | ||||
-rwxr-xr-x | scripts/device-crash-test | 2 | ||||
-rw-r--r-- | scripts/make_device_config.sh | 30 | ||||
-rw-r--r-- | scripts/minikconf.py | 708 | ||||
-rwxr-xr-x | scripts/qmp/qemu-ga-client | 5 | ||||
-rwxr-xr-x | scripts/qmp/qmp-shell | 4 | ||||
-rwxr-xr-x | scripts/render_block_graph.py | 2 | ||||
-rw-r--r-- | slirp/Makefile | 47 | ||||
-rw-r--r-- | slirp/Makefile.objs | 34 | ||||
-rw-r--r-- | slirp/src/arp_table.c (renamed from slirp/arp_table.c) | 0 | ||||
-rw-r--r-- | slirp/src/bootp.c (renamed from slirp/bootp.c) | 0 | ||||
-rw-r--r-- | slirp/src/bootp.h (renamed from slirp/bootp.h) | 0 | ||||
-rw-r--r-- | slirp/src/cksum.c (renamed from slirp/cksum.c) | 0 | ||||
-rw-r--r-- | slirp/src/debug.h (renamed from slirp/debug.h) | 0 | ||||
-rw-r--r-- | slirp/src/dhcpv6.c (renamed from slirp/dhcpv6.c) | 0 | ||||
-rw-r--r-- | slirp/src/dhcpv6.h (renamed from slirp/dhcpv6.h) | 0 | ||||
-rw-r--r-- | slirp/src/dnssearch.c (renamed from slirp/dnssearch.c) | 0 | ||||
-rw-r--r-- | slirp/src/if.c (renamed from slirp/if.c) | 0 | ||||
-rw-r--r-- | slirp/src/if.h (renamed from slirp/if.h) | 0 | ||||
-rw-r--r-- | slirp/src/ip.h (renamed from slirp/ip.h) | 0 | ||||
-rw-r--r-- | slirp/src/ip6.h (renamed from slirp/ip6.h) | 0 | ||||
-rw-r--r-- | slirp/src/ip6_icmp.c (renamed from slirp/ip6_icmp.c) | 0 | ||||
-rw-r--r-- | slirp/src/ip6_icmp.h (renamed from slirp/ip6_icmp.h) | 0 | ||||
-rw-r--r-- | slirp/src/ip6_input.c (renamed from slirp/ip6_input.c) | 0 | ||||
-rw-r--r-- | slirp/src/ip6_output.c (renamed from slirp/ip6_output.c) | 0 | ||||
-rw-r--r-- | slirp/src/ip_icmp.c (renamed from slirp/ip_icmp.c) | 0 | ||||
-rw-r--r-- | slirp/src/ip_icmp.h (renamed from slirp/ip_icmp.h) | 0 | ||||
-rw-r--r-- | slirp/src/ip_input.c (renamed from slirp/ip_input.c) | 0 | ||||
-rw-r--r-- | slirp/src/ip_output.c (renamed from slirp/ip_output.c) | 0 | ||||
-rw-r--r-- | slirp/src/libslirp.h (renamed from slirp/libslirp.h) | 10 | ||||
-rw-r--r-- | slirp/src/main.h (renamed from slirp/main.h) | 0 | ||||
-rw-r--r-- | slirp/src/mbuf.c (renamed from slirp/mbuf.c) | 0 | ||||
-rw-r--r-- | slirp/src/mbuf.h (renamed from slirp/mbuf.h) | 0 | ||||
-rw-r--r-- | slirp/src/misc.c (renamed from slirp/misc.c) | 3 | ||||
-rw-r--r-- | slirp/src/misc.h (renamed from slirp/misc.h) | 0 | ||||
-rw-r--r-- | slirp/src/ncsi-pkt.h (renamed from slirp/ncsi-pkt.h) | 0 | ||||
-rw-r--r-- | slirp/src/ncsi.c (renamed from slirp/ncsi.c) | 0 | ||||
-rw-r--r-- | slirp/src/ndp_table.c (renamed from slirp/ndp_table.c) | 0 | ||||
-rw-r--r-- | slirp/src/qtailq.h (renamed from slirp/qtailq.h) | 0 | ||||
-rw-r--r-- | slirp/src/sbuf.c (renamed from slirp/sbuf.c) | 0 | ||||
-rw-r--r-- | slirp/src/sbuf.h (renamed from slirp/sbuf.h) | 0 | ||||
-rw-r--r-- | slirp/src/slirp.c (renamed from slirp/slirp.c) | 14 | ||||
-rw-r--r-- | slirp/src/slirp.h (renamed from slirp/slirp.h) | 2 | ||||
-rw-r--r-- | slirp/src/socket.c (renamed from slirp/socket.c) | 11 | ||||
-rw-r--r-- | slirp/src/socket.h (renamed from slirp/socket.h) | 0 | ||||
-rw-r--r-- | slirp/src/state.c (renamed from slirp/state.c) | 52 | ||||
-rw-r--r-- | slirp/src/state.h (renamed from scripts/qmp/__init__.py) | 0 | ||||
-rw-r--r-- | slirp/src/stream.c | 119 | ||||
-rw-r--r-- | slirp/src/stream.h | 34 | ||||
-rw-r--r-- | slirp/src/tcp.h (renamed from slirp/tcp.h) | 0 | ||||
-rw-r--r-- | slirp/src/tcp_input.c (renamed from slirp/tcp_input.c) | 2 | ||||
-rw-r--r-- | slirp/src/tcp_output.c (renamed from slirp/tcp_output.c) | 0 | ||||
-rw-r--r-- | slirp/src/tcp_subr.c (renamed from slirp/tcp_subr.c) | 16 | ||||
-rw-r--r-- | slirp/src/tcp_timer.c (renamed from slirp/tcp_timer.c) | 0 | ||||
-rw-r--r-- | slirp/src/tcp_timer.h (renamed from slirp/tcp_timer.h) | 0 | ||||
-rw-r--r-- | slirp/src/tcp_var.h (renamed from slirp/tcp_var.h) | 0 | ||||
-rw-r--r-- | slirp/src/tcpip.h (renamed from slirp/tcpip.h) | 0 | ||||
-rw-r--r-- | slirp/src/tftp.c (renamed from slirp/tftp.c) | 0 | ||||
-rw-r--r-- | slirp/src/tftp.h (renamed from slirp/tftp.h) | 0 | ||||
-rw-r--r-- | slirp/src/udp.c (renamed from slirp/udp.c) | 1 | ||||
-rw-r--r-- | slirp/src/udp.h (renamed from slirp/udp.h) | 0 | ||||
-rw-r--r-- | slirp/src/udp6.c (renamed from slirp/udp6.c) | 0 | ||||
-rw-r--r-- | slirp/src/util.c (renamed from slirp/util.c) | 4 | ||||
-rw-r--r-- | slirp/src/util.h (renamed from slirp/util.h) | 4 | ||||
-rw-r--r-- | slirp/src/vmstate.c | 413 | ||||
-rw-r--r-- | slirp/src/vmstate.h | 396 | ||||
-rw-r--r-- | slirp/state.h | 9 | ||||
-rw-r--r-- | tests/acceptance/avocado_qemu/__init__.py | 30 | ||||
-rw-r--r-- | tests/acceptance/boot_linux_console.py | 1 | ||||
-rw-r--r-- | tests/acceptance/linux_initrd.py | 52 | ||||
-rw-r--r-- | tests/acceptance/migration.py | 53 | ||||
-rw-r--r-- | tests/acceptance/version.py | 1 | ||||
-rw-r--r-- | tests/acceptance/virtio_version.py | 3 | ||||
-rw-r--r-- | tests/acceptance/vnc.py | 1 | ||||
-rw-r--r-- | tests/migration/guestperf/engine.py | 7 | ||||
-rwxr-xr-x | tests/qemu-iotests/235 | 2 | ||||
-rwxr-xr-x | tests/qemu-iotests/238 | 2 | ||||
-rw-r--r-- | tests/qemu-iotests/iotests.py | 4 | ||||
-rw-r--r-- | tests/requirements.txt | 2 | ||||
-rwxr-xr-x | tests/vm/basevm.py | 2 | ||||
-rw-r--r-- | util/Makefile.objs | 1 | ||||
-rw-r--r-- | util/main-loop.c | 2 | ||||
-rw-r--r-- | vl.c | 3 |
219 files changed, 5160 insertions, 770 deletions
diff --git a/.gitignore b/.gitignore index b66b772551..77522561b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.doctrees /config-devices.* /config-all-devices.* /config-all-disas.* diff --git a/.travis.yml b/.travis.yml index cca57f4314..e942175dd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -151,6 +151,12 @@ matrix: # We manually include builds which we disable "make check" for - env: + - CONFIG="--without-default-devices" + - TEST_CMD="" + + + # We manually include builds which we disable "make check" for + - env: - CONFIG="--enable-debug --enable-tcg-interpreter" - TEST_CMD="" diff --git a/Kconfig.host b/Kconfig.host new file mode 100644 index 0000000000..add5b179f7 --- /dev/null +++ b/Kconfig.host @@ -0,0 +1,33 @@ +# These are "proxy" symbols used to pass config-host.mak values +# down to Kconfig. See also MINIKCONF_ARGS in the Makefile: +# these two need to be kept in sync. + +config KVM + bool + +config LINUX + bool + +config OPENGL + bool + +config X11 + bool + +config SPICE + bool + +config IVSHMEM + bool + +config TPM + bool + +config VHOST_USER + bool + +config XEN + bool + +config VIRTFS + bool diff --git a/MAINTAINERS b/MAINTAINERS index 5040d9dfb1..074ad46d47 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2567,3 +2567,9 @@ GIT submodules M: Daniel P. Berrange <berrange@redhat.com> S: Odd Fixes F: scripts/git-submodule.sh + +Sphinx documentation configuration and build machinery +M: Peter Maydell <peter.maydell@linaro.org> +S: Maintained +F: docs/conf.py +F: docs/*/conf.py @@ -87,6 +87,20 @@ endif include $(SRC_PATH)/rules.mak +# Create QEMU_PKGVERSION and FULL_VERSION strings +# If PKGVERSION is set, use that; otherwise get version and -dirty status from git +QEMU_PKGVERSION := $(if $(PKGVERSION),$(PKGVERSION),$(shell \ + cd $(SRC_PATH); \ + if test -e .git; then \ + git describe --match 'v*' 2>/dev/null | tr -d '\n'; \ + if ! git diff-index --quiet HEAD &>/dev/null; then \ + echo "-dirty"; \ + fi; \ + fi)) + +# Either "version (pkgversion)", or just "version" if pkgversion not set +FULL_VERSION := $(if $(QEMU_PKGVERSION),$(VERSION) ($(QEMU_PKGVERSION)),$(VERSION)) + GENERATED_FILES = qemu-version.h config-host.h qemu-options.def GENERATED_QAPI_FILES = qapi/qapi-builtin-types.h qapi/qapi-builtin-types.c @@ -313,8 +327,8 @@ DOCS= endif SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet) BUILD_DIR=$(BUILD_DIR) -SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(TARGET_DIRS)) -SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %-config-devices.mak.d, $(TARGET_DIRS)) +SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(filter %-softmmu, $(TARGET_DIRS))) +SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %.d, $(SUBDIR_DEVICES_MAK)) ifeq ($(SUBDIR_DEVICES_MAK),) config-all-devices.mak: @@ -329,9 +343,26 @@ endif -include $(SUBDIR_DEVICES_MAK_DEP) -%/config-devices.mak: default-configs/%.mak $(SRC_PATH)/scripts/make_device_config.sh - $(call quiet-command, \ - $(SHELL) $(SRC_PATH)/scripts/make_device_config.sh $< $*-config-devices.mak.d $@ > $@.tmp,"GEN","$@.tmp") +# This has to be kept in sync with Kconfig.host. +MINIKCONF_ARGS = \ + $(CONFIG_MINIKCONF_MODE) \ + $@ $*-config.devices.mak.d $< $(MINIKCONF_INPUTS) \ + CONFIG_KVM=$(CONFIG_KVM) \ + CONFIG_SPICE=$(CONFIG_SPICE) \ + CONFIG_IVSHMEM=$(CONFIG_IVSHMEM) \ + CONFIG_TPM=$(CONFIG_TPM) \ + CONFIG_XEN=$(CONFIG_XEN) \ + CONFIG_OPENGL=$(CONFIG_OPENGL) \ + CONFIG_X11=$(CONFIG_X11) \ + CONFIG_VHOST_USER=$(CONFIG_VHOST_USER) \ + CONFIG_VIRTFS=$(CONFIG_VIRTFS) \ + CONFIG_LINUX=$(CONFIG_LINUX) + +MINIKCONF_INPUTS = $(SRC_PATH)/Kconfig.host $(SRC_PATH)/hw/Kconfig +MINIKCONF = $(PYTHON) $(SRC_PATH)/scripts/minikconf.py \ + +$(SUBDIR_DEVICES_MAK): %/config-devices.mak: default-configs/%.mak $(MINIKCONF_INPUTS) $(BUILD_DIR)/config-host.mak + $(call quiet-command, $(MINIKCONF) $(MINIKCONF_ARGS) > $@.tmp, "GEN", "$@.tmp") $(call quiet-command, if test -f $@; then \ if cmp -s $@.old $@; then \ mv $@.tmp $@; \ @@ -383,32 +414,16 @@ dummy := $(call unnest-vars,, \ ui-obj-m \ audio-obj-y \ audio-obj-m \ - trace-obj-y \ - slirp-obj-y) + trace-obj-y) include $(SRC_PATH)/tests/Makefile.include -all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules +all: $(DOCS) $(if $(BUILD_DOCS),sphinxdocs) $(TOOLS) $(HELPERS-y) recurse-all modules qemu-version.h: FORCE $(call quiet-command, \ - (cd $(SRC_PATH); \ - if test -n "$(PKGVERSION)"; then \ - pkgvers="$(PKGVERSION)"; \ - else \ - if test -d .git; then \ - pkgvers=$$(git describe --match 'v*' 2>/dev/null | tr -d '\n');\ - if ! git diff-index --quiet HEAD &>/dev/null; then \ - pkgvers="$${pkgvers}-dirty"; \ - fi; \ - fi; \ - fi; \ - printf "#define QEMU_PKGVERSION \"$${pkgvers}\"\n"; \ - if test -n "$${pkgvers}"; then \ - printf '#define QEMU_FULL_VERSION QEMU_VERSION " (" QEMU_PKGVERSION ")"\n'; \ - else \ - printf '#define QEMU_FULL_VERSION QEMU_VERSION\n'; \ - fi; \ + (printf '#define QEMU_PKGVERSION "$(QEMU_PKGVERSION)"\n'; \ + printf '#define QEMU_FULL_VERSION "$(FULL_VERSION)"\n'; \ ) > $@.tmp) $(call quiet-command, if ! cmp -s $@ $@.tmp; then \ mv $@.tmp $@; \ @@ -458,7 +473,10 @@ CAP_CFLAGS += -DCAPSTONE_HAS_X86 subdir-capstone: .git-submodule-status $(call quiet-command,$(MAKE) -C $(SRC_PATH)/capstone CAPSTONE_SHARED=no BUILDDIR="$(BUILD_DIR)/capstone" CC="$(CC)" AR="$(AR)" LD="$(LD)" RANLIB="$(RANLIB)" CFLAGS="$(CAP_CFLAGS)" $(SUBDIR_MAKEFLAGS) $(BUILD_DIR)/capstone/$(LIBCAPSTONE)) -$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) $(slirp-obj-y) \ +subdir-slirp: .git-submodule-status + $(call quiet-command,$(MAKE) -C $(SRC_PATH)/slirp BUILD_DIR="$(BUILD_DIR)/slirp" CC="$(CC)" AR="$(AR)" LD="$(LD)" RANLIB="$(RANLIB)" CFLAGS="$(QEMU_CFLAGS)") + +$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) \ $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY)) ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS)) @@ -637,6 +655,14 @@ dist: qemu-$(VERSION).tar.bz2 qemu-%.tar.bz2: $(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.bz2,%,$@)" +# Note that these commands assume that there are no HTML files in +# the docs subdir in the source tree! If there are then this will +# blow them away for an in-source-tree 'make clean'. +define clean-manual = +rm -rf docs/$1/_static +rm -f docs/$1/objects.inv docs/$1/searchindex.js docs/$1/*.html +endef + distclean: clean rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi qemu-monitor-info.texi rm -f config-all-devices.mak config-all-disas.mak config.status @@ -657,6 +683,9 @@ distclean: clean rm -f docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html rm -f docs/qemu-block-drivers.7 rm -f docs/qemu-cpu-models.7 + rm -f .doctrees + $(call clean-manual,devel) + $(call clean-manual,interop) for d in $(TARGET_DIRS); do \ rm -rf $$d || exit 1 ; \ done @@ -690,7 +719,18 @@ else BLOBS= endif -install-doc: $(DOCS) +define install-manual = +for d in $$(cd docs && find $1 -type d); do $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/$$d"; done +for f in $$(cd docs && find $1 -type f); do $(INSTALL_DATA) "docs/$$f" "$(DESTDIR)$(qemu_docdir)/$$f"; done +endef + +# Note that we deliberately do not install the "devel" manual: it is +# for QEMU developers, and not interesting to our users. +.PHONY: install-sphinxdocs +install-sphinxdocs: sphinxdocs + $(call install-manual,interop) + +install-doc: $(DOCS) install-sphinxdocs $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)" $(INSTALL_DATA) qemu-doc.html "$(DESTDIR)$(qemu_docdir)" $(INSTALL_DATA) qemu-doc.txt "$(DESTDIR)$(qemu_docdir)" @@ -841,6 +881,23 @@ docs/version.texi: $(SRC_PATH)/VERSION %.pdf: %.texi docs/version.texi $(call quiet-command,texi2pdf $(TEXI2PDFFLAGS) $< -o $@,"GEN","$@") +# Sphinx builds all its documentation at once in one invocation +# and handles "don't rebuild things unless necessary" itself. +# The '.doctrees' files are cached information to speed this up. +.PHONY: sphinxdocs +sphinxdocs: docs/devel/index.html docs/interop/index.html + +# Canned command to build a single manual +build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -b html -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 docs/$1 ,"SPHINX","docs/$1") +# We assume all RST files in the manual's directory are used in it +manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py + +docs/devel/index.html: $(call manual-deps,devel) + $(call build-manual,devel) + +docs/interop/index.html: $(call manual-deps,interop) + $(call build-manual,interop) + qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@") @@ -869,7 +926,7 @@ docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi -html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html +html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html sphinxdocs info: qemu-doc.info docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info pdf: qemu-doc.pdf docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt diff --git a/Makefile.objs b/Makefile.objs index 6e91ee5674..ef65a6c12e 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -4,7 +4,6 @@ stub-obj-y = stubs/ util/ crypto/ util-obj-y = util/ qobject/ qapi/ chardev-obj-y = chardev/ -slirp-obj-$(CONFIG_SLIRP) = slirp/ ####################################################################### # authz-obj-y is code used by both qemu system emulation and qemu-img diff --git a/Makefile.target b/Makefile.target index 3b79e7074c..40830c5646 100644 --- a/Makefile.target +++ b/Makefile.target @@ -4,9 +4,12 @@ BUILD_DIR?=$(CURDIR)/.. include ../config-host.mak include config-target.mak -include config-devices.mak include $(SRC_PATH)/rules.mak +ifdef CONFIG_SOFTMMU +include config-devices.mak +endif + $(call set-vpath, $(SRC_PATH):$(BUILD_DIR)) ifdef CONFIG_LINUX QEMU_CFLAGS += -I../linux-headers @@ -174,7 +177,6 @@ target-obj-y := block-obj-y := common-obj-y := chardev-obj-y := -slirp-obj-y := include $(SRC_PATH)/Makefile.objs dummy := $(call unnest-vars,,target-obj-y) target-obj-y-save := $(target-obj-y) @@ -188,8 +190,7 @@ dummy := $(call unnest-vars,.., \ qom-obj-y \ io-obj-y \ common-obj-y \ - common-obj-m \ - slirp-obj-y) + common-obj-m) target-obj-y := $(target-obj-y-save) all-obj-y += $(common-obj-y) all-obj-y += $(target-obj-y) @@ -199,9 +200,10 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y) all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y) all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y) all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y) -all-obj-$(CONFIG_SOFTMMU) += $(slirp-obj-y) +ifdef CONFIG_SOFTMMU $(QEMU_PROG_BUILD): config-devices.mak +endif COMMON_LDADDS = ../libqemuutil.a @@ -406,7 +406,7 @@ includedir="\${prefix}/include" sysconfdir="\${prefix}/etc" local_statedir="\${prefix}/var" confsuffix="/qemu" -slirp="yes" +slirp="" oss_lib="" bsd="no" linux="no" @@ -466,7 +466,7 @@ gcrypt_hmac="no" auth_pam="" vte="" virglrenderer="" -tpm="yes" +tpm="" libssh2="" live_block_migration="yes" numa="" @@ -487,7 +487,7 @@ libxml2="" docker="no" debug_mutex="no" libpmem="" -libudev="no" +default_devices="yes" # cross compilers defaults, can be overridden with --cross-cc-ARCH cross_cc_aarch64="aarch64-linux-gnu-gcc" @@ -996,6 +996,10 @@ for opt do ;; --with-trace-file=*) trace_file="$optarg" ;; + --with-default-devices) default_devices="yes" + ;; + --without-default-devices) default_devices="no" + ;; --enable-gprof) gprof="yes" ;; --enable-gcov) gcov="yes" @@ -1105,6 +1109,10 @@ for opt do ;; --disable-slirp) slirp="no" ;; + --enable-slirp=git) slirp="git" + ;; + --enable-slirp=system) slirp="system" + ;; --disable-vde) vde="no" ;; --enable-vde) vde="yes" @@ -3873,20 +3881,20 @@ EOF fi ########################################## -# TPM passthrough is only on x86 Linux +# TPM emulation is only on POSIX -if test "$targetos" = Linux && { test "$cpu" = i386 || test "$cpu" = x86_64; }; then - tpm_passthrough=$tpm -else - tpm_passthrough=no +if test "$tpm" = ""; then + if test "$mingw32" = "yes"; then + tpm=no + else + tpm=yes + fi +elif test "$tpm" = "yes"; then + if test "$mingw32" = "yes" ; then + error_exit "TPM emulation only available on POSIX systems" + fi fi -# TPM emulator is for all posix systems -if test "$mingw32" != "yes"; then - tpm_emulator=$tpm -else - tpm_emulator=no -fi ########################################## # attr probe @@ -4589,13 +4597,24 @@ if compile_prog "" "" ; then syncfs=yes fi +# Check we have a new enough version of sphinx-build +has_sphinx_build() { + # This is a bit awkward but works: create a trivial document and + # try to run it with our configuration file (which enforces a + # version requirement). This will fail if either + # sphinx-build doesn't exist at all or if it is too old. + mkdir -p "$TMPDIR1/sphinx" + touch "$TMPDIR1/sphinx/index.rst" + sphinx-build -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1 +} + # Check if tools are available to build documentation. if test "$docs" != "no" ; then - if has makeinfo && has pod2man; then + if has makeinfo && has pod2man && has_sphinx_build; then docs=yes else if test "$docs" = "yes" ; then - feature_not_found "docs" "Install texinfo and Perl/perl-podlators" + feature_not_found "docs" "Install texinfo, Perl/perl-podlators and python-sphinx" fi docs=no fi @@ -5755,6 +5774,55 @@ if test "$libpmem" != "no"; then fi ########################################## +# check for slirp + +case "$slirp" in + "" | yes) + if $pkg_config slirp; then + slirp=system + elif test -e "${source_path}/.git" && test $git_update = 'yes' ; then + slirp=git + elif test -e "${source_path}/slirp/Makefile" ; then + slirp=internal + elif test -z "$slirp" ; then + slirp=no + else + feature_not_found "slirp" "Install slirp devel or git submodule" + fi + ;; + + system) + if ! $pkg_config slirp; then + feature_not_found "slirp" "Install slirp devel" + fi + ;; +esac + +case "$slirp" in + git | internal) + if test "$slirp" = git; then + git_submodules="${git_submodules} slirp" + fi + mkdir -p slirp + slirp_cflags="-I\$(SRC_PATH)/slirp/src -I\$(BUILD_DIR)/slirp/src" + slirp_libs="-L\$(BUILD_DIR)/slirp -lslirp" + ;; + + system) + slirp_version=$($pkg_config --modversion slirp 2>/dev/null) + slirp_cflags=$($pkg_config --cflags slirp 2>/dev/null) + slirp_libs=$($pkg_config --libs slirp 2>/dev/null) + ;; + + no) + ;; + *) + error_exit "Unknown state for slirp: $slirp" + ;; +esac + + +########################################## # End of CC checks # After here, no more $cc or $ld runs @@ -6111,7 +6179,8 @@ echo "QEMU_LDFLAGS $QEMU_LDFLAGS" echo "make $make" echo "install $install" echo "python $python ($python_version)" -if test "$slirp" = "yes" ; then +echo "slirp support $slirp $(echo_version $slirp $slirp_version)" +if test "$slirp" != "no" ; then echo "smbd $smbd" fi echo "module support $modules" @@ -6250,6 +6319,7 @@ echo "capstone $capstone" echo "docker $docker" echo "libpmem support $libpmem" echo "libudev $libudev" +echo "default devices $default_devices" if test "$supported_cpu" = "no"; then echo @@ -6311,6 +6381,11 @@ echo "GIT_UPDATE=$git_update" >> $config_host_mak echo "ARCH=$ARCH" >> $config_host_mak +if test "$default_devices" = "yes" ; then + echo "CONFIG_MINIKCONF_MODE=--defconfig" >> $config_host_mak +else + echo "CONFIG_MINIKCONF_MODE=--allnoconfig" >> $config_host_mak +fi if test "$debug_tcg" = "yes" ; then echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak fi @@ -6372,9 +6447,14 @@ fi if test "$profiler" = "yes" ; then echo "CONFIG_PROFILER=y" >> $config_host_mak fi -if test "$slirp" = "yes" ; then +if test "$slirp" != "no"; then echo "CONFIG_SLIRP=y" >> $config_host_mak echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak + echo "SLIRP_CFLAGS=$slirp_cflags" >> $config_host_mak + echo "SLIRP_LIBS=$slirp_libs" >> $config_host_mak +fi +if [ "$slirp" = "git" -o "$slirp" = "internal" ]; then + echo "config-host.h: subdir-slirp" >> $config_host_mak fi if test "$vde" = "yes" ; then echo "CONFIG_VDE=y" >> $config_host_mak @@ -7427,12 +7507,18 @@ fi if supported_xen_target $target; then echo "CONFIG_XEN=y" >> $config_target_mak + echo "$target/config-devices.mak: CONFIG_XEN=y" >> $config_host_mak if test "$xen_pci_passthrough" = yes; then echo "CONFIG_XEN_PCI_PASSTHROUGH=y" >> "$config_target_mak" fi +else + echo "$target/config-devices.mak: CONFIG_XEN=n" >> $config_host_mak fi if supported_kvm_target $target; then echo "CONFIG_KVM=y" >> $config_target_mak + echo "$target/config-devices.mak: CONFIG_KVM=y" >> $config_host_mak +else + echo "$target/config-devices.mak: CONFIG_KVM=n" >> $config_host_mak fi if supported_hax_target $target; then echo "CONFIG_HAX=y" >> $config_target_mak @@ -7663,6 +7749,7 @@ LINKS="$LINKS pc-bios/qemu-icon.bmp" LINKS="$LINKS .gdbinit scripts" # scripts needed by relative path in .gdbinit LINKS="$LINKS tests/acceptance tests/data" LINKS="$LINKS tests/qemu-iotests/check" +LINKS="$LINKS python" for bios_file in \ $source_path/pc-bios/*.bin \ $source_path/pc-bios/*.lid \ diff --git a/default-configs/alpha-softmmu.mak b/default-configs/alpha-softmmu.mak index 49cb7ce351..d186fe8e9b 100644 --- a/default-configs/alpha-softmmu.mak +++ b/default-configs/alpha-softmmu.mak @@ -1,22 +1,10 @@ # Default configuration for alpha-softmmu -include pci.mak -include usb.mak -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_I82374=y -CONFIG_I8254=y -CONFIG_I8257=y -CONFIG_PARALLEL=y -CONFIG_FDC=y -CONFIG_PCKBD=y -CONFIG_VGA_CIRRUS=y -CONFIG_IDE_CORE=y -CONFIG_IDE_QDEV=y -CONFIG_VMWARE_VGA=y -CONFIG_IDE_CMD646=y -CONFIG_I8259=y -CONFIG_MC146818RTC=y -CONFIG_ISA_TESTDEV=y -CONFIG_SMC37C669=y +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_PCI_DEVICES=n +#CONFIG_TEST_DEVICES=n + +# Boards: +# CONFIG_DP264=y diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index bd6943b691..2a7efc1167 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -1,13 +1,11 @@ # Default configuration for arm-softmmu -include pci.mak -include usb.mak +CONFIG_PCI=y +CONFIG_PCI_DEVICES=y CONFIG_VGA=y CONFIG_NAND=y CONFIG_ECC=y CONFIG_SERIAL=y -CONFIG_PTIMER=y -CONFIG_SD=y CONFIG_MAX7310=y CONFIG_WM8750=y CONFIG_TWL92230=y @@ -25,7 +23,6 @@ CONFIG_DDC=y CONFIG_SII9022=y CONFIG_ADS7846=y CONFIG_MAX111X=y -CONFIG_SSI=y CONFIG_SSI_SD=y CONFIG_SSI_M25P80=y CONFIG_LAN9118=y @@ -37,7 +34,6 @@ CONFIG_DS1338=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y CONFIG_MICRODRIVE=y -CONFIG_USB=y CONFIG_USB_MUSB=y CONFIG_USB_EHCI_SYSBUS=y CONFIG_PLATFORM_BUS=y @@ -51,7 +47,6 @@ CONFIG_ARM_V7M=y CONFIG_NETDUINO2=y CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_KVM=$(CONFIG_KVM) CONFIG_ARM_TIMER=y CONFIG_ARM_MPTIMER=y CONFIG_A9_GTIMER=y @@ -71,7 +66,6 @@ CONFIG_CADENCE=y CONFIG_XGMAC=y CONFIG_EXYNOS4=y CONFIG_PXA2XX=y -CONFIG_I2C=y CONFIG_BITBANG_I2C=y CONFIG_FRAMEBUFFER=y CONFIG_XILINX_SPIPS=y @@ -125,11 +119,8 @@ CONFIG_VERSATILE=y CONFIG_VERSATILE_PCI=y CONFIG_VERSATILE_I2C=y +CONFIG_PCI_EXPRESS=y CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y -CONFIG_VFIO=$(CONFIG_LINUX) -CONFIG_VFIO_PLATFORM=y -CONFIG_VFIO_XGMAC=y -CONFIG_VFIO_AMD_XGBE=y CONFIG_SDHCI=y CONFIG_INTEGRATOR=y @@ -165,3 +156,6 @@ CONFIG_PCI_EXPRESS_DESIGNWARE=y CONFIG_STRONGARM=y CONFIG_HIGHBANK=y CONFIG_MUSICPAL=y + +# for realview and versatilepb +CONFIG_LSI_SCSI_PCI=y diff --git a/default-configs/cris-softmmu.mak b/default-configs/cris-softmmu.mak index a637c4b4bf..5932cf4d06 100644 --- a/default-configs/cris-softmmu.mak +++ b/default-configs/cris-softmmu.mak @@ -1,7 +1,5 @@ # Default configuration for cris-softmmu -CONFIG_ETRAXFS=y -CONFIG_NAND=y -CONFIG_PTIMER=y -CONFIG_PFLASH_CFI02=y +# Boards: +# CONFIG_AXIS=y diff --git a/default-configs/hppa-softmmu.mak b/default-configs/hppa-softmmu.mak index b594a6ddd9..b64c5eb3ff 100644 --- a/default-configs/hppa-softmmu.mak +++ b/default-configs/hppa-softmmu.mak @@ -1,13 +1,9 @@ -include pci.mak -include usb.mak -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_ISA_BUS=y -CONFIG_I8259=y -CONFIG_E1000_PCI=y -CONFIG_IDE_ISA=y -CONFIG_IDE_CMD646=y -# CONFIG_IDE_MMIO=y -CONFIG_VIRTIO_VGA=y -CONFIG_MC146818RTC=y +# Default configuration for hppa-softmmu + +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_PCI_DEVICES=n + +# Boards: +# CONFIG_DINO=y diff --git a/default-configs/hyperv.mak b/default-configs/hyperv.mak deleted file mode 100644 index 5d0d9fd830..0000000000 --- a/default-configs/hyperv.mak +++ /dev/null @@ -1,2 +0,0 @@ -CONFIG_HYPERV=$(CONFIG_KVM) -CONFIG_HYPERV_TESTDEV=y diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 15b628757b..ba3fb3ff50 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -1,74 +1,27 @@ # Default configuration for i386-softmmu -include pci.mak -include sound.mak -include usb.mak -include hyperv.mak -CONFIG_QXL=$(CONFIG_SPICE) -CONFIG_VGA_ISA=y -CONFIG_VGA_CIRRUS=y -CONFIG_VMWARE_VGA=y -CONFIG_VMXNET3_PCI=y -CONFIG_VIRTIO_VGA=y -CONFIG_VMMOUSE=y -CONFIG_IPMI=y -CONFIG_IPMI_LOCAL=y -CONFIG_IPMI_EXTERN=y -CONFIG_ISA_IPMI_KCS=y -CONFIG_ISA_IPMI_BT=y -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_PARALLEL=y -CONFIG_I8254=y -CONFIG_PCSPK=y -CONFIG_PCKBD=y -CONFIG_FDC=y -CONFIG_ACPI=y -CONFIG_ACPI_X86=y -CONFIG_ACPI_X86_ICH=y -CONFIG_ACPI_MEMORY_HOTPLUG=y -CONFIG_ACPI_CPU_HOTPLUG=y -CONFIG_APM=y -CONFIG_I8257=y -CONFIG_IDE_ISA=y -CONFIG_IDE_PIIX=y -CONFIG_NE2000_ISA=y -CONFIG_HPET=y -CONFIG_APPLESMC=y -CONFIG_I8259=y -CONFIG_PFLASH_CFI01=y -CONFIG_TPM_TIS=$(CONFIG_TPM) -CONFIG_TPM_CRB=$(CONFIG_TPM) -CONFIG_MC146818RTC=y -CONFIG_PCI_PIIX=y -CONFIG_WDT_IB700=y -CONFIG_ISA_DEBUG=y -CONFIG_ISA_TESTDEV=y -CONFIG_VMPORT=y -CONFIG_SGA=y -CONFIG_LPC_ICH9=y -CONFIG_PCI_EXPRESS_Q35=y -CONFIG_APIC=y -CONFIG_IOAPIC=y -CONFIG_PVPANIC=y -CONFIG_MEM_DEVICE=y -CONFIG_DIMM=y -CONFIG_NVDIMM=y -CONFIG_ACPI_NVDIMM=y -CONFIG_PCIE_PORT=y -CONFIG_XIO3130=y -CONFIG_IOH3420=y -CONFIG_I82801B11=y -CONFIG_SMBIOS=y -CONFIG_PXB=y -CONFIG_ACPI_VMGENID=y -CONFIG_ACPI_SMBUS=y -CONFIG_SMBUS_EEPROM=y -CONFIG_FW_CFG_DMA=y -CONFIG_I2C=y -CONFIG_SEV=$(CONFIG_KVM) -CONFIG_VTD=y -CONFIG_AMD_IOMMU=y -CONFIG_PAM=y +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_AMD_IOMMU=n +#CONFIG_APPLESMC=n +#CONFIG_FDC=n +#CONFIG_HPET=n +#CONFIG_HYPERV=n +#CONFIG_ISA_DEBUG=n +#CONFIG_ISA_IPMI_BT=n +#CONFIG_ISA_IPMI_KCS=n +#CONFIG_PCI_DEVICES=n +#CONFIG_PVPANIC=n +#CONFIG_QXL=n +#CONFIG_SEV=n +#CONFIG_SGA=n +#CONFIG_TEST_DEVICES=n +#CONFIG_TPM_CRB=n +#CONFIG_TPM_TIS=n +#CONFIG_VTD=n + +# Boards: +# +CONFIG_ISAPC=y CONFIG_I440FX=y CONFIG_Q35=y diff --git a/default-configs/lm32-softmmu.mak b/default-configs/lm32-softmmu.mak index 4049b23562..6d259665d6 100644 --- a/default-configs/lm32-softmmu.mak +++ b/default-configs/lm32-softmmu.mak @@ -1,10 +1,10 @@ # Default configuration for lm32-softmmu +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_MILKYMIST_TMU2=n # disabling it actually causes compile-time failures + +# Boards: +# CONFIG_LM32=y CONFIG_MILKYMIST=y -CONFIG_MILKYMIST_TMU2=$(call land,$(CONFIG_X11),$(CONFIG_OPENGL)) -CONFIG_FRAMEBUFFER=y -CONFIG_PTIMER=y -CONFIG_PFLASH_CFI01=y -CONFIG_PFLASH_CFI02=y -CONFIG_SD=y diff --git a/default-configs/m68k-softmmu.mak b/default-configs/m68k-softmmu.mak index 27f5274244..e17495e2a0 100644 --- a/default-configs/m68k-softmmu.mak +++ b/default-configs/m68k-softmmu.mak @@ -1,6 +1,6 @@ # Default configuration for m68k-softmmu -CONFIG_COLDFIRE=y -CONFIG_PTIMER=y +# Boards: +# CONFIG_AN5206=y CONFIG_MCF5208=y diff --git a/default-configs/microblaze-softmmu.mak b/default-configs/microblaze-softmmu.mak index 14837cf74a..db8c6e4bba 100644 --- a/default-configs/microblaze-softmmu.mak +++ b/default-configs/microblaze-softmmu.mak @@ -1,15 +1,7 @@ # Default configuration for microblaze-softmmu -CONFIG_PTIMER=y -CONFIG_PFLASH_CFI01=y -CONFIG_SERIAL=y -CONFIG_XILINX=y -CONFIG_XILINX_AXI=y -CONFIG_XILINX_SPI=y -CONFIG_XILINX_ETHLITE=y -CONFIG_SSI=y -CONFIG_SSI_M25P80=y -CONFIG_XLNX_ZYNQMP=y +# Boards: +# CONFIG_PETALOGIX_S3ADSP1800=y CONFIG_PETALOGIX_ML605=y CONFIG_XLNX_ZYNQMP_PMU=y diff --git a/default-configs/mips-softmmu-common.mak b/default-configs/mips-softmmu-common.mak index ded74980e1..0795d522db 100644 --- a/default-configs/mips-softmmu-common.mak +++ b/default-configs/mips-softmmu-common.mak @@ -1,10 +1,9 @@ # Common mips*-softmmu CONFIG defines -include pci.mak -include sound.mak -include usb.mak +CONFIG_ISA_BUS=y +CONFIG_PCI=y +CONFIG_PCI_DEVICES=y CONFIG_ESP=y -CONFIG_SCSI=y CONFIG_VGA_ISA=y CONFIG_VGA_ISA_MM=y CONFIG_VGA_CIRRUS=y @@ -31,13 +30,12 @@ CONFIG_MIPSNET=y CONFIG_PFLASH_CFI01=y CONFIG_I8259=y CONFIG_MC146818RTC=y -CONFIG_ISA_TESTDEV=y CONFIG_EMPTY_SLOT=y CONFIG_MIPS_CPS=y CONFIG_MIPS_ITU=y -CONFIG_I2C=y CONFIG_R4K=y CONFIG_MALTA=y CONFIG_MIPSSIM=y CONFIG_ACPI_SMBUS=y CONFIG_SMBUS_EEPROM=y +CONFIG_TEST_DEVICES=y diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index 9eb1208b58..8b255efc54 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -10,6 +10,8 @@ CONFIG_JAZZ=y CONFIG_G364FB=y CONFIG_JAZZ_LED=y CONFIG_VT82C686=y +CONFIG_AHCI=y CONFIG_MIPS_BOSTON=y CONFIG_FITLOADER=y +CONFIG_PCI_EXPRESS=y CONFIG_PCI_EXPRESS_XILINX=y diff --git a/default-configs/moxie-softmmu.mak b/default-configs/moxie-softmmu.mak index 17ba906dc2..bd50da3c58 100644 --- a/default-configs/moxie-softmmu.mak +++ b/default-configs/moxie-softmmu.mak @@ -1,8 +1,5 @@ # Default configuration for moxie-softmmu -CONFIG_ISA_BUS=y -CONFIG_MC146818RTC=y -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_VGA=y +# Boards: +# CONFIG_MOXIESIM=y diff --git a/default-configs/nios2-softmmu.mak b/default-configs/nios2-softmmu.mak index ab42d0fc28..e11dc54960 100644 --- a/default-configs/nios2-softmmu.mak +++ b/default-configs/nios2-softmmu.mak @@ -1,7 +1,5 @@ # Default configuration for nios2-softmmu -CONFIG_NIOS2=y -CONFIG_SERIAL=y -CONFIG_PTIMER=y -CONFIG_ALTERA_TIMER=y +# Boards: +# CONFIG_NIOS2_10M50=y diff --git a/default-configs/or1k-softmmu.mak b/default-configs/or1k-softmmu.mak index 6a0f2ef6cf..168101c39a 100644 --- a/default-configs/or1k-softmmu.mak +++ b/default-configs/or1k-softmmu.mak @@ -1,6 +1,5 @@ # Default configuration for or1k-softmmu -CONFIG_SERIAL=y -CONFIG_OPENCORES_ETH=y -CONFIG_OMPIC=y +# Boards: +# CONFIG_OR1K_SIM=y diff --git a/default-configs/pci.mak b/default-configs/pci.mak deleted file mode 100644 index 037636fa33..0000000000 --- a/default-configs/pci.mak +++ /dev/null @@ -1,51 +0,0 @@ -CONFIG_PCI=y -# For now, CONFIG_IDE_CORE requires ISA, so we enable it here -CONFIG_ISA_BUS=y -CONFIG_VIRTIO_PCI=y -include virtio.mak -CONFIG_USB_UHCI=y -CONFIG_USB_OHCI=y -CONFIG_USB_EHCI=y -CONFIG_USB_XHCI=y -CONFIG_USB_XHCI_NEC=y -CONFIG_NE2000_PCI=y -CONFIG_EEPRO100_PCI=y -CONFIG_PCNET_PCI=y -CONFIG_PCNET_COMMON=y -CONFIG_AC97=y -CONFIG_HDA=y -CONFIG_ES1370=y -CONFIG_SCSI=y -CONFIG_LSI_SCSI_PCI=y -CONFIG_VMW_PVSCSI_SCSI_PCI=y -CONFIG_MEGASAS_SCSI_PCI=y -CONFIG_MPTSAS_SCSI_PCI=y -CONFIG_RTL8139_PCI=y -CONFIG_E1000_PCI=y -CONFIG_E1000E_PCI_EXPRESS=y -CONFIG_IDE_CORE=y -CONFIG_IDE_QDEV=y -CONFIG_IDE_PCI=y -CONFIG_AHCI=y -CONFIG_ESP=y -CONFIG_ESP_PCI=y -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_SERIAL_PCI=y -CONFIG_CAN_BUS=y -CONFIG_CAN_SJA1000=y -CONFIG_CAN_PCI=y -CONFIG_IPACK=y -CONFIG_WDT_IB6300ESB=y -CONFIG_PCI_TESTDEV=y -CONFIG_NVME_PCI=y -CONFIG_SD=y -CONFIG_SDHCI=y -CONFIG_EDU=y -CONFIG_VGA=y -CONFIG_VGA_PCI=y -CONFIG_BOCHS_DISPLAY=y -CONFIG_IVSHMEM_DEVICE=$(CONFIG_IVSHMEM) -CONFIG_ROCKER=y -CONFIG_VFIO=$(CONFIG_LINUX) -CONFIG_VFIO_PCI=y diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak index 52acb7cf39..6ea36d4090 100644 --- a/default-configs/ppc-softmmu.mak +++ b/default-configs/ppc-softmmu.mak @@ -1,77 +1,17 @@ # Default configuration for ppc-softmmu -include pci.mak -include sound.mak -include usb.mak - # For embedded PPCs: -CONFIG_PPC4XX=y -CONFIG_M48T59=y -CONFIG_SERIAL=y -CONFIG_I8257=y -CONFIG_OPENPIC=y -CONFIG_PPCE500_PCI=y -CONFIG_PFLASH_CFI01=y -CONFIG_PFLASH_CFI02=y -CONFIG_PTIMER=y -CONFIG_I8259=y -CONFIG_XILINX=y -CONFIG_XILINX_ETHLITE=y CONFIG_E500=y -CONFIG_OPENPIC_KVM=$(call land,$(CONFIG_E500),$(CONFIG_KVM)) -CONFIG_PLATFORM_BUS=y -CONFIG_ETSEC=y CONFIG_PPC405=y CONFIG_PPC440=y CONFIG_VIRTEX=y # For Sam460ex CONFIG_SAM460EX=y -CONFIG_USB_EHCI_SYSBUS=y -CONFIG_SM501=y -CONFIG_DDC=y -CONFIG_IDE_SII3112=y -CONFIG_I2C=y -CONFIG_AT24C=y -CONFIG_BITBANG_I2C=y -CONFIG_M41T80=y -CONFIG_VGA_CIRRUS=y -CONFIG_SMBUS_EEPROM=y # For Macs -CONFIG_ESCC=y -CONFIG_MACIO=y -CONFIG_MACIO_GPIO=y -CONFIG_SUNGEM=y -CONFIG_MOS6522=y -CONFIG_CUDA=y -CONFIG_ADB=y -CONFIG_MAC_NVRAM=y -CONFIG_MAC_DBDMA=y -CONFIG_MAC_PMU=y -CONFIG_HEATHROW_PIC=y -CONFIG_GRACKLE_PCI=y -CONFIG_UNIN_PCI=y -CONFIG_DEC_PCI=y -CONFIG_IDE_MACIO=y CONFIG_MAC_OLDWORLD=y CONFIG_MAC_NEWWORLD=y # For PReP CONFIG_PREP=y -CONFIG_PREP_PCI=y -CONFIG_SERIAL_ISA=y -CONFIG_MC146818RTC=y -CONFIG_ISA_TESTDEV=y -CONFIG_RS6000_MC=y -CONFIG_PARALLEL=y -CONFIG_I82374=y -CONFIG_I82378=y -CONFIG_I8254=y -CONFIG_PCKBD=y -CONFIG_FDC=y -CONFIG_NE2000_ISA=y -CONFIG_PC87312=y -CONFIG_PCSPK=y -CONFIG_IDE_ISA=y -CONFIG_CS4231A=y diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index 7f34ad0528..cca52665d9 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -5,19 +5,6 @@ include ppc-softmmu.mak # For PowerNV CONFIG_POWERNV=y -CONFIG_IPMI=y -CONFIG_IPMI_LOCAL=y -CONFIG_IPMI_EXTERN=y -CONFIG_ISA_IPMI_BT=y # For pSeries CONFIG_PSERIES=y -CONFIG_VIRTIO_VGA=y -CONFIG_XICS=$(CONFIG_PSERIES) -CONFIG_XICS_SPAPR=$(CONFIG_PSERIES) -CONFIG_XICS_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM)) -CONFIG_XIVE=$(CONFIG_PSERIES) -CONFIG_XIVE_SPAPR=$(CONFIG_PSERIES) -CONFIG_MEM_DEVICE=y -CONFIG_DIMM=y -CONFIG_SPAPR_RNG=y diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak index 65337166e1..1ae077ed87 100644 --- a/default-configs/riscv32-softmmu.mak +++ b/default-configs/riscv32-softmmu.mak @@ -1,21 +1,12 @@ -# Default configuration for riscv-softmmu +# Default configuration for riscv32-softmmu -include pci.mak -include usb.mak - -CONFIG_SERIAL=y -CONFIG_VIRTIO_MMIO=y - -CONFIG_CADENCE=y - -CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y - -CONFIG_VGA=y -CONFIG_VGA_PCI=y +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_PCI_DEVICES=n +# Boards: +# CONFIG_SPIKE=y -CONFIG_HART=y CONFIG_SIFIVE_E=y -CONFIG_SIFIVE=y CONFIG_SIFIVE_U=y CONFIG_RISCV_VIRT=y diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak index 65337166e1..235c6f473f 100644 --- a/default-configs/riscv64-softmmu.mak +++ b/default-configs/riscv64-softmmu.mak @@ -1,21 +1,3 @@ -# Default configuration for riscv-softmmu +# Default configuration for riscv64-softmmu -include pci.mak -include usb.mak - -CONFIG_SERIAL=y -CONFIG_VIRTIO_MMIO=y - -CONFIG_CADENCE=y - -CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y - -CONFIG_VGA=y -CONFIG_VGA_PCI=y - -CONFIG_SPIKE=y -CONFIG_HART=y -CONFIG_SIFIVE_E=y -CONFIG_SIFIVE=y -CONFIG_SIFIVE_U=y -CONFIG_RISCV_VIRT=y +include riscv32-softmmu.mak diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak index 6f2c6cec18..f2287a133f 100644 --- a/default-configs/s390x-softmmu.mak +++ b/default-configs/s390x-softmmu.mak @@ -1,12 +1,13 @@ -CONFIG_PCI=y -CONFIG_VIRTIO_PCI=$(CONFIG_PCI) -include virtio.mak -CONFIG_SCLPCONSOLE=y -CONFIG_TERMINAL3270=y -CONFIG_S390_FLIC=y -CONFIG_S390_FLIC_KVM=$(CONFIG_KVM) -CONFIG_WDT_DIAG288=y +# Default configuration for s390x-softmmu + +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_TERMINAL3270=n +#CONFIG_VFIO_AP=n +#CONFIG_VFIO_CCW=n +#CONFIG_VIRTIO_PCI=n +#CONFIG_WDT_DIAG288=n + +# Boards: +# CONFIG_S390_CCW_VIRTIO=y -CONFIG_VFIO=$(CONFIG_LINUX) -CONFIG_VFIO_CCW=y -CONFIG_VFIO_AP=y diff --git a/default-configs/sh4-softmmu.mak b/default-configs/sh4-softmmu.mak index 1fdb009151..565e8b0b5d 100644 --- a/default-configs/sh4-softmmu.mak +++ b/default-configs/sh4-softmmu.mak @@ -1,23 +1,11 @@ -# Default configuration for sh4-softmmu +# Default configuration for sh4eb-softmmu -include pci.mak -include usb.mak -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_PTIMER=y -CONFIG_PFLASH_CFI02=y -CONFIG_SH4=y -CONFIG_IDE_MMIO=y -CONFIG_SM501=y -CONFIG_I2C=y -CONFIG_DDC=y -CONFIG_ISA_TESTDEV=y -CONFIG_I82378=y -CONFIG_I8259=y -CONFIG_I8254=y -CONFIG_PCSPK=y -CONFIG_I82374=y -CONFIG_I8257=y -CONFIG_MC146818RTC=y +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_PCI_DEVICES=n +#CONFIG_TEST_DEVICES=n + +# Boards: +# CONFIG_R2D=y CONFIG_SHIX=y diff --git a/default-configs/sh4eb-softmmu.mak b/default-configs/sh4eb-softmmu.mak index 3b550a5fe8..522a7a50fa 100644 --- a/default-configs/sh4eb-softmmu.mak +++ b/default-configs/sh4eb-softmmu.mak @@ -1,23 +1,3 @@ # Default configuration for sh4eb-softmmu -include pci.mak -include usb.mak -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_PTIMER=y -CONFIG_PFLASH_CFI02=y -CONFIG_SH4=y -CONFIG_IDE_MMIO=y -CONFIG_SM501=y -CONFIG_I2C=y -CONFIG_DDC=y -CONFIG_ISA_TESTDEV=y -CONFIG_I82378=y -CONFIG_I8259=y -CONFIG_I8254=y -CONFIG_PCSPK=y -CONFIG_I82374=y -CONFIG_I8257=y -CONFIG_MC146818RTC=y -CONFIG_R2D=y -CONFIG_SHIX=y +include sh4-softmmu.mak diff --git a/default-configs/sound.mak b/default-configs/sound.mak deleted file mode 100644 index 4f22c34b5d..0000000000 --- a/default-configs/sound.mak +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG_SB16=y -CONFIG_ADLIB=y -CONFIG_GUS=y -CONFIG_CS4231A=y diff --git a/default-configs/sparc-softmmu.mak b/default-configs/sparc-softmmu.mak index 59a4a3d693..ee85218115 100644 --- a/default-configs/sparc-softmmu.mak +++ b/default-configs/sparc-softmmu.mak @@ -1,23 +1,11 @@ # Default configuration for sparc-softmmu -CONFIG_ISA_BUS=y -CONFIG_ECC=y -CONFIG_SCSI=y -CONFIG_ESP=y -CONFIG_ESCC=y -CONFIG_M48T59=y -CONFIG_PTIMER=y -CONFIG_FDC=y -CONFIG_EMPTY_SLOT=y -CONFIG_PCNET_COMMON=y -CONFIG_LANCE=y -CONFIG_TCX=y -CONFIG_CG3=y -CONFIG_SLAVIO=y -CONFIG_CS4231=y -CONFIG_GRLIB=y -CONFIG_STP2000=y -CONFIG_ECCMEMCTL=y +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_TCX=n +#CONFIG_CG3=n +# Boards: +# CONFIG_SUN4M=y CONFIG_LEON3=y diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak index 1fae4888db..e50030a229 100644 --- a/default-configs/sparc64-softmmu.mak +++ b/default-configs/sparc64-softmmu.mak @@ -1,21 +1,12 @@ # Default configuration for sparc64-softmmu -include pci.mak -include usb.mak -CONFIG_M48T59=y -CONFIG_PTIMER=y -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_PARALLEL=y -CONFIG_PCKBD=y -CONFIG_FDC=y -CONFIG_IDE_ISA=y -CONFIG_IDE_CMD646=y -CONFIG_PCI_SABRE=y -CONFIG_SIMBA=y -CONFIG_SUNHME=y -CONFIG_MC146818RTC=y -CONFIG_ISA_TESTDEV=y -CONFIG_SUN4V_RTC=y +# Uncomment the following lines to disable these optional devices: +# +#CONFIG_PCI_DEVICES=n +#CONFIG_SUNHME=n +#CONFIG_TEST_DEVICES=n + +# Boards: +# CONFIG_SUN4U=y CONFIG_NIAGARA=y diff --git a/default-configs/unicore32-softmmu.mak b/default-configs/unicore32-softmmu.mak index 5f6c4a8047..0bfce48c6d 100644 --- a/default-configs/unicore32-softmmu.mak +++ b/default-configs/unicore32-softmmu.mak @@ -1,5 +1,5 @@ # Default configuration for unicore32-softmmu -CONFIG_ISA_BUS=y + +# Boards: +# CONFIG_PUV3=y -CONFIG_PTIMER=y -CONFIG_PCKBD=y diff --git a/default-configs/usb.mak b/default-configs/usb.mak deleted file mode 100644 index e42cfeabbe..0000000000 --- a/default-configs/usb.mak +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG_USB=y -CONFIG_USB_TABLET_WACOM=y -CONFIG_USB_STORAGE_BOT=y -CONFIG_USB_STORAGE_UAS=y -CONFIG_USB_STORAGE_MTP=y -CONFIG_SCSI=y -CONFIG_USB_SMARTCARD=y -CONFIG_USB_AUDIO=y -CONFIG_USB_SERIAL=y -CONFIG_USB_NETWORK=y -CONFIG_USB_BLUETOOTH=y diff --git a/default-configs/virtio.mak b/default-configs/virtio.mak deleted file mode 100644 index b653aa06b1..0000000000 --- a/default-configs/virtio.mak +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG_VHOST_USER_SCSI=$(CONFIG_VHOST_USER) -CONFIG_VHOST_USER_BLK=$(CONFIG_VHOST_USER) -CONFIG_VIRTIO=y -CONFIG_VIRTIO_9P=$(CONFIG_VIRTFS) -CONFIG_VIRTIO_BALLOON=y -CONFIG_VIRTIO_BLK=y -CONFIG_VIRTIO_CRYPTO=y -CONFIG_VIRTIO_GPU=y -CONFIG_VIRTIO_INPUT=y -CONFIG_VIRTIO_NET=y -CONFIG_VIRTIO_RNG=y -CONFIG_SCSI=y -CONFIG_VIRTIO_SCSI=y -CONFIG_VIRTIO_SERIAL=y -CONFIG_VIRTIO_INPUT_HOST=$(CONFIG_LINUX) diff --git a/default-configs/xtensa-softmmu.mak b/default-configs/xtensa-softmmu.mak index baf90ca162..7e4d1cc097 100644 --- a/default-configs/xtensa-softmmu.mak +++ b/default-configs/xtensa-softmmu.mak @@ -1,8 +1,6 @@ # Default configuration for Xtensa -CONFIG_SERIAL=y -CONFIG_OPENCORES_ETH=y -CONFIG_PFLASH_CFI01=y - +# Boards: +# CONFIG_XTENSA_SIM=y -CONFIG_XTENSA_FPGA=y +CONFIG_XTENSA_XTFPGA=y diff --git a/default-configs/xtensaeb-softmmu.mak b/default-configs/xtensaeb-softmmu.mak index baf90ca162..f7e48c750c 100644 --- a/default-configs/xtensaeb-softmmu.mak +++ b/default-configs/xtensaeb-softmmu.mak @@ -1,8 +1,3 @@ # Default configuration for Xtensa -CONFIG_SERIAL=y -CONFIG_OPENCORES_ETH=y -CONFIG_PFLASH_CFI01=y - -CONFIG_XTENSA_SIM=y -CONFIG_XTENSA_FPGA=y +include xtensa-softmmu.mak diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000000..befbcc6c3e --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# +# QEMU documentation build configuration file, created by +# sphinx-quickstart on Thu Jan 31 16:40:14 2019. +# +# This config file can be used in one of two ways: +# (1) as a common config file which is included by the conf.py +# for each of QEMU's manuals: in this case sphinx-build is run multiple +# times, once per subdirectory. +# (2) as a top level conf file which will result in building all +# the manuals into a single document: in this case sphinx-build is +# run once, on the top-level docs directory. +# +# QEMU's makefiles take option (1), which allows us to install +# only the ones the user cares about (in particular we don't want +# to ship the 'devel' manual to end-users). +# Third-party sites such as readthedocs.org will take option (2). +# +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import os +import sys + +# The per-manual conf.py will set qemu_docdir for a single-manual build; +# otherwise set it here if this is an entire-manual-set build. +# This is always the absolute path of the docs/ directory in the source tree. +try: + qemu_docdir +except NameError: + qemu_docdir = os.path.abspath(".") + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use an absolute path starting from qemu_docdir. +# +# sys.path.insert(0, os.path.join(qemu_docdir, "my_subdir")) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# 1.3 is where the 'alabaster' theme was shipped with Sphinx. +needs_sphinx = '1.3' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'QEMU' +copyright = u'2019, The QEMU Project Developers' +author = u'The QEMU Project Developers' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. + +# Extract this information from the VERSION file, for the benefit of +# standalone Sphinx runs as used by readthedocs.org. Builds run from +# the Makefile will pass version and release on the sphinx-build +# command line, which override this. +try: + extracted_version = None + with open(os.path.join(qemu_docdir, '../VERSION')) as f: + extracted_version = f.readline().strip() +except: + pass +finally: + if extracted_version: + version = release = extracted_version + else: + version = release = "unknown version" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +# Sphinx defaults to warning about use of :option: for options not defined +# with "option::" in the document being processed. Turn that off. +suppress_warnings = ["ref.option"] + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# We initialize this to empty here, so the per-manual conf.py can just +# add individual key/value entries. +html_theme_options = { +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# QEMU doesn't yet have any static files, so comment this out so we don't +# get a warning about a missing directory. +# If we do ever add this then it would probably be better to call the +# subdirectory sphinx_static, as the Linux kernel does. +# html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'searchbox.html', + ] +} + +# Don't copy the rST source files to the HTML output directory, +# and don't put links to the sources into the output HTML. +html_copy_source = False + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'QEMUdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'QEMU.tex', u'QEMU Documentation', + u'The QEMU Project Developers', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'qemu', u'QEMU Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'QEMU', u'QEMU Documentation', + author, 'QEMU', 'One line description of project.', + 'Miscellaneous'), +] + + + diff --git a/docs/cpu-hotplug.rst b/docs/cpu-hotplug.rst index cfeb79f571..d0b06403f1 100644 --- a/docs/cpu-hotplug.rst +++ b/docs/cpu-hotplug.rst @@ -60,7 +60,7 @@ vCPU hotplug hot-plugged (no "qom-path" member). From its output in step (3), we can see that ``IvyBridge-IBRS-x86_64-cpu`` is present in socket 0, while hot-plugging a CPU into socket 1 requires passing the listed - properties to QMP ``device_add``: + properties to QMP ``device_add``:: (QEMU) device_add id=cpu-2 driver=IvyBridge-IBRS-x86_64-cpu socket-id=1 core-id=0 thread-id=0 { diff --git a/docs/devel/build-system.txt b/docs/devel/build-system.txt index f9fd27fab0..addd274eeb 100644 --- a/docs/devel/build-system.txt +++ b/docs/devel/build-system.txt @@ -417,7 +417,6 @@ into each QEMU system and userspace emulator targets. They merely contain a long list of config variable definitions. For example, default-configs/x86_64-softmmu.mak has: - include pci.mak include sound.mak include usb.mak CONFIG_QXL=$(CONFIG_SPICE) diff --git a/docs/devel/conf.py b/docs/devel/conf.py new file mode 100644 index 0000000000..7441f87e7f --- /dev/null +++ b/docs/devel/conf.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# +# QEMU documentation build configuration file for the 'devel' manual. +# +# This includes the top level conf file and then makes any necessary tweaks. +import sys +import os + +qemu_docdir = os.path.abspath("..") +parent_config = os.path.join(qemu_docdir, "conf.py") +exec(compile(open(parent_config, "rb").read(), parent_config, 'exec')) + +# This slightly misuses the 'description', but is the best way to get +# the manual title to appear in the sidebar. +html_theme_options['description'] = u'Developer''s Guide' diff --git a/docs/devel/index.rst b/docs/devel/index.rst new file mode 100644 index 0000000000..6b11e49caa --- /dev/null +++ b/docs/devel/index.rst @@ -0,0 +1,22 @@ +.. This is the top level page for the 'devel' manual. + + +QEMU Developer's Guide +====================== + +This manual documents various parts of the internals of QEMU. +You only need to read it if you are interested in reading or +modifying QEMU's source code. + +Contents: + +.. toctree:: + :maxdepth: 2 + + kconfig + loads-stores + memory + migration + stable-process + testing + diff --git a/docs/devel/kconfig.rst b/docs/devel/kconfig.rst new file mode 100644 index 0000000000..cce146f87d --- /dev/null +++ b/docs/devel/kconfig.rst @@ -0,0 +1,306 @@ +================ +QEMU and Kconfig +================ + +QEMU is a very versatile emulator; it can be built for a variety of +targets, where each target can emulate various boards and at the same +time different targets can share large amounts of code. For example, +a POWER and an x86 board can run the same code to emulate a PCI network +card, even though the boards use different PCI host bridges, and they +can run the same code to emulate a SCSI disk while using different +SCSI adapters. ARM, s390 and x86 boards can all present a virtio-blk +disk to their guests, but with three different virtio guest interfaces. + +Each QEMU target enables a subset of the boards, devices and buses that +are included in QEMU's source code. As a result, each QEMU executable +only links a small subset of the files that form QEMU's source code; +anything that is not needed to support a particular target is culled. + +QEMU uses a simple domain-specific language to describe the dependencies +between components. This is useful for two reasons: + +* new targets and boards can be added without knowing in detail the + architecture of the hardware emulation subsystems. Boards only have + to list the components they need, and the compiled executable will + include all the required dependencies and all the devices that the + user can add to that board; + +* users can easily build reduced versions of QEMU that support only a subset + of boards or devices. For example, by default most targets will include + all emulated PCI devices that QEMU supports, but the build process is + configurable and it is easy to drop unnecessary (or otherwise unwanted) + code to make a leaner binary. + +This domain-specific language is based on the Kconfig language that +originated in the Linux kernel, though it was heavily simplified and +the handling of dependencies is stricter in QEMU. + +Unlike Linux, there is no user interface to edit the configuration, which +is instead specified in per-target files under the ``default-configs/`` +directory of the QEMU source tree. This is because, unlike Linux, +configuration and dependencies can be treated as a black box when building +QEMU; the default configuration that QEMU ships with should be okay in +almost all cases. + +The Kconfig language +-------------------- + +Kconfig defines configurable components in files named ``hw/*/Kconfig``. +Note that configurable components are _not_ visible in C code as preprocessor +symbols; they are only visible in the Makefile. Each configurable component +defines a Makefile variable whose name starts with ``CONFIG_``. + +All elements have boolean (true/false) type; truth is written as ``y``, while +falsehood is written ``n``. They are defined in a Kconfig +stanza like the following:: + + config ARM_VIRT + bool + imply PCI_DEVICES + imply VFIO_AMD_XGBE + imply VFIO_XGMAC + select A15MPCORE + select ACPI + select ARM_SMMUV3 + +The ``config`` keyword introduces a new configuration element. In the example +above, Makefiles will have access to a variable named ``CONFIG_ARM_VIRT``, +with value ``y`` or ``n`` (respectively for boolean true and false). + +Boolean expressions can be used within the language, whenever ``<expr>`` +is written in the remainder of this section. The ``&&``, ``||`` and +``!`` operators respectively denote conjunction (AND), disjunction (OR) +and negation (NOT). + +The ``bool`` data type declaration is optional, but it is suggested to +include it for clarity and future-proofing. After ``bool`` the following +directives can be included: + +**dependencies**: ``depends on <expr>`` + + This defines a dependency for this configurable element. Dependencies + evaluate an expression and force the value of the variable to false + if the expression is false. + +**reverse dependencies**: ``select <symbol> [if <expr>]`` + + While ``depends on`` can force a symbol to false, reverse dependencies can + be used to force another symbol to true. In the following example, + ``CONFIG_BAZ`` will be true whenever ``CONFIG_FOO`` is true:: + + config FOO + select BAZ + + The optional expression will prevent ``select`` from having any effect + unless it is true. + + Note that unlike Linux's Kconfig implementation, QEMU will detect + contradictions between ``depends on`` and ``select`` statements and prevent + you from building such a configuration. + +**default value**: ``default <value> [if <expr>]`` + + Default values are assigned to the config symbol if no other value was + set by the user via ``default-configs/*.mak`` files, and only if + ``select`` or ``depends on`` directives do not force the value to true + or false respectively. ``<value>`` can be ``y`` or ``n``; it cannot + be an arbitrary Boolean expression. However, a condition for applying + the default value can be added with ``if``. + + A configuration element can have any number of default values (usually, + if more than one default is present, they will have different + conditions). If multiple default values satisfy their condition, + only the first defined one is active. + +**reverse default** (weak reverse dependency): ``imply <symbol> [if <expr>]`` + + This is similar to ``select`` as it applies a lower limit of ``y`` + to another symbol. However, the lower limit is only a default + and the "implied" symbol's value may still be set to ``n`` from a + ``default-configs/*.mak`` files. The following two examples are + equivalent:: + + config FOO + bool + imply BAZ + + config BAZ + bool + default y if FOO + + The next section explains where to use ``imply`` or ``default y``. + +Guidelines for writing Kconfig files +------------------------------------ + +Configurable elements in QEMU fall under five broad groups. Each group +declares its dependencies in different ways: + +**subsystems**, of which **buses** are a special case + + Example:: + + config SCSI + bool + + Subsystems always default to false (they have no ``default`` directive) + and are never visible in ``default-configs/*.mak`` files. It's + up to other symbols to ``select`` whatever subsystems they require. + + They sometimes have ``select`` directives to bring in other required + subsystems or buses. For example, ``AUX`` (the DisplayPort auxiliary + channel "bus") selects ``I2C`` because it can act as an I2C master too. + +**devices** + + Example:: + + config MEGASAS_SCSI_PCI + bool + default y if PCI_DEVICES + depends on PCI + select SCSI + + Devices are the most complex of the five. They can have a variety + of directives that cooperate so that a default configuration includes + all the devices that can be accessed from QEMU. + + Devices *depend on* the bus that they lie on, for example a PCI + device would specify ``depends on PCI``. An MMIO device will likely + have no ``depends on`` directive. Devices also *select* the buses + that the device provides, for example a SCSI adapter would specify + ``select SCSI``. Finally, devices are usually ``default y`` if and + only if they have at least one ``depends on``; the default could be + conditional on a device group. + + Devices also select any optional subsystem that they use; for example + a video card might specify ``select EDID`` if it needs to build EDID + information and publish it to the guest. + +**device groups** + + Example:: + + config PCI_DEVICES + bool + + Device groups provide a convenient mechanism to enable/disable many + devices in one go. This is useful when a set of devices is likely to + be enabled/disabled by several targets. Device groups usually need + no directive and are not used in the Makefile either; they only appear + as conditions for ``default y`` directives. + + QEMU currently has two device groups, ``PCI_DEVICES`` and + ``TEST_DEVICES``. PCI devices usually have a ``default y if + PCI_DEVICES`` directive rather than just ``default y``. This lets + some boards (notably s390) easily support a subset of PCI devices, + for example only VFIO (passthrough) and virtio-pci devices. + ``TEST_DEVICES`` instead is used for devices that are rarely used on + production virtual machines, but provide useful hooks to test QEMU + or KVM. + +**boards** + + Example:: + + config SUN4M + bool + imply TCX + imply CG3 + select CS4231 + select ECCMEMCTL + select EMPTY_SLOT + select ESCC + select ESP + select FDC + select SLAVIO + select LANCE + select M48T59 + select STP2000 + + Boards specify their constituent devices using ``imply`` and ``select`` + directives. A device should be listed under ``select`` if the board + cannot be started at all without it. It should be listed under + ``imply`` if (depending on the QEMU command line) the board may or + may not be started without it. Boards also default to false; they are + enabled by the ``default-configs/*.mak`` for the target they apply to. + +**internal elements** + + Example:: + + config ECCMEMCTL + bool + select ECC + + Internal elements group code that is useful in several boards or + devices. They are usually enabled with ``select`` and in turn select + other elements; they are never visible in ``default-configs/*.mak`` + files, and often not even in the Makefile. + +Writing and modifying default configurations +-------------------------------------------- + +In addition to the Kconfig files under hw/, each target also includes +a file called ``default-configs/TARGETNAME-softmmu.mak``. These files +initialize some Kconfig variables to non-default values and provide the +starting point to turn on devices and subsystems. + +A file in ``default-configs/`` looks like the following example:: + + # Default configuration for alpha-softmmu + + # Uncomment the following lines to disable these optional devices: + # + #CONFIG_PCI_DEVICES=n + #CONFIG_TEST_DEVICES=n + + # Boards: + # + CONFIG_DP264=y + +The first part, consisting of commented-out ``=n`` assignments, tells +the user which devices or device groups are implied by the boards. +The second part, consisting of ``=y`` assignments, tells the user which +boards are supported by the target. The user will typically modify +the default configuration by uncommenting lines in the first group, +or commenting out lines in the second group. + +It is also possible to run QEMU's configure script with the +``--with-default-devices`` option. When this is done, everything defaults +to ``n`` unless it is ``select``ed or explicitly switched on in the +``.mak`` files. In other words, ``default`` and ``imply`` directives +are disabled. When QEMU is built with this option, the user will probably +want to change some lines in the first group, for example like this:: + + CONFIG_PCI_DEVICES=y + #CONFIG_TEST_DEVICES=n + +and/or pick a subset of the devices in those device groups. Right now +there is no single place that lists all the optional devices for +``CONFIG_PCI_DEVICES`` and ``CONFIG_TEST_DEVICES``. In the future, +we expect that ``.mak`` files will be automatically generated, so that +they will include all these symbols and some help text on what they do. + +``Kconfig.host`` +---------------- + +In some special cases, a configurable element depends on host features +that are detected by QEMU's configure script; for example some devices +depend on the availability of KVM or on the presence of a library on +the host. + +These symbols should be listed in ``Kconfig.host`` like this:: + + config KVM + bool + +and also listed as follows in the top-level Makefile's ``MINIKCONF_ARGS`` +variable:: + + MINIKCONF_ARGS = \ + $@ $*-config.devices.mak.d $< $(MINIKCONF_INPUTS) \ + CONFIG_KVM=$(CONFIG_KVM) \ + CONFIG_SPICE=$(CONFIG_SPICE) \ + CONFIG_TPM=$(CONFIG_TPM) \ + ... diff --git a/docs/devel/memory.txt b/docs/devel/memory.rst index 42577e1d86..b6a4c37ea5 100644 --- a/docs/devel/memory.txt +++ b/docs/devel/memory.rst @@ -1,19 +1,20 @@ +============== The memory API ============== The memory API models the memory and I/O buses and controllers of a QEMU machine. It attempts to allow modelling of: - - ordinary RAM - - memory-mapped I/O (MMIO) - - memory controllers that can dynamically reroute physical memory regions - to different destinations +- ordinary RAM +- memory-mapped I/O (MMIO) +- memory controllers that can dynamically reroute physical memory regions + to different destinations The memory model provides support for - - tracking RAM changes by the guest - - setting up coalesced memory for kvm - - setting up ioeventfd regions for kvm +- tracking RAM changes by the guest +- setting up coalesced memory for kvm +- setting up ioeventfd regions for kvm Memory is modelled as an acyclic graph of MemoryRegion objects. Sinks (leaves) are RAM and MMIO regions, while other nodes represent @@ -98,25 +99,30 @@ ROM device memory region types), this host memory needs to be copied to the destination on migration. These APIs which allocate the host memory for you will also register the memory so it is migrated: - - memory_region_init_ram() - - memory_region_init_rom() - - memory_region_init_rom_device() + +- memory_region_init_ram() +- memory_region_init_rom() +- memory_region_init_rom_device() For most devices and boards this is the correct thing. If you have a special case where you need to manage the migration of the backing memory yourself, you can call the functions: - - memory_region_init_ram_nomigrate() - - memory_region_init_rom_nomigrate() - - memory_region_init_rom_device_nomigrate() + +- memory_region_init_ram_nomigrate() +- memory_region_init_rom_nomigrate() +- memory_region_init_rom_device_nomigrate() + which only initialize the MemoryRegion and leave handling migration to the caller. The functions: - - memory_region_init_resizeable_ram() - - memory_region_init_ram_from_file() - - memory_region_init_ram_from_fd() - - memory_region_init_ram_ptr() - - memory_region_init_ram_device_ptr() + +- memory_region_init_resizeable_ram() +- memory_region_init_ram_from_file() +- memory_region_init_ram_from_fd() +- memory_region_init_ram_ptr() +- memory_region_init_ram_device_ptr() + are for special cases only, and so they do not automatically register the backing memory for migration; the caller must manage migration if necessary. @@ -218,7 +224,7 @@ For example, suppose we have a container A of size 0x8000 with two subregions B and C. B is a container mapped at 0x2000, size 0x4000, priority 2; C is an MMIO region mapped at 0x0, size 0x6000, priority 1. B currently has two of its own subregions: D of size 0x1000 at offset 0 and E of size 0x1000 at -offset 0x2000. As a diagram: +offset 0x2000. As a diagram:: 0 1000 2000 3000 4000 5000 6000 7000 8000 |------|------|------|------|------|------|------|------| @@ -228,8 +234,9 @@ offset 0x2000. As a diagram: D: [DDDDD] E: [EEEEE] -The regions that will be seen within this address range then are: - [CCCCCCCCCCCC][DDDDD][CCCCC][EEEEE][CCCCC] +The regions that will be seen within this address range then are:: + + [CCCCCCCCCCCC][DDDDD][CCCCC][EEEEE][CCCCC] Since B has higher priority than C, its subregions appear in the flat map even where they overlap with C. In ranges where B has not mapped anything @@ -237,8 +244,9 @@ C's region appears. If B had provided its own MMIO operations (ie it was not a pure container) then these would be used for any addresses in its range not handled by -D or E, and the result would be: - [CCCCCCCCCCCC][DDDDD][BBBBB][EEEEE][BBBBB] +D or E, and the result would be:: + + [CCCCCCCCCCCC][DDDDD][BBBBB][EEEEE][BBBBB] Priority values are local to a container, because the priorities of two regions are only compared when they are both children of the same container. @@ -257,6 +265,7 @@ guest accesses an address: - all direct subregions of the root region are matched against the address, in descending priority order + - if the address lies outside the region offset/size, the subregion is discarded - if the subregion is a leaf (RAM or MMIO), the search terminates, returning @@ -270,36 +279,39 @@ guest accesses an address: address range), then if this is a container with its own MMIO or RAM backing the search terminates, returning the container itself. Otherwise we continue with the next subregion in priority order + - if none of the subregions match the address then the search terminates with no match found Example memory map ------------------ -system_memory: container@0-2^48-1 - | - +---- lomem: alias@0-0xdfffffff ---> #ram (0-0xdfffffff) - | - +---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff) - | - +---- vga-window: alias@0xa0000-0xbffff ---> #pci (0xa0000-0xbffff) - | (prio 1) - | - +---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff) - -pci (0-2^32-1) - | - +--- vga-area: container@0xa0000-0xbffff - | | - | +--- alias@0x00000-0x7fff ---> #vram (0x010000-0x017fff) - | | - | +--- alias@0x08000-0xffff ---> #vram (0x020000-0x027fff) - | - +---- vram: ram@0xe1000000-0xe1ffffff - | - +---- vga-mmio: mmio@0xe2000000-0xe200ffff - -ram: ram@0x00000000-0xffffffff +:: + + system_memory: container@0-2^48-1 + | + +---- lomem: alias@0-0xdfffffff ---> #ram (0-0xdfffffff) + | + +---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff) + | + +---- vga-window: alias@0xa0000-0xbffff ---> #pci (0xa0000-0xbffff) + | (prio 1) + | + +---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff) + + pci (0-2^32-1) + | + +--- vga-area: container@0xa0000-0xbffff + | | + | +--- alias@0x00000-0x7fff ---> #vram (0x010000-0x017fff) + | | + | +--- alias@0x08000-0xffff ---> #vram (0x020000-0x027fff) + | + +---- vram: ram@0xe1000000-0xe1ffffff + | + +---- vga-mmio: mmio@0xe2000000-0xe200ffff + + ram: ram@0x00000000-0xffffffff This is a (simplified) PC memory map. The 4GB RAM block is mapped into the system address space via two aliases: "lomem" is a 1:1 mapping of the first @@ -336,16 +348,16 @@ rather than completing successfully; those devices can use the In addition various constraints can be supplied to control how these callbacks are called: - - .valid.min_access_size, .valid.max_access_size define the access sizes - (in bytes) which the device accepts; accesses outside this range will - have device and bus specific behaviour (ignored, or machine check) - - .valid.unaligned specifies that the *device being modelled* supports - unaligned accesses; if false, unaligned accesses will invoke the - appropriate bus or CPU specific behaviour. - - .impl.min_access_size, .impl.max_access_size define the access sizes - (in bytes) supported by the *implementation*; other access sizes will be - emulated using the ones available. For example a 4-byte write will be - emulated using four 1-byte writes, if .impl.max_access_size = 1. - - .impl.unaligned specifies that the *implementation* supports unaligned - accesses; if false, unaligned accesses will be emulated by two aligned - accesses. +- .valid.min_access_size, .valid.max_access_size define the access sizes + (in bytes) which the device accepts; accesses outside this range will + have device and bus specific behaviour (ignored, or machine check) +- .valid.unaligned specifies that the *device being modelled* supports + unaligned accesses; if false, unaligned accesses will invoke the + appropriate bus or CPU specific behaviour. +- .impl.min_access_size, .impl.max_access_size define the access sizes + (in bytes) supported by the *implementation*; other access sizes will be + emulated using the ones available. For example a 4-byte write will be + emulated using four 1-byte writes, if .impl.max_access_size = 1. +- .impl.unaligned specifies that the *implementation* supports unaligned + accesses; if false, unaligned accesses will be emulated by two aligned + accesses. diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index 135743a2bf..60f897d915 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -600,7 +600,6 @@ the ``avocado_qemu.Test`` class. Here's a simple usage example: class Version(Test): """ - :avocado: enable :avocado: tags=quick """ def test_qmp_human_info_version(self): @@ -634,7 +633,46 @@ instance, available at ``self.vm``. Because many tests will tweak the QEMU command line, launching the QEMUMachine (by using ``self.vm.launch()``) is left to the test writer. -At test "tear down", ``avocado_qemu.Test`` handles the QEMUMachine +The base test class has also support for tests with more than one +QEMUMachine. The way to get machines is through the ``self.get_vm()`` +method which will return a QEMUMachine instance. The ``self.get_vm()`` +method accepts arguments that will be passed to the QEMUMachine creation +and also an optional `name` attribute so you can identify a specific +machine and get it more than once through the tests methods. A simple +and hypothetical example follows: + +.. code:: + + from avocado_qemu import Test + + + class MultipleMachines(Test): + """ + :avocado: enable + """ + def test_multiple_machines(self): + first_machine = self.get_vm() + second_machine = self.get_vm() + self.get_vm(name='third_machine').launch() + + first_machine.launch() + second_machine.launch() + + first_res = first_machine.command( + 'human-monitor-command', + command_line='info version') + + second_res = second_machine.command( + 'human-monitor-command', + command_line='info version') + + third_res = self.get_vm(name='third_machine').command( + 'human-monitor-command', + command_line='info version') + + self.assertEquals(first_res, second_res, third_res) + +At test "tear down", ``avocado_qemu.Test`` handles all the QEMUMachines shutdown. QEMUMachine diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000000..3690955dd1 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,15 @@ +.. QEMU documentation master file, created by + sphinx-quickstart on Thu Jan 31 16:40:14 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to QEMU's documentation! +================================ + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + interop/index + devel/index + diff --git a/docs/interop/conf.py b/docs/interop/conf.py new file mode 100644 index 0000000000..cf3c69d4a7 --- /dev/null +++ b/docs/interop/conf.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# +# QEMU documentation build configuration file for the 'interop' manual. +# +# This includes the top level conf file and then makes any necessary tweaks. +import sys +import os + +qemu_docdir = os.path.abspath("..") +parent_config = os.path.join(qemu_docdir, "conf.py") +exec(compile(open(parent_config, "rb").read(), parent_config, 'exec')) + +# This slightly misuses the 'description', but is the best way to get +# the manual title to appear in the sidebar. +html_theme_options['description'] = u'System Emulation Management and Interoperability Guide' diff --git a/docs/interop/index.rst b/docs/interop/index.rst new file mode 100644 index 0000000000..2df977dd52 --- /dev/null +++ b/docs/interop/index.rst @@ -0,0 +1,18 @@ +.. This is the top level page for the 'interop' manual. + + +QEMU System Emulation Management and Interoperability Guide +=========================================================== + +This manual contains documents and specifications that are useful +for making QEMU interoperate with other software. + +Contents: + +.. toctree:: + :maxdepth: 2 + + bitmaps + live-block-operations + pr-helper + diff --git a/hw/9pfs/Kconfig b/hw/9pfs/Kconfig new file mode 100644 index 0000000000..8c5032c575 --- /dev/null +++ b/hw/9pfs/Kconfig @@ -0,0 +1,4 @@ +config VIRTIO_9P + bool + default y + depends on VIRTFS && VIRTIO diff --git a/hw/9pfs/Makefile.objs b/hw/9pfs/Makefile.objs index 8ac04962bd..70ded6fd8f 100644 --- a/hw/9pfs/Makefile.objs +++ b/hw/9pfs/Makefile.objs @@ -1,11 +1,9 @@ -ifeq ($(call lor,$(CONFIG_VIRTIO_9P),$(CONFIG_XEN)),y) common-obj-y = 9p.o 9p-util.o common-obj-y += 9p-local.o 9p-xattr.o common-obj-y += 9p-xattr-user.o 9p-posix-acl.o common-obj-y += coth.o cofs.o codir.o cofile.o common-obj-y += coxattr.o 9p-synth.o common-obj-y += 9p-proxy.o -endif common-obj-$(CONFIG_XEN) += xen-9p-backend.o obj-$(CONFIG_VIRTIO_9P) += virtio-9p-device.o diff --git a/hw/Kconfig b/hw/Kconfig new file mode 100644 index 0000000000..d5ecd02070 --- /dev/null +++ b/hw/Kconfig @@ -0,0 +1,73 @@ +# devices Kconfig +source 9pfs/Kconfig +source acpi/Kconfig +source adc/Kconfig +source audio/Kconfig +source block/Kconfig +source bt/Kconfig +source char/Kconfig +source core/Kconfig +source display/Kconfig +source dma/Kconfig +source gpio/Kconfig +source hyperv/Kconfig +source i2c/Kconfig +source ide/Kconfig +source input/Kconfig +source intc/Kconfig +source ipack/Kconfig +source ipmi/Kconfig +source isa/Kconfig +source mem/Kconfig +source misc/Kconfig +source net/Kconfig +source nvram/Kconfig +source pci-bridge/Kconfig +source pci-host/Kconfig +source pcmcia/Kconfig +source pci/Kconfig +source scsi/Kconfig +source sd/Kconfig +source smbios/Kconfig +source ssi/Kconfig +source timer/Kconfig +source tpm/Kconfig +source usb/Kconfig +source virtio/Kconfig +source vfio/Kconfig +source watchdog/Kconfig + +# arch Kconfig +source arm/Kconfig +source alpha/Kconfig +source cris/Kconfig +source hppa/Kconfig +source i386/Kconfig +source lm32/Kconfig +source m68k/Kconfig +source microblaze/Kconfig +source mips/Kconfig +source moxie/Kconfig +source nios2/Kconfig +source openrisc/Kconfig +source ppc/Kconfig +source riscv/Kconfig +source s390x/Kconfig +source sh4/Kconfig +source sparc/Kconfig +source sparc64/Kconfig +source tricore/Kconfig +source unicore32/Kconfig +source xtensa/Kconfig + +# Symbols used by multiple targets +config TEST_DEVICES + bool + +config XILINX + bool + select PTIMER # for hw/timer/xilinx_timer.c + +config XILINX_AXI + bool + select PTIMER # for hw/dma/xilinx_axidma.c diff --git a/hw/Makefile.objs b/hw/Makefile.objs index e2fcd6aafc..82aa7fab8e 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -1,4 +1,4 @@ -devices-dirs-$(call land,$(CONFIG_VIRTFS),$(call lor,$(CONFIG_VIRTIO),$(CONFIG_XEN))) += 9pfs/ +devices-dirs-$(call lor,$(CONFIG_VIRTIO_9P),$(call land,$(CONFIG_VIRTFS),$(CONFIG_XEN))) += 9pfs/ devices-dirs-$(CONFIG_SOFTMMU) += acpi/ devices-dirs-$(CONFIG_SOFTMMU) += adc/ devices-dirs-$(CONFIG_SOFTMMU) += audio/ @@ -10,7 +10,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += display/ devices-dirs-$(CONFIG_SOFTMMU) += dma/ devices-dirs-$(CONFIG_SOFTMMU) += gpio/ devices-dirs-$(CONFIG_HYPERV) += hyperv/ -devices-dirs-$(CONFIG_SOFTMMU) += i2c/ +devices-dirs-$(CONFIG_I2C) += i2c/ devices-dirs-$(CONFIG_SOFTMMU) += ide/ devices-dirs-$(CONFIG_SOFTMMU) += input/ devices-dirs-$(CONFIG_SOFTMMU) += intc/ diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig new file mode 100644 index 0000000000..eca3beed75 --- /dev/null +++ b/hw/acpi/Kconfig @@ -0,0 +1,29 @@ +config ACPI + bool + +config ACPI_X86 + bool + select ACPI + select ACPI_NVDIMM + select ACPI_CPU_HOTPLUG + select ACPI_MEMORY_HOTPLUG + +config ACPI_X86_ICH + bool + select ACPI_X86 + +config ACPI_CPU_HOTPLUG + bool + +config ACPI_MEMORY_HOTPLUG + bool + select MEM_DEVICE + +config ACPI_NVDIMM + bool + depends on ACPI + +config ACPI_VMGENID + bool + default y + depends on PC diff --git a/hw/adc/Kconfig b/hw/adc/Kconfig new file mode 100644 index 0000000000..25d2229fb8 --- /dev/null +++ b/hw/adc/Kconfig @@ -0,0 +1,2 @@ +config STM32F2XX_ADC + bool diff --git a/hw/alpha/Kconfig b/hw/alpha/Kconfig new file mode 100644 index 0000000000..22cefd9577 --- /dev/null +++ b/hw/alpha/Kconfig @@ -0,0 +1,12 @@ +config DP264 + bool + imply PCI_DEVICES + imply TEST_DEVICES + select I82374 + select I8254 + select I8259 + select IDE_CMD646 + select MC146818RTC + select PCI + select PCKBD + select SMC37C669 diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig new file mode 100644 index 0000000000..d298fbdc89 --- /dev/null +++ b/hw/arm/Kconfig @@ -0,0 +1,124 @@ +config ARM_VIRT + bool + imply VFIO_PLATFORM + +config DIGIC + bool + select PTIMER + +config EXYNOS4 + bool + select PTIMER + +config HIGHBANK + bool + +config INTEGRATOR + bool + +config MAINSTONE + bool + +config MUSICPAL + bool + select PTIMER + +config NETDUINO2 + bool + +config NSERIES + bool + +config OMAP + bool + +config PXA2XX + bool + +config REALVIEW + bool + +config STELLARIS + bool + +config STRONGARM + bool + +config VERSATILE + bool + +config ZYNQ + bool + +config ARM_V7M + bool + +config ALLWINNER_A10 + bool + +config RASPI + bool + +config STM32F205_SOC + bool + +config XLNX_ZYNQMP_ARM + bool + +config XLNX_VERSAL + bool + +config FSL_IMX25 + bool + +config FSL_IMX31 + bool + +config FSL_IMX6 + bool + +config ASPEED_SOC + bool + +config MPS2 + bool + +config FSL_IMX7 + bool + +config ARM_SMMUV3 + bool + +config FSL_IMX6UL + bool + +config NRF51_SOC + bool + +config MSF2 + bool + select PTIMER + +config ZAURUS + bool + +config A9MPCORE + bool + +config A15MPCORE + bool + +config ARM11MPCORE + bool + +config ARMSSE + bool + +config ARMSSE_CPUID + bool + +config ARMSSE_MHU + bool + +config MUSCA + bool diff --git a/hw/audio/Kconfig b/hw/audio/Kconfig new file mode 100644 index 0000000000..e9c6fed826 --- /dev/null +++ b/hw/audio/Kconfig @@ -0,0 +1,52 @@ +config SB16 + bool + default y + depends on ISA_BUS + +config ES1370 + bool + default y if PCI_DEVICES + depends on PCI + +config AC97 + bool + default y if PCI_DEVICES + depends on PCI + +config ADLIB + bool + default y + depends on ISA_BUS + +config GUS + bool + default y + depends on ISA_BUS + +config CS4231A + bool + default y + depends on ISA_BUS + +config HDA + bool + default y if PCI_DEVICES + depends on PCI + +config PCSPK + bool + default y + depends on I8254 + +config WM8750 + bool + depends on I2C + +config PL041 + bool + +config CS4231 + bool + +config MARVELL_88W8618 + bool diff --git a/hw/block/Kconfig b/hw/block/Kconfig new file mode 100644 index 0000000000..df96dc5dcc --- /dev/null +++ b/hw/block/Kconfig @@ -0,0 +1,39 @@ +config FDC + bool + # FIXME: there is no separate file for the MMIO floppy disk controller, so + # select ISA_BUS here instead of polluting each board that requires one + select ISA_BUS + +config SSI_M25P80 + bool + +config NAND + bool + +config PFLASH_CFI01 + bool + +config PFLASH_CFI02 + bool + +config ECC + bool + +config ONENAND + bool + +config NVME_PCI + bool + default y if PCI_DEVICES + depends on PCI + +config VIRTIO_BLK + bool + default y + depends on VIRTIO + +config VHOST_USER_BLK + bool + # Only PCI devices are provided for now + default y if VIRTIO_PCI + depends on VIRTIO && VHOST_USER && LINUX diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs index e206b8e712..f5f643f0cc 100644 --- a/hw/block/Makefile.objs +++ b/hw/block/Makefile.objs @@ -12,5 +12,6 @@ common-obj-$(CONFIG_NVME_PCI) += nvme.o obj-$(CONFIG_SH4) += tc58128.o obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o -obj-$(CONFIG_VIRTIO_BLK) += dataplane/ obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o + +obj-y += dataplane/ diff --git a/hw/block/dataplane/Makefile.objs b/hw/block/dataplane/Makefile.objs index c6c68dbc00..0c5270268e 100644 --- a/hw/block/dataplane/Makefile.objs +++ b/hw/block/dataplane/Makefile.objs @@ -1,2 +1,2 @@ -obj-y += virtio-blk.o +obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o obj-$(CONFIG_XEN) += xen-block.o diff --git a/hw/bt/Kconfig b/hw/bt/Kconfig new file mode 100644 index 0000000000..554a9ee75e --- /dev/null +++ b/hw/bt/Kconfig @@ -0,0 +1,2 @@ +config BLUETOOTH + bool diff --git a/hw/char/Kconfig b/hw/char/Kconfig new file mode 100644 index 0000000000..6360c9fffa --- /dev/null +++ b/hw/char/Kconfig @@ -0,0 +1,42 @@ +config ESCC + bool + +config PARALLEL + bool + default y + depends on ISA_BUS + +config PL011 + bool + +config SERIAL + bool + +config SERIAL_ISA + bool + default y + depends on ISA_BUS + select SERIAL + +config SERIAL_PCI + bool + default y if PCI_DEVICES + depends on PCI + select SERIAL + +config VIRTIO_SERIAL + bool + default y + depends on VIRTIO + +config STM32F2XX_USART + bool + +config CMSDK_APB_UART + bool + +config SCLPCONSOLE + bool + +config TERMINAL3270 + bool diff --git a/hw/core/Kconfig b/hw/core/Kconfig new file mode 100644 index 0000000000..c2a1ae8122 --- /dev/null +++ b/hw/core/Kconfig @@ -0,0 +1,11 @@ +config EMPTY_SLOT + bool + +config PTIMER + bool + +config FITLOADER + bool + +config PLATFORM_BUS + bool diff --git a/hw/cpu/Kconfig b/hw/cpu/Kconfig new file mode 100644 index 0000000000..1767d028ac --- /dev/null +++ b/hw/cpu/Kconfig @@ -0,0 +1,8 @@ +config ARM11MPCORE + bool + +config A9MPCORE + bool + +config A15MPCORE + bool diff --git a/hw/cris/Kconfig b/hw/cris/Kconfig new file mode 100644 index 0000000000..884ad2cbc0 --- /dev/null +++ b/hw/cris/Kconfig @@ -0,0 +1,9 @@ +config AXIS + bool + select ETRAXFS + select PFLASH_CFI02 + select NAND + +config ETRAXFS + bool + select PTIMER diff --git a/hw/display/Kconfig b/hw/display/Kconfig new file mode 100644 index 0000000000..a96ea763a8 --- /dev/null +++ b/hw/display/Kconfig @@ -0,0 +1,108 @@ +config EDID + bool + +config FW_CFG_DMA + bool + +config ADS7846 + bool + +config VGA_CIRRUS + bool + default y if PCI_DEVICES + depends on PCI + select VGA + +config G364FB + bool + +config JAZZ_LED + bool + +config PL110 + bool + +config SII9022 + bool + depends on I2C + +config SSD0303 + bool + depends on I2C + +config SSD0323 + bool + +config VGA_PCI + bool + default y if PCI_DEVICES + depends on PCI + select VGA + select EDID + +config VGA_ISA + bool + depends on ISA_BUS + select VGA + +config VGA_ISA_MM + bool + select VGA + +config VMWARE_VGA + bool + default y if PCI_DEVICES + depends on PCI + select VGA + +config BOCHS_DISPLAY + bool + default y if PCI_DEVICES + depends on PCI + select VGA + select EDID + +config BLIZZARD + bool + +config FRAMEBUFFER + bool + +config MILKYMIST_TMU2 + bool + depends on OPENGL && X11 + +config SM501 + bool + select I2C + select DDC + select SERIAL + +config TCX + bool + +config CG3 + bool + +config VGA + bool + +config QXL + bool + depends on SPICE && PCI + select VGA + +config VIRTIO_GPU + bool + default y + depends on VIRTIO + select EDID + +config VIRTIO_VGA + bool + default y if PCI_DEVICES + depends on VIRTIO_PCI + select VGA + +config DPCD + bool diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index 7c4ae9a0fd..576fca4eb6 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -1,4 +1,4 @@ -common-obj-y += edid-generate.o +common-obj-$(CONFIG_EDID) += edid-generate.o edid-region.o common-obj-$(CONFIG_FW_CFG_DMA) += ramfb.o common-obj-$(CONFIG_FW_CFG_DMA) += ramfb-standalone.o @@ -15,12 +15,10 @@ common-obj-$(CONFIG_SSD0323) += ssd0323.o common-obj-$(CONFIG_XEN) += xenfb.o common-obj-$(CONFIG_VGA_PCI) += vga-pci.o -common-obj-$(CONFIG_VGA_PCI) += edid-region.o common-obj-$(CONFIG_VGA_ISA) += vga-isa.o common-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o common-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o common-obj-$(CONFIG_BOCHS_DISPLAY) += bochs-display.o -common-obj-$(CONFIG_BOCHS_DISPLAY) += edid-region.o common-obj-$(CONFIG_BLIZZARD) += blizzard.o common-obj-$(CONFIG_EXYNOS4) += exynos4210_fimd.o diff --git a/hw/dma/Kconfig b/hw/dma/Kconfig new file mode 100644 index 0000000000..751dec5426 --- /dev/null +++ b/hw/dma/Kconfig @@ -0,0 +1,21 @@ +config RC4030 + bool + +config PL080 + bool + +config PL330 + bool + +config I82374 + bool + select I8257 + +config I8257 + bool + +config ZYNQ_DEVCFG + bool + +config STP2000 + bool diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig new file mode 100644 index 0000000000..9227cb5598 --- /dev/null +++ b/hw/gpio/Kconfig @@ -0,0 +1,9 @@ +config MAX7310 + bool + depends on I2C + +config PL061 + bool + +config GPIO_KEY + bool diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig new file mode 100644 index 0000000000..2d9b072c21 --- /dev/null +++ b/hw/hppa/Kconfig @@ -0,0 +1,10 @@ +config DINO + bool + imply PCI_DEVICES + select PCI + select SERIAL + select ISA_BUS + select I8259 + select IDE_CMD646 + select MC146818RTC + select LSI_SCSI_PCI diff --git a/hw/hyperv/Kconfig b/hw/hyperv/Kconfig new file mode 100644 index 0000000000..a1fa8ff9be --- /dev/null +++ b/hw/hyperv/Kconfig @@ -0,0 +1,8 @@ +config HYPERV + bool + depends on KVM + +config HYPERV_TESTDEV + bool + default y if TEST_DEVICES + depends on HYPERV diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig new file mode 100644 index 0000000000..ef1caa6d89 --- /dev/null +++ b/hw/i2c/Kconfig @@ -0,0 +1,27 @@ +config I2C + bool + +config SMBUS_EEPROM + bool + depends on I2C + +config DDC + bool + depends on I2C + select EDID + +config VERSATILE_I2C + bool + select I2C + +config ACPI_SMBUS + bool + select I2C + +config BITBANG_I2C + bool + select I2C + +config IMX_I2C + bool + select I2C diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs index 9205cbee16..2a3c106551 100644 --- a/hw/i2c/Makefile.objs +++ b/hw/i2c/Makefile.objs @@ -2,7 +2,7 @@ common-obj-$(CONFIG_I2C) += core.o smbus_slave.o smbus_master.o common-obj-$(CONFIG_SMBUS_EEPROM) += smbus_eeprom.o common-obj-$(CONFIG_DDC) += i2c-ddc.o common-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o -common-obj-$(CONFIG_ACPI_X86) += smbus_ich9.o +common-obj-$(CONFIG_ACPI_X86_ICH) += smbus_ich9.o common-obj-$(CONFIG_ACPI_SMBUS) += pm_smbus.o common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig new file mode 100644 index 0000000000..78fd70396a --- /dev/null +++ b/hw/i386/Kconfig @@ -0,0 +1,99 @@ +config SEV + bool + depends on KVM + +config PC + bool + imply APPLESMC + imply HYPERV + imply ISA_IPMI_KCS + imply ISA_IPMI_BT + imply ISA_DEBUG + imply PCI_DEVICES + imply PVPANIC + imply QXL + imply SEV + imply SGA + imply TEST_DEVICES + imply TPM_CRB + imply TPM_TIS + select FDC + select I8259 + select I8254 + select PCKBD + select PCSPK + select I82374 + select I8257 + select MC146818RTC + # Needed by the board code: + select PARALLEL + # For ACPI builder: + select SERIAL_ISA + select ACPI_VMGENID + +config PC_PCI + bool + select APIC + select IOAPIC + select APM + select PC + +config PC_ACPI + bool + select ACPI_X86 + select ACPI_CPU_HOTPLUG + select ACPI_MEMORY_HOTPLUG + select SMBUS_EEPROM + select PFLASH_CFI01 + depends on ACPI_SMBUS + +config I440FX + bool + select PC_PCI + select PC_ACPI + select ACPI_SMBUS + select PCI_PIIX + select IDE_PIIX + select DIMM + select SMBIOS + select VMPORT + select VMMOUSE + select FW_CFG_DMA + +config ISAPC + bool + select ISA_BUS + select PC + select IDE_ISA + select VGA_ISA + # FIXME: it is in the same file as i440fx, and does not compile + # if separated + depends on I440FX + +config Q35 + bool + imply VTD + imply AMD_IOMMU + select PC_PCI + select PC_ACPI + select PCI_EXPRESS_Q35 + select LPC_ICH9 + select AHCI + select DIMM + select SMBIOS + select VMPORT + select VMMOUSE + select FW_CFG_DMA + +config VTD + bool + +config AMD_IOMMU + bool + +config VMPORT + bool + +config VMMOUSE + bool + depends on VMPORT diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 3de7ca2bb9..27248a0777 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -4,8 +4,9 @@ obj-y += pc.o obj-$(CONFIG_I440FX) += pc_piix.o obj-$(CONFIG_Q35) += pc_q35.o obj-y += pc_sysfw.o -obj-$(CONFIG_VTD) += x86-iommu.o intel_iommu.o -obj-$(CONFIG_AMD_IOMMU) += x86-iommu.o amd_iommu.o +obj-y += x86-iommu.o +obj-$(CONFIG_VTD) += intel_iommu.o +obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o obj-$(CONFIG_XEN) += ../xenpv/ xen/ obj-$(CONFIG_VMPORT) += vmport.o obj-$(CONFIG_VMMOUSE) += vmmouse.o diff --git a/hw/ide/Kconfig b/hw/ide/Kconfig new file mode 100644 index 0000000000..ab47b6a7a3 --- /dev/null +++ b/hw/ide/Kconfig @@ -0,0 +1,54 @@ +config IDE_CORE + bool + +config IDE_QDEV + bool + select IDE_CORE + +config IDE_PCI + bool + depends on PCI + select IDE_CORE + +config IDE_ISA + bool + depends on ISA_BUS + select IDE_QDEV + +config IDE_PIIX + bool + select IDE_PCI + select IDE_QDEV + +config IDE_CMD646 + bool + select IDE_PCI + select IDE_QDEV + +config IDE_MACIO + bool + select IDE_QDEV + +config IDE_MMIO + bool + select IDE_QDEV + +config IDE_VIA + bool + select IDE_PCI + select IDE_QDEV + +config MICRODRIVE + bool + select IDE_QDEV + +config AHCI + bool + default y if PCI_DEVICES + depends on PCI + select IDE_QDEV + +config IDE_SII3112 + bool + select IDE_PCI + select IDE_QDEV diff --git a/hw/input/Kconfig b/hw/input/Kconfig new file mode 100644 index 0000000000..e2e66f0858 --- /dev/null +++ b/hw/input/Kconfig @@ -0,0 +1,33 @@ +config ADB + bool + +config LM832X + bool + depends on I2C + +config PCKBD + bool + default y + depends on ISA_BUS + +config PL050 + bool + +config STELLARIS_INPUT + bool + +config TSC2005 + bool + +config VIRTIO_INPUT + bool + default y + depends on VIRTIO + +config VIRTIO_INPUT_HOST + bool + default y + depends on VIRTIO && LINUX + +config TSC210X + bool diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig new file mode 100644 index 0000000000..de10a6bcbf --- /dev/null +++ b/hw/intc/Kconfig @@ -0,0 +1,57 @@ +config HEATHROW_PIC + bool + +config I8259 + bool + +config PL190 + bool + +config IOAPIC + bool + +config ARM_GIC + bool + +config OPENPIC + bool + +config APIC + bool + +config ARM_GIC_KVM + bool + default y + depends on ARM_GIC && KVM + +config OPENPIC_KVM + bool + default y + depends on OPENPIC && KVM + +config XICS + bool + depends on POWERNV || PSERIES + +config XICS_SPAPR + bool + select XICS + +config XICS_KVM + bool + default y + depends on XICS && KVM + +config ALLWINNER_A10_PIC + bool + +config S390_FLIC + bool + +config S390_FLIC_KVM + bool + default y + depends on S390_FLIC && KVM + +config OMPIC + bool diff --git a/hw/ipack/Kconfig b/hw/ipack/Kconfig new file mode 100644 index 0000000000..f8da24a62b --- /dev/null +++ b/hw/ipack/Kconfig @@ -0,0 +1,4 @@ +config IPACK + bool + default y if PCI_DEVICES + depends on PCI diff --git a/hw/ipmi/Kconfig b/hw/ipmi/Kconfig new file mode 100644 index 0000000000..b944fae100 --- /dev/null +++ b/hw/ipmi/Kconfig @@ -0,0 +1,22 @@ +config IPMI + bool + +config IPMI_LOCAL + bool + default y + depends on IPMI + +config IPMI_EXTERN + bool + default y + depends on IPMI + +config ISA_IPMI_KCS + bool + depends on ISA_BUS + select IPMI + +config ISA_IPMI_BT + bool + depends on ISA_BUS + select IPMI diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig new file mode 100644 index 0000000000..57e09a0cb8 --- /dev/null +++ b/hw/isa/Kconfig @@ -0,0 +1,53 @@ +config ISA_BUS + bool + +config APM + bool + +config I82378 + bool + select ISA_BUS + select I8259 + select I8254 + select I82374 + select MC146818RTC + +config PC87312 + bool + select ISA_BUS + select I8259 + select I8254 + select I8257 + select MC146818RTC + select SERIAL_ISA + select PARALLEL + select FDC + select IDE_ISA + +config PIIX4 + bool + # For historical reasons, SuperIO devices are created in the board + # for PIIX4. + select ISA_BUS + +config VT82C686 + bool + select ISA_BUS + select ACPI_SMBUS + select SERIAL_ISA + select FDC + +config SMC37C669 + bool + select ISA_BUS + select SERIAL_ISA + select PARALLEL + select FDC + +config LPC_ICH9 + bool + # For historical reasons, SuperIO devices are created in the board + # for ICH9. + select ISA_BUS + select ACPI_SMBUS + select ACPI_X86_ICH diff --git a/hw/lm32/Kconfig b/hw/lm32/Kconfig new file mode 100644 index 0000000000..3d09c2dd6f --- /dev/null +++ b/hw/lm32/Kconfig @@ -0,0 +1,13 @@ +config LM32 + bool + select PTIMER + select PFLASH_CFI02 + +config MILKYMIST + bool + # FIXME: disabling it results in compile-time errors + select MILKYMIST_TMU2 if OPENGL && X11 + select PTIMER + select PFLASH_CFI01 + select FRAMEBUFFER + select SD diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig new file mode 100644 index 0000000000..49ef0b3f6d --- /dev/null +++ b/hw/m68k/Kconfig @@ -0,0 +1,9 @@ +config AN5206 + bool + select COLDFIRE + select PTIMER + +config MCF5208 + bool + select COLDFIRE + select PTIMER diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig new file mode 100644 index 0000000000..620fd4cb59 --- /dev/null +++ b/hw/mem/Kconfig @@ -0,0 +1,11 @@ +config DIMM + bool + select MEM_DEVICE + +config MEM_DEVICE + bool + +config NVDIMM + bool + default y + depends on PC diff --git a/hw/microblaze/Kconfig b/hw/microblaze/Kconfig new file mode 100644 index 0000000000..c4dc120973 --- /dev/null +++ b/hw/microblaze/Kconfig @@ -0,0 +1,20 @@ +config PETALOGIX_S3ADSP1800 + bool + select PFLASH_CFI01 + select XILINX + select XILINX_AXI + select XILINX_ETHLITE + +config PETALOGIX_ML605 + bool + select PFLASH_CFI01 + select SERIAL + select SSI_M25P80 + select XILINX + select XILINX_AXI + select XILINX_ETHLITE + select XILINX_SPI + +config XLNX_ZYNQMP_PMU + bool + select XLNX_ZYNQMP diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig new file mode 100644 index 0000000000..cdc07e59b6 --- /dev/null +++ b/hw/mips/Kconfig @@ -0,0 +1,21 @@ +config R4K + bool + +config MALTA + bool + +config MIPSSIM + bool + +config JAZZ + bool + +config FULONG + bool + +config MIPS_CPS + bool + select PTIMER + +config MIPS_BOSTON + bool diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig new file mode 100644 index 0000000000..2c60be99bc --- /dev/null +++ b/hw/misc/Kconfig @@ -0,0 +1,118 @@ +config APPLESMC + bool + depends on ISA_BUS + +config MAX111X + bool + +config TMP105 + bool + depends on I2C + +config TMP421 + bool + depends on I2C + +config ISA_DEBUG + bool + depends on ISA_BUS + +config SGA + bool + depends on ISA_BUS + +config ISA_TESTDEV + bool + default y if TEST_DEVICES + depends on ISA_BUS + +config PCI_TESTDEV + bool + default y if TEST_DEVICES + depends on PCI + +config EDU + bool + default y if TEST_DEVICES + depends on PCI + +config PCA9552 + bool + depends on I2C + +config PL310 + bool + +config INTEGRATOR_DEBUG + bool + +config A9SCU + bool + +config ARM11SCU + bool + +config MOS6522 + bool + +config MACIO + bool + select CUDA + select ESCC + select IDE_MACIO + select MAC_DBDMA + select MAC_NVRAM + select MOS6522 + +config IVSHMEM_DEVICE + bool + default y if PCI_DEVICES + depends on PCI && LINUX && IVSHMEM + +config ECCMEMCTL + bool + select ECC + +config IMX + bool + select PTIMER + +config STM32F2XX_SYSCFG + bool + +config MIPS_ITU + bool + +config MPS2_FPGAIO + bool + +config MPS2_SCC + bool + +config TZ_MPC + bool + +config TZ_MSC + bool + +config TZ_PPC + bool + +config IOTKIT_SECCTL + bool + +config IOTKIT_SYSCTL + bool + +config IOTKIT_SYSINFO + bool + +config PVPANIC + bool + depends on ISA_BUS + +config AUX + bool + select I2C + +source macio/Kconfig diff --git a/hw/misc/macio/Kconfig b/hw/misc/macio/Kconfig new file mode 100644 index 0000000000..c6caeb672f --- /dev/null +++ b/hw/misc/macio/Kconfig @@ -0,0 +1,11 @@ +config CUDA + bool + +config MAC_PMU + bool + +config MAC_DBDMA + bool + +config MACIO_GPIO + bool diff --git a/hw/moxie/Kconfig b/hw/moxie/Kconfig new file mode 100644 index 0000000000..3793ef0372 --- /dev/null +++ b/hw/moxie/Kconfig @@ -0,0 +1,3 @@ +config MOXIESIM + bool + select SERIAL diff --git a/hw/net/Kconfig b/hw/net/Kconfig new file mode 100644 index 0000000000..c00ec03cd1 --- /dev/null +++ b/hw/net/Kconfig @@ -0,0 +1,125 @@ +config DP8393X + bool + +config NE2000_PCI + bool + default y if PCI_DEVICES + depends on PCI + +config EEPRO100_PCI + bool + default y if PCI_DEVICES + depends on PCI + +config PCNET_PCI + bool + default y if PCI_DEVICES + depends on PCI + select PCNET_COMMON + +config PCNET_COMMON + bool + +config E1000_PCI + bool + default y if PCI_DEVICES + depends on PCI + +config E1000E_PCI_EXPRESS + bool + default y if PCI_DEVICES + depends on PCI_EXPRESS + +config RTL8139_PCI + bool + default y if PCI_DEVICES + depends on PCI + +config VMXNET3_PCI + bool + default y if PCI_DEVICES + depends on PCI + +config SMC91C111 + bool + +config LAN9118 + bool + select PTIMER + +config NE2000_ISA + bool + default y + depends on ISA_BUS + depends on PCI # for NE2000State + select NE2000_PCI + +config OPENCORES_ETH + bool + +config XGMAC + bool + +config MIPSNET + bool + +config ALLWINNER_EMAC + bool + +config IMX_FEC + bool + +config CADENCE + bool + +config STELLARIS_ENET + bool + +config LANCE + bool + select PCNET_COMMON + +config SUNHME + bool + +config FTGMAC100 + bool + +config SUNGEM + bool + depends on PCI + +config COLDFIRE + bool + +config XILINX_ETHLITE + bool + +config VIRTIO_NET + bool + default y + depends on VIRTIO + +config ETSEC + bool + select PTIMER + +config ROCKER + bool + default y if PCI_DEVICES + depends on PCI + +config CAN_BUS + bool + +config CAN_PCI + bool + default y if PCI_DEVICES + depends on PCI + select CAN_BUS + +config CAN_SJA1000 + bool + default y if PCI_DEVICES + depends on PCI + select CAN_BUS diff --git a/hw/nios2/Kconfig b/hw/nios2/Kconfig new file mode 100644 index 0000000000..ab953e0077 --- /dev/null +++ b/hw/nios2/Kconfig @@ -0,0 +1,8 @@ +config NIOS2_10M50 + bool + select NIOS2 + select SERIAL + select ALTERA_TIMER + +config NIOS2 + bool diff --git a/hw/nvram/Kconfig b/hw/nvram/Kconfig new file mode 100644 index 0000000000..ebaa749ce9 --- /dev/null +++ b/hw/nvram/Kconfig @@ -0,0 +1,9 @@ +config DS1225Y + bool + +config AT24C + bool + depends on I2C + +config MAC_NVRAM + bool diff --git a/hw/openrisc/Kconfig b/hw/openrisc/Kconfig new file mode 100644 index 0000000000..6c1e86884e --- /dev/null +++ b/hw/openrisc/Kconfig @@ -0,0 +1,5 @@ +config OR1K_SIM + bool + select SERIAL + select OPENCORES_ETH + select OMPIC diff --git a/hw/pci-bridge/Kconfig b/hw/pci-bridge/Kconfig new file mode 100644 index 0000000000..b167b98497 --- /dev/null +++ b/hw/pci-bridge/Kconfig @@ -0,0 +1,29 @@ +config PCIE_PORT + bool + default y if PCI_DEVICES + depends on PCI_EXPRESS + +config PXB + bool + default y if Q35 + +config XIO3130 + bool + default y if PCI_DEVICES + depends on PCI_EXPRESS + +config IOH3420 + bool + default y if PCI_DEVICES + depends on PCI_EXPRESS + +config I82801B11 + bool + default y if PCI_DEVICES + depends on PCI_EXPRESS + +config DEC_PCI + bool + +config SIMBA + bool diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig new file mode 100644 index 0000000000..b39ea297ba --- /dev/null +++ b/hw/pci-host/Kconfig @@ -0,0 +1,51 @@ +config PAM + bool + +config PREP_PCI + select PCI + bool + +config GRACKLE_PCI + select PCI + bool + +config UNIN_PCI + bool + select PCI + select DEC_PCI + select OPENPIC + +config PPCE500_PCI + select PCI + bool + +config VERSATILE_PCI + select PCI + bool + +config PCI_SABRE + select PCI + bool + +config PCI_PIIX + bool + select PCI + select PAM + select ISA_BUS + +config PCI_EXPRESS_Q35 + bool + select PCI_EXPRESS + select PAM + +config PCI_EXPRESS_GENERIC_BRIDGE + bool + select PCI_EXPRESS + +config PCI_EXPRESS_XILINX + bool + select PCI_EXPRESS + +config PCI_EXPRESS_DESIGNWARE + bool + select PCI_EXPRESS diff --git a/hw/pci/Kconfig b/hw/pci/Kconfig new file mode 100644 index 0000000000..3b8638b51d --- /dev/null +++ b/hw/pci/Kconfig @@ -0,0 +1,9 @@ +config PCI + bool + +config PCI_EXPRESS + bool + select PCI + +config PCI_DEVICES + bool diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs index 9f905e6344..c78f2fb24b 100644 --- a/hw/pci/Makefile.objs +++ b/hw/pci/Makefile.objs @@ -2,8 +2,13 @@ common-obj-$(CONFIG_PCI) += pci.o pci_bridge.o common-obj-$(CONFIG_PCI) += msix.o msi.o common-obj-$(CONFIG_PCI) += shpc.o common-obj-$(CONFIG_PCI) += slotid_cap.o -common-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o -common-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o +common-obj-$(CONFIG_PCI) += pci_host.o + +# The functions in these modules can be used by devices too. Since we +# allow plugging PCIe devices into PCI buses, include them even if +# CONFIG_PCI_EXPRESS=n. +common-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o +common-obj-$(CONFIG_PCI_EXPRESS) += pcie_port.o pcie_host.o common-obj-$(call lnot,$(CONFIG_PCI)) += pci-stub.o common-obj-$(CONFIG_ALL) += pci-stub.o diff --git a/hw/pcmcia/Kconfig b/hw/pcmcia/Kconfig new file mode 100644 index 0000000000..41f2df9136 --- /dev/null +++ b/hw/pcmcia/Kconfig @@ -0,0 +1,2 @@ +config PCMCIA + bool diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig new file mode 100644 index 0000000000..2b83637511 --- /dev/null +++ b/hw/ppc/Kconfig @@ -0,0 +1,121 @@ +config PSERIES + bool + imply PCI_DEVICES + imply TEST_DEVICES + select DIMM + select PCI + select SPAPR_VSCSI + select VFIO if LINUX # needed by spapr_pci_vfio.c + select XICS_SPAPR + select XIVE_SPAPR + +config SPAPR_RNG + bool + default y + depends on PSERIES + +config POWERNV + bool + imply PCI_DEVICES + imply TEST_DEVICES + select ISA_IPMI_BT + select IPMI_LOCAL + select ISA_BUS + select MC146818RTC + select XICS + select XIVE + +config PPC405 + bool + select M48T59 + select PFLASH_CFI02 + select PPC4XX + select SERIAL + +config PPC440 + bool + imply PCI_DEVICES + imply TEST_DEVICES + select PCI_EXPRESS + select PPC4XX + select SERIAL + +config PPC4XX + bool + select BITBANG_I2C + select PCI + +config SAM460EX + bool + select PFLASH_CFI01 + select IDE_SII3112 + select M41T80 + select PPC440 + select SERIAL + select SM501 + select SMBUS_EEPROM + select USB_EHCI_SYSBUS + select USB_OHCI + +config PREP + bool + imply PCI_DEVICES + imply TEST_DEVICES + select CS4231A + select PREP_PCI + select I82374 + select I82378 + select LSI_SCSI_PCI + select M48T59 + select PC87312 + select RS6000_MC + +config RS6000_MC + bool + +config MAC_OLDWORLD + bool + imply PCI_DEVICES + imply SUNGEM + imply TEST_DEVICES + select ADB + select GRACKLE_PCI + select HEATHROW_PIC + select MACIO + +config MAC_NEWWORLD + bool + imply PCI_DEVICES + imply SUNGEM + imply TEST_DEVICES + select ADB + select MACIO + select MACIO_GPIO + select MAC_PMU + select UNIN_PCI + +config E500 + bool + imply AT24C + select ETSEC + select OPENPIC + select PLATFORM_BUS + select PPCE500_PCI + select SERIAL + +config VIRTEX + bool + select PFLASH_CFI01 + select SERIAL + select XILINX + select XILINX_ETHLITE + +config XIVE + bool + depends on POWERNV || PSERIES + +config XIVE_SPAPR + bool + default y + depends on PSERIES + select XIVE diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig new file mode 100644 index 0000000000..e0ee3043a6 --- /dev/null +++ b/hw/riscv/Kconfig @@ -0,0 +1,33 @@ +config HTIF + bool + +config HART + bool + +config SIFIVE + bool + +config SIFIVE_E + bool + select HART + select SIFIVE + +config SIFIVE_U + bool + select CADENCE + select HART + select SIFIVE + +config SPIKE + bool + select HART + select HTIF + select SIFIVE + +config RISCV_VIRT + bool + select HART + select SERIAL + select VIRTIO_MMIO + select PCI_EXPRESS_GENERIC_BRIDGE + select SIFIVE diff --git a/hw/s390x/Kconfig b/hw/s390x/Kconfig new file mode 100644 index 0000000000..a7046ea41f --- /dev/null +++ b/hw/s390x/Kconfig @@ -0,0 +1,11 @@ +config S390_CCW_VIRTIO + bool + imply VIRTIO_PCI + imply TERMINAL3270 + imply VFIO_AP + imply VFIO_CCW + imply WDT_DIAG288 + select PCI + select S390_FLIC + select SCLPCONSOLE + select VIRTIO_CCW diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs index bfd5326d7c..e02ed80b68 100644 --- a/hw/s390x/Makefile.objs +++ b/hw/s390x/Makefile.objs @@ -6,7 +6,8 @@ obj-y += sclpcpu.o obj-y += ipl.o obj-y += css.o obj-$(CONFIG_S390_CCW_VIRTIO) += s390-virtio-ccw.o -obj-y += 3270-ccw.o +obj-$(CONFIG_TERMINAL3270) += 3270-ccw.o +ifeq ($(CONFIG_VIRTIO_CCW),y) obj-y += virtio-ccw.o obj-$(CONFIG_VIRTIO_SERIAL) += virtio-ccw-serial.o obj-$(CONFIG_VIRTIO_BALLOON) += virtio-ccw-balloon.o @@ -19,6 +20,7 @@ obj-$(CONFIG_VIRTIO_NET) += virtio-ccw-net.o obj-$(CONFIG_VIRTIO_BLK) += virtio-ccw-blk.o obj-$(call land,$(CONFIG_VIRTIO_9P),$(CONFIG_VIRTFS)) += virtio-ccw-9p.o obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock-ccw.o +endif obj-y += css-bridge.o obj-y += ccw-device.o obj-y += s390-pci-bus.o s390-pci-inst.o diff --git a/hw/scsi/Kconfig b/hw/scsi/Kconfig new file mode 100644 index 0000000000..b3ba540c17 --- /dev/null +++ b/hw/scsi/Kconfig @@ -0,0 +1,54 @@ +config SCSI + bool + +config LSI_SCSI_PCI + bool + default y if PCI_DEVICES + depends on PCI + select SCSI + +config MPTSAS_SCSI_PCI + bool + default y if PCI_DEVICES + depends on PCI + select SCSI + +config MEGASAS_SCSI_PCI + bool + default y if PCI_DEVICES + depends on PCI + select SCSI + +config VMW_PVSCSI_SCSI_PCI + bool + default y if PCI_DEVICES + depends on PCI + select SCSI + +config ESP + bool + select SCSI + +config ESP_PCI + bool + default y if PCI_DEVICES + depends on PCI + select ESP + +config SPAPR_VSCSI + bool + default y + depends on PSERIES + select SCSI + +config VIRTIO_SCSI + bool + default y + depends on VIRTIO + select SCSI + +config VHOST_USER_SCSI + bool + # Only PCI devices are provided for now + default y if VIRTIO_PCI + depends on VIRTIO && VHOST_USER && LINUX diff --git a/hw/scsi/Makefile.objs b/hw/scsi/Makefile.objs index 45167baeaf..54b36ed8b1 100644 --- a/hw/scsi/Makefile.objs +++ b/hw/scsi/Makefile.objs @@ -6,7 +6,7 @@ common-obj-$(CONFIG_MEGASAS_SCSI_PCI) += megasas.o common-obj-$(CONFIG_VMW_PVSCSI_SCSI_PCI) += vmw_pvscsi.o common-obj-$(CONFIG_ESP) += esp.o common-obj-$(CONFIG_ESP_PCI) += esp-pci.o -obj-$(CONFIG_PSERIES) += spapr_vscsi.o +obj-$(CONFIG_SPAPR_VSCSI) += spapr_vscsi.o ifeq ($(CONFIG_VIRTIO_SCSI),y) obj-y += virtio-scsi.o virtio-scsi-dataplane.o diff --git a/hw/sd/Kconfig b/hw/sd/Kconfig new file mode 100644 index 0000000000..864f535011 --- /dev/null +++ b/hw/sd/Kconfig @@ -0,0 +1,17 @@ +config PL181 + bool + select SD + +config SSI_SD + bool + depends on SSI + select SD + +config SD + bool + +config SDHCI + bool + default y if PCI_DEVICES + depends on PCI + select SD diff --git a/hw/sh4/Kconfig b/hw/sh4/Kconfig new file mode 100644 index 0000000000..8597613a35 --- /dev/null +++ b/hw/sh4/Kconfig @@ -0,0 +1,23 @@ +config R2D + bool + imply PCI_DEVICES + imply TEST_DEVICES + select I82378 if TEST_DEVICES + select IDE_MMIO + select PFLASH_CFI02 + select USB_OHCI + select PCI + select SM501 + select SH4 + +config SHIX + bool + select SH7750 + select SH4 + +config SH7750 + bool + +config SH4 + bool + select PTIMER diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig new file mode 100644 index 0000000000..553adf4bfc --- /dev/null +++ b/hw/smbios/Kconfig @@ -0,0 +1,2 @@ +config SMBIOS + bool diff --git a/hw/sparc/Kconfig b/hw/sparc/Kconfig new file mode 100644 index 0000000000..2a83a8010e --- /dev/null +++ b/hw/sparc/Kconfig @@ -0,0 +1,26 @@ +config SUN4M + bool + imply TCX + imply CG3 + select CS4231 + select ECCMEMCTL + select EMPTY_SLOT + select ESCC + select ESP + select FDC + select SLAVIO + select LANCE + select M48T59 + select STP2000 + +config LEON3 + bool + select GRLIB + +config GRLIB + bool + select PTIMER + +config SLAVIO + bool + select PTIMER diff --git a/hw/sparc64/Kconfig b/hw/sparc64/Kconfig new file mode 100644 index 0000000000..4a8166ebb7 --- /dev/null +++ b/hw/sparc64/Kconfig @@ -0,0 +1,19 @@ +config SUN4U + bool + imply PCI_DEVICES + imply SUNHME + imply TEST_DEVICES + select M48T59 + select ISA_BUS + select FDC + select SERIAL_ISA + select PCI_SABRE + select IDE_CMD646 + select PARALLEL + select PCKBD + select SIMBA + +config NIAGARA + bool + select EMPTY_SLOT + select SUN4V_RTC diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig new file mode 100644 index 0000000000..9e54a0c8dd --- /dev/null +++ b/hw/ssi/Kconfig @@ -0,0 +1,18 @@ +config PL022 + bool + select SSI + +config SSI + bool + +config XILINX_SPI + bool + select SSI + +config XILINX_SPIPS + bool + select SSI + +config STM32F2XX_SPI + bool + select SSI diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig new file mode 100644 index 0000000000..51921eb63f --- /dev/null +++ b/hw/timer/Kconfig @@ -0,0 +1,63 @@ +config ARM_TIMER + bool + select PTIMER + +config ARM_MPTIMER + bool + select PTIMER + +config A9_GTIMER + bool + +config DS1338 + bool + depends on I2C + +config HPET + bool + default y if PC + +config I8254 + bool + +config M41T80 + bool + depends on I2C + +config M48T59 + bool + +config PL031 + bool + +config TWL92230 + bool + depends on I2C + +config XLNX_ZYNQMP + bool + +config ALTERA_TIMER + bool + select PTIMER + +config MC146818RTC + bool + +config ALLWINNER_A10_PIT + bool + select PTIMER + +config STM32F2XX_TIMER + bool + +config SUN4V_RTC + bool + +config CMSDK_APB_TIMER + bool + select PTIMER + +config CMSDK_APB_DUALTIMER + bool + select PTIMER diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig new file mode 100644 index 0000000000..4c8ee87d67 --- /dev/null +++ b/hw/tpm/Kconfig @@ -0,0 +1,24 @@ +config TPMDEV + bool + depends on TPM + +config TPM_TIS + bool + depends on TPM && ISA_BUS + select TPMDEV + +config TPM_CRB + bool + depends on TPM && PC + select TPMDEV + +config TPM_PASSTHROUGH + bool + default y + # FIXME: should check for x86 host as well + depends on TPMDEV && LINUX + +config TPM_EMULATOR + bool + default y + depends on TPMDEV diff --git a/hw/tricore/Kconfig b/hw/tricore/Kconfig new file mode 100644 index 0000000000..9313409309 --- /dev/null +++ b/hw/tricore/Kconfig @@ -0,0 +1,2 @@ +config TRICORE + bool diff --git a/hw/unicore32/Kconfig b/hw/unicore32/Kconfig new file mode 100644 index 0000000000..4443a29dd2 --- /dev/null +++ b/hw/unicore32/Kconfig @@ -0,0 +1,5 @@ +config PUV3 + bool + select ISA_BUS + select PCKBD + select PTIMER diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig new file mode 100644 index 0000000000..a1b7acb12a --- /dev/null +++ b/hw/usb/Kconfig @@ -0,0 +1,91 @@ +config USB + bool + +config USB_UHCI + bool + default y if PCI_DEVICES + depends on PCI + select USB + +config USB_OHCI + bool + default y if PCI_DEVICES + depends on PCI + select USB + +config USB_EHCI + bool + default y if PCI_DEVICES + depends on PCI + select USB + +config USB_EHCI_SYSBUS + bool + select USB + +config USB_XHCI + bool + default y if PCI_DEVICES + depends on PCI + select USB + +config USB_XHCI_NEC + bool + default y if PCI_DEVICES + depends on PCI + select USB + +config USB_MUSB + bool + select USB + +config TUSB6010 + bool + select USB_MUSB + +config USB_TABLET_WACOM + bool + default y + depends on USB + +config USB_STORAGE_BOT + bool + default y + depends on USB + select SCSI + +config USB_STORAGE_UAS + bool + default y + depends on USB + select SCSI + +config USB_AUDIO + bool + default y + depends on USB + +config USB_SERIAL + bool + default y + depends on USB + +config USB_NETWORK + bool + default y + depends on USB + +config USB_BLUETOOTH + bool + default y + depends on USB + +config USB_SMARTCARD + bool + default y + depends on USB + +config USB_STORAGE_MTP + bool + default y + depends on USB diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs index 41be700812..2b929649ac 100644 --- a/hw/usb/Makefile.objs +++ b/hw/usb/Makefile.objs @@ -6,7 +6,7 @@ common-obj-$(CONFIG_USB) += desc.o desc-msos.o common-obj-$(CONFIG_USB_UHCI) += hcd-uhci.o common-obj-$(CONFIG_USB_OHCI) += hcd-ohci.o common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o hcd-ehci-pci.o -common-obj-$(CONFIG_USB_EHCI_SYSBUS) += hcd-ehci-sysbus.o +common-obj-$(CONFIG_USB_EHCI_SYSBUS) += hcd-ehci.o hcd-ehci-sysbus.o common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o diff --git a/hw/vfio/Kconfig b/hw/vfio/Kconfig new file mode 100644 index 0000000000..ebda9fdf22 --- /dev/null +++ b/hw/vfio/Kconfig @@ -0,0 +1,36 @@ +config VFIO + bool + depends on LINUX + +config VFIO_PCI + bool + select VFIO + depends on LINUX + +config VFIO_CCW + bool + default y + select VFIO + depends on LINUX && S390_CCW_VIRTIO + +config VFIO_PLATFORM + bool + default y + select VFIO + depends on LINUX && PLATFORM_BUS + +config VFIO_XGMAC + bool + default y + depends on VFIO_PLATFORM + +config VFIO_AMD_XGBE + bool + default y + depends on VFIO_PLATFORM + +config VFIO_AP + bool + default y + select VFIO + depends on LINUX && S390_CCW_VIRTIO diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig new file mode 100644 index 0000000000..e0452de4ba --- /dev/null +++ b/hw/virtio/Kconfig @@ -0,0 +1,31 @@ +config VIRTIO + bool + +config VIRTIO_RNG + bool + default y + depends on VIRTIO + +config VIRTIO_PCI + bool + default y if PCI_DEVICES + depends on PCI + select VIRTIO + +config VIRTIO_MMIO + bool + select VIRTIO + +config VIRTIO_CCW + bool + select VIRTIO + +config VIRTIO_BALLOON + bool + default y + depends on VIRTIO + +config VIRTIO_CRYPTO + bool + default y + depends on VIRTIO diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index a3eb8ed866..f2ab667a21 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -29,6 +29,8 @@ obj-$(CONFIG_VIRTIO_BLK) += virtio-blk-pci.o obj-$(CONFIG_VIRTIO_NET) += virtio-net-pci.o obj-$(CONFIG_VIRTIO_SERIAL) += virtio-serial-pci.o endif +else +common-obj-y += vhost-stub.o endif common-obj-$(CONFIG_ALL) += vhost-stub.o diff --git a/hw/watchdog/Kconfig b/hw/watchdog/Kconfig new file mode 100644 index 0000000000..2118d897c9 --- /dev/null +++ b/hw/watchdog/Kconfig @@ -0,0 +1,16 @@ +config CMSDK_APB_WATCHDOG + bool + select PTIMER + +config WDT_IB6300ESB + bool + default y if PCI_DEVICES + depends on PCI + +config WDT_IB700 + bool + default y + depends on ISA_BUS + +config WDT_DIAG288 + bool diff --git a/hw/xtensa/Kconfig b/hw/xtensa/Kconfig new file mode 100644 index 0000000000..d72817d012 --- /dev/null +++ b/hw/xtensa/Kconfig @@ -0,0 +1,8 @@ +config XTENSA_SIM + bool + +config XTENSA_XTFPGA + bool + select OPENCORES_ETH + select PFLASH_CFI01 + select SERIAL diff --git a/hw/xtensa/Makefile.objs b/hw/xtensa/Makefile.objs index fa86730e23..0bbfccd6de 100644 --- a/hw/xtensa/Makefile.objs +++ b/hw/xtensa/Makefile.objs @@ -2,4 +2,4 @@ obj-y += mx_pic.o obj-y += pic_cpu.o obj-y += xtensa_memory.o obj-$(CONFIG_XTENSA_SIM) += sim.o -obj-$(CONFIG_XTENSA_FPGA) += xtfpga.o +obj-$(CONFIG_XTENSA_XTFPGA) += xtfpga.o diff --git a/include/migration/qemu-file-types.h b/include/migration/qemu-file-types.h index bd6d7dd7f9..bbe04d4484 100644 --- a/include/migration/qemu-file-types.h +++ b/include/migration/qemu-file-types.h @@ -25,6 +25,8 @@ #ifndef QEMU_FILE_H #define QEMU_FILE_H +int qemu_file_get_error(QEMUFile *f); + void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size); void qemu_put_byte(QEMUFile *f, int v); diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 6e8762b40d..c1a26021f8 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -500,13 +500,48 @@ static uint32_t get_elf_hwcap2(void) #undef GET_FEATURE #undef GET_FEATURE_ID +#define ELF_PLATFORM get_elf_platform() + +static const char *get_elf_platform(void) +{ + CPUARMState *env = thread_cpu->env_ptr; + +#ifdef TARGET_WORDS_BIGENDIAN +# define END "b" +#else +# define END "l" +#endif + + if (arm_feature(env, ARM_FEATURE_V8)) { + return "v8" END; + } else if (arm_feature(env, ARM_FEATURE_V7)) { + if (arm_feature(env, ARM_FEATURE_M)) { + return "v7m" END; + } else { + return "v7" END; + } + } else if (arm_feature(env, ARM_FEATURE_V6)) { + return "v6" END; + } else if (arm_feature(env, ARM_FEATURE_V5)) { + return "v5" END; + } else { + return "v4" END; + } + +#undef END +} + #else /* 64 bit ARM definitions */ #define ELF_START_MMAP 0x80000000 #define ELF_ARCH EM_AARCH64 #define ELF_CLASS ELFCLASS64 -#define ELF_PLATFORM "aarch64" +#ifdef TARGET_WORDS_BIGENDIAN +# define ELF_PLATFORM "aarch64_be" +#else +# define ELF_PLATFORM "aarch64" +#endif static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c index 30425c9df6..612819c1b1 100644 --- a/linux-user/fd-trans.c +++ b/linux-user/fd-trans.c @@ -75,6 +75,8 @@ enum { QEMU_IFLA_BR_MCAST_STATS_ENABLED, QEMU_IFLA_BR_MCAST_IGMP_VERSION, QEMU_IFLA_BR_MCAST_MLD_VERSION, + QEMU_IFLA_BR_VLAN_STATS_PER_PORT, + QEMU_IFLA_BR_MULTI_BOOLOPT, QEMU___IFLA_BR_MAX, }; @@ -438,6 +440,7 @@ static abi_long host_to_target_data_bridge_nlattr(struct nlattr *nlattr, case QEMU_IFLA_BR_MCAST_STATS_ENABLED: case QEMU_IFLA_BR_MCAST_IGMP_VERSION: case QEMU_IFLA_BR_MCAST_MLD_VERSION: + case QEMU_IFLA_BR_VLAN_STATS_PER_PORT: break; /* uint16_t */ case QEMU_IFLA_BR_PRIORITY: @@ -543,6 +546,12 @@ static abi_long host_to_target_slave_data_bridge_nlattr(struct nlattr *nlattr, case QEMU_IFLA_BRPORT_ROOT_ID: case QEMU_IFLA_BRPORT_BRIDGE_ID: break; + /* br_boolopt_multi { uint32_t, uint32_t } */ + case QEMU_IFLA_BR_MULTI_BOOLOPT: + u32 = NLA_DATA(nlattr); + u32[0] = tswap32(u32[0]); /* optval */ + u32[1] = tswap32(u32[1]); /* optmask */ + break; default: gemu_log("Unknown QEMU_IFLA_BRPORT type %d\n", nlattr->nla_type); break; diff --git a/linux-user/nios2/cpu_loop.c b/linux-user/nios2/cpu_loop.c index b96b1aa119..5aa1eca740 100644 --- a/linux-user/nios2/cpu_loop.c +++ b/linux-user/nios2/cpu_loop.c @@ -73,6 +73,12 @@ void cpu_loop(CPUNios2State *env) queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; } + case EXCP_DEBUG: + info.si_signo = TARGET_SIGTRAP; + info.si_errno = 0; + info.si_code = TARGET_TRAP_BRKPT; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; case 0xaa: switch (env->regs[R_PC]) { /*case 0x1000:*/ /* TODO:__kuser_helper_version */ diff --git a/linux-user/strace.c b/linux-user/strace.c index 7318392e57..6f72a74c09 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1235,6 +1235,18 @@ print_chdir(const struct syscallname *name, } #endif +#ifdef TARGET_NR_chroot +static void +print_chroot(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + print_string(arg0, 1); + print_syscall_epilogue(name); +} +#endif + #ifdef TARGET_NR_chmod static void print_chmod(const struct syscallname *name, diff --git a/linux-user/strace.list b/linux-user/strace.list index ff8bb19f5f..db21ce4177 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -77,7 +77,7 @@ { TARGET_NR_chown32, "chown32" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_chroot -{ TARGET_NR_chroot, "chroot" , NULL, NULL, NULL }, +{ TARGET_NR_chroot, "chroot" , NULL, print_chroot, NULL }, #endif #ifdef TARGET_NR_clock_adjtime { TARGET_NR_clock_adjtime, "clock_adjtime" , NULL, print_clock_adjtime, NULL }, diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5bbb72f3d5..208fd1813d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2759,6 +2759,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, } if (!is_error(ret)) { msgp->msg_namelen = tswap32(msg.msg_namelen); + msgp->msg_flags = tswap32(msg.msg_flags); if (msg.msg_name != NULL && msg.msg_name != (void *)-1) { ret = host_to_target_sockaddr(tswapal(msgp->msg_name), msg.msg_name, msg.msg_namelen); @@ -2846,7 +2847,7 @@ static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec, static abi_long do_accept4(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr, int flags) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; int host_flags; @@ -2870,11 +2871,13 @@ static abi_long do_accept4(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(safe_accept4(fd, addr, &addrlen, host_flags)); + ret_addrlen = addrlen; + ret = get_errno(safe_accept4(fd, addr, &ret_addrlen, host_flags)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -2883,7 +2886,7 @@ static abi_long do_accept4(int fd, abi_ulong target_addr, static abi_long do_getpeername(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; @@ -2899,11 +2902,13 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(getpeername(fd, addr, &addrlen)); + ret_addrlen = addrlen; + ret = get_errno(getpeername(fd, addr, &ret_addrlen)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -2912,7 +2917,7 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, static abi_long do_getsockname(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; @@ -2928,11 +2933,13 @@ static abi_long do_getsockname(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(getsockname(fd, addr, &addrlen)); + ret_addrlen = addrlen; + ret = get_errno(getsockname(fd, addr, &ret_addrlen)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -3004,7 +3011,7 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, abi_ulong target_addrlen) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; void *host_msg; abi_long ret; @@ -3022,10 +3029,12 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, goto fail; } addr = alloca(addrlen); + ret_addrlen = addrlen; ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, - addr, &addrlen)); + addr, &ret_addrlen)); } else { addr = NULL; /* To keep compiler quiet. */ + addrlen = 0; /* To keep compiler quiet. */ ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0)); } if (!is_error(ret)) { @@ -3038,8 +3047,9 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, } } if (target_addr) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen)) { + host_to_target_sockaddr(target_addr, addr, + MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen)) { ret = -TARGET_EFAULT; goto fail; } @@ -4723,8 +4733,8 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, const int *dst_offsets, *src_offsets; int target_size; void *argptr; - abi_ulong *target_rt_dev_ptr; - unsigned long *host_rt_dev_ptr; + abi_ulong *target_rt_dev_ptr = NULL; + unsigned long *host_rt_dev_ptr = NULL; abi_long ret; int i; @@ -4770,6 +4780,9 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, unlock_user(argptr, arg, 0); ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + + assert(host_rt_dev_ptr != NULL); + assert(target_rt_dev_ptr != NULL); if (*host_rt_dev_ptr != 0) { unlock_user((void *)*host_rt_dev_ptr, *target_rt_dev_ptr, 0); @@ -6999,8 +7012,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, _exit(arg1); return 0; /* avoid warning */ case TARGET_NR_read: - if (arg3 == 0) { - return 0; + if (arg2 == 0 && arg3 == 0) { + return get_errno(safe_read(arg1, 0, 0)); } else { if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) return -TARGET_EFAULT; diff --git a/migration/qemu-file.h b/migration/qemu-file.h index 2ccfcfb2a8..13baf896bd 100644 --- a/migration/qemu-file.h +++ b/migration/qemu-file.h @@ -149,7 +149,6 @@ void qemu_update_position(QEMUFile *f, size_t size); void qemu_file_reset_rate_limit(QEMUFile *f); void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate); int64_t qemu_file_get_rate_limit(QEMUFile *f); -int qemu_file_get_error(QEMUFile *f); void qemu_file_set_error(QEMUFile *f, int ret); int qemu_file_shutdown(QEMUFile *f); QEMUFile *qemu_file_get_return_path(QEMUFile *f); diff --git a/net/Makefile.objs b/net/Makefile.objs index 8262f033b9..c5d076d19c 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -8,6 +8,8 @@ common-obj-$(call land,$(CONFIG_VIRTIO_NET),$(CONFIG_VHOST_NET_USER)) += vhost-u common-obj-$(call land,$(call lnot,$(CONFIG_VIRTIO_NET)),$(CONFIG_VHOST_NET_USER)) += vhost-user-stub.o common-obj-$(CONFIG_ALL) += vhost-user-stub.o common-obj-$(CONFIG_SLIRP) += slirp.o +slirp.o-cflags := $(SLIRP_CFLAGS) +slirp.o-libs := $(SLIRP_LIBS) common-obj-$(CONFIG_VDE) += vde.o common-obj-$(CONFIG_NETMAP) += netmap.o common-obj-y += filter.o diff --git a/net/slirp.c b/net/slirp.c index 4ec989b592..95934fb36d 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -37,13 +37,15 @@ #include "monitor/monitor.h" #include "qemu/error-report.h" #include "qemu/sockets.h" -#include "slirp/libslirp.h" +#include <libslirp.h> #include "chardev/char-fe.h" #include "sysemu/sysemu.h" #include "qemu/cutils.h" #include "qapi/error.h" #include "qapi/qmp/qdict.h" #include "util.h" +#include "migration/register.h" +#include "migration/qemu-file-types.h" static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) { @@ -146,6 +148,7 @@ static void net_slirp_cleanup(NetClientState *nc) g_slist_free_full(s->fwd, slirp_free_fwd); main_loop_poll_remove_notifier(&s->poll_notifier); + unregister_savevm(NULL, "slirp", s->slirp); slirp_cleanup(s->slirp); if (s->exit_notifier.notify) { qemu_remove_exit_notifier(&s->exit_notifier); @@ -303,6 +306,46 @@ static void net_slirp_poll_notify(Notifier *notifier, void *data) } } +static ssize_t +net_slirp_stream_read(void *buf, size_t size, void *opaque) +{ + QEMUFile *f = opaque; + + return qemu_get_buffer(f, buf, size); +} + +static ssize_t +net_slirp_stream_write(const void *buf, size_t size, void *opaque) +{ + QEMUFile *f = opaque; + + qemu_put_buffer(f, buf, size); + if (qemu_file_get_error(f)) { + return -1; + } + + return size; +} + +static int net_slirp_state_load(QEMUFile *f, void *opaque, int version_id) +{ + Slirp *slirp = opaque; + + return slirp_state_load(slirp, version_id, net_slirp_stream_read, f); +} + +static void net_slirp_state_save(QEMUFile *f, void *opaque) +{ + Slirp *slirp = opaque; + + slirp_state_save(slirp, net_slirp_stream_write, f); +} + +static SaveVMHandlers savevm_slirp_state = { + .save_state = net_slirp_state_save, + .load_state = net_slirp_state_load, +}; + static int net_slirp_init(NetClientState *peer, const char *model, const char *name, int restricted, bool ipv4, const char *vnetwork, const char *vhost, @@ -523,6 +566,18 @@ static int net_slirp_init(NetClientState *peer, const char *model, &slirp_cb, s); QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry); + /* + * Make sure the current bitstream version of slirp is 4, to avoid + * QEMU migration incompatibilities, if upstream slirp bumped the + * version. + * + * FIXME: use bitfields of features? teach libslirp to save with + * specific version? + */ + g_assert(slirp_state_version() == 4); + register_savevm_live(NULL, "slirp", 0, slirp_state_version(), + &savevm_slirp_state, s->slirp); + s->poll_notifier.notify = net_slirp_poll_notify; main_loop_poll_add_notifier(&s->poll_notifier); @@ -885,6 +940,7 @@ static ssize_t guestfwd_write(const void *buf, size_t len, void *chr) static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp) { + /* TODO: IPv6 */ struct in_addr server = { .s_addr = 0 }; struct GuestFwd *fwd; const char *p; diff --git a/scripts/qemu.py b/python/qemu/__init__.py index f7269eefbb..fd144c0006 100644 --- a/scripts/qemu.py +++ b/python/qemu/__init__.py @@ -16,12 +16,13 @@ import errno import logging import os import subprocess -import qmp.qmp import re import shutil import socket import tempfile +from . import qmp + LOG = logging.getLogger(__name__) @@ -66,7 +67,7 @@ class QEMUMachineAddDeviceError(QEMUMachineError): failures reported by the QEMU binary itself. """ -class MonitorResponseError(qmp.qmp.QMPError): +class MonitorResponseError(qmp.QMPError): """ Represents erroneous QMP monitor reply """ @@ -266,8 +267,8 @@ class QEMUMachine(object): self._qemu_log_path = os.path.join(self._temp_dir, self._name + ".log") self._qemu_log_file = open(self._qemu_log_path, 'wb') - self._qmp = qmp.qmp.QEMUMonitorProtocol(self._vm_monitor, - server=True) + self._qmp = qmp.QEMUMonitorProtocol(self._vm_monitor, + server=True) def _post_launch(self): self._qmp.accept() @@ -319,6 +320,7 @@ class QEMUMachine(object): self._pre_launch() self._qemu_full_args = (self._wrapper + [self._binary] + self._base_args() + self._args) + LOG.debug('VM launch command: %r', ' '.join(self._qemu_full_args)) self._popen = subprocess.Popen(self._qemu_full_args, stdin=devnull, stdout=self._qemu_log_file, @@ -383,7 +385,7 @@ class QEMUMachine(object): """ reply = self.qmp(cmd, conv_keys, **args) if reply is None: - raise qmp.qmp.QMPError("Monitor is closed") + raise qmp.QMPError("Monitor is closed") if "error" in reply: raise MonitorResponseError(reply) return reply["return"] diff --git a/scripts/qmp/qmp.py b/python/qemu/qmp.py index 5c8cf6a056..5c8cf6a056 100644 --- a/scripts/qmp/qmp.py +++ b/python/qemu/qmp.py diff --git a/scripts/qtest.py b/python/qemu/qtest.py index afac3fe900..eb45824dd0 100644 --- a/scripts/qtest.py +++ b/python/qemu/qtest.py @@ -13,7 +13,8 @@ import socket import os -import qemu + +from . import QEMUMachine class QEMUQtestProtocol(object): @@ -79,7 +80,7 @@ class QEMUQtestProtocol(object): self._sock.settimeout(timeout) -class QEMUQtestMachine(qemu.QEMUMachine): +class QEMUQtestMachine(QEMUMachine): '''A QEMU VM''' def __init__(self, binary, args=None, name=None, test_dir="/var/tmp", @@ -144,7 +144,7 @@ cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \ cc-c-option = $(if $(shell $(CC) $1 $2 -c -o /dev/null -xc /dev/null \ >/dev/null 2>&1 && echo OK), $2, $3) -VPATH_SUFFIXES = %.c %.h %.S %.cc %.cpp %.m %.mak %.texi %.sh %.rc +VPATH_SUFFIXES = %.c %.h %.S %.cc %.cpp %.m %.mak %.texi %.sh %.rc Kconfig% set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1))) # install-prog list, dir diff --git a/scripts/device-crash-test b/scripts/device-crash-test index 2a13fa4f84..a6748910ad 100755 --- a/scripts/device-crash-test +++ b/scripts/device-crash-test @@ -25,6 +25,7 @@ check for crashes and unexpected errors. """ from __future__ import print_function +import os import sys import glob import logging @@ -34,6 +35,7 @@ import random import argparse from itertools import chain +sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python')) from qemu import QEMUMachine logger = logging.getLogger('device-crash-test') diff --git a/scripts/make_device_config.sh b/scripts/make_device_config.sh deleted file mode 100644 index 354af317b3..0000000000 --- a/scripts/make_device_config.sh +++ /dev/null @@ -1,30 +0,0 @@ -#! /bin/sh -# Writes a target device config file to stdout, from a default and from -# include directives therein. Also emits Makefile dependencies. -# -# Usage: make_device_config.sh SRC DEPFILE-NAME DEPFILE-TARGET > DEST - -src=$1 -dep=$2 -target=$3 -src_dir=$(dirname $src) -all_includes= - -process_includes () { - cat $1 | grep '^include' | \ - while read include file ; do - all_includes="$all_includes $src_dir/$file" - process_includes $src_dir/$file - done -} - -f=$src -while [ -n "$f" ] ; do - f=$(cat $f | tr -d '\r' | awk '/^include / {printf "'$src_dir'/%s ", $2}') - [ $? = 0 ] || exit 1 - all_includes="$all_includes $f" -done -process_includes $src - -cat $src $all_includes | grep -v '^include' -echo "$target: $all_includes" > $dep diff --git a/scripts/minikconf.py b/scripts/minikconf.py new file mode 100644 index 0000000000..5421db0ed0 --- /dev/null +++ b/scripts/minikconf.py @@ -0,0 +1,708 @@ +# +# Mini-Kconfig parser +# +# Copyright (c) 2015 Red Hat Inc. +# +# Authors: +# Paolo Bonzini <pbonzini@redhat.com> +# +# This work is licensed under the terms of the GNU GPL, version 2 +# or, at your option, any later version. See the COPYING file in +# the top-level directory. + +from __future__ import print_function +import os +import sys +import re +import random + +__all__ = [ 'KconfigDataError', 'KconfigParserError', + 'KconfigData', 'KconfigParser' , + 'defconfig', 'allyesconfig', 'allnoconfig', 'randconfig' ] + +def debug_print(*args): + #print('# ' + (' '.join(str(x) for x in args))) + pass + +# ------------------------------------------- +# KconfigData implements the Kconfig semantics. For now it can only +# detect undefined symbols, i.e. symbols that were referenced in +# assignments or dependencies but were not declared with "config FOO". +# +# Semantic actions are represented by methods called do_*. The do_var +# method return the semantic value of a variable (which right now is +# just its name). +# ------------------------------------------- + +class KconfigDataError(Exception): + def __init__(self, msg): + self.msg = msg + + def __str__(self): + return self.msg + +allyesconfig = lambda x: True +allnoconfig = lambda x: False +defconfig = lambda x: x +randconfig = lambda x: random.randint(0, 1) == 1 + +class KconfigData: + class Expr: + def __and__(self, rhs): + return KconfigData.AND(self, rhs) + def __or__(self, rhs): + return KconfigData.OR(self, rhs) + def __invert__(self): + return KconfigData.NOT(self) + + # Abstract methods + def add_edges_to(self, var): + pass + def evaluate(self): + assert False + + class AND(Expr): + def __init__(self, lhs, rhs): + self.lhs = lhs + self.rhs = rhs + def __str__(self): + return "(%s && %s)" % (self.lhs, self.rhs) + + def add_edges_to(self, var): + self.lhs.add_edges_to(var) + self.rhs.add_edges_to(var) + def evaluate(self): + return self.lhs.evaluate() and self.rhs.evaluate() + + class OR(Expr): + def __init__(self, lhs, rhs): + self.lhs = lhs + self.rhs = rhs + def __str__(self): + return "(%s || %s)" % (self.lhs, self.rhs) + + def add_edges_to(self, var): + self.lhs.add_edges_to(var) + self.rhs.add_edges_to(var) + def evaluate(self): + return self.lhs.evaluate() or self.rhs.evaluate() + + class NOT(Expr): + def __init__(self, lhs): + self.lhs = lhs + def __str__(self): + return "!%s" % (self.lhs) + + def add_edges_to(self, var): + self.lhs.add_edges_to(var) + def evaluate(self): + return not self.lhs.evaluate() + + class Var(Expr): + def __init__(self, name): + self.name = name + self.value = None + self.outgoing = set() + self.clauses_for_var = list() + def __str__(self): + return self.name + + def has_value(self): + return not (self.value is None) + def set_value(self, val, clause): + self.clauses_for_var.append(clause) + if self.has_value() and self.value != val: + print("The following clauses were found for " + self.name) + for i in self.clauses_for_var: + print(" " + str(i), file=sys.stderr) + raise KconfigDataError('contradiction between clauses when setting %s' % self) + debug_print("=> %s is now %s" % (self.name, val)) + self.value = val + + # depth first search of the dependency graph + def dfs(self, visited, f): + if self in visited: + return + visited.add(self) + for v in self.outgoing: + v.dfs(visited, f) + f(self) + + def add_edges_to(self, var): + self.outgoing.add(var) + def evaluate(self): + if not self.has_value(): + raise KconfigDataError('cycle found including %s' % self) + return self.value + + class Clause: + def __init__(self, dest): + self.dest = dest + def priority(self): + return 0 + def process(self): + pass + + class AssignmentClause(Clause): + def __init__(self, dest, value): + KconfigData.Clause.__init__(self, dest) + self.value = value + def __str__(self): + return "CONFIG_%s=%s" % (self.dest, 'y' if self.value else 'n') + + def process(self): + self.dest.set_value(self.value, self) + + class DefaultClause(Clause): + def __init__(self, dest, value, cond=None): + KconfigData.Clause.__init__(self, dest) + self.value = value + self.cond = cond + if not (self.cond is None): + self.cond.add_edges_to(self.dest) + def __str__(self): + value = 'y' if self.value else 'n' + if self.cond is None: + return "config %s default %s" % (self.dest, value) + else: + return "config %s default %s if %s" % (self.dest, value, self.cond) + + def priority(self): + # Defaults are processed just before leaving the variable + return -1 + def process(self): + if not self.dest.has_value() and \ + (self.cond is None or self.cond.evaluate()): + self.dest.set_value(self.value, self) + + class DependsOnClause(Clause): + def __init__(self, dest, expr): + KconfigData.Clause.__init__(self, dest) + self.expr = expr + self.expr.add_edges_to(self.dest) + def __str__(self): + return "config %s depends on %s" % (self.dest, self.expr) + + def process(self): + if not self.expr.evaluate(): + self.dest.set_value(False, self) + + class SelectClause(Clause): + def __init__(self, dest, cond): + KconfigData.Clause.__init__(self, dest) + self.cond = cond + self.cond.add_edges_to(self.dest) + def __str__(self): + return "select %s if %s" % (self.dest, self.cond) + + def process(self): + if self.cond.evaluate(): + self.dest.set_value(True, self) + + def __init__(self, value_mangler=defconfig): + self.value_mangler = value_mangler + self.previously_included = [] + self.incl_info = None + self.defined_vars = set() + self.referenced_vars = dict() + self.clauses = list() + + # semantic analysis ------------- + + def check_undefined(self): + undef = False + for i in self.referenced_vars: + if not (i in self.defined_vars): + print("undefined symbol %s" % (i), file=sys.stderr) + undef = True + return undef + + def compute_config(self): + if self.check_undefined(): + raise KconfigDataError("there were undefined symbols") + return None + + debug_print("Input:") + for clause in self.clauses: + debug_print(clause) + + debug_print("\nDependency graph:") + for i in self.referenced_vars: + debug_print(i, "->", [str(x) for x in self.referenced_vars[i].outgoing]) + + # The reverse of the depth-first order is the topological sort + dfo = dict() + visited = set() + debug_print("\n") + def visit_fn(var): + debug_print(var, "has DFS number", len(dfo)) + dfo[var] = len(dfo) + + for name, v in self.referenced_vars.items(): + self.do_default(v, False) + v.dfs(visited, visit_fn) + + # Put higher DFS numbers and higher priorities first. This + # places the clauses in topological order and places defaults + # after assignments and dependencies. + self.clauses.sort(key=lambda x: (-dfo[x.dest], -x.priority())) + + debug_print("\nSorted clauses:") + for clause in self.clauses: + debug_print(clause) + clause.process() + + debug_print("") + values = dict() + for name, v in self.referenced_vars.items(): + debug_print("Evaluating", name) + values[name] = v.evaluate() + + return values + + # semantic actions ------------- + + def do_declaration(self, var): + if (var in self.defined_vars): + raise KconfigDataError('variable "' + var + '" defined twice') + + self.defined_vars.add(var.name) + + # var is a string with the variable's name. + def do_var(self, var): + if (var in self.referenced_vars): + return self.referenced_vars[var] + + var_obj = self.referenced_vars[var] = KconfigData.Var(var) + return var_obj + + def do_assignment(self, var, val): + self.clauses.append(KconfigData.AssignmentClause(var, val)) + + def do_default(self, var, val, cond=None): + val = self.value_mangler(val) + self.clauses.append(KconfigData.DefaultClause(var, val, cond)) + + def do_depends_on(self, var, expr): + self.clauses.append(KconfigData.DependsOnClause(var, expr)) + + def do_select(self, var, symbol, cond=None): + cond = (cond & var) if cond is not None else var + self.clauses.append(KconfigData.SelectClause(symbol, cond)) + + def do_imply(self, var, symbol, cond=None): + # "config X imply Y [if COND]" is the same as + # "config Y default y if X [&& COND]" + cond = (cond & var) if cond is not None else var + self.do_default(symbol, True, cond) + +# ------------------------------------------- +# KconfigParser implements a recursive descent parser for (simplified) +# Kconfig syntax. +# ------------------------------------------- + +# tokens table +TOKENS = {} +TOK_NONE = -1 +TOK_LPAREN = 0; TOKENS[TOK_LPAREN] = '"("'; +TOK_RPAREN = 1; TOKENS[TOK_RPAREN] = '")"'; +TOK_EQUAL = 2; TOKENS[TOK_EQUAL] = '"="'; +TOK_AND = 3; TOKENS[TOK_AND] = '"&&"'; +TOK_OR = 4; TOKENS[TOK_OR] = '"||"'; +TOK_NOT = 5; TOKENS[TOK_NOT] = '"!"'; +TOK_DEPENDS = 6; TOKENS[TOK_DEPENDS] = '"depends"'; +TOK_ON = 7; TOKENS[TOK_ON] = '"on"'; +TOK_SELECT = 8; TOKENS[TOK_SELECT] = '"select"'; +TOK_IMPLY = 9; TOKENS[TOK_IMPLY] = '"imply"'; +TOK_CONFIG = 10; TOKENS[TOK_CONFIG] = '"config"'; +TOK_DEFAULT = 11; TOKENS[TOK_DEFAULT] = '"default"'; +TOK_Y = 12; TOKENS[TOK_Y] = '"y"'; +TOK_N = 13; TOKENS[TOK_N] = '"n"'; +TOK_SOURCE = 14; TOKENS[TOK_SOURCE] = '"source"'; +TOK_BOOL = 15; TOKENS[TOK_BOOL] = '"bool"'; +TOK_IF = 16; TOKENS[TOK_IF] = '"if"'; +TOK_ID = 17; TOKENS[TOK_ID] = 'identifier'; +TOK_EOF = 18; TOKENS[TOK_EOF] = 'end of file'; + +class KconfigParserError(Exception): + def __init__(self, parser, msg, tok=None): + self.loc = parser.location() + tok = tok or parser.tok + if tok != TOK_NONE: + location = TOKENS.get(tok, None) or ('"%s"' % tok) + msg = '%s before %s' % (msg, location) + self.msg = msg + + def __str__(self): + return "%s: %s" % (self.loc, self.msg) + +class KconfigParser: + + @classmethod + def parse(self, fp, mode=None): + data = KconfigData(mode or KconfigParser.defconfig) + parser = KconfigParser(data) + parser.parse_file(fp) + return data + + def __init__(self, data): + self.data = data + + def parse_file(self, fp): + self.abs_fname = os.path.abspath(fp.name) + self.fname = fp.name + self.data.previously_included.append(self.abs_fname) + self.src = fp.read() + if self.src == '' or self.src[-1] != '\n': + self.src += '\n' + self.cursor = 0 + self.line = 1 + self.line_pos = 0 + self.get_token() + self.parse_config() + + def do_assignment(self, var, val): + if not var.startswith("CONFIG_"): + raise Error('assigned variable should start with CONFIG_') + var = self.data.do_var(var[7:]) + self.data.do_assignment(var, val) + + # file management ----- + + def error_path(self): + inf = self.data.incl_info + res = "" + while inf: + res = ("In file included from %s:%d:\n" % (inf['file'], + inf['line'])) + res + inf = inf['parent'] + return res + + def location(self): + col = 1 + for ch in self.src[self.line_pos:self.pos]: + if ch == '\t': + col += 8 - ((col - 1) % 8) + else: + col += 1 + return '%s%s:%d:%d' %(self.error_path(), self.fname, self.line, col) + + def do_include(self, include): + incl_abs_fname = os.path.join(os.path.dirname(self.abs_fname), + include) + # catch inclusion cycle + inf = self.data.incl_info + while inf: + if incl_abs_fname == os.path.abspath(inf['file']): + raise KconfigParserError(self, "Inclusion loop for %s" + % include) + inf = inf['parent'] + + # skip multiple include of the same file + if incl_abs_fname in self.data.previously_included: + return + try: + fp = open(incl_abs_fname, 'r') + except IOError as e: + raise KconfigParserError(self, + '%s: %s' % (e.strerror, include)) + + inf = self.data.incl_info + self.data.incl_info = { 'file': self.fname, 'line': self.line, + 'parent': inf } + KconfigParser(self.data).parse_file(fp) + self.data.incl_info = inf + + # recursive descent parser ----- + + # y_or_n: Y | N + def parse_y_or_n(self): + if self.tok == TOK_Y: + self.get_token() + return True + if self.tok == TOK_N: + self.get_token() + return False + raise KconfigParserError(self, 'Expected "y" or "n"') + + # var: ID + def parse_var(self): + if self.tok == TOK_ID: + val = self.val + self.get_token() + return self.data.do_var(val) + else: + raise KconfigParserError(self, 'Expected identifier') + + # assignment_var: ID (starting with "CONFIG_") + def parse_assignment_var(self): + if self.tok == TOK_ID: + val = self.val + if not val.startswith("CONFIG_"): + raise KconfigParserError(self, + 'Expected identifier starting with "CONFIG_"', TOK_NONE) + self.get_token() + return self.data.do_var(val[7:]) + else: + raise KconfigParserError(self, 'Expected identifier') + + # assignment: var EQUAL y_or_n + def parse_assignment(self): + var = self.parse_assignment_var() + if self.tok != TOK_EQUAL: + raise KconfigParserError(self, 'Expected "="') + self.get_token() + self.data.do_assignment(var, self.parse_y_or_n()) + + # primary: NOT primary + # | LPAREN expr RPAREN + # | var + def parse_primary(self): + if self.tok == TOK_NOT: + self.get_token() + val = ~self.parse_primary() + elif self.tok == TOK_LPAREN: + self.get_token() + val = self.parse_expr() + if self.tok != TOK_RPAREN: + raise KconfigParserError(self, 'Expected ")"') + self.get_token() + elif self.tok == TOK_ID: + val = self.parse_var() + else: + raise KconfigParserError(self, 'Expected "!" or "(" or identifier') + return val + + # disj: primary (OR primary)* + def parse_disj(self): + lhs = self.parse_primary() + while self.tok == TOK_OR: + self.get_token() + lhs = lhs | self.parse_primary() + return lhs + + # expr: disj (AND disj)* + def parse_expr(self): + lhs = self.parse_disj() + while self.tok == TOK_AND: + self.get_token() + lhs = lhs & self.parse_disj() + return lhs + + # condition: IF expr + # | empty + def parse_condition(self): + if self.tok == TOK_IF: + self.get_token() + return self.parse_expr() + else: + return None + + # property: DEFAULT y_or_n condition + # | DEPENDS ON expr + # | SELECT var condition + # | BOOL + def parse_property(self, var): + if self.tok == TOK_DEFAULT: + self.get_token() + val = self.parse_y_or_n() + cond = self.parse_condition() + self.data.do_default(var, val, cond) + elif self.tok == TOK_DEPENDS: + self.get_token() + if self.tok != TOK_ON: + raise KconfigParserError(self, 'Expected "on"') + self.get_token() + self.data.do_depends_on(var, self.parse_expr()) + elif self.tok == TOK_SELECT: + self.get_token() + symbol = self.parse_var() + cond = self.parse_condition() + self.data.do_select(var, symbol, cond) + elif self.tok == TOK_IMPLY: + self.get_token() + symbol = self.parse_var() + cond = self.parse_condition() + self.data.do_imply(var, symbol, cond) + elif self.tok == TOK_BOOL: + self.get_token() + else: + raise KconfigParserError(self, 'Error in recursive descent?') + + # properties: properties property + # | /* empty */ + def parse_properties(self, var): + had_default = False + while self.tok == TOK_DEFAULT or self.tok == TOK_DEPENDS or \ + self.tok == TOK_SELECT or self.tok == TOK_BOOL or \ + self.tok == TOK_IMPLY: + self.parse_property(var) + + # for nicer error message + if self.tok != TOK_SOURCE and self.tok != TOK_CONFIG and \ + self.tok != TOK_ID and self.tok != TOK_EOF: + raise KconfigParserError(self, 'expected "source", "config", identifier, ' + + '"default", "depends on", "imply" or "select"') + + # declaration: config var properties + def parse_declaration(self): + if self.tok == TOK_CONFIG: + self.get_token() + var = self.parse_var() + self.data.do_declaration(var) + self.parse_properties(var) + else: + raise KconfigParserError(self, 'Error in recursive descent?') + + # clause: SOURCE + # | declaration + # | assignment + def parse_clause(self): + if self.tok == TOK_SOURCE: + val = self.val + self.get_token() + self.do_include(val) + elif self.tok == TOK_CONFIG: + self.parse_declaration() + elif self.tok == TOK_ID: + self.parse_assignment() + else: + raise KconfigParserError(self, 'expected "source", "config" or identifier') + + # config: clause+ EOF + def parse_config(self): + while self.tok != TOK_EOF: + self.parse_clause() + return self.data + + # scanner ----- + + def get_token(self): + while True: + self.tok = self.src[self.cursor] + self.pos = self.cursor + self.cursor += 1 + + self.val = None + self.tok = self.scan_token() + if self.tok is not None: + return + + def check_keyword(self, rest): + if not self.src.startswith(rest, self.cursor): + return False + length = len(rest) + if self.src[self.cursor + length].isalnum() or self.src[self.cursor + length] == '|': + return False + self.cursor += length + return True + + def scan_token(self): + if self.tok == '#': + self.cursor = self.src.find('\n', self.cursor) + return None + elif self.tok == '=': + return TOK_EQUAL + elif self.tok == '(': + return TOK_LPAREN + elif self.tok == ')': + return TOK_RPAREN + elif self.tok == '&' and self.src[self.pos+1] == '&': + self.cursor += 1 + return TOK_AND + elif self.tok == '|' and self.src[self.pos+1] == '|': + self.cursor += 1 + return TOK_OR + elif self.tok == '!': + return TOK_NOT + elif self.tok == 'd' and self.check_keyword("epends"): + return TOK_DEPENDS + elif self.tok == 'o' and self.check_keyword("n"): + return TOK_ON + elif self.tok == 's' and self.check_keyword("elect"): + return TOK_SELECT + elif self.tok == 'i' and self.check_keyword("mply"): + return TOK_IMPLY + elif self.tok == 'c' and self.check_keyword("onfig"): + return TOK_CONFIG + elif self.tok == 'd' and self.check_keyword("efault"): + return TOK_DEFAULT + elif self.tok == 'b' and self.check_keyword("ool"): + return TOK_BOOL + elif self.tok == 'i' and self.check_keyword("f"): + return TOK_IF + elif self.tok == 'y' and self.check_keyword(""): + return TOK_Y + elif self.tok == 'n' and self.check_keyword(""): + return TOK_N + elif (self.tok == 's' and self.check_keyword("ource")) or \ + self.tok == 'i' and self.check_keyword("nclude"): + # source FILENAME + # include FILENAME + while self.src[self.cursor].isspace(): + self.cursor += 1 + start = self.cursor + self.cursor = self.src.find('\n', self.cursor) + self.val = self.src[start:self.cursor] + return TOK_SOURCE + elif self.tok.isalpha(): + # identifier + while self.src[self.cursor].isalnum() or self.src[self.cursor] == '_': + self.cursor += 1 + self.val = self.src[self.pos:self.cursor] + return TOK_ID + elif self.tok == '\n': + if self.cursor == len(self.src): + return TOK_EOF + self.line += 1 + self.line_pos = self.cursor + elif not self.tok.isspace(): + raise KconfigParserError(self, 'invalid input') + + return None + +if __name__ == '__main__': + argv = sys.argv + mode = defconfig + if len(sys.argv) > 1: + if argv[1] == '--defconfig': + del argv[1] + elif argv[1] == '--randconfig': + random.seed() + mode = randconfig + del argv[1] + elif argv[1] == '--allyesconfig': + mode = allyesconfig + del argv[1] + elif argv[1] == '--allnoconfig': + mode = allnoconfig + del argv[1] + + if len(argv) == 1: + print ("%s: at least one argument is required" % argv[0], file=sys.stderr) + sys.exit(1) + + if argv[1].startswith('-'): + print ("%s: invalid option %s" % (argv[0], argv[1]), file=sys.stderr) + sys.exit(1) + + data = KconfigData(mode) + parser = KconfigParser(data) + for arg in argv[3:]: + m = re.match(r'^(CONFIG_[A-Z0-9_]+)=([yn]?)$', arg) + if m is not None: + name, value = m.groups() + parser.do_assignment(name, value == 'y') + else: + fp = open(arg, 'r') + parser.parse_file(fp) + fp.close() + + config = data.compute_config() + for key in sorted(config.keys()): + print ('CONFIG_%s=%s' % (key, ('y' if config[key] else 'n'))) + + deps = open(argv[2], 'w') + for fname in data.previously_included: + print ('%s: %s' % (argv[1], fname), file=deps) + deps.close() diff --git a/scripts/qmp/qemu-ga-client b/scripts/qmp/qemu-ga-client index e8cb7646a0..30cf8a9a0d 100755 --- a/scripts/qmp/qemu-ga-client +++ b/scripts/qmp/qemu-ga-client @@ -37,10 +37,13 @@ # from __future__ import print_function +import os +import sys import base64 import random -import qmp +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu import qmp class QemuGuestAgent(qmp.QEMUMonitorProtocol): diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index 770140772d..9fec46e2ed 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -66,7 +66,6 @@ # sent to QEMU, which is useful for debugging and documentation generation. from __future__ import print_function -import qmp import json import ast import readline @@ -76,6 +75,9 @@ import errno import atexit import shlex +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu import qmp + class QMPCompleter(list): def complete(self, text, state): for cmd in self: diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py index ed7e581b4f..3e9d282a49 100755 --- a/scripts/render_block_graph.py +++ b/scripts/render_block_graph.py @@ -23,6 +23,8 @@ import sys import subprocess import json from graphviz import Digraph + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python')) from qemu import MonitorResponseError diff --git a/slirp/Makefile b/slirp/Makefile new file mode 100644 index 0000000000..6d48f626ba --- /dev/null +++ b/slirp/Makefile @@ -0,0 +1,47 @@ +ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +BUILD_DIR ?= . + +LIBSLIRP = $(BUILD_DIR)/libslirp.a + +all: $(LIBSLIRP) + +SRCS := $(wildcard src/*.c) +OBJS := $(SRCS:%.c=$(BUILD_DIR)/%.o) +DEPS := $(OBJS:%.o=%.d) + +INC_DIRS := $(BUILD_DIR)/src +INC_FLAGS := $(addprefix -I,$(INC_DIRS)) + +override CFLAGS += \ + -DG_LOG_DOMAIN='"Slirp"' \ + $(shell $(PKG_CONFIG) --cflags glib-2.0) \ + $(INC_FLAGS) \ + -MMD -MP +override LDFLAGS += $(shell $(PKG_CONFIG) --libs glib-2.0) + +$(LIBSLIRP): $(OBJS) + +.PHONY: clean + +clean: + rm -r $(OBJS) $(DEPS) $(LIBSLIRP) + +$(BUILD_DIR)/src/%.o: $(ROOT_DIR)/src/%.c + @$(MKDIR_P) $(dir $@) + $(call quiet-command,$(CC) $(CFLAGS) -c -o $@ $<,"CC","$@") + +%.a: + $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^,"AR","$@") + +PKG_CONFIG ?= pkg-config +MKDIR_P ?= mkdir -p +quiet-command-run = $(if $(V),,$(if $2,printf " %-7s %s\n" $2 $3 && ))$1 +quiet-@ = $(if $(V),,@) +quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3) + +print-%: + @echo '$*=$($*)' + +.SUFFIXES: + +-include $(DEPS) diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs deleted file mode 100644 index 88340a583b..0000000000 --- a/slirp/Makefile.objs +++ /dev/null @@ -1,34 +0,0 @@ -slirp-obj-y = slirp.mo - -slirp.mo-objs = \ - arp_table.o \ - bootp.o \ - cksum.o \ - dhcpv6.o \ - dnssearch.o \ - if.o \ - ip6_icmp.o \ - ip6_input.o \ - ip6_output.o \ - ip_icmp.o \ - ip_input.o \ - ip_output.o \ - mbuf.o \ - misc.o \ - ncsi.o \ - ndp_table.o \ - sbuf.o \ - slirp.o \ - socket.o \ - state.o \ - tcp_input.o \ - tcp_output.o \ - tcp_subr.o \ - tcp_timer.o \ - tftp.o \ - udp.o \ - udp6.o \ - util.o \ - $(NULL) - -slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU diff --git a/slirp/arp_table.c b/slirp/src/arp_table.c index 58eafdcfd8..58eafdcfd8 100644 --- a/slirp/arp_table.c +++ b/slirp/src/arp_table.c diff --git a/slirp/bootp.c b/slirp/src/bootp.c index d396849a05..d396849a05 100644 --- a/slirp/bootp.c +++ b/slirp/src/bootp.c diff --git a/slirp/bootp.h b/slirp/src/bootp.h index 4043489835..4043489835 100644 --- a/slirp/bootp.h +++ b/slirp/src/bootp.h diff --git a/slirp/cksum.c b/slirp/src/cksum.c index 25bfa67348..25bfa67348 100644 --- a/slirp/cksum.c +++ b/slirp/src/cksum.c diff --git a/slirp/debug.h b/slirp/src/debug.h index 44d922df37..44d922df37 100644 --- a/slirp/debug.h +++ b/slirp/src/debug.h diff --git a/slirp/dhcpv6.c b/slirp/src/dhcpv6.c index e655c7d5b1..e655c7d5b1 100644 --- a/slirp/dhcpv6.c +++ b/slirp/src/dhcpv6.c diff --git a/slirp/dhcpv6.h b/slirp/src/dhcpv6.h index 3373f6cb89..3373f6cb89 100644 --- a/slirp/dhcpv6.h +++ b/slirp/src/dhcpv6.h diff --git a/slirp/dnssearch.c b/slirp/src/dnssearch.c index c459cece8d..c459cece8d 100644 --- a/slirp/dnssearch.c +++ b/slirp/src/dnssearch.c diff --git a/slirp/if.c b/slirp/src/if.c index 1830cc396c..1830cc396c 100644 --- a/slirp/if.c +++ b/slirp/src/if.c diff --git a/slirp/if.h b/slirp/src/if.h index 69569c10df..69569c10df 100644 --- a/slirp/if.h +++ b/slirp/src/if.h diff --git a/slirp/ip.h b/slirp/src/ip.h index 73a4d2a3d2..73a4d2a3d2 100644 --- a/slirp/ip.h +++ b/slirp/src/ip.h diff --git a/slirp/ip6.h b/slirp/src/ip6.h index 1b3364f960..1b3364f960 100644 --- a/slirp/ip6.h +++ b/slirp/src/ip6.h diff --git a/slirp/ip6_icmp.c b/slirp/src/ip6_icmp.c index c1e3d30470..c1e3d30470 100644 --- a/slirp/ip6_icmp.c +++ b/slirp/src/ip6_icmp.c diff --git a/slirp/ip6_icmp.h b/slirp/src/ip6_icmp.h index e8ed753db5..e8ed753db5 100644 --- a/slirp/ip6_icmp.h +++ b/slirp/src/ip6_icmp.h diff --git a/slirp/ip6_input.c b/slirp/src/ip6_input.c index 1b8c003c66..1b8c003c66 100644 --- a/slirp/ip6_input.c +++ b/slirp/src/ip6_input.c diff --git a/slirp/ip6_output.c b/slirp/src/ip6_output.c index 19d1ae7748..19d1ae7748 100644 --- a/slirp/ip6_output.c +++ b/slirp/src/ip6_output.c diff --git a/slirp/ip_icmp.c b/slirp/src/ip_icmp.c index 120108f582..120108f582 100644 --- a/slirp/ip_icmp.c +++ b/slirp/src/ip_icmp.c diff --git a/slirp/ip_icmp.h b/slirp/src/ip_icmp.h index a4e5b8b265..a4e5b8b265 100644 --- a/slirp/ip_icmp.h +++ b/slirp/src/ip_icmp.h diff --git a/slirp/ip_input.c b/slirp/src/ip_input.c index e0b94b0e42..e0b94b0e42 100644 --- a/slirp/ip_input.c +++ b/slirp/src/ip_input.c diff --git a/slirp/ip_output.c b/slirp/src/ip_output.c index f6ec141df5..f6ec141df5 100644 --- a/slirp/ip_output.c +++ b/slirp/src/ip_output.c diff --git a/slirp/libslirp.h b/slirp/src/libslirp.h index fccab42518..2d13950065 100644 --- a/slirp/libslirp.h +++ b/slirp/src/libslirp.h @@ -3,6 +3,7 @@ #include <stdint.h> #include <stdbool.h> +#include <sys/types.h> #ifdef _WIN32 #include <winsock2.h> @@ -26,6 +27,7 @@ enum { SLIRP_POLL_HUP = 1 << 4, }; +typedef ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque); typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque); typedef void (*SlirpTimerCb)(void *opaque); typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque); @@ -100,6 +102,14 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port, const uint8_t *buf, int size); size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port); + +void slirp_state_save(Slirp *s, SlirpWriteCb write_cb, void *opaque); + +int slirp_state_load(Slirp *s, int version_id, + SlirpReadCb read_cb, void *opaque); + +int slirp_state_version(void); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/slirp/main.h b/slirp/src/main.h index f11d4572b7..f11d4572b7 100644 --- a/slirp/main.h +++ b/slirp/src/main.h diff --git a/slirp/mbuf.c b/slirp/src/mbuf.c index 521c02c967..521c02c967 100644 --- a/slirp/mbuf.c +++ b/slirp/src/mbuf.c diff --git a/slirp/mbuf.h b/slirp/src/mbuf.h index e2d443418a..e2d443418a 100644 --- a/slirp/mbuf.h +++ b/slirp/src/mbuf.h diff --git a/slirp/misc.c b/slirp/src/misc.c index d9fc586a24..937a418d4e 100644 --- a/slirp/misc.c +++ b/slirp/src/misc.c @@ -28,6 +28,7 @@ remque(void *a) element->qh_rlink = NULL; } +/* TODO: IPv6 */ struct gfwd_list * add_guestfwd(struct gfwd_list **ex_ptr, SlirpWriteCb write_cb, void *opaque, @@ -254,6 +255,8 @@ char *slirp_connection_info(Slirp *slirp) " Protocol[State] FD Source Address Port " "Dest. Address Port RecvQ SendQ\n"); + /* TODO: IPv6 */ + for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) { if (so->so_state & SS_HOSTFWD) { state = "HOST_FORWARD"; diff --git a/slirp/misc.h b/slirp/src/misc.h index c2ceadb591..c2ceadb591 100644 --- a/slirp/misc.h +++ b/slirp/src/misc.h diff --git a/slirp/ncsi-pkt.h b/slirp/src/ncsi-pkt.h index ea07d1cd0f..ea07d1cd0f 100644 --- a/slirp/ncsi-pkt.h +++ b/slirp/src/ncsi-pkt.h diff --git a/slirp/ncsi.c b/slirp/src/ncsi.c index 359f52c284..359f52c284 100644 --- a/slirp/ncsi.c +++ b/slirp/src/ncsi.c diff --git a/slirp/ndp_table.c b/slirp/src/ndp_table.c index 34ea4fdf1f..34ea4fdf1f 100644 --- a/slirp/ndp_table.c +++ b/slirp/src/ndp_table.c diff --git a/slirp/qtailq.h b/slirp/src/qtailq.h index a89b0c439a..a89b0c439a 100644 --- a/slirp/qtailq.h +++ b/slirp/src/qtailq.h diff --git a/slirp/sbuf.c b/slirp/src/sbuf.c index 51a9f0cc7d..51a9f0cc7d 100644 --- a/slirp/sbuf.c +++ b/slirp/src/sbuf.c diff --git a/slirp/sbuf.h b/slirp/src/sbuf.h index 1cb9a42834..1cb9a42834 100644 --- a/slirp/sbuf.h +++ b/slirp/src/sbuf.h diff --git a/slirp/slirp.c b/slirp/src/slirp.c index 55591430dc..18af670a0a 100644 --- a/slirp/slirp.c +++ b/slirp/src/slirp.c @@ -23,9 +23,6 @@ */ #include "slirp.h" -#ifdef WITH_QEMU -#include "state.h" -#endif #ifndef _WIN32 #include <net/if.h> @@ -326,9 +323,6 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork, translate_dnssearch(slirp, vdnssearch); } -#ifdef WITH_QEMU - slirp_state_register(slirp); -#endif return slirp; } @@ -342,9 +336,6 @@ void slirp_cleanup(Slirp *slirp) g_free(e); } -#ifdef WITH_QEMU - slirp_state_unregister(slirp); -#endif ip_cleanup(slirp); ip6_cleanup(slirp); m_cleanup(slirp); @@ -729,6 +720,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) if (ah->ar_tip == slirp->vnameserver_addr.s_addr || ah->ar_tip == slirp->vhost_addr.s_addr) goto arp_ok; + /* TODO: IPv6 */ for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { if (ex_ptr->ex_addr.s_addr == ah->ar_tip) goto arp_ok; @@ -945,6 +937,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm) } /* Drop host forwarding rule, return 0 if found. */ +/* TODO: IPv6 */ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, int host_port) { @@ -970,6 +963,7 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, return -1; } +/* TODO: IPv6 */ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, int host_port, struct in_addr guest_addr, int guest_port) { @@ -988,6 +982,7 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, return 0; } +/* TODO: IPv6 */ static bool check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port) { @@ -1065,6 +1060,7 @@ slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, int guest_port) { struct socket *so; + /* TODO: IPv6 */ for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) { if (so->so_faddr.s_addr == guest_addr.s_addr && htons(so->so_fport) == guest_port) { diff --git a/slirp/slirp.h b/slirp/src/slirp.h index 752a4cd8c8..8068ba1d1e 100644 --- a/slirp/slirp.h +++ b/slirp/src/slirp.h @@ -106,7 +106,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr, struct ndpentry { unsigned char eth_addr[ETH_ALEN]; /* sender hardware address */ struct in6_addr ip_addr; /* sender IP address */ -} SLIRP_PACKED; +}; #define NDP_TABLE_SIZE 16 diff --git a/slirp/socket.c b/slirp/src/socket.c index 4876ea3f31..f2428a3ae8 100644 --- a/slirp/socket.c +++ b/slirp/src/socket.c @@ -529,6 +529,15 @@ sorecvfrom(struct socket *so) int n; #endif + if (ioctlsocket(so->s, FIONREAD, &n) != 0) { + DEBUG_MISC(" ioctlsocket errno = %d-%s\n", + errno,strerror(errno)); + return; + } + if (n == 0) { + return; + } + m = m_get(so->slirp); if (!m) { return; @@ -552,7 +561,6 @@ sorecvfrom(struct socket *so) */ len = M_FREEROOM(m); /* if (so->so_fport != htons(53)) { */ - ioctlsocket(so->s, FIONREAD, &n); if (n > len) { n = (m->m_data - m->m_dat) + m->m_len + n + 1; @@ -679,6 +687,7 @@ struct socket * tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, uint32_t laddr, unsigned lport, int flags) { + /* TODO: IPv6 */ struct sockaddr_in addr; struct socket *so; int s, opt = 1; diff --git a/slirp/socket.h b/slirp/src/socket.h index e4d12cd591..e4d12cd591 100644 --- a/slirp/socket.h +++ b/slirp/src/socket.h diff --git a/slirp/state.c b/slirp/src/state.c index 0e5a706e87..f5dd80cdc8 100644 --- a/slirp/state.c +++ b/slirp/src/state.c @@ -21,13 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "qemu/osdep.h" - #include "slirp.h" +#include "vmstate.h" #include "state.h" -#include "migration/vmstate.h" -#include "migration/qemu-file-types.h" -#include "migration/register.h" +#include "stream.h" static int slirp_tcp_post_load(void *opaque, int version) { @@ -180,7 +177,7 @@ static int slirp_socket_pre_load(void *opaque) #else /* Win uses u_long rather than uint32_t - but it's still 32bits long */ #define VMSTATE_SIN4_ADDR(f, s, t) VMSTATE_SINGLE_TEST(f, s, t, 0, \ - vmstate_info_uint32, u_long) + slirp_vmstate_info_uint32, u_long) #endif /* The OS provided ss_family field isn't that portable; it's size @@ -322,10 +319,13 @@ static const VMStateDescription vmstate_slirp = { } }; -static void slirp_state_save(QEMUFile *f, void *opaque) +void slirp_state_save(Slirp *slirp, SlirpWriteCb write_cb, void *opaque) { - Slirp *slirp = opaque; struct gfwd_list *ex_ptr; + SlirpOStream f = { + .write_cb = write_cb, + .opaque = opaque, + }; for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) if (ex_ptr->write_cb) { @@ -336,25 +336,29 @@ static void slirp_state_save(QEMUFile *f, void *opaque) continue; } - qemu_put_byte(f, 42); - vmstate_save_state(f, &vmstate_slirp_socket, so, NULL); + slirp_ostream_write_u8(&f, 42); + slirp_vmstate_save_state(&f, &vmstate_slirp_socket, so); } - qemu_put_byte(f, 0); + slirp_ostream_write_u8(&f, 0); - vmstate_save_state(f, &vmstate_slirp, slirp, NULL); + slirp_vmstate_save_state(&f, &vmstate_slirp, slirp); } -static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) +int slirp_state_load(Slirp *slirp, int version_id, + SlirpReadCb read_cb, void *opaque) { - Slirp *slirp = opaque; struct gfwd_list *ex_ptr; + SlirpIStream f = { + .read_cb = read_cb, + .opaque = opaque, + }; - while (qemu_get_byte(f)) { + while (slirp_istream_read_u8(&f)) { int ret; struct socket *so = socreate(slirp); - ret = vmstate_load_state(f, &vmstate_slirp_socket, so, version_id); + ret = slirp_vmstate_load_state(&f, &vmstate_slirp_socket, so, version_id); if (ret < 0) { return ret; } @@ -375,20 +379,10 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) } } - return vmstate_load_state(f, &vmstate_slirp, slirp, version_id); -} - -void slirp_state_register(Slirp *slirp) -{ - static SaveVMHandlers savevm_slirp_state = { - .save_state = slirp_state_save, - .load_state = slirp_state_load, - }; - - register_savevm_live(NULL, "slirp", 0, 4, &savevm_slirp_state, slirp); + return slirp_vmstate_load_state(&f, &vmstate_slirp, slirp, version_id); } -void slirp_state_unregister(Slirp *slirp) +int slirp_state_version(void) { - unregister_savevm(NULL, "slirp", slirp); + return 4; } diff --git a/scripts/qmp/__init__.py b/slirp/src/state.h index e69de29bb2..e69de29bb2 100644 --- a/scripts/qmp/__init__.py +++ b/slirp/src/state.h diff --git a/slirp/src/stream.c b/slirp/src/stream.c new file mode 100644 index 0000000000..d114dde334 --- /dev/null +++ b/slirp/src/stream.c @@ -0,0 +1,119 @@ +/* + * libslirp io streams + * + * Copyright (c) 2018 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "stream.h" +#include <glib.h> + +bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size) +{ + return f->read_cb(buf, size, f->opaque) == size; +} + +bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size) +{ + return f->write_cb(buf, size, f->opaque) == size; +} + +uint8_t slirp_istream_read_u8(SlirpIStream *f) +{ + uint8_t b; + + if (slirp_istream_read(f, &b, sizeof(b))) { + return b; + } + + return 0; +} + +bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b) +{ + return slirp_ostream_write(f, &b, sizeof(b)); +} + +uint16_t slirp_istream_read_u16(SlirpIStream *f) +{ + uint16_t b; + + if (slirp_istream_read(f, &b, sizeof(b))) { + return GUINT16_FROM_BE(b); + } + + return 0; +} + +bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b) +{ + b = GUINT16_TO_BE(b); + return slirp_ostream_write(f, &b, sizeof(b)); +} + +uint32_t slirp_istream_read_u32(SlirpIStream *f) +{ + uint32_t b; + + if (slirp_istream_read(f, &b, sizeof(b))) { + return GUINT32_FROM_BE(b); + } + + return 0; +} + +bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b) +{ + b = GUINT32_TO_BE(b); + return slirp_ostream_write(f, &b, sizeof(b)); +} + +int16_t slirp_istream_read_i16(SlirpIStream *f) +{ + int16_t b; + + if (slirp_istream_read(f, &b, sizeof(b))) { + return GINT16_FROM_BE(b); + } + + return 0; +} + +bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b) +{ + b = GINT16_TO_BE(b); + return slirp_ostream_write(f, &b, sizeof(b)); +} + +int32_t slirp_istream_read_i32(SlirpIStream *f) +{ + int32_t b; + + if (slirp_istream_read(f, &b, sizeof(b))) { + return GINT32_FROM_BE(b); + } + + return 0; +} + +bool slirp_ostream_write_i32(SlirpOStream *f, int32_t b) +{ + b = GINT32_TO_BE(b); + return slirp_ostream_write(f, &b, sizeof(b)); +} diff --git a/slirp/src/stream.h b/slirp/src/stream.h new file mode 100644 index 0000000000..985334c043 --- /dev/null +++ b/slirp/src/stream.h @@ -0,0 +1,34 @@ +#ifndef STREAM_H_ +#define STREAM_H_ + +#include "libslirp.h" + +typedef struct SlirpIStream { + SlirpReadCb read_cb; + void *opaque; +} SlirpIStream; + +typedef struct SlirpOStream { + SlirpWriteCb write_cb; + void *opaque; +} SlirpOStream; + +bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size); +bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size); + +uint8_t slirp_istream_read_u8(SlirpIStream *f); +bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b); + +uint16_t slirp_istream_read_u16(SlirpIStream *f); +bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b); + +uint32_t slirp_istream_read_u32(SlirpIStream *f); +bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b); + +int16_t slirp_istream_read_i16(SlirpIStream *f); +bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b); + +int32_t slirp_istream_read_i32(SlirpIStream *f); +bool slirp_ostream_write_i32(SlirpOStream *f, int32_t b); + +#endif /* STREAM_H_ */ diff --git a/slirp/tcp.h b/slirp/src/tcp.h index 47aaea6c5b..47aaea6c5b 100644 --- a/slirp/tcp.h +++ b/slirp/src/tcp.h diff --git a/slirp/tcp_input.c b/slirp/src/tcp_input.c index 6749b32f5d..b10477fc57 100644 --- a/slirp/tcp_input.c +++ b/slirp/src/tcp_input.c @@ -388,6 +388,7 @@ findso: * as if it was LISTENING, and continue... */ if (so == NULL) { + /* TODO: IPv6 */ if (slirp->restricted) { /* Any hostfwds will have an existing socket, so we only get here * for non-hostfwd connections. These should be dropped, unless it @@ -609,6 +610,7 @@ findso: * If this is destined for the control address, then flag to * tcp_ctl once connected, otherwise connect */ + /* TODO: IPv6 */ if (af == AF_INET && (so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) == slirp->vnetwork_addr.s_addr) { diff --git a/slirp/tcp_output.c b/slirp/src/tcp_output.c index e9674df121..e9674df121 100644 --- a/slirp/tcp_output.c +++ b/slirp/src/tcp_output.c diff --git a/slirp/tcp_subr.c b/slirp/src/tcp_subr.c index 262a42d6c8..1db59caa89 100644 --- a/slirp/tcp_subr.c +++ b/slirp/src/tcp_subr.c @@ -626,6 +626,7 @@ tcp_emu(struct socket *so, struct mbuf *m) switch(so->so_emu) { int x, i; + /* TODO: IPv6 */ case EMU_IDENT: /* * Identification protocol as per rfc-1413 @@ -660,16 +661,18 @@ tcp_emu(struct socket *so, struct mbuf *m) tmpso->so_fport == n1) { if (getsockname(tmpso->s, (struct sockaddr *)&addr, &addrlen) == 0) - n2 = ntohs(addr.sin_port); + n2 = addr.sin_port; break; } } + NTOHS(n1); + NTOHS(n2); + so_rcv->sb_cc = snprintf(so_rcv->sb_data, + so_rcv->sb_datalen, + "%d,%d\r\n", n1, n2); + so_rcv->sb_rptr = so_rcv->sb_data; + so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; } - so_rcv->sb_cc = snprintf(so_rcv->sb_data, - so_rcv->sb_datalen, - "%d,%d\r\n", n1, n2); - so_rcv->sb_rptr = so_rcv->sb_data; - so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; } m_free(m); return 0; @@ -962,6 +965,7 @@ int tcp_ctl(struct socket *so) DEBUG_CALL("tcp_ctl"); DEBUG_ARG("so = %p", so); + /* TODO: IPv6 */ if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) { /* Check if it's pty_exec */ for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { diff --git a/slirp/tcp_timer.c b/slirp/src/tcp_timer.c index 7be54570af..7be54570af 100644 --- a/slirp/tcp_timer.c +++ b/slirp/src/tcp_timer.c diff --git a/slirp/tcp_timer.h b/slirp/src/tcp_timer.h index b25b3911d7..b25b3911d7 100644 --- a/slirp/tcp_timer.h +++ b/slirp/src/tcp_timer.h diff --git a/slirp/tcp_var.h b/slirp/src/tcp_var.h index 27ef1a51cb..27ef1a51cb 100644 --- a/slirp/tcp_var.h +++ b/slirp/src/tcp_var.h diff --git a/slirp/tcpip.h b/slirp/src/tcpip.h index 07dbf2c432..07dbf2c432 100644 --- a/slirp/tcpip.h +++ b/slirp/src/tcpip.h diff --git a/slirp/tftp.c b/slirp/src/tftp.c index 2d8f978786..2d8f978786 100644 --- a/slirp/tftp.c +++ b/slirp/src/tftp.c diff --git a/slirp/tftp.h b/slirp/src/tftp.h index a4c4a64e64..a4c4a64e64 100644 --- a/slirp/tftp.h +++ b/slirp/src/tftp.h diff --git a/slirp/udp.c b/slirp/src/udp.c index 3d9a19b85a..fa9f4a08bd 100644 --- a/slirp/udp.c +++ b/slirp/src/udp.c @@ -322,6 +322,7 @@ struct socket * udp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, uint32_t laddr, unsigned lport, int flags) { + /* TODO: IPv6 */ struct sockaddr_in addr; struct socket *so; socklen_t addrlen = sizeof(struct sockaddr_in); diff --git a/slirp/udp.h b/slirp/src/udp.h index 3d29504caa..3d29504caa 100644 --- a/slirp/udp.h +++ b/slirp/src/udp.h diff --git a/slirp/udp6.c b/slirp/src/udp6.c index be5cba1f54..be5cba1f54 100644 --- a/slirp/udp6.c +++ b/slirp/src/udp6.c diff --git a/slirp/util.c b/slirp/src/util.c index 1cbaa26b60..5ec2fa87ab 100644 --- a/slirp/util.c +++ b/slirp/src/util.c @@ -31,8 +31,8 @@ #include <fcntl.h> #include <stdint.h> -#if defined(_WIN32) && !defined(WITH_QEMU) -int inet_aton(const char *cp, struct in_addr *ia) +#if defined(_WIN32) +int slirp_inet_aton(const char *cp, struct in_addr *ia) { uint32_t addr = inet_addr(cp); if (addr == 0xffffffff) { diff --git a/slirp/util.h b/slirp/src/util.h index c4207a49d6..e94ee4e7f1 100644 --- a/slirp/util.h +++ b/slirp/src/util.h @@ -138,8 +138,8 @@ int slirp_getsockopt_wrap(int sockfd, int level, int optname, #define setsockopt slirp_setsockopt_wrap int slirp_setsockopt_wrap(int sockfd, int level, int optname, const void *optval, int optlen); - -int inet_aton(const char *cp, struct in_addr *ia); +#define inet_aton slirp_inet_aton +int slirp_inet_aton(const char *cp, struct in_addr *ia); #else #define closesocket(s) close(s) #define ioctlsocket(s, r, v) ioctl(s, r, v) diff --git a/slirp/src/vmstate.c b/slirp/src/vmstate.c new file mode 100644 index 0000000000..4d08b47c61 --- /dev/null +++ b/slirp/src/vmstate.c @@ -0,0 +1,413 @@ +/* + * VMState interpreter + * + * Copyright (c) 2009-2018 Red Hat Inc + * + * Authors: + * Juan Quintela <quintela@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <glib.h> + +#include "stream.h" +#include "vmstate.h" + +static int get_nullptr(SlirpIStream *f, void *pv, size_t size, + const VMStateField *field) +{ + if (slirp_istream_read_u8(f) == VMS_NULLPTR_MARKER) { + return 0; + } + g_warning("vmstate: get_nullptr expected VMS_NULLPTR_MARKER"); + return -EINVAL; +} + +static int put_nullptr(SlirpOStream *f, void *pv, size_t size, + const VMStateField *field) + +{ + if (pv == NULL) { + slirp_ostream_write_u8(f, VMS_NULLPTR_MARKER); + return 0; + } + g_warning("vmstate: put_nullptr must be called with pv == NULL"); + return -EINVAL; +} + +const VMStateInfo slirp_vmstate_info_nullptr = { + .name = "uint64", + .get = get_nullptr, + .put = put_nullptr, +}; + +/* 8 bit unsigned int */ + +static int get_uint8(SlirpIStream *f, void *pv, size_t size, const VMStateField *field) +{ + uint8_t *v = pv; + *v = slirp_istream_read_u8(f); + return 0; +} + +static int put_uint8(SlirpOStream *f, void *pv, size_t size, const VMStateField *field) +{ + uint8_t *v = pv; + slirp_ostream_write_u8(f, *v); + return 0; +} + +const VMStateInfo slirp_vmstate_info_uint8 = { + .name = "uint8", + .get = get_uint8, + .put = put_uint8, +}; + +/* 16 bit unsigned int */ + +static int get_uint16(SlirpIStream *f, void *pv, size_t size, + const VMStateField *field) +{ + uint16_t *v = pv; + *v = slirp_istream_read_u16(f); + return 0; +} + +static int put_uint16(SlirpOStream *f, void *pv, size_t size, + const VMStateField *field) +{ + uint16_t *v = pv; + slirp_ostream_write_u16(f, *v); + return 0; +} + +const VMStateInfo slirp_vmstate_info_uint16 = { + .name = "uint16", + .get = get_uint16, + .put = put_uint16, +}; + +/* 32 bit unsigned int */ + +static int get_uint32(SlirpIStream *f, void *pv, size_t size, + const VMStateField *field) +{ + uint32_t *v = pv; + *v = slirp_istream_read_u32(f); + return 0; +} + +static int put_uint32(SlirpOStream *f, void *pv, size_t size, + const VMStateField *field) +{ + uint32_t *v = pv; + slirp_ostream_write_u32(f, *v); + return 0; +} + +const VMStateInfo slirp_vmstate_info_uint32 = { + .name = "uint32", + .get = get_uint32, + .put = put_uint32, +}; + +/* 16 bit int */ + +static int get_int16(SlirpIStream *f, void *pv, size_t size, const VMStateField *field) +{ + int16_t *v = pv; + *v = slirp_istream_read_i16(f); + return 0; +} + +static int put_int16(SlirpOStream *f, void *pv, size_t size, const VMStateField *field) +{ + int16_t *v = pv; + slirp_ostream_write_i16(f, *v); + return 0; +} + +const VMStateInfo slirp_vmstate_info_int16 = { + .name = "int16", + .get = get_int16, + .put = put_int16, +}; + +/* 32 bit int */ + +static int get_int32(SlirpIStream *f, void *pv, size_t size, const VMStateField *field) +{ + int32_t *v = pv; + *v = slirp_istream_read_i32(f); + return 0; +} + +static int put_int32(SlirpOStream *f, void *pv, size_t size, const VMStateField *field) +{ + int32_t *v = pv; + slirp_ostream_write_i32(f, *v); + return 0; +} + +const VMStateInfo slirp_vmstate_info_int32 = { + .name = "int32", + .get = get_int32, + .put = put_int32, +}; + +/* vmstate_info_tmp, see VMSTATE_WITH_TMP, the idea is that we allocate + * a temporary buffer and the pre_load/pre_save methods in the child vmsd + * copy stuff from the parent into the child and do calculations to fill + * in fields that don't really exist in the parent but need to be in the + * stream. + */ +static int get_tmp(SlirpIStream *f, void *pv, size_t size, const VMStateField *field) +{ + int ret; + const VMStateDescription *vmsd = field->vmsd; + int version_id = field->version_id; + void *tmp = g_malloc(size); + + /* Writes the parent field which is at the start of the tmp */ + *(void **)tmp = pv; + ret = slirp_vmstate_load_state(f, vmsd, tmp, version_id); + g_free(tmp); + return ret; +} + +static int put_tmp(SlirpOStream *f, void *pv, size_t size, const VMStateField *field) +{ + const VMStateDescription *vmsd = field->vmsd; + void *tmp = g_malloc(size); + int ret; + + /* Writes the parent field which is at the start of the tmp */ + *(void **)tmp = pv; + ret = slirp_vmstate_save_state(f, vmsd, tmp); + g_free(tmp); + + return ret; +} + +const VMStateInfo slirp_vmstate_info_tmp = { + .name = "tmp", + .get = get_tmp, + .put = put_tmp, +}; + +/* uint8_t buffers */ + +static int get_buffer(SlirpIStream *f, void *pv, size_t size, + const VMStateField *field) +{ + slirp_istream_read(f, pv, size); + return 0; +} + +static int put_buffer(SlirpOStream *f, void *pv, size_t size, + const VMStateField *field) +{ + slirp_ostream_write(f, pv, size); + return 0; +} + +const VMStateInfo slirp_vmstate_info_buffer = { + .name = "buffer", + .get = get_buffer, + .put = put_buffer, +}; + +static int vmstate_n_elems(void *opaque, const VMStateField *field) +{ + int n_elems = 1; + + if (field->flags & VMS_ARRAY) { + n_elems = field->num; + } else if (field->flags & VMS_VARRAY_INT32) { + n_elems = *(int32_t *)(opaque + field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT32) { + n_elems = *(uint32_t *)(opaque + field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT16) { + n_elems = *(uint16_t *)(opaque + field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT8) { + n_elems = *(uint8_t *)(opaque + field->num_offset); + } + + if (field->flags & VMS_MULTIPLY_ELEMENTS) { + n_elems *= field->num; + } + + return n_elems; +} + +static int vmstate_size(void *opaque, const VMStateField *field) +{ + int size = field->size; + + if (field->flags & VMS_VBUFFER) { + size = *(int32_t *)(opaque + field->size_offset); + if (field->flags & VMS_MULTIPLY) { + size *= field->size; + } + } + + return size; +} + +static int +vmstate_save_state_v(SlirpOStream *f, const VMStateDescription *vmsd, + void *opaque, int version_id) +{ + int ret = 0; + const VMStateField *field = vmsd->fields; + + if (vmsd->pre_save) { + ret = vmsd->pre_save(opaque); + if (ret) { + g_warning("pre-save failed: %s", vmsd->name); + return ret; + } + } + + while (field->name) { + if ((field->field_exists && + field->field_exists(opaque, version_id)) || + (!field->field_exists && + field->version_id <= version_id)) { + void *first_elem = opaque + field->offset; + int i, n_elems = vmstate_n_elems(opaque, field); + int size = vmstate_size(opaque, field); + + if (field->flags & VMS_POINTER) { + first_elem = *(void **)first_elem; + assert(first_elem || !n_elems || !size); + } + for (i = 0; i < n_elems; i++) { + void *curr_elem = first_elem + size * i; + ret = 0; + + if (field->flags & VMS_ARRAY_OF_POINTER) { + assert(curr_elem); + curr_elem = *(void **)curr_elem; + } + if (!curr_elem && size) { + /* if null pointer write placeholder and do not follow */ + assert(field->flags & VMS_ARRAY_OF_POINTER); + ret = slirp_vmstate_info_nullptr.put(f, curr_elem, size, NULL); + } else if (field->flags & VMS_STRUCT) { + ret = slirp_vmstate_save_state(f, field->vmsd, curr_elem); + } else if (field->flags & VMS_VSTRUCT) { + ret = vmstate_save_state_v(f, field->vmsd, curr_elem, + field->struct_version_id); + } else { + ret = field->info->put(f, curr_elem, size, field); + } + if (ret) { + g_warning("Save of field %s/%s failed", + vmsd->name, field->name); + return ret; + } + } + } else { + if (field->flags & VMS_MUST_EXIST) { + g_warning("Output state validation failed: %s/%s", + vmsd->name, field->name); + assert(!(field->flags & VMS_MUST_EXIST)); + } + } + field++; + } + + return 0; +} + +int slirp_vmstate_save_state(SlirpOStream *f, const VMStateDescription *vmsd, + void *opaque) +{ + return vmstate_save_state_v(f, vmsd, opaque, vmsd->version_id); +} + +static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque) +{ + if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) { + size_t size = vmstate_size(opaque, field); + size *= vmstate_n_elems(opaque, field); + if (size) { + *(void **)ptr = g_malloc(size); + } + } +} + +int slirp_vmstate_load_state(SlirpIStream *f, const VMStateDescription *vmsd, + void *opaque, int version_id) +{ + VMStateField *field = vmsd->fields; + int ret = 0; + + if (version_id > vmsd->version_id) { + g_warning("%s: incoming version_id %d is too new " + "for local version_id %d", + vmsd->name, version_id, vmsd->version_id); + return -EINVAL; + } + if (vmsd->pre_load) { + int ret = vmsd->pre_load(opaque); + if (ret) { + return ret; + } + } + while (field->name) { + if ((field->field_exists && + field->field_exists(opaque, version_id)) || + (!field->field_exists && + field->version_id <= version_id)) { + void *first_elem = opaque + field->offset; + int i, n_elems = vmstate_n_elems(opaque, field); + int size = vmstate_size(opaque, field); + + vmstate_handle_alloc(first_elem, field, opaque); + if (field->flags & VMS_POINTER) { + first_elem = *(void **)first_elem; + assert(first_elem || !n_elems || !size); + } + for (i = 0; i < n_elems; i++) { + void *curr_elem = first_elem + size * i; + + if (field->flags & VMS_ARRAY_OF_POINTER) { + curr_elem = *(void **)curr_elem; + } + if (!curr_elem && size) { + /* if null pointer check placeholder and do not follow */ + assert(field->flags & VMS_ARRAY_OF_POINTER); + ret = slirp_vmstate_info_nullptr.get(f, curr_elem, size, NULL); + } else if (field->flags & VMS_STRUCT) { + ret = slirp_vmstate_load_state(f, field->vmsd, curr_elem, + field->vmsd->version_id); + } else if (field->flags & VMS_VSTRUCT) { + ret = slirp_vmstate_load_state(f, field->vmsd, curr_elem, + field->struct_version_id); + } else { + ret = field->info->get(f, curr_elem, size, field); + } + if (ret < 0) { + g_warning("Failed to load %s:%s", vmsd->name, + field->name); + return ret; + } + } + } else if (field->flags & VMS_MUST_EXIST) { + g_warning("Input validation failed: %s/%s", + vmsd->name, field->name); + return -1; + } + field++; + } + if (vmsd->post_load) { + ret = vmsd->post_load(opaque, version_id); + } + return ret; +} diff --git a/slirp/src/vmstate.h b/slirp/src/vmstate.h new file mode 100644 index 0000000000..cfa7b8c825 --- /dev/null +++ b/slirp/src/vmstate.h @@ -0,0 +1,396 @@ +/* + * QEMU migration/snapshot declarations + * + * Copyright (c) 2009-2011 Red Hat, Inc. + * + * Original author: Juan Quintela <quintela@redhat.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef VMSTATE_H_ +#define VMSTATE_H_ + +#include <unistd.h> +#include <stdint.h> +#include <stdbool.h> +#include "slirp.h" +#include "stream.h" + +#define stringify(s) tostring(s) +#define tostring(s) #s + +typedef struct VMStateInfo VMStateInfo; +typedef struct VMStateDescription VMStateDescription; +typedef struct VMStateField VMStateField; + +int slirp_vmstate_save_state(SlirpOStream *f, const VMStateDescription *vmsd, + void *opaque); +int slirp_vmstate_load_state(SlirpIStream *f, const VMStateDescription *vmsd, + void *opaque, int version_id); + +/* VMStateInfo allows customized migration of objects that don't fit in + * any category in VMStateFlags. Additional information is always passed + * into get and put in terms of field and vmdesc parameters. However + * these two parameters should only be used in cases when customized + * handling is needed, such as QTAILQ. For primitive data types such as + * integer, field and vmdesc parameters should be ignored inside get/put. + */ +struct VMStateInfo { + const char *name; + int (*get)(SlirpIStream *f, void *pv, size_t size, const VMStateField *field); + int (*put)(SlirpOStream *f, void *pv, size_t size, const VMStateField *field); +}; + +enum VMStateFlags { + /* Ignored */ + VMS_SINGLE = 0x001, + + /* The struct member at opaque + VMStateField.offset is a pointer + * to the actual field (e.g. struct a { uint8_t *b; + * }). Dereference the pointer before using it as basis for + * further pointer arithmetic (see e.g. VMS_ARRAY). Does not + * affect the meaning of VMStateField.num_offset or + * VMStateField.size_offset; see VMS_VARRAY* and VMS_VBUFFER for + * those. */ + VMS_POINTER = 0x002, + + /* The field is an array of fixed size. VMStateField.num contains + * the number of entries in the array. The size of each entry is + * given by VMStateField.size and / or opaque + + * VMStateField.size_offset; see VMS_VBUFFER and + * VMS_MULTIPLY. Each array entry will be processed individually + * (VMStateField.info.get()/put() if VMS_STRUCT is not set, + * recursion into VMStateField.vmsd if VMS_STRUCT is set). May not + * be combined with VMS_VARRAY*. */ + VMS_ARRAY = 0x004, + + /* The field is itself a struct, containing one or more + * fields. Recurse into VMStateField.vmsd. Most useful in + * combination with VMS_ARRAY / VMS_VARRAY*, recursing into each + * array entry. */ + VMS_STRUCT = 0x008, + + /* The field is an array of variable size. The int32_t at opaque + + * VMStateField.num_offset contains the number of entries in the + * array. See the VMS_ARRAY description regarding array handling + * in general. May not be combined with VMS_ARRAY or any other + * VMS_VARRAY*. */ + VMS_VARRAY_INT32 = 0x010, + + /* Ignored */ + VMS_BUFFER = 0x020, + + /* The field is a (fixed-size or variable-size) array of pointers + * (e.g. struct a { uint8_t *b[]; }). Dereference each array entry + * before using it. Note: Does not imply any one of VMS_ARRAY / + * VMS_VARRAY*; these need to be set explicitly. */ + VMS_ARRAY_OF_POINTER = 0x040, + + /* The field is an array of variable size. The uint16_t at opaque + * + VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) + * contains the number of entries in the array. See the VMS_ARRAY + * description regarding array handling in general. May not be + * combined with VMS_ARRAY or any other VMS_VARRAY*. */ + VMS_VARRAY_UINT16 = 0x080, + + /* The size of the individual entries (a single array entry if + * VMS_ARRAY or any of VMS_VARRAY* are set, or the field itself if + * neither is set) is variable (i.e. not known at compile-time), + * but the same for all entries. Use the int32_t at opaque + + * VMStateField.size_offset (subject to VMS_MULTIPLY) to determine + * the size of each (and every) entry. */ + VMS_VBUFFER = 0x100, + + /* Multiply the entry size given by the int32_t at opaque + + * VMStateField.size_offset (see VMS_VBUFFER description) with + * VMStateField.size to determine the number of bytes to be + * allocated. Only valid in combination with VMS_VBUFFER. */ + VMS_MULTIPLY = 0x200, + + /* The field is an array of variable size. The uint8_t at opaque + + * VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) + * contains the number of entries in the array. See the VMS_ARRAY + * description regarding array handling in general. May not be + * combined with VMS_ARRAY or any other VMS_VARRAY*. */ + VMS_VARRAY_UINT8 = 0x400, + + /* The field is an array of variable size. The uint32_t at opaque + * + VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) + * contains the number of entries in the array. See the VMS_ARRAY + * description regarding array handling in general. May not be + * combined with VMS_ARRAY or any other VMS_VARRAY*. */ + VMS_VARRAY_UINT32 = 0x800, + + /* Fail loading the serialised VM state if this field is missing + * from the input. */ + VMS_MUST_EXIST = 0x1000, + + /* When loading serialised VM state, allocate memory for the + * (entire) field. Only valid in combination with + * VMS_POINTER. Note: Not all combinations with other flags are + * currently supported, e.g. VMS_ALLOC|VMS_ARRAY_OF_POINTER won't + * cause the individual entries to be allocated. */ + VMS_ALLOC = 0x2000, + + /* Multiply the number of entries given by the integer at opaque + + * VMStateField.num_offset (see VMS_VARRAY*) with VMStateField.num + * to determine the number of entries in the array. Only valid in + * combination with one of VMS_VARRAY*. */ + VMS_MULTIPLY_ELEMENTS = 0x4000, + + /* A structure field that is like VMS_STRUCT, but uses + * VMStateField.struct_version_id to tell which version of the + * structure we are referencing to use. */ + VMS_VSTRUCT = 0x8000, +}; + +struct VMStateField { + const char *name; + size_t offset; + size_t size; + size_t start; + int num; + size_t num_offset; + size_t size_offset; + const VMStateInfo *info; + enum VMStateFlags flags; + const VMStateDescription *vmsd; + int version_id; + int struct_version_id; + bool (*field_exists)(void *opaque, int version_id); +}; + +struct VMStateDescription { + const char *name; + int version_id; + int (*pre_load)(void *opaque); + int (*post_load)(void *opaque, int version_id); + int (*pre_save)(void *opaque); + VMStateField *fields; +}; + + +extern const VMStateInfo slirp_vmstate_info_int16; +extern const VMStateInfo slirp_vmstate_info_int32; +extern const VMStateInfo slirp_vmstate_info_uint8; +extern const VMStateInfo slirp_vmstate_info_uint16; +extern const VMStateInfo slirp_vmstate_info_uint32; + +/** Put this in the stream when migrating a null pointer.*/ +#define VMS_NULLPTR_MARKER (0x30U) /* '0' */ +extern const VMStateInfo slirp_vmstate_info_nullptr; + +extern const VMStateInfo slirp_vmstate_info_buffer; +extern const VMStateInfo slirp_vmstate_info_tmp; + +#define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0) +#define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0) +#define typeof_field(type, field) typeof(((type *)0)->field) +#define type_check(t1,t2) ((t1*)0 - (t2*)0) + +#define vmstate_offset_value(_state, _field, _type) \ + (offsetof(_state, _field) + \ + type_check(_type, typeof_field(_state, _field))) + +#define vmstate_offset_pointer(_state, _field, _type) \ + (offsetof(_state, _field) + \ + type_check_pointer(_type, typeof_field(_state, _field))) + +#define vmstate_offset_array(_state, _field, _type, _num) \ + (offsetof(_state, _field) + \ + type_check_array(_type, typeof_field(_state, _field), _num)) + +#define vmstate_offset_buffer(_state, _field) \ + vmstate_offset_array(_state, _field, uint8_t, \ + sizeof(typeof_field(_state, _field))) + +/* In the macros below, if there is a _version, that means the macro's + * field will be processed only if the version being received is >= + * the _version specified. In general, if you add a new field, you + * would increment the structure's version and put that version + * number into the new field so it would only be processed with the + * new version. + * + * In particular, for VMSTATE_STRUCT() and friends the _version does + * *NOT* pick the version of the sub-structure. It works just as + * specified above. The version of the top-level structure received + * is passed down to all sub-structures. This means that the + * sub-structures must have version that are compatible with all the + * structures that use them. + * + * If you want to specify the version of the sub-structure, use + * VMSTATE_VSTRUCT(), which allows the specific sub-structure version + * to be directly specified. + */ + +#define VMSTATE_SINGLE_TEST(_field, _state, _test, _version, _info, _type) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .field_exists = (_test), \ + .size = sizeof(_type), \ + .info = &(_info), \ + .flags = VMS_SINGLE, \ + .offset = vmstate_offset_value(_state, _field, _type), \ +} + +#define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .num = (_num), \ + .info = &(_info), \ + .size = sizeof(_type), \ + .flags = VMS_ARRAY, \ + .offset = vmstate_offset_array(_state, _field, _type, _num), \ +} + +#define VMSTATE_STRUCT_TEST(_field, _state, _test, _version, _vmsd, _type) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .field_exists = (_test), \ + .vmsd = &(_vmsd), \ + .size = sizeof(_type), \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, _type), \ +} + +#define VMSTATE_STRUCT_POINTER_V(_field, _state, _version, _vmsd, _type) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .vmsd = &(_vmsd), \ + .size = sizeof(_type *), \ + .flags = VMS_STRUCT|VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, _type), \ +} + +#define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \ + .name = (stringify(_field)), \ + .num = (_num), \ + .field_exists = (_test), \ + .version_id = (_version), \ + .vmsd = &(_vmsd), \ + .size = sizeof(_type), \ + .flags = VMS_STRUCT|VMS_ARRAY, \ + .offset = vmstate_offset_array(_state, _field, _type, _num),\ +} + +#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .field_exists = (_test), \ + .size = (_size - _start), \ + .info = &slirp_vmstate_info_buffer, \ + .flags = VMS_BUFFER, \ + .offset = vmstate_offset_buffer(_state, _field) + _start, \ +} + +#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _field_size) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .field_exists = (_test), \ + .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\ + .info = &slirp_vmstate_info_buffer, \ + .flags = VMS_VBUFFER|VMS_POINTER, \ + .offset = offsetof(_state, _field), \ +} + +#define QEMU_BUILD_BUG_ON_STRUCT(x) \ + struct { \ + int:(x) ? -1 : 1; \ + } + +#define QEMU_BUILD_BUG_ON_ZERO(x) (sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)) - \ + sizeof(QEMU_BUILD_BUG_ON_STRUCT(x))) + +/* Allocate a temporary of type 'tmp_type', set tmp->parent to _state + * and execute the vmsd on the temporary. Note that we're working with + * the whole of _state here, not a field within it. + * We compile time check that: + * That _tmp_type contains a 'parent' member that's a pointer to the + * '_state' type + * That the pointer is right at the start of _tmp_type. + */ +#define VMSTATE_WITH_TMP(_state, _tmp_type, _vmsd) { \ + .name = "tmp", \ + .size = sizeof(_tmp_type) + \ + QEMU_BUILD_BUG_ON_ZERO(offsetof(_tmp_type, parent) != 0) + \ + type_check_pointer(_state, \ + typeof_field(_tmp_type, parent)), \ + .vmsd = &(_vmsd), \ + .info = &slirp_vmstate_info_tmp, \ +} + +#define VMSTATE_SINGLE(_field, _state, _version, _info, _type) \ + VMSTATE_SINGLE_TEST(_field, _state, NULL, _version, _info, _type) + +#define VMSTATE_STRUCT(_field, _state, _version, _vmsd, _type) \ + VMSTATE_STRUCT_TEST(_field, _state, NULL, _version, _vmsd, _type) + +#define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type) \ + VMSTATE_STRUCT_POINTER_V(_field, _state, 0, _vmsd, _type) + +#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \ + VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version, \ + _vmsd, _type) + +#define VMSTATE_INT16_V(_f, _s, _v) \ + VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_int16, int16_t) +#define VMSTATE_INT32_V(_f, _s, _v) \ + VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_int32, int32_t) + +#define VMSTATE_UINT8_V(_f, _s, _v) \ + VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_uint8, uint8_t) +#define VMSTATE_UINT16_V(_f, _s, _v) \ + VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_uint16, uint16_t) +#define VMSTATE_UINT32_V(_f, _s, _v) \ + VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_uint32, uint32_t) + +#define VMSTATE_INT16(_f, _s) \ + VMSTATE_INT16_V(_f, _s, 0) +#define VMSTATE_INT32(_f, _s) \ + VMSTATE_INT32_V(_f, _s, 0) + +#define VMSTATE_UINT8(_f, _s) \ + VMSTATE_UINT8_V(_f, _s, 0) +#define VMSTATE_UINT16(_f, _s) \ + VMSTATE_UINT16_V(_f, _s, 0) +#define VMSTATE_UINT32(_f, _s) \ + VMSTATE_UINT32_V(_f, _s, 0) + +#define VMSTATE_UINT16_TEST(_f, _s, _t) \ + VMSTATE_SINGLE_TEST(_f, _s, _t, 0, slirp_vmstate_info_uint16, uint16_t) + +#define VMSTATE_UINT32_TEST(_f, _s, _t) \ + VMSTATE_SINGLE_TEST(_f, _s, _t, 0, slirp_vmstate_info_uint32, uint32_t) + +#define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v) \ + VMSTATE_ARRAY(_f, _s, _n, _v, slirp_vmstate_info_int16, int16_t) + +#define VMSTATE_INT16_ARRAY(_f, _s, _n) \ + VMSTATE_INT16_ARRAY_V(_f, _s, _n, 0) + +#define VMSTATE_BUFFER_V(_f, _s, _v) \ + VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f))) + +#define VMSTATE_BUFFER(_f, _s) \ + VMSTATE_BUFFER_V(_f, _s, 0) + +#define VMSTATE_END_OF_LIST() \ + {} + +#endif diff --git a/slirp/state.h b/slirp/state.h deleted file mode 100644 index 154866898f..0000000000 --- a/slirp/state.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef SLIRP_STATE_H_ -#define SLIRP_STATE_H_ - -#include "libslirp.h" - -void slirp_state_register(Slirp *slirp); -void slirp_state_unregister(Slirp *slirp); - -#endif /* SLIRP_STATE_H_ */ diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 1e54fd5932..a66ec72daa 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -10,12 +10,12 @@ import os import sys +import uuid import avocado -SRC_ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) -SRC_ROOT_DIR = os.path.abspath(os.path.dirname(SRC_ROOT_DIR)) -sys.path.append(os.path.join(SRC_ROOT_DIR, 'scripts')) +SRC_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..', '..') +sys.path.append(os.path.join(SRC_ROOT_DIR, 'python')) from qemu import QEMUMachine @@ -42,13 +42,29 @@ def pick_default_qemu_bin(): class Test(avocado.Test): def setUp(self): - self.vm = None + self._vms = {} self.qemu_bin = self.params.get('qemu_bin', default=pick_default_qemu_bin()) if self.qemu_bin is None: self.cancel("No QEMU binary defined or found in the source tree") - self.vm = QEMUMachine(self.qemu_bin) + + def _new_vm(self, *args): + vm = QEMUMachine(self.qemu_bin) + if args: + vm.add_args(*args) + return vm + + @property + def vm(self): + return self.get_vm(name='default') + + def get_vm(self, *args, name=None): + if not name: + name = str(uuid.uuid4()) + if self._vms.get(name) is None: + self._vms[name] = self._new_vm(*args) + return self._vms[name] def tearDown(self): - if self.vm is not None: - self.vm.shutdown() + for vm in self._vms.values(): + vm.shutdown() diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py index 98324f7591..beeb1e59e8 100644 --- a/tests/acceptance/boot_linux_console.py +++ b/tests/acceptance/boot_linux_console.py @@ -18,7 +18,6 @@ class BootLinuxConsole(Test): Boots a x86_64 Linux kernel and checks that the console is operational and the kernel command line is properly passed from QEMU to the kernel - :avocado: enable :avocado: tags=x86_64 """ diff --git a/tests/acceptance/linux_initrd.py b/tests/acceptance/linux_initrd.py index 737355c2ef..fbdb48e43f 100644 --- a/tests/acceptance/linux_initrd.py +++ b/tests/acceptance/linux_initrd.py @@ -8,6 +8,7 @@ # This work is licensed under the terms of the GNU GPL, version 2 or # later. See the COPYING file in the top-level directory. +import logging import tempfile from avocado.utils.process import run @@ -18,20 +19,21 @@ class LinuxInitrd(Test): """ Checks QEMU evaluates correctly the initrd file passed as -initrd option. - :avocado: enable :avocado: tags=x86_64 """ - timeout = 60 + timeout = 300 - def test_with_2gib_file_should_exit_error_msg(self): + def test_with_2gib_file_should_exit_error_msg_with_linux_v3_6(self): """ Pretends to boot QEMU with an initrd file with size of 2GiB and expect it exits with error message. + Fedora-18 shipped with linux-3.6 which have not supported xloadflags + cannot support more than 2GiB initrd. """ - kernel_url = ('https://mirrors.kernel.org/fedora/releases/28/' - 'Everything/x86_64/os/images/pxeboot/vmlinuz') - kernel_hash = '238e083e114c48200f80d889f7e32eeb2793e02a' + kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora/li' + 'nux/releases/18/Fedora/x86_64/os/images/pxeboot/vmlinuz') + kernel_hash = '41464f68efe42b9991250bed86c7081d2ccdbb21' kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) max_size = 2 * (1024 ** 3) - 1 @@ -39,10 +41,44 @@ class LinuxInitrd(Test): initrd.seek(max_size) initrd.write(b'\0') initrd.flush() - cmd = "%s -kernel %s -initrd %s" % (self.qemu_bin, kernel_path, - initrd.name) + cmd = "%s -kernel %s -initrd %s -m 4096" % ( + self.qemu_bin, kernel_path, initrd.name) res = run(cmd, ignore_status=True) self.assertEqual(res.exit_status, 1) expected_msg = r'.*initrd is too large.*max: \d+, need %s.*' % ( max_size + 1) self.assertRegex(res.stderr_text, expected_msg) + + def test_with_2gib_file_should_work_with_linux_v4_16(self): + """ + QEMU has supported up to 4 GiB initrd for recent kernel + Expect guest can reach 'Unpacking initramfs...' + """ + kernel_url = ('https://mirrors.kernel.org/fedora/releases/28/' + 'Everything/x86_64/os/images/pxeboot/vmlinuz') + kernel_hash = '238e083e114c48200f80d889f7e32eeb2793e02a' + kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) + max_size = 2 * (1024 ** 3) + 1 + + with tempfile.NamedTemporaryFile() as initrd: + initrd.seek(max_size) + initrd.write(b'\0') + initrd.flush() + + self.vm.set_machine('pc') + self.vm.set_console() + kernel_command_line = 'console=ttyS0' + self.vm.add_args('-kernel', kernel_path, + '-append', kernel_command_line, + '-initrd', initrd.name, + '-m', '5120') + self.vm.launch() + console = self.vm.console_socket.makefile() + console_logger = logging.getLogger('console') + while True: + msg = console.readline() + console_logger.debug(msg.strip()) + if 'Unpacking initramfs...' in msg: + break + if 'Kernel panic - not syncing' in msg: + self.fail("Kernel panic reached") diff --git a/tests/acceptance/migration.py b/tests/acceptance/migration.py new file mode 100644 index 0000000000..6115cf6c24 --- /dev/null +++ b/tests/acceptance/migration.py @@ -0,0 +1,53 @@ +# Migration test +# +# Copyright (c) 2019 Red Hat, Inc. +# +# Authors: +# Cleber Rosa <crosa@redhat.com> +# Caio Carrara <ccarrara@redhat.com> +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. + + +from avocado_qemu import Test + +from avocado.utils import network +from avocado.utils import wait + + +class Migration(Test): + """ + :avocado: enable + """ + + timeout = 10 + + @staticmethod + def migration_finished(vm): + return vm.command('query-migrate')['status'] in ('completed', 'failed') + + def _get_free_port(self): + port = network.find_free_port() + if port is None: + self.cancel('Failed to find a free port') + return port + + + def test_migration_with_tcp_localhost(self): + source_vm = self.get_vm() + dest_uri = 'tcp:localhost:%u' % self._get_free_port() + dest_vm = self.get_vm('-incoming', dest_uri) + dest_vm.launch() + source_vm.launch() + source_vm.qmp('migrate', uri=dest_uri) + wait.wait_for( + self.migration_finished, + timeout=self.timeout, + step=0.1, + args=(source_vm,) + ) + self.assertEqual(dest_vm.command('query-migrate')['status'], 'completed') + self.assertEqual(source_vm.command('query-migrate')['status'], 'completed') + self.assertEqual(dest_vm.command('query-status')['status'], 'running') + self.assertEqual(source_vm.command('query-status')['status'], 'postmigrate') diff --git a/tests/acceptance/version.py b/tests/acceptance/version.py index 13b0a7440d..67c2192c93 100644 --- a/tests/acceptance/version.py +++ b/tests/acceptance/version.py @@ -14,7 +14,6 @@ from avocado_qemu import Test class Version(Test): """ - :avocado: enable :avocado: tags=quick """ def test_qmp_human_info_version(self): diff --git a/tests/acceptance/virtio_version.py b/tests/acceptance/virtio_version.py index ce990250d8..37fc01ea18 100644 --- a/tests/acceptance/virtio_version.py +++ b/tests/acceptance/virtio_version.py @@ -11,7 +11,7 @@ Check compatibility of virtio device types import sys import os -sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts")) +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) from qemu import QEMUMachine from avocado_qemu import Test @@ -61,7 +61,6 @@ class VirtioVersionCheck(Test): same device tree created by `disable-modern` and `disable-legacy`. - :avocado: enable :avocado: tags=x86_64 """ diff --git a/tests/acceptance/vnc.py b/tests/acceptance/vnc.py index b1ef9d71b1..064ceabcc1 100644 --- a/tests/acceptance/vnc.py +++ b/tests/acceptance/vnc.py @@ -13,7 +13,6 @@ from avocado_qemu import Test class Vnc(Test): """ - :avocado: enable :avocado: tags=vnc,quick """ def test_no_vnc(self): diff --git a/tests/migration/guestperf/engine.py b/tests/migration/guestperf/engine.py index 398e3f2706..0e304660b8 100644 --- a/tests/migration/guestperf/engine.py +++ b/tests/migration/guestperf/engine.py @@ -24,13 +24,14 @@ import re import sys import time -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'scripts')) -import qemu -import qmp.qmp from guestperf.progress import Progress, ProgressStats from guestperf.report import Report from guestperf.timings import TimingRecord, Timings +sys.path.append(os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'python')) +import qemu + class Engine(object): diff --git a/tests/qemu-iotests/235 b/tests/qemu-iotests/235 index d6edd97ab4..75c203b30c 100755 --- a/tests/qemu-iotests/235 +++ b/tests/qemu-iotests/235 @@ -23,7 +23,7 @@ import os import iotests from iotests import qemu_img_create, qemu_io, file_path, log -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts')) +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) from qemu import QEMUMachine diff --git a/tests/qemu-iotests/238 b/tests/qemu-iotests/238 index f81ee1112f..688abc9acb 100755 --- a/tests/qemu-iotests/238 +++ b/tests/qemu-iotests/238 @@ -23,7 +23,7 @@ import os import iotests from iotests import log -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts')) +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) from qemu import QEMUMachine diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 4910fb2005..3d15571688 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -32,8 +32,8 @@ import atexit import io from collections import OrderedDict -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts')) -import qtest +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu import qtest # This will not work if arguments contain spaces but is necessary if we diff --git a/tests/requirements.txt b/tests/requirements.txt index 64c6e27a94..002ded6a22 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,4 +1,4 @@ # Add Python module requirements, one per line, to be installed # in the tests/venv Python virtual environment. For more info, # refer to: https://pip.pypa.io/en/stable/user_guide/#id1 -avocado-framework==65.0 +avocado-framework==68.0 diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index bdca6cb2fc..0556bdcf9e 100755 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -17,7 +17,7 @@ import sys import logging import time import datetime -sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts")) +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) from qemu import QEMUMachine, kvm_available import subprocess import hashlib diff --git a/util/Makefile.objs b/util/Makefile.objs index 0808575e3e..835fcd69e2 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -3,6 +3,7 @@ util-obj-y += bufferiszero.o util-obj-y += lockcnt.o util-obj-y += aiocb.o async.o aio-wait.o thread-pool.o qemu-timer.o util-obj-y += main-loop.o iohandler.o +main-loop.o-cflags := $(SLIRP_CFLAGS) util-obj-$(call lnot,$(CONFIG_ATOMIC64)) += atomic64.o util-obj-$(CONFIG_POSIX) += aio-posix.o util-obj-$(CONFIG_POSIX) += compatfd.o diff --git a/util/main-loop.c b/util/main-loop.c index d4a521caeb..e1e349ca5c 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -26,11 +26,9 @@ #include "qapi/error.h" #include "qemu/cutils.h" #include "qemu/timer.h" -#include "qemu/sockets.h" // struct in_addr needed for libslirp.h #include "sysemu/qtest.h" #include "sysemu/cpus.h" #include "sysemu/replay.h" -#include "slirp/libslirp.h" #include "qemu/main-loop.h" #include "block/aio.h" #include "qemu/error-report.h" @@ -106,9 +106,6 @@ int main(int argc, char **argv) #include "disas/disas.h" - -#include "slirp/libslirp.h" - #include "trace-root.h" #include "trace/control.h" #include "qemu/queue.h" |