diff options
-rw-r--r-- | Makefile | 56 | ||||
-rw-r--r-- | Makefile.objs | 128 | ||||
-rw-r--r-- | Makefile.target | 17 | ||||
-rw-r--r-- | block.c | 18 | ||||
-rw-r--r-- | block/iscsi.c | 27 | ||||
-rw-r--r-- | block/raw-posix.c | 28 | ||||
-rw-r--r-- | block/sheepdog.c | 70 | ||||
-rw-r--r-- | blockdev.c | 118 | ||||
-rwxr-xr-x | configure | 85 | ||||
-rw-r--r-- | docs/specs/pci-ids.txt | 50 | ||||
-rw-r--r-- | exec.c | 2 | ||||
-rw-r--r-- | fsdev/Makefile.objs | 1 | ||||
-rw-r--r-- | fsdev/qemu-fsdev-dummy.c | 7 | ||||
-rw-r--r-- | fsdev/qemu-fsdev-opts.c | 85 | ||||
-rw-r--r-- | fsdev/qemu-fsdev.c | 8 | ||||
-rw-r--r-- | hw/9pfs/virtio-9p-device.c | 2 | ||||
-rw-r--r-- | hw/Makefile.objs | 7 | ||||
-rw-r--r-- | hw/dataplane/virtio-blk.c | 71 | ||||
-rw-r--r-- | hw/ivshmem.c | 7 | ||||
-rw-r--r-- | hw/kvm/pci-assign.c | 17 | ||||
-rw-r--r-- | hw/pc-testdev.c | 18 | ||||
-rw-r--r-- | hw/pci/msix.c | 2 | ||||
-rw-r--r-- | hw/pci/msix.h | 1 | ||||
-rw-r--r-- | hw/pci/pci.h | 8 | ||||
-rw-r--r-- | hw/pci_bridge_dev.c | 8 | ||||
-rw-r--r-- | hw/qdev-monitor.c | 51 | ||||
-rw-r--r-- | hw/qxl.c | 26 | ||||
-rw-r--r-- | hw/serial-pci.c | 12 | ||||
-rw-r--r-- | hw/usb/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/vhost.c | 112 | ||||
-rw-r--r-- | hw/vhost.h | 10 | ||||
-rw-r--r-- | hw/vhost_net.c | 27 | ||||
-rw-r--r-- | hw/vhost_net.h | 3 | ||||
-rw-r--r-- | hw/virtio-net.c | 22 | ||||
-rw-r--r-- | hw/virtio-pci.c | 203 | ||||
-rw-r--r-- | hw/virtio-pci.h | 2 | ||||
-rw-r--r-- | hw/virtio.h | 15 | ||||
-rw-r--r-- | include/block/block.h | 1 | ||||
-rw-r--r-- | include/qemu/config-file.h | 5 | ||||
-rw-r--r-- | include/sysemu/sysemu.h | 8 | ||||
-rw-r--r-- | include/trace.h (renamed from trace.h) | 0 | ||||
-rw-r--r-- | kvm-stub.c | 5 | ||||
-rw-r--r-- | libcacard/Makefile | 64 | ||||
-rw-r--r-- | libcacard/libcacard.syms | 77 | ||||
-rw-r--r-- | monitor.c | 23 | ||||
-rw-r--r-- | net/net.c | 26 | ||||
-rw-r--r-- | pci-ids.txt | 31 | ||||
-rw-r--r-- | qapi/Makefile.objs | 8 | ||||
-rw-r--r-- | qemu-char.c | 72 | ||||
-rw-r--r-- | qemu-config.c | 894 | ||||
-rw-r--r-- | qemu-tool.c | 115 | ||||
-rw-r--r-- | qemu-user.c | 37 | ||||
-rw-r--r-- | qobject/Makefile.objs | 3 | ||||
-rw-r--r-- | qobject/json-lexer.c (renamed from json-lexer.c) | 0 | ||||
-rw-r--r-- | qobject/json-parser.c (renamed from json-parser.c) | 0 | ||||
-rw-r--r-- | qobject/json-streamer.c (renamed from json-streamer.c) | 0 | ||||
-rw-r--r-- | qobject/qbool.c (renamed from qbool.c) | 0 | ||||
-rw-r--r-- | qobject/qdict.c (renamed from qdict.c) | 0 | ||||
-rw-r--r-- | qobject/qerror.c (renamed from qerror.c) | 0 | ||||
-rw-r--r-- | qobject/qfloat.c (renamed from qfloat.c) | 0 | ||||
-rw-r--r-- | qobject/qint.c (renamed from qint.c) | 0 | ||||
-rw-r--r-- | qobject/qjson.c (renamed from qjson.c) | 0 | ||||
-rw-r--r-- | qobject/qlist.c (renamed from qlist.c) | 0 | ||||
-rw-r--r-- | qobject/qstring.c (renamed from qstring.c) | 0 | ||||
-rw-r--r-- | qom/Makefile.objs | 6 | ||||
-rw-r--r-- | rules.mak | 20 | ||||
-rw-r--r-- | stubs/Makefile.objs | 17 | ||||
-rw-r--r-- | stubs/clock-warp.c | 7 | ||||
-rw-r--r-- | stubs/cpu-get-clock.c | 7 | ||||
-rw-r--r-- | stubs/cpu-get-icount.c | 9 | ||||
-rw-r--r-- | stubs/get-vm-name.c | 7 | ||||
-rw-r--r-- | stubs/iothread-lock.c | 10 | ||||
-rw-r--r-- | stubs/migr-blocker.c | 10 | ||||
-rw-r--r-- | stubs/mon-is-qmp.c | 7 | ||||
-rw-r--r-- | stubs/mon-print-filename.c | 6 | ||||
-rw-r--r-- | stubs/mon-printf.c | 10 | ||||
-rw-r--r-- | stubs/mon-protocol-event.c | 6 | ||||
-rw-r--r-- | stubs/mon-set-error.c | 8 | ||||
-rw-r--r-- | stubs/slirp.c | 17 | ||||
-rw-r--r-- | stubs/vm-stop.c | 7 | ||||
-rw-r--r-- | target-i386/arch_memory_mapping.c | 11 | ||||
-rw-r--r-- | tests/Makefile | 48 | ||||
-rw-r--r-- | trace/Makefile.objs | 44 | ||||
-rw-r--r-- | ui/spice-core.c | 84 | ||||
-rw-r--r-- | util/Makefile.objs | 10 | ||||
-rw-r--r-- | util/acl.c (renamed from acl.c) | 0 | ||||
-rw-r--r-- | util/aes.c (renamed from aes.c) | 0 | ||||
-rw-r--r-- | util/bitmap.c (renamed from bitmap.c) | 0 | ||||
-rw-r--r-- | util/bitops.c (renamed from bitops.c) | 0 | ||||
-rw-r--r-- | util/cache-utils.c (renamed from cache-utils.c) | 0 | ||||
-rw-r--r-- | util/compatfd.c (renamed from compatfd.c) | 0 | ||||
-rw-r--r-- | util/cutils.c (renamed from cutils.c) | 0 | ||||
-rw-r--r-- | util/envlist.c (renamed from envlist.c) | 0 | ||||
-rw-r--r-- | util/error.c (renamed from error.c) | 0 | ||||
-rw-r--r-- | util/event_notifier-posix.c (renamed from event_notifier-posix.c) | 0 | ||||
-rw-r--r-- | util/event_notifier-win32.c (renamed from event_notifier-win32.c) | 0 | ||||
-rw-r--r-- | util/host-utils.c (renamed from host-utils.c) | 0 | ||||
-rw-r--r-- | util/iov.c (renamed from iov.c) | 0 | ||||
-rw-r--r-- | util/module.c (renamed from module.c) | 0 | ||||
-rw-r--r-- | util/notify.c (renamed from notify.c) | 0 | ||||
-rw-r--r-- | util/osdep.c (renamed from osdep.c) | 0 | ||||
-rw-r--r-- | util/oslib-posix.c (renamed from oslib-posix.c) | 0 | ||||
-rw-r--r-- | util/oslib-win32.c (renamed from oslib-win32.c) | 0 | ||||
-rw-r--r-- | util/path.c (renamed from path.c) | 0 | ||||
-rw-r--r-- | util/qemu-config.c | 215 | ||||
-rw-r--r-- | util/qemu-error.c (renamed from qemu-error.c) | 0 | ||||
-rw-r--r-- | util/qemu-option.c (renamed from qemu-option.c) | 0 | ||||
-rw-r--r-- | util/qemu-progress.c (renamed from qemu-progress.c) | 0 | ||||
-rw-r--r-- | util/qemu-sockets.c (renamed from qemu-sockets.c) | 0 | ||||
-rw-r--r-- | util/qemu-thread-posix.c (renamed from qemu-thread-posix.c) | 0 | ||||
-rw-r--r-- | util/qemu-thread-win32.c (renamed from qemu-thread-win32.c) | 0 | ||||
-rw-r--r-- | util/qemu-timer-common.c (renamed from qemu-timer-common.c) | 0 | ||||
-rw-r--r-- | util/uri.c (renamed from uri.c) | 0 | ||||
-rw-r--r-- | vl.c | 205 |
114 files changed, 1895 insertions, 1571 deletions
@@ -104,6 +104,14 @@ defconfig: -include config-all-devices.mak -include config-all-disas.mak +ifneq ($(wildcard config-host.mak),) +include $(SRC_PATH)/Makefile.objs +include $(SRC_PATH)/tests/Makefile +endif +ifeq ($(CONFIG_SMARTCARD_NSS),y) +include $(SRC_PATH)/libcacard/Makefile +endif + all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all config-host.h: config-host.h-timestamp @@ -116,12 +124,6 @@ SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS)) subdir-%: $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" all,) -ifneq ($(wildcard config-host.mak),) -include $(SRC_PATH)/Makefile.objs -endif - -subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o - subdir-pixman: pixman/Makefile $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman V="$(V)" all,) @@ -131,11 +133,11 @@ pixman/Makefile: $(SRC_PATH)/pixman/configure $(SRC_PATH)/pixman/configure: (cd $(SRC_PATH)/pixman; autoreconf -v --install) -$(SUBDIR_RULES): libqemustub.a +$(SUBDIR_RULES): libqemuutil.a libqemustub.a -$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) $(extra-obj-y) +$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(common-obj-y) $(extra-obj-y) -$(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(user-obj-y) +$(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(user-obj-y) ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS)) romsubdir-%: @@ -153,39 +155,22 @@ version.o: $(SRC_PATH)/version.rc config-host.h version-obj-$(CONFIG_WIN32) += version.o ###################################################################### -# Build library with stubs +# Build libraries libqemustub.a: $(stub-obj-y) - -###################################################################### -# Support building shared library libcacard - -.PHONY: libcacard.la install-libcacard -libcacard.la: $(oslib-obj-y) qemu-timer-common.o $(trace-obj-y) - $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" libcacard.la,) - -install-libcacard: libcacard.la - $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" install-libcacard,) +libqemuutil.a: $(util-obj-y) ###################################################################### qemu-img.o: qemu-img-cmds.h -tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \ - main-loop.o iohandler.o error.o -tools-obj-$(CONFIG_POSIX) += compatfd.o - -qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y) libqemustub.a -qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y) libqemustub.a -qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) libqemustub.a +qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a +qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a +qemu-io$(EXESUF): qemu-io.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o -vscclient$(EXESUF): LIBS += $(libcacard_libs) -vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) libcacard/vscclient.o libqemustub.a - $(call LINK, $^) - -fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o oslib-posix.o $(trace-obj-y) +fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o libqemuutil.a libqemustub.a fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx @@ -196,10 +181,6 @@ qemu-ga$(EXESUF): QEMU_CFLAGS += -I qga/qapi-generated gen-out-type = $(subst .,-,$(suffix $@)) -ifneq ($(wildcard config-host.mak),) -include $(SRC_PATH)/tests/Makefile -endif - qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\ @@ -225,7 +206,7 @@ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h) $(qga-obj-y) qemu-ga.o: $(QGALIB_GEN) -qemu-ga$(EXESUF): $(qga-obj-y) $(oslib-obj-y) $(trace-obj-y) $(qapi-obj-y) $(qobject-obj-y) $(version-obj-y) libqemustub.a +qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a $(call LINK, $^) clean: @@ -234,6 +215,7 @@ clean: rm -f qemu-options.def find . -name '*.[od]' -type f -exec rm -f {} + rm -f *.a *.lo $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ + rm -f *.la rm -Rf .libs rm -f qemu-img-cmds.h @# May not be present in GENERATED_HEADERS diff --git a/Makefile.objs b/Makefile.objs index 12a314e3fb..d465a72030 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -1,67 +1,31 @@ ####################################################################### -# Stub library, linked in tools +# Common libraries for tools and emulators stub-obj-y = stubs/ +util-obj-y = util/ qobject/ qapi/ trace/ ####################################################################### -# Target-independent parts used in system and user emulation -universal-obj-y = -universal-obj-y += qemu-log.o - -####################################################################### -# QObject -qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o -qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o -qobject-obj-y += qerror.o error.o qemu-error.o - -universal-obj-y += $(qobject-obj-y) - -####################################################################### -# QOM -qom-obj-y = qom/ - -universal-obj-y += $(qom-obj-y) - -####################################################################### -# Core hw code (qdev core) -hw-core-obj-y += hw/ -hw-core-obj-y += qemu-option.o - -universal-obj-y += $(hw-core-obj-y) - -####################################################################### -# oslib-obj-y is code depending on the OS (win32 vs posix) -oslib-obj-y = osdep.o cutils.o qemu-timer-common.o -oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o -oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o +# block-obj-y is code used by both qemu system emulation and qemu-img -####################################################################### -# coroutines -coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o -coroutine-obj-y += qemu-coroutine-sleep.o +block-obj-y = async.o thread-pool.o +block-obj-y += nbd.o block.o blockjob.o +block-obj-y += main-loop.o iohandler.o qemu-timer.o +block-obj-$(CONFIG_POSIX) += aio-posix.o +block-obj-$(CONFIG_WIN32) += aio-win32.o +block-obj-y += block/ +block-obj-y += qapi-types.o qapi-visit.o -# If you change this logic, please also check tests/Makefile +block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o +block-obj-y += qemu-coroutine-sleep.o ifeq ($(CONFIG_UCONTEXT_COROUTINE),y) -coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o +block-obj-$(CONFIG_POSIX) += coroutine-ucontext.o else ifeq ($(CONFIG_SIGALTSTACK_COROUTINE),y) -coroutine-obj-$(CONFIG_POSIX) += coroutine-sigaltstack.o +block-obj-$(CONFIG_POSIX) += coroutine-sigaltstack.o else -coroutine-obj-$(CONFIG_POSIX) += coroutine-gthread.o +block-obj-$(CONFIG_POSIX) += coroutine-gthread.o endif endif -coroutine-obj-$(CONFIG_WIN32) += coroutine-win32.o - -####################################################################### -# block-obj-y is code used by both qemu system emulation and qemu-img - -block-obj-y = iov.o cache-utils.o qemu-option.o module.o async.o -block-obj-y += nbd.o block.o blockjob.o aes.o qemu-config.o -block-obj-y += thread-pool.o qemu-progress.o qemu-sockets.o uri.o notify.o -block-obj-y += $(coroutine-obj-y) $(qobject-obj-y) $(version-obj-y) -block-obj-$(CONFIG_POSIX) += event_notifier-posix.o aio-posix.o -block-obj-$(CONFIG_WIN32) += event_notifier-win32.o aio-win32.o -block-obj-y += block/ -block-obj-y += $(qapi-obj-y) qapi-types.o qapi-visit.o +block-obj-$(CONFIG_WIN32) += coroutine-win32.o ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy) # Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add. @@ -76,25 +40,19 @@ endif common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/ common-obj-y += net/ -common-obj-y += qom/ common-obj-y += readline.o -common-obj-y += $(oslib-obj-y) common-obj-$(CONFIG_WIN32) += os-win32.o common-obj-$(CONFIG_POSIX) += os-posix.o common-obj-$(CONFIG_LINUX) += fsdev/ extra-obj-$(CONFIG_LINUX) += fsdev/ -common-obj-y += tcg-runtime.o host-utils.o main-loop.o -common-obj-y += migration.o migration-tcp.o common-obj-y += migration.o migration-tcp.o common-obj-y += qemu-char.o #aio.o -common-obj-y += block-migration.o iohandler.o -common-obj-y += bitmap.o bitops.o +common-obj-y += block-migration.o common-obj-y += page_cache.o common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o -common-obj-$(CONFIG_WIN32) += version.o common-obj-$(CONFIG_SPICE) += spice-qemu-char.o @@ -106,9 +64,6 @@ common-obj-y += ui/ common-obj-y += bt-host.o bt-vhci.o common-obj-y += dma-helpers.o -common-obj-y += acl.o -common-obj-$(CONFIG_POSIX) += compatfd.o -common-obj-y += qemu-timer.o qemu-timer-common.o common-obj-y += qtest.o common-obj-y += vl.o @@ -123,30 +78,6 @@ common-obj-y += qemu-seccomp.o endif ###################################################################### -# libuser - -user-obj-y = -user-obj-y += envlist.o path.o -user-obj-y += tcg-runtime.o host-utils.o -user-obj-y += cache-utils.o -user-obj-y += module.o -user-obj-y += qemu-user.o -user-obj-y += qom/ - -###################################################################### -# disassemblers -# NOTE: the disassembler code is only needed for debugging - -universal-obj-y += disas/ - -###################################################################### -# trace - -trace-obj-y += trace/ - -universal-obj-y += $(trace-obj-y) - -###################################################################### # smartcard libcacard-y += libcacard/cac.o libcacard/event.o @@ -160,19 +91,24 @@ common-obj-$(CONFIG_SMARTCARD_NSS) += $(libcacard-y) ###################################################################### # qapi -qapi-obj-y = qapi/ -qapi-obj-y += qapi-types.o qapi-visit.o - common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o common-obj-y += qmp.o hmp.o -universal-obj-y += $(qapi-obj-y) +####################################################################### +# Target-independent parts used in system and user emulation +universal-obj-y = +universal-obj-y += qemu-log.o +universal-obj-y += tcg-runtime.o +universal-obj-y += hw/ +universal-obj-y += qom/ +universal-obj-y += disas/ ###################################################################### # guest agent -qga-obj-y = qga/ module.o qemu-tool.o -qga-obj-$(CONFIG_POSIX) += qemu-sockets.o qemu-option.o +# FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed +# by libqemuutil.a. These should be moved to a separate .json schema. +qga-obj-y = qga/ qapi-types.o qapi-visit.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) @@ -182,14 +118,10 @@ QEMU_CFLAGS+=$(GLIB_CFLAGS) nested-vars += \ stub-obj-y \ + util-obj-y \ qga-obj-y \ - qom-obj-y \ - qapi-obj-y \ block-obj-y \ - user-obj-y \ common-obj-y \ universal-obj-y \ - hw-core-obj-y \ - extra-obj-y \ - trace-obj-y + extra-obj-y dummy := $(call unnest-vars) diff --git a/Makefile.target b/Makefile.target index 5bfa496080..eb84b1f8e3 100644 --- a/Makefile.target +++ b/Makefile.target @@ -54,7 +54,7 @@ $(QEMU_PROG).stp: $(SRC_PATH)/trace-events --binary=$(bindir)/$(QEMU_PROG) \ --target-arch=$(TARGET_ARCH) \ --target-type=$(TARGET_TYPE) \ - < $< > $@," GEN $(QEMU_PROG).stp") + < $< > $@," GEN $(TARGET_DIR)$(QEMU_PROG).stp") else stap: endif @@ -83,7 +83,7 @@ ifdef CONFIG_LINUX_USER QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user obj-y += linux-user/ -obj-y += gdbstub.o thunk.o user-exec.o $(oslib-obj-y) +obj-y += gdbstub.o thunk.o user-exec.o endif #CONFIG_LINUX_USER @@ -95,7 +95,7 @@ ifdef CONFIG_BSD_USER QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH) obj-y += bsd-user/ -obj-y += gdbstub.o user-exec.o $(oslib-obj-y) +obj-y += gdbstub.o user-exec.o endif #CONFIG_BSD_USER @@ -146,21 +146,16 @@ include $(SRC_PATH)/Makefile.objs all-obj-y = $(obj-y) all-obj-y += $(addprefix ../, $(universal-obj-y)) - -ifdef CONFIG_SOFTMMU -all-obj-y += $(addprefix ../, $(common-obj-y)) -else -all-obj-y += $(addprefix ../, $(user-obj-y)) -endif #CONFIG_LINUX_USER +all-obj-$(CONFIG_SOFTMMU) += $(addprefix ../, $(common-obj-y)) ifdef QEMU_PROGW # The linker builds a windows executable. Make also a console executable. -$(QEMU_PROGW): $(all-obj-y) ../libqemustub.a +$(QEMU_PROGW): $(all-obj-y) ../libqemuutil.a ../libqemustub.a $(call LINK,$^) $(QEMU_PROG): $(QEMU_PROGW) $(call quiet-command,$(OBJCOPY) --subsystem console $(QEMU_PROGW) $(QEMU_PROG)," GEN $(TARGET_DIR)$(QEMU_PROG)") else -$(QEMU_PROG): $(all-obj-y) ../libqemustub.a +$(QEMU_PROG): $(all-obj-y) ../libqemuutil.a ../libqemustub.a $(call LINK,$^) endif @@ -527,7 +527,7 @@ static int find_image_format(BlockDriverState *bs, const char *filename, int ret = 0; /* Return the raw BlockDriver * to scsi-generic devices or empty drives */ - if (bs->sg || !bdrv_is_inserted(bs)) { + if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) { drv = bdrv_find_format("raw"); if (!drv) { ret = -ENOENT; @@ -4313,6 +4313,22 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size) return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); } +/* + * Check if all memory in this vector is sector aligned. + */ +bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) +{ + int i; + + for (i = 0; i < qiov->niov; i++) { + if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) { + return false; + } + } + + return true; +} + void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) { int64_t bitmap_size; diff --git a/block/iscsi.c b/block/iscsi.c index 041ee07de3..f08cf9663b 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -980,9 +980,36 @@ static BlockDriver bdrv_iscsi = { #endif }; +static QemuOptsList qemu_iscsi_opts = { + .name = "iscsi", + .head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head), + .desc = { + { + .name = "user", + .type = QEMU_OPT_STRING, + .help = "username for CHAP authentication to target", + },{ + .name = "password", + .type = QEMU_OPT_STRING, + .help = "password for CHAP authentication to target", + },{ + .name = "header-digest", + .type = QEMU_OPT_STRING, + .help = "HeaderDigest setting. " + "{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}", + },{ + .name = "initiator-name", + .type = QEMU_OPT_STRING, + .help = "Initiator iqn name to use when connecting", + }, + { /* end of list */ } + }, +}; + static void iscsi_block_init(void) { bdrv_register(&bdrv_iscsi); + qemu_add_opts(&qemu_iscsi_opts); } block_init(iscsi_block_init); diff --git a/block/raw-posix.c b/block/raw-posix.c index 87d888ed01..c3d7fda7b7 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -430,22 +430,6 @@ static void raw_reopen_abort(BDRVReopenState *state) #endif */ -/* - * Check if all memory in this vector is sector aligned. - */ -static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) -{ - int i; - - for (i = 0; i < qiov->niov; i++) { - if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) { - return 0; - } - } - - return 1; -} - static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb) { int ret; @@ -455,15 +439,7 @@ static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb) return -errno; } - /* - * This looks weird, but the aio code only considers a request - * successful if it has written the full number of bytes. - * - * Now we overload aio_nbytes as aio_ioctl_cmd for the ioctl command, - * so in fact we return the ioctl command here to make posix_aio_read() - * happy.. - */ - return aiocb->aio_nbytes; + return 0; } static ssize_t handle_aiocb_flush(RawPosixAIOData *aiocb) @@ -722,7 +698,7 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs, * driver that it needs to copy the buffer. */ if ((bs->open_flags & BDRV_O_NOCACHE)) { - if (!qiov_is_aligned(bs, qiov)) { + if (!bdrv_qiov_is_aligned(bs, qiov)) { type |= QEMU_AIO_MISALIGNED; #ifdef CONFIG_LINUX_AIO } else if (s->use_aio) { diff --git a/block/sheepdog.c b/block/sheepdog.c index e821746116..462c4b2d5d 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -36,7 +36,8 @@ #define SD_FLAG_CMD_WRITE 0x01 #define SD_FLAG_CMD_COW 0x02 -#define SD_FLAG_CMD_CACHE 0x04 +#define SD_FLAG_CMD_CACHE 0x04 /* Writeback mode for cache */ +#define SD_FLAG_CMD_DIRECT 0x08 /* Don't use cache */ #define SD_RES_SUCCESS 0x00 /* Success */ #define SD_RES_UNKNOWN 0x01 /* Unknown error */ @@ -293,7 +294,7 @@ typedef struct BDRVSheepdogState { char name[SD_MAX_VDI_LEN]; bool is_snapshot; - bool cache_enabled; + uint32_t cache_flags; char *addr; char *port; @@ -977,8 +978,8 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, hdr.flags = SD_FLAG_CMD_WRITE | flags; } - if (s->cache_enabled) { - hdr.flags |= SD_FLAG_CMD_CACHE; + if (s->cache_flags) { + hdr.flags |= s->cache_flags; } hdr.oid = oid; @@ -1023,7 +1024,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, static int read_write_object(int fd, char *buf, uint64_t oid, int copies, unsigned int datalen, uint64_t offset, - bool write, bool create, bool cache) + bool write, bool create, uint32_t cache_flags) { SheepdogObjReq hdr; SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr; @@ -1047,9 +1048,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, hdr.opcode = SD_OP_READ_OBJ; } - if (cache) { - hdr.flags |= SD_FLAG_CMD_CACHE; - } + hdr.flags |= cache_flags; hdr.oid = oid; hdr.data_length = datalen; @@ -1072,18 +1071,19 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, } static int read_object(int fd, char *buf, uint64_t oid, int copies, - unsigned int datalen, uint64_t offset, bool cache) + unsigned int datalen, uint64_t offset, + uint32_t cache_flags) { return read_write_object(fd, buf, oid, copies, datalen, offset, false, - false, cache); + false, cache_flags); } static int write_object(int fd, char *buf, uint64_t oid, int copies, unsigned int datalen, uint64_t offset, bool create, - bool cache) + uint32_t cache_flags) { return read_write_object(fd, buf, oid, copies, datalen, offset, true, - create, cache); + create, cache_flags); } static int sd_open(BlockDriverState *bs, const char *filename, int flags) @@ -1118,12 +1118,22 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags) goto out; } - s->cache_enabled = true; - s->flush_fd = connect_to_sdog(s->addr, s->port); - if (s->flush_fd < 0) { - error_report("failed to connect"); - ret = s->flush_fd; - goto out; + /* + * QEMU block layer emulates writethrough cache as 'writeback + flush', so + * we always set SD_FLAG_CMD_CACHE (writeback cache) as default. + */ + s->cache_flags = SD_FLAG_CMD_CACHE; + if (flags & BDRV_O_NOCACHE) { + s->cache_flags = SD_FLAG_CMD_DIRECT; + } + + if (s->cache_flags == SD_FLAG_CMD_CACHE) { + s->flush_fd = connect_to_sdog(s->addr, s->port); + if (s->flush_fd < 0) { + error_report("failed to connect"); + ret = s->flush_fd; + goto out; + } } if (snapid || tag[0] != '\0') { @@ -1140,7 +1150,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags) buf = g_malloc(SD_INODE_SIZE); ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0, - s->cache_enabled); + s->cache_flags); closesocket(fd); @@ -1387,7 +1397,7 @@ static void sd_close(BlockDriverState *bs) qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL); closesocket(s->fd); - if (s->cache_enabled) { + if (s->cache_flags) { closesocket(s->flush_fd); } g_free(s->addr); @@ -1423,7 +1433,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id); s->inode.vdi_size = offset; ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id), - s->inode.nr_copies, datalen, 0, false, s->cache_enabled); + s->inode.nr_copies, datalen, 0, false, s->cache_flags); close(fd); if (ret < 0) { @@ -1506,7 +1516,7 @@ static int sd_create_branch(BDRVSheepdogState *s) } ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies, - SD_INODE_SIZE, 0, s->cache_enabled); + SD_INODE_SIZE, 0, s->cache_flags); closesocket(fd); @@ -1707,7 +1717,7 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs) int ret; unsigned int wlen = 0, rlen = 0; - if (!s->cache_enabled) { + if (s->cache_flags != SD_FLAG_CMD_CACHE) { return 0; } @@ -1723,7 +1733,7 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs) if (rsp->result == SD_RES_INVALID_PARMS) { dprintf("disable write cache since the server doesn't support it\n"); - s->cache_enabled = false; + s->cache_flags = SD_FLAG_CMD_DIRECT; closesocket(s->flush_fd); return 0; } @@ -1774,7 +1784,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) } ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id), - s->inode.nr_copies, datalen, 0, false, s->cache_enabled); + s->inode.nr_copies, datalen, 0, false, s->cache_flags); if (ret < 0) { error_report("failed to write snapshot's inode."); goto cleanup; @@ -1791,7 +1801,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) inode = (SheepdogInode *)g_malloc(datalen); ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid), - s->inode.nr_copies, datalen, 0, s->cache_enabled); + s->inode.nr_copies, datalen, 0, s->cache_flags); if (ret < 0) { error_report("failed to read new inode info. %s", strerror(errno)); @@ -1845,7 +1855,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) buf = g_malloc(SD_INODE_SIZE); ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies, - SD_INODE_SIZE, 0, s->cache_enabled); + SD_INODE_SIZE, 0, s->cache_flags); closesocket(fd); @@ -1942,7 +1952,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) /* we don't need to read entire object */ ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0, - s->cache_enabled); + s->cache_flags); if (ret) { continue; @@ -2003,11 +2013,11 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data, if (load) { ret = read_object(fd, (char *)data, vmstate_oid, s->inode.nr_copies, data_len, offset, - s->cache_enabled); + s->cache_flags); } else { ret = write_object(fd, (char *)data, vmstate_oid, s->inode.nr_copies, data_len, offset, create, - s->cache_enabled); + s->cache_flags); } if (ret < 0) { diff --git a/blockdev.c b/blockdev.c index d724e2dc5b..9126587c45 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1427,3 +1427,121 @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp) bdrv_iterate(do_qmp_query_block_jobs_one, &prev); return dummy.next; } + +QemuOptsList qemu_drive_opts = { + .name = "drive", + .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head), + .desc = { + { + .name = "bus", + .type = QEMU_OPT_NUMBER, + .help = "bus number", + },{ + .name = "unit", + .type = QEMU_OPT_NUMBER, + .help = "unit number (i.e. lun for scsi)", + },{ + .name = "if", + .type = QEMU_OPT_STRING, + .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)", + },{ + .name = "index", + .type = QEMU_OPT_NUMBER, + .help = "index number", + },{ + .name = "cyls", + .type = QEMU_OPT_NUMBER, + .help = "number of cylinders (ide disk geometry)", + },{ + .name = "heads", + .type = QEMU_OPT_NUMBER, + .help = "number of heads (ide disk geometry)", + },{ + .name = "secs", + .type = QEMU_OPT_NUMBER, + .help = "number of sectors (ide disk geometry)", + },{ + .name = "trans", + .type = QEMU_OPT_STRING, + .help = "chs translation (auto, lba. none)", + },{ + .name = "media", + .type = QEMU_OPT_STRING, + .help = "media type (disk, cdrom)", + },{ + .name = "snapshot", + .type = QEMU_OPT_BOOL, + .help = "enable/disable snapshot mode", + },{ + .name = "file", + .type = QEMU_OPT_STRING, + .help = "disk image", + },{ + .name = "cache", + .type = QEMU_OPT_STRING, + .help = "host cache usage (none, writeback, writethrough, " + "directsync, unsafe)", + },{ + .name = "aio", + .type = QEMU_OPT_STRING, + .help = "host AIO implementation (threads, native)", + },{ + .name = "format", + .type = QEMU_OPT_STRING, + .help = "disk format (raw, qcow2, ...)", + },{ + .name = "serial", + .type = QEMU_OPT_STRING, + .help = "disk serial number", + },{ + .name = "rerror", + .type = QEMU_OPT_STRING, + .help = "read error action", + },{ + .name = "werror", + .type = QEMU_OPT_STRING, + .help = "write error action", + },{ + .name = "addr", + .type = QEMU_OPT_STRING, + .help = "pci address (virtio only)", + },{ + .name = "readonly", + .type = QEMU_OPT_BOOL, + .help = "open drive file as read-only", + },{ + .name = "iops", + .type = QEMU_OPT_NUMBER, + .help = "limit total I/O operations per second", + },{ + .name = "iops_rd", + .type = QEMU_OPT_NUMBER, + .help = "limit read operations per second", + },{ + .name = "iops_wr", + .type = QEMU_OPT_NUMBER, + .help = "limit write operations per second", + },{ + .name = "bps", + .type = QEMU_OPT_NUMBER, + .help = "limit total bytes per second", + },{ + .name = "bps_rd", + .type = QEMU_OPT_NUMBER, + .help = "limit read bytes per second", + },{ + .name = "bps_wr", + .type = QEMU_OPT_NUMBER, + .help = "limit write bytes per second", + },{ + .name = "copy-on-read", + .type = QEMU_OPT_BOOL, + .help = "copy read data from backing file into image file", + },{ + .name = "boot", + .type = QEMU_OPT_BOOL, + .help = "(deprecated, ignored)", + }, + { /* end of list */ } + }, +}; @@ -214,7 +214,6 @@ trace_backend="nop" trace_file="trace" spice="" rbd="" -smartcard="" smartcard_nss="" usb_redir="" opengl="" @@ -861,10 +860,6 @@ for opt do ;; --enable-xfsctl) xfs="yes" ;; - --disable-smartcard) smartcard="no" - ;; - --enable-smartcard) smartcard="yes" - ;; --disable-smartcard-nss) smartcard_nss="no" ;; --enable-smartcard-nss) smartcard_nss="yes" @@ -1128,8 +1123,6 @@ echo " --enable-spice enable spice" echo " --enable-rbd enable building the rados block device (rbd)" echo " --disable-libiscsi disable iscsi support" echo " --enable-libiscsi enable iscsi support" -echo " --disable-smartcard disable smartcard support" -echo " --enable-smartcard enable smartcard support" echo " --disable-smartcard-nss disable smartcard nss support" echo " --enable-smartcard-nss enable smartcard nss support" echo " --disable-usb-redir disable usb network redirection support" @@ -2813,43 +2806,38 @@ EOF fi # check for libcacard for smartcard support -if test "$smartcard" != "no" ; then - smartcard="yes" - smartcard_cflags="" - # TODO - what's the minimal nss version we support? - if test "$smartcard_nss" != "no"; then - cat > $TMPC << EOF +smartcard_cflags="" +# TODO - what's the minimal nss version we support? +if test "$smartcard_nss" != "no"; then + cat > $TMPC << EOF #include <pk11pub.h> int main(void) { PK11_FreeSlot(0); return 0; } EOF - smartcard_includes="-I\$(SRC_PATH)/libcacard" - libcacard_libs="$($pkg_config --libs nss 2>/dev/null) $glib_libs" - libcacard_cflags="$($pkg_config --cflags nss 2>/dev/null) $glib_cflags" - test_cflags="$libcacard_cflags" - # The header files in nss < 3.13.3 have a bug which causes them to - # emit a warning. If we're going to compile QEMU with -Werror, then - # test that the headers don't have this bug. Otherwise we would pass - # the configure test but fail to compile QEMU later. - if test "$werror" = "yes"; then - test_cflags="-Werror $test_cflags" - fi - if $pkg_config --atleast-version=3.12.8 nss >/dev/null 2>&1 && \ - compile_prog "$test_cflags" "$libcacard_libs"; then - smartcard_nss="yes" - QEMU_CFLAGS="$QEMU_CFLAGS $libcacard_cflags" - QEMU_INCLUDES="$QEMU_INCLUDES $smartcard_includes" - libs_softmmu="$libcacard_libs $libs_softmmu" - else - if test "$smartcard_nss" = "yes"; then - feature_not_found "nss" - fi - smartcard_nss="no" + smartcard_includes="-I\$(SRC_PATH)/libcacard" + libcacard_libs="$($pkg_config --libs nss 2>/dev/null) $glib_libs" + libcacard_cflags="$($pkg_config --cflags nss 2>/dev/null) $glib_cflags" + test_cflags="$libcacard_cflags" + # The header files in nss < 3.13.3 have a bug which causes them to + # emit a warning. If we're going to compile QEMU with -Werror, then + # test that the headers don't have this bug. Otherwise we would pass + # the configure test but fail to compile QEMU later. + if test "$werror" = "yes"; then + test_cflags="-Werror $test_cflags" + fi + if test -n "$libtool" && + $pkg_config --atleast-version=3.12.8 nss >/dev/null 2>&1 && \ + compile_prog "$test_cflags" "$libcacard_libs"; then + smartcard_nss="yes" + QEMU_CFLAGS="$QEMU_CFLAGS $libcacard_cflags" + QEMU_INCLUDES="$QEMU_INCLUDES $smartcard_includes" + libs_softmmu="$libcacard_libs $libs_softmmu" + else + if test "$smartcard_nss" = "yes"; then + feature_not_found "nss" fi + smartcard_nss="no" fi fi -if test "$smartcard" = "no" ; then - smartcard_nss="no" -fi # check for usbredirparser for usb network redirection support if test "$usb_redir" != "no" ; then @@ -3203,9 +3191,6 @@ if test "$softmmu" = yes ; then tools="qemu-ga\$(EXESUF) $tools" fi fi - if test "$smartcard_nss" = "yes" ; then - tools="vscclient\$(EXESUF) $tools" - fi fi # Mac OS X ships with a broken assembler @@ -3594,10 +3579,6 @@ if test "$spice" = "yes" ; then echo "CONFIG_SPICE=y" >> $config_host_mak fi -if test "$smartcard" = "yes" ; then - echo "CONFIG_SMARTCARD=y" >> $config_host_mak -fi - if test "$smartcard_nss" = "yes" ; then echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak echo "libcacard_libs=$libcacard_libs" >> $config_host_mak @@ -3721,7 +3702,13 @@ echo "MAKE=$make" >> $config_host_mak echo "INSTALL=$install" >> $config_host_mak echo "INSTALL_DIR=$install -d -m 0755" >> $config_host_mak echo "INSTALL_DATA=$install -c -m 0644" >> $config_host_mak -echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak +if test -n "$libtool"; then + echo "INSTALL_PROG=\$(LIBTOOL) --mode=install $install -c -m 0755" >> $config_host_mak + echo "INSTALL_LIB=\$(LIBTOOL) --mode=install $install -c -m 0644" >> $config_host_mak +else + echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak + echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak +fi echo "PYTHON=$python" >> $config_host_mak echo "CC=$cc" >> $config_host_mak echo "CC_I386=$cc_i386" >> $config_host_mak @@ -4049,9 +4036,6 @@ fi if test "$target_softmmu" = "yes" ; then echo "CONFIG_SOFTMMU=y" >> $config_target_mak echo "LIBS+=$libs_softmmu $target_libs_softmmu" >> $config_target_mak - if test "$smartcard_nss" = "yes" ; then - echo "subdir-$target: subdir-libcacard" >> $config_host_mak - fi case "$target_arch2" in i386|x86_64) echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak @@ -4252,10 +4236,9 @@ DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32" DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas" DIRS="$DIRS roms/seabios roms/vgabios" DIRS="$DIRS qapi-generated" -DIRS="$DIRS libcacard libcacard/libcacard libcacard/trace" FILES="Makefile tests/tcg/Makefile qdict-test-data.txt" FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit" -FILES="$FILES tests/tcg/lm32/Makefile libcacard/Makefile" +FILES="$FILES tests/tcg/lm32/Makefile" FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps" FILES="$FILES pc-bios/spapr-rtas/Makefile" FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile" diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt new file mode 100644 index 0000000000..3c65e1a6ef --- /dev/null +++ b/docs/specs/pci-ids.txt @@ -0,0 +1,50 @@ + +PCI IDs for qemu +================ + +Red Hat, Inc. donates a part of its device ID range to qemu, to be used for +virtual devices. The vendor IDs are 1af4 (formerly Qumranet ID) and 1b36. + +Contact Gerd Hoffmann <kraxel@redhat.com> to get a device ID assigned +for your devices. + +1af4 vendor ID +-------------- + +The 1000 -> 10ff device ID range is used as follows for virtio-pci devices. +Note that this allocation separate from the virtio device IDs, which are +maintained as part of the virtio specification. + +1af4:1000 network device +1af4:1001 block device +1af4:1002 balloon device +1af4:1003 console device +1af4:1004 SCSI host bus adapter device +1af4:1005 entropy generator device +1af4:1009 9p filesystem device + +1af4:10f0 Available for experimental usage without registration. Must get + to official ID when the code leaves the test lab (i.e. when seeking +1af4:10ff upstream merge or shipping a distro/product) to avoid conflicts. + +1af4:1100 Used as PCI Subsystem ID for existing hardware devices emulated + by qemu. + +1af4:1110 ivshmem device (shared memory, docs/specs/ivshmem_device_spec.txt) + +All other device IDs are reserved. + +1b36 vendor ID +-------------- + +The 0000 -> 00ff device ID range is used as follows for QEMU-specific +PCI devices (other than virtio): + +1b36:0001 PCI-PCI bridge +1b36:0002 PCI serial port (16550A) adapter (docs/specs/pci-serial.txt) +1b36:0003 PCI Dual-port 16550A adapter (docs/specs/pci-serial.txt) +1b36:0004 PCI Quad-port 16550A adapter (docs/specs/pci-serial.txt) + +All these devices are documented in docs/specs. + +The 0100 device ID is used for the QXL video card device. @@ -78,7 +78,7 @@ DEFINE_TLS(CPUArchState *,cpu_single_env); /* 0 = Do not count executed instructions. 1 = Precise instruction counting. 2 = Adaptive rate instruction counting. */ -int use_icount = 0; +int use_icount; #if !defined(CONFIG_USER_ONLY) diff --git a/fsdev/Makefile.objs b/fsdev/Makefile.objs index cb1e2500b9..ee16ca600c 100644 --- a/fsdev/Makefile.objs +++ b/fsdev/Makefile.objs @@ -7,3 +7,4 @@ extra-obj-y = qemu-fsdev-dummy.o else common-obj-y = qemu-fsdev-dummy.o endif +common-obj-y += qemu-fsdev-opts.o diff --git a/fsdev/qemu-fsdev-dummy.c b/fsdev/qemu-fsdev-dummy.c index 4bcf38fe4b..7dc2630a78 100644 --- a/fsdev/qemu-fsdev-dummy.c +++ b/fsdev/qemu-fsdev-dummy.c @@ -20,10 +20,3 @@ int qemu_fsdev_add(QemuOpts *opts) { return 0; } - -static void fsdev_register_config(void) -{ - qemu_add_opts(&qemu_fsdev_opts); - qemu_add_opts(&qemu_virtfs_opts); -} -machine_init(fsdev_register_config); diff --git a/fsdev/qemu-fsdev-opts.c b/fsdev/qemu-fsdev-opts.c new file mode 100644 index 0000000000..6311c7a7e5 --- /dev/null +++ b/fsdev/qemu-fsdev-opts.c @@ -0,0 +1,85 @@ +/* + * Virtio 9p + * + * 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 "qemu/config-file.h" +#include "qemu/option.h" +#include "qemu/module.h" + +static QemuOptsList qemu_fsdev_opts = { + .name = "fsdev", + .implied_opt_name = "fsdriver", + .head = QTAILQ_HEAD_INITIALIZER(qemu_fsdev_opts.head), + .desc = { + { + .name = "fsdriver", + .type = QEMU_OPT_STRING, + }, { + .name = "path", + .type = QEMU_OPT_STRING, + }, { + .name = "security_model", + .type = QEMU_OPT_STRING, + }, { + .name = "writeout", + .type = QEMU_OPT_STRING, + }, { + .name = "readonly", + .type = QEMU_OPT_BOOL, + + }, { + .name = "socket", + .type = QEMU_OPT_STRING, + }, { + .name = "sock_fd", + .type = QEMU_OPT_NUMBER, + }, + + { /*End of list */ } + }, +}; + +static QemuOptsList qemu_virtfs_opts = { + .name = "virtfs", + .implied_opt_name = "fsdriver", + .head = QTAILQ_HEAD_INITIALIZER(qemu_virtfs_opts.head), + .desc = { + { + .name = "fsdriver", + .type = QEMU_OPT_STRING, + }, { + .name = "path", + .type = QEMU_OPT_STRING, + }, { + .name = "mount_tag", + .type = QEMU_OPT_STRING, + }, { + .name = "security_model", + .type = QEMU_OPT_STRING, + }, { + .name = "writeout", + .type = QEMU_OPT_STRING, + }, { + .name = "readonly", + .type = QEMU_OPT_BOOL, + }, { + .name = "socket", + .type = QEMU_OPT_STRING, + }, { + .name = "sock_fd", + .type = QEMU_OPT_NUMBER, + }, + + { /*End of list */ } + }, +}; + +static void fsdev_register_config(void) +{ + qemu_add_opts(&qemu_fsdev_opts); + qemu_add_opts(&qemu_virtfs_opts); +} +machine_init(fsdev_register_config); diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c index 4cc04d4fde..6eaf36dbfa 100644 --- a/fsdev/qemu-fsdev.c +++ b/fsdev/qemu-fsdev.c @@ -97,11 +97,3 @@ FsDriverEntry *get_fsdev_fsentry(char *id) } return NULL; } - -static void fsdev_register_config(void) -{ - qemu_add_opts(&qemu_fsdev_opts); - qemu_add_opts(&qemu_virtfs_opts); -} -machine_init(fsdev_register_config); - diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 2a7c2a3d62..6f427dfc5d 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -170,7 +170,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data) k->init = virtio_9p_init_pci; k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; - k->device_id = 0x1009; + k->device_id = PCI_DEVICE_ID_VIRTIO_9P; k->revision = VIRTIO_PCI_ABI_VERSION; k->class_id = 0x2; dc->props = virtio_9p_properties; diff --git a/hw/Makefile.objs b/hw/Makefile.objs index d8671847fe..aa55ce9873 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -1,8 +1,7 @@ # core qdev-related obj files, also used by *-user: -hw-core-obj-y += qdev.o qdev-properties.o +universal-obj-y += qdev.o qdev-properties.o # irq.o needed for qdev GPIO handling: -hw-core-obj-y += irq.o - +universal-obj-y += irq.o common-obj-y = usb/ ide/ pci/ common-obj-y += loader.o @@ -37,7 +36,7 @@ common-obj-$(CONFIG_DMA) += dma.o common-obj-$(CONFIG_I82374) += i82374.o common-obj-$(CONFIG_HPET) += hpet.o common-obj-$(CONFIG_APPLESMC) += applesmc.o -common-obj-$(CONFIG_SMARTCARD) += ccid-card-passthru.o +common-obj-y += ccid-card-passthru.o common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o common-obj-y += fifo.o diff --git a/hw/dataplane/virtio-blk.c b/hw/dataplane/virtio-blk.c index 4c4ad8422a..1f7346ea19 100644 --- a/hw/dataplane/virtio-blk.c +++ b/hw/dataplane/virtio-blk.c @@ -34,6 +34,8 @@ typedef struct { struct iocb iocb; /* Linux AIO control block */ QEMUIOVector *inhdr; /* iovecs for virtio_blk_inhdr */ unsigned int head; /* vring descriptor index */ + struct iovec *bounce_iov; /* used if guest buffers are unaligned */ + QEMUIOVector *read_qiov; /* for read completion /w bounce buffer */ } VirtIOBlockRequest; struct VirtIOBlockDataPlane { @@ -89,6 +91,18 @@ static void complete_request(struct iocb *iocb, ssize_t ret, void *opaque) trace_virtio_blk_data_plane_complete_request(s, req->head, ret); + if (req->read_qiov) { + assert(req->bounce_iov); + qemu_iovec_from_buf(req->read_qiov, 0, req->bounce_iov->iov_base, len); + qemu_iovec_destroy(req->read_qiov); + g_slice_free(QEMUIOVector, req->read_qiov); + } + + if (req->bounce_iov) { + qemu_vfree(req->bounce_iov->iov_base); + g_slice_free(struct iovec, req->bounce_iov); + } + qemu_iovec_from_buf(req->inhdr, 0, &hdr, sizeof(hdr)); qemu_iovec_destroy(req->inhdr); g_slice_free(QEMUIOVector, req->inhdr); @@ -130,6 +144,48 @@ static void do_get_id_cmd(VirtIOBlockDataPlane *s, complete_request_early(s, head, inhdr, VIRTIO_BLK_S_OK); } +static int do_rdwr_cmd(VirtIOBlockDataPlane *s, bool read, + struct iovec *iov, unsigned int iov_cnt, + long long offset, unsigned int head, + QEMUIOVector *inhdr) +{ + struct iocb *iocb; + QEMUIOVector qiov; + struct iovec *bounce_iov = NULL; + QEMUIOVector *read_qiov = NULL; + + qemu_iovec_init_external(&qiov, iov, iov_cnt); + if (!bdrv_qiov_is_aligned(s->blk->conf.bs, &qiov)) { + void *bounce_buffer = qemu_blockalign(s->blk->conf.bs, qiov.size); + + if (read) { + /* Need to copy back from bounce buffer on completion */ + read_qiov = g_slice_new(QEMUIOVector); + qemu_iovec_init(read_qiov, iov_cnt); + qemu_iovec_concat_iov(read_qiov, iov, iov_cnt, 0, qiov.size); + } else { + qemu_iovec_to_buf(&qiov, 0, bounce_buffer, qiov.size); + } + + /* Redirect I/O to aligned bounce buffer */ + bounce_iov = g_slice_new(struct iovec); + bounce_iov->iov_base = bounce_buffer; + bounce_iov->iov_len = qiov.size; + iov = bounce_iov; + iov_cnt = 1; + } + + iocb = ioq_rdwr(&s->ioqueue, read, iov, iov_cnt, offset); + + /* Fill in virtio block metadata needed for completion */ + VirtIOBlockRequest *req = container_of(iocb, VirtIOBlockRequest, iocb); + req->head = head; + req->inhdr = inhdr; + req->bounce_iov = bounce_iov; + req->read_qiov = read_qiov; + return 0; +} + static int process_request(IOQueue *ioq, struct iovec iov[], unsigned int out_num, unsigned int in_num, unsigned int head) @@ -139,7 +195,6 @@ static int process_request(IOQueue *ioq, struct iovec iov[], struct virtio_blk_outhdr outhdr; QEMUIOVector *inhdr; size_t in_size; - struct iocb *iocb; /* Copy in outhdr */ if (unlikely(iov_to_buf(iov, out_num, 0, &outhdr, @@ -167,12 +222,12 @@ static int process_request(IOQueue *ioq, struct iovec iov[], switch (outhdr.type) { case VIRTIO_BLK_T_IN: - iocb = ioq_rdwr(ioq, true, in_iov, in_num, outhdr.sector * 512); - break; + do_rdwr_cmd(s, true, in_iov, in_num, outhdr.sector * 512, head, inhdr); + return 0; case VIRTIO_BLK_T_OUT: - iocb = ioq_rdwr(ioq, false, iov, out_num, outhdr.sector * 512); - break; + do_rdwr_cmd(s, false, iov, out_num, outhdr.sector * 512, head, inhdr); + return 0; case VIRTIO_BLK_T_SCSI_CMD: /* TODO support SCSI commands */ @@ -198,12 +253,6 @@ static int process_request(IOQueue *ioq, struct iovec iov[], g_slice_free(QEMUIOVector, inhdr); return -EFAULT; } - - /* Fill in virtio block metadata needed for completion */ - VirtIOBlockRequest *req = container_of(iocb, VirtIOBlockRequest, iocb); - req->head = head; - req->inhdr = inhdr; - return 0; } static void handle_notify(EventHandler *handler) diff --git a/hw/ivshmem.c b/hw/ivshmem.c index 3adcc98a34..afaf9b3bbf 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -29,6 +29,9 @@ #include <sys/mman.h> #include <sys/types.h> +#define PCI_VENDOR_ID_IVSHMEM PCI_VENDOR_ID_REDHAT_QUMRANET +#define PCI_DEVICE_ID_IVSHMEM 0x1110 + #define IVSHMEM_IOEVENTFD 0 #define IVSHMEM_MSI 1 @@ -800,8 +803,8 @@ static void ivshmem_class_init(ObjectClass *klass, void *data) k->init = pci_ivshmem_init; k->exit = pci_ivshmem_uninit; - k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; - k->device_id = 0x1110; + k->vendor_id = PCI_VENDOR_ID_IVSHMEM; + k->device_id = PCI_DEVICE_ID_IVSHMEM; k->class_id = PCI_CLASS_MEMORY_RAM; dc->reset = ivshmem_reset; dc->props = ivshmem_properties; diff --git a/hw/kvm/pci-assign.c b/hw/kvm/pci-assign.c index 8ee94287ff..896cfe8a59 100644 --- a/hw/kvm/pci-assign.c +++ b/hw/kvm/pci-assign.c @@ -1031,6 +1031,19 @@ static bool assigned_dev_msix_masked(MSIXTableEntry *entry) return (entry->ctrl & cpu_to_le32(0x1)) != 0; } +/* + * When MSI-X is first enabled the vector table typically has all the + * vectors masked, so we can't use that as the obvious test to figure out + * how many vectors to initially enable. Instead we look at the data field + * because this is what worked for pci-assign for a long time. This makes + * sure the physical MSI-X state tracks the guest's view, which is important + * for some VF/PF and PF/fw communication channels. + */ +static bool assigned_dev_msix_skipped(MSIXTableEntry *entry) +{ + return !entry->data; +} + static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) { AssignedDevice *adev = DO_UPCAST(AssignedDevice, dev, pci_dev); @@ -1041,7 +1054,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) /* Get the usable entry number for allocating */ for (i = 0; i < adev->msix_max; i++, entry++) { - if (assigned_dev_msix_masked(entry)) { + if (assigned_dev_msix_skipped(entry)) { continue; } entries_nr++; @@ -1070,7 +1083,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) for (i = 0; i < adev->msix_max; i++, entry++) { adev->msi_virq[i] = -1; - if (assigned_dev_msix_masked(entry)) { + if (assigned_dev_msix_skipped(entry)) { continue; } diff --git a/hw/pc-testdev.c b/hw/pc-testdev.c index ec0bc4bb95..cf64a1f203 100644 --- a/hw/pc-testdev.c +++ b/hw/pc-testdev.c @@ -58,13 +58,13 @@ typedef struct PCTestdev { #define TYPE_TESTDEV "pc-testdev" #define TESTDEV(obj) \ - OBJECT_CHECK(struct PCTestdev, (obj), TYPE_TESTDEV) + OBJECT_CHECK(PCTestdev, (obj), TYPE_TESTDEV) static void test_irq_line(void *opaque, hwaddr addr, uint64_t data, unsigned len) { - struct PCTestdev *dev = opaque; - struct ISADevice *isa = ISA_DEVICE(dev); + PCTestdev *dev = opaque; + ISADevice *isa = ISA_DEVICE(dev); qemu_set_irq(isa_get_irq(isa, addr), !!data); } @@ -79,13 +79,13 @@ static const MemoryRegionOps test_irq_ops = { static void test_ioport_write(void *opaque, hwaddr addr, uint64_t data, unsigned len) { - struct PCTestdev *dev = opaque; + PCTestdev *dev = opaque; dev->ioport_data = data; } static uint64_t test_ioport_read(void *opaque, hwaddr addr, unsigned len) { - struct PCTestdev *dev = opaque; + PCTestdev *dev = opaque; return dev->ioport_data; } @@ -119,7 +119,7 @@ static const MemoryRegionOps test_flush_ops = { static uint64_t test_iomem_read(void *opaque, hwaddr addr, unsigned len) { - struct PCTestdev *dev = opaque; + PCTestdev *dev = opaque; uint64_t ret = 0; memcpy(&ret, &dev->iomem_buf[addr], len); ret = le64_to_cpu(ret); @@ -130,7 +130,7 @@ static uint64_t test_iomem_read(void *opaque, hwaddr addr, unsigned len) static void test_iomem_write(void *opaque, hwaddr addr, uint64_t val, unsigned len) { - struct PCTestdev *dev = opaque; + PCTestdev *dev = opaque; val = cpu_to_le64(val); memcpy(&dev->iomem_buf[addr], &val, len); dev->iomem_buf[addr] = val; @@ -144,7 +144,7 @@ static const MemoryRegionOps test_iomem_ops = { static int init_test_device(ISADevice *isa) { - struct PCTestdev *dev = TESTDEV(isa); + PCTestdev *dev = TESTDEV(isa); MemoryRegion *mem = isa_address_space(isa); MemoryRegion *io = isa_address_space_io(isa); @@ -175,7 +175,7 @@ static void testdev_class_init(ObjectClass *klass, void *data) static const TypeInfo testdev_info = { .name = TYPE_TESTDEV, .parent = TYPE_ISA_DEVICE, - .instance_size = sizeof(struct PCTestdev), + .instance_size = sizeof(PCTestdev), .class_init = testdev_class_init, }; diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 9eee6570c2..e231a0dc4b 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -27,7 +27,7 @@ #define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8) #define MSIX_MASKALL_MASK (PCI_MSIX_FLAGS_MASKALL >> 8) -static MSIMessage msix_get_message(PCIDevice *dev, unsigned vector) +MSIMessage msix_get_message(PCIDevice *dev, unsigned vector) { uint8_t *table_entry = dev->msix_table + vector * PCI_MSIX_ENTRY_SIZE; MSIMessage msg; diff --git a/hw/pci/msix.h b/hw/pci/msix.h index d0c4429843..e648410535 100644 --- a/hw/pci/msix.h +++ b/hw/pci/msix.h @@ -5,6 +5,7 @@ #include "hw/pci/pci.h" void msix_set_message(PCIDevice *dev, int vector, MSIMessage msg); +MSIMessage msix_get_message(PCIDevice *dev, unsigned int vector); int msix_init(PCIDevice *dev, unsigned short nentries, MemoryRegion *table_bar, uint8_t table_bar_nr, unsigned table_offset, MemoryRegion *pba_bar, diff --git a/hw/pci/pci.h b/hw/pci/pci.h index 72927e3149..f340fe57c9 100644 --- a/hw/pci/pci.h +++ b/hw/pci/pci.h @@ -77,6 +77,14 @@ #define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003 #define PCI_DEVICE_ID_VIRTIO_SCSI 0x1004 #define PCI_DEVICE_ID_VIRTIO_RNG 0x1005 +#define PCI_DEVICE_ID_VIRTIO_9P 0x1009 + +#define PCI_VENDOR_ID_REDHAT 0x1b36 +#define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001 +#define PCI_DEVICE_ID_REDHAT_SERIAL 0x0002 +#define PCI_DEVICE_ID_REDHAT_SERIAL2 0x0003 +#define PCI_DEVICE_ID_REDHAT_SERIAL4 0x0004 +#define PCI_DEVICE_ID_REDHAT_QXL 0x0100 #define FMT_PCIBUS PRIx64 diff --git a/hw/pci_bridge_dev.c b/hw/pci_bridge_dev.c index 1a7b2cd897..1124c53b8c 100644 --- a/hw/pci_bridge_dev.c +++ b/hw/pci_bridge_dev.c @@ -27,10 +27,6 @@ #include "exec/memory.h" #include "pci/pci_bus.h" -#define REDHAT_PCI_VENDOR_ID 0x1b36 -#define PCI_BRIDGE_DEV_VENDOR_ID REDHAT_PCI_VENDOR_ID -#define PCI_BRIDGE_DEV_DEVICE_ID 0x1 - struct PCIBridgeDev { PCIBridge bridge; MemoryRegion bar; @@ -146,8 +142,8 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data) k->init = pci_bridge_dev_initfn; k->exit = pci_bridge_dev_exitfn; k->config_write = pci_bridge_dev_write_config; - k->vendor_id = PCI_BRIDGE_DEV_VENDOR_ID; - k->device_id = PCI_BRIDGE_DEV_DEVICE_ID; + k->vendor_id = PCI_VENDOR_ID_REDHAT; + k->device_id = PCI_DEVICE_ID_REDHAT_BRIDGE; k->class_id = PCI_CLASS_BRIDGE_PCI; k->is_bridge = 1, dc->desc = "Standard PCI Bridge"; diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index b73986759b..93283ee57a 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -615,3 +615,54 @@ void qdev_machine_init(void) qdev_get_peripheral_anon(); qdev_get_peripheral(); } + +QemuOptsList qemu_device_opts = { + .name = "device", + .implied_opt_name = "driver", + .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head), + .desc = { + /* + * no elements => accept any + * sanity checking will happen later + * when setting device properties + */ + { /* end of list */ } + }, +}; + +QemuOptsList qemu_global_opts = { + .name = "global", + .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head), + .desc = { + { + .name = "driver", + .type = QEMU_OPT_STRING, + },{ + .name = "property", + .type = QEMU_OPT_STRING, + },{ + .name = "value", + .type = QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +int qemu_global_option(const char *str) +{ + char driver[64], property[64]; + QemuOpts *opts; + int rc, offset; + + rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset); + if (rc < 2 || str[offset] != '=') { + error_report("can't parse: \"%s\"", str); + return -1; + } + + opts = qemu_opts_create_nofail(&qemu_global_opts); + qemu_opt_set(opts, "driver", driver); + qemu_opt_set(opts, "property", property); + qemu_opt_set(opts, "value", str+offset+1); + return 0; +} @@ -37,33 +37,25 @@ */ #undef SPICE_RING_PROD_ITEM #define SPICE_RING_PROD_ITEM(qxl, r, ret) { \ - typeof(r) start = r; \ - typeof(r) end = r + 1; \ uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r); \ - typeof(&(r)->items[prod]) m_item = &(r)->items[prod]; \ - if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \ + if (prod >= ARRAY_SIZE((r)->items)) { \ qxl_set_guest_bug(qxl, "SPICE_RING_PROD_ITEM indices mismatch " \ - "! %p <= %p < %p", (uint8_t *)start, \ - (uint8_t *)m_item, (uint8_t *)end); \ + "%u >= %zu", prod, ARRAY_SIZE((r)->items)); \ ret = NULL; \ } else { \ - ret = &m_item->el; \ + ret = &(r)->items[prod].el; \ } \ } #undef SPICE_RING_CONS_ITEM #define SPICE_RING_CONS_ITEM(qxl, r, ret) { \ - typeof(r) start = r; \ - typeof(r) end = r + 1; \ uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r); \ - typeof(&(r)->items[cons]) m_item = &(r)->items[cons]; \ - if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \ + if (cons >= ARRAY_SIZE((r)->items)) { \ qxl_set_guest_bug(qxl, "SPICE_RING_CONS_ITEM indices mismatch " \ - "! %p <= %p < %p", (uint8_t *)start, \ - (uint8_t *)m_item, (uint8_t *)end); \ + "%u >= %zu", cons, ARRAY_SIZE((r)->items)); \ ret = NULL; \ } else { \ - ret = &m_item->el; \ + ret = &(r)->items[cons].el; \ } \ } @@ -959,9 +951,11 @@ static void interface_set_client_capabilities(QXLInstance *sin, } qxl->shadow_rom.client_present = client_present; - memcpy(qxl->shadow_rom.client_capabilities, caps, sizeof(caps)); + memcpy(qxl->shadow_rom.client_capabilities, caps, + sizeof(qxl->shadow_rom.client_capabilities)); qxl->rom->client_present = client_present; - memcpy(qxl->rom->client_capabilities, caps, sizeof(caps)); + memcpy(qxl->rom->client_capabilities, caps, + sizeof(qxl->rom->client_capabilities)); qxl_rom_set_dirty(qxl); qxl_send_events(qxl, QXL_INTERRUPT_CLIENT); diff --git a/hw/serial-pci.c b/hw/serial-pci.c index c62cc9e375..1c31353f6d 100644 --- a/hw/serial-pci.c +++ b/hw/serial-pci.c @@ -185,8 +185,8 @@ static void serial_pci_class_initfn(ObjectClass *klass, void *data) PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); pc->init = serial_pci_init; pc->exit = serial_pci_exit; - pc->vendor_id = 0x1b36; /* Red Hat */ - pc->device_id = 0x0002; + pc->vendor_id = PCI_VENDOR_ID_REDHAT; + pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL; pc->revision = 1; pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL; dc->vmsd = &vmstate_pci_serial; @@ -199,8 +199,8 @@ static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data) PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); pc->init = multi_serial_pci_init; pc->exit = multi_serial_pci_exit; - pc->vendor_id = 0x1b36; /* Red Hat */ - pc->device_id = 0x0003; + pc->vendor_id = PCI_VENDOR_ID_REDHAT; + pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL2; pc->revision = 1; pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL; dc->vmsd = &vmstate_pci_multi_serial; @@ -213,8 +213,8 @@ static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data) PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); pc->init = multi_serial_pci_init; pc->exit = multi_serial_pci_exit; - pc->vendor_id = 0x1b36; /* Red Hat */ - pc->device_id = 0x0004; + pc->vendor_id = PCI_VENDOR_ID_REDHAT; + pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL4; pc->revision = 1; pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL; dc->vmsd = &vmstate_pci_multi_serial; diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs index dad4cb9f3c..d1bbbc06e7 100644 --- a/hw/usb/Makefile.objs +++ b/hw/usb/Makefile.objs @@ -4,11 +4,11 @@ common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o hcd-ehci-pci.o hcd-ehci-sysbus.o common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o common-obj-y += libhw.o -common-obj-$(CONFIG_SMARTCARD) += dev-smartcard-reader.o common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o common-obj-y += core.o combined-packet.o bus.o desc.o dev-hub.o common-obj-y += host-$(HOST_USB).o dev-bluetooth.o common-obj-y += dev-hid.o dev-storage.o dev-wacom.o common-obj-y += dev-serial.o dev-network.o dev-audio.o +common-obj-y += dev-smartcard-reader.o common-obj-y += dev-uas.o diff --git a/hw/vhost.c b/hw/vhost.c index 4e1cb47418..cee8aad4a1 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -612,7 +612,7 @@ static void vhost_log_stop(MemoryListener *listener, /* FIXME: implement */ } -static int vhost_virtqueue_init(struct vhost_dev *dev, +static int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev, struct vhost_virtqueue *vq, unsigned idx) @@ -681,16 +681,11 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, goto fail_kick; } - file.fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq)); - r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file); - if (r) { - r = -errno; - goto fail_call; - } + /* Clear and discard previous events if any. */ + event_notifier_test_and_clear(&vq->masked_notifier); return 0; -fail_call: fail_kick: fail_alloc: cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx), @@ -708,7 +703,7 @@ fail_alloc_desc: return r; } -static void vhost_virtqueue_cleanup(struct vhost_dev *dev, +static void vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev, struct vhost_virtqueue *vq, unsigned idx) @@ -746,11 +741,39 @@ static void vhost_eventfd_del(MemoryListener *listener, { } +static int vhost_virtqueue_init(struct vhost_dev *dev, + struct vhost_virtqueue *vq, int n) +{ + struct vhost_vring_file file = { + .index = n, + }; + int r = event_notifier_init(&vq->masked_notifier, 0); + if (r < 0) { + return r; + } + + file.fd = event_notifier_get_fd(&vq->masked_notifier); + r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file); + if (r) { + r = -errno; + goto fail_call; + } + return 0; +fail_call: + event_notifier_cleanup(&vq->masked_notifier); + return r; +} + +static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq) +{ + event_notifier_cleanup(&vq->masked_notifier); +} + int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath, bool force) { uint64_t features; - int r; + int i, r; if (devfd >= 0) { hdev->control = devfd; } else { @@ -768,6 +791,13 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath, if (r < 0) { goto fail; } + + for (i = 0; i < hdev->nvqs; ++i) { + r = vhost_virtqueue_init(hdev, hdev->vqs + i, i); + if (r < 0) { + goto fail_vq; + } + } hdev->features = features; hdev->memory_listener = (MemoryListener) { @@ -795,6 +825,10 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath, memory_listener_register(&hdev->memory_listener, &address_space_memory); hdev->force = force; return 0; +fail_vq: + while (--i >= 0) { + vhost_virtqueue_cleanup(hdev->vqs + i); + } fail: r = -errno; close(hdev->control); @@ -803,6 +837,10 @@ fail: void vhost_dev_cleanup(struct vhost_dev *hdev) { + int i; + for (i = 0; i < hdev->nvqs; ++i) { + vhost_virtqueue_cleanup(hdev->vqs + i); + } memory_listener_unregister(&hdev->memory_listener); g_free(hdev->mem); g_free(hdev->mem_sections); @@ -869,17 +907,53 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) } } +/* Test and clear event pending status. + * Should be called after unmask to avoid losing events. + */ +bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n) +{ + struct vhost_virtqueue *vq = hdev->vqs + n; + assert(hdev->started); + return event_notifier_test_and_clear(&vq->masked_notifier); +} + +/* Mask/unmask events from this vq. */ +void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, + bool mask) +{ + struct VirtQueue *vvq = virtio_get_queue(vdev, n); + int r; + + assert(hdev->started); + + struct vhost_vring_file file = { + .index = n, + }; + if (mask) { + file.fd = event_notifier_get_fd(&hdev->vqs[n].masked_notifier); + } else { + file.fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq)); + } + r = ioctl(hdev->control, VHOST_SET_VRING_CALL, &file); + assert(r >= 0); +} + /* Host notifiers must be enabled at this point. */ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; + + hdev->started = true; + if (!vdev->binding->set_guest_notifiers) { fprintf(stderr, "binding does not support guest notifiers\n"); r = -ENOSYS; goto fail; } - r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, true); + r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, + hdev->nvqs, + true); if (r < 0) { fprintf(stderr, "Error binding guest notifier: %d\n", -r); goto fail_notifiers; @@ -895,7 +969,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) goto fail_mem; } for (i = 0; i < hdev->nvqs; ++i) { - r = vhost_virtqueue_init(hdev, + r = vhost_virtqueue_start(hdev, vdev, hdev->vqs + i, i); @@ -916,22 +990,22 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) } } - hdev->started = true; - return 0; fail_log: fail_vq: while (--i >= 0) { - vhost_virtqueue_cleanup(hdev, + vhost_virtqueue_stop(hdev, vdev, hdev->vqs + i, i); } fail_mem: fail_features: - vdev->binding->set_guest_notifiers(vdev->binding_opaque, false); + vdev->binding->set_guest_notifiers(vdev->binding_opaque, hdev->nvqs, false); fail_notifiers: fail: + + hdev->started = false; return r; } @@ -941,7 +1015,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) int i, r; for (i = 0; i < hdev->nvqs; ++i) { - vhost_virtqueue_cleanup(hdev, + vhost_virtqueue_stop(hdev, vdev, hdev->vqs + i, i); @@ -950,7 +1024,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) vhost_sync_dirty_bitmap(hdev, &hdev->mem_sections[i], 0, (hwaddr)~0x0ull); } - r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, false); + r = vdev->binding->set_guest_notifiers(vdev->binding_opaque, + hdev->nvqs, + false); if (r < 0) { fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r); fflush(stderr); diff --git a/hw/vhost.h b/hw/vhost.h index 6f6a906f4f..44c61a5877 100644 --- a/hw/vhost.h +++ b/hw/vhost.h @@ -18,6 +18,7 @@ struct vhost_virtqueue { void *ring; unsigned long long ring_phys; unsigned ring_size; + EventNotifier masked_notifier; }; typedef unsigned long vhost_log_chunk_t; @@ -53,4 +54,13 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); +/* Test and clear masked event pending status. + * Should be called after unmask to avoid losing events. + */ +bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n); + +/* Mask/unmask events from this vq. + */ +void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, + bool mask); #endif diff --git a/hw/vhost_net.c b/hw/vhost_net.c index ae2785d83f..d3a04caef6 100644 --- a/hw/vhost_net.c +++ b/hw/vhost_net.c @@ -109,6 +109,9 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd, (1 << VHOST_NET_F_VIRTIO_NET_HDR); net->backend = r; + net->dev.nvqs = 2; + net->dev.vqs = net->vqs; + r = vhost_dev_init(&net->dev, devfd, "/dev/vhost-net", force); if (r < 0) { goto fail; @@ -143,9 +146,6 @@ int vhost_net_start(struct vhost_net *net, struct vhost_vring_file file = { }; int r; - net->dev.nvqs = 2; - net->dev.vqs = net->vqs; - r = vhost_dev_enable_notifiers(&net->dev, dev); if (r < 0) { goto fail_notifiers; @@ -200,6 +200,17 @@ void vhost_net_cleanup(struct vhost_net *net) vhost_dev_cleanup(&net->dev); g_free(net); } + +bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) +{ + return vhost_virtqueue_pending(&net->dev, idx); +} + +void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, + int idx, bool mask) +{ + vhost_virtqueue_mask(&net->dev, dev, idx, mask); +} #else struct vhost_net *vhost_net_init(NetClientState *backend, int devfd, bool force) @@ -234,4 +245,14 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features) void vhost_net_ack_features(struct vhost_net *net, unsigned features) { } + +bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) +{ + return -ENOSYS; +} + +void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, + int idx, bool mask) +{ +} #endif diff --git a/hw/vhost_net.h b/hw/vhost_net.h index 012aba4148..88912b85fd 100644 --- a/hw/vhost_net.h +++ b/hw/vhost_net.h @@ -17,4 +17,7 @@ void vhost_net_cleanup(VHostNetState *net); unsigned vhost_net_get_features(VHostNetState *net, unsigned features); void vhost_net_ack_features(VHostNetState *net, unsigned features); +bool vhost_net_virtqueue_pending(VHostNetState *net, int n); +void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, + int idx, bool mask); #endif diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 5d03b31c1b..3bb01b1037 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -126,12 +126,12 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status) if (!vhost_net_query(tap_get_vhost_net(n->nic->nc.peer), &n->vdev)) { return; } + n->vhost_started = 1; r = vhost_net_start(tap_get_vhost_net(n->nic->nc.peer), &n->vdev); if (r < 0) { error_report("unable to start vhost net: %d: " "falling back on userspace virtio", -r); - } else { - n->vhost_started = 1; + n->vhost_started = 0; } } else { vhost_net_stop(tap_get_vhost_net(n->nic->nc.peer), &n->vdev); @@ -1010,6 +1010,22 @@ static NetClientInfo net_virtio_info = { .link_status_changed = virtio_net_set_link_status, }; +static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) +{ + VirtIONet *n = to_virtio_net(vdev); + assert(n->vhost_started); + return vhost_net_virtqueue_pending(tap_get_vhost_net(n->nic->nc.peer), idx); +} + +static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, + bool mask) +{ + VirtIONet *n = to_virtio_net(vdev); + assert(n->vhost_started); + vhost_net_virtqueue_mask(tap_get_vhost_net(n->nic->nc.peer), + vdev, idx, mask); +} + VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, virtio_net_conf *net) { @@ -1026,6 +1042,8 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, n->vdev.bad_features = virtio_net_bad_features; n->vdev.reset = virtio_net_reset; n->vdev.set_status = virtio_net_set_status; + n->vdev.guest_notifier_mask = virtio_net_guest_notifier_mask; + n->vdev.guest_notifier_pending = virtio_net_guest_notifier_pending; n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx); if (net->tx && strcmp(net->tx, "timer") && strcmp(net->tx, "bh")) { diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 08d2d1ba82..0b49739946 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -487,8 +487,6 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, unsigned int vector, MSIMessage msg) { - VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no); - EventNotifier *n = virtio_queue_get_guest_notifier(vq); VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; int ret; @@ -500,21 +498,34 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, irqfd->virq = ret; } irqfd->users++; - - ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, irqfd->virq); - if (ret < 0) { - if (--irqfd->users == 0) { - kvm_irqchip_release_virq(kvm_state, irqfd->virq); - } - return ret; - } return 0; } static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy, - unsigned int queue_no, unsigned int vector) { + VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; + if (--irqfd->users == 0) { + kvm_irqchip_release_virq(kvm_state, irqfd->virq); + } +} + +static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy, + unsigned int queue_no, + unsigned int vector) +{ + VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; + VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no); + EventNotifier *n = virtio_queue_get_guest_notifier(vq); + int ret; + ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, irqfd->virq); + return ret; +} + +static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy, + unsigned int queue_no, + unsigned int vector) +{ VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no); EventNotifier *n = virtio_queue_get_guest_notifier(vq); VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; @@ -522,27 +533,143 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy, ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd->virq); assert(ret == 0); +} - if (--irqfd->users == 0) { - kvm_irqchip_release_virq(kvm_state, irqfd->virq); +static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) +{ + PCIDevice *dev = &proxy->pci_dev; + VirtIODevice *vdev = proxy->vdev; + unsigned int vector; + int ret, queue_no; + MSIMessage msg; + + for (queue_no = 0; queue_no < nvqs; queue_no++) { + if (!virtio_queue_get_num(vdev, queue_no)) { + break; + } + vector = virtio_queue_vector(vdev, queue_no); + if (vector >= msix_nr_vectors_allocated(dev)) { + continue; + } + msg = msix_get_message(dev, vector); + ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg); + if (ret < 0) { + goto undo; + } + /* If guest supports masking, set up irqfd now. + * Otherwise, delay until unmasked in the frontend. + */ + if (proxy->vdev->guest_notifier_mask) { + ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); + if (ret < 0) { + kvm_virtio_pci_vq_vector_release(proxy, vector); + goto undo; + } + } + } + return 0; + +undo: + while (--queue_no >= 0) { + vector = virtio_queue_vector(vdev, queue_no); + if (vector >= msix_nr_vectors_allocated(dev)) { + continue; + } + if (proxy->vdev->guest_notifier_mask) { + kvm_virtio_pci_irqfd_release(proxy, vector, queue_no); + } + kvm_virtio_pci_vq_vector_release(proxy, vector); + } + return ret; +} + +static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) +{ + PCIDevice *dev = &proxy->pci_dev; + VirtIODevice *vdev = proxy->vdev; + unsigned int vector; + int queue_no; + + for (queue_no = 0; queue_no < nvqs; queue_no++) { + if (!virtio_queue_get_num(vdev, queue_no)) { + break; + } + vector = virtio_queue_vector(vdev, queue_no); + if (vector >= msix_nr_vectors_allocated(dev)) { + continue; + } + /* If guest supports masking, clean up irqfd now. + * Otherwise, it was cleaned when masked in the frontend. + */ + if (proxy->vdev->guest_notifier_mask) { + kvm_virtio_pci_irqfd_release(proxy, vector, queue_no); + } + kvm_virtio_pci_vq_vector_release(proxy, vector); + } +} + +static int kvm_virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, + unsigned int queue_no, + unsigned int vector, + MSIMessage msg) +{ + VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no); + EventNotifier *n = virtio_queue_get_guest_notifier(vq); + VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; + int ret; + + if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) { + ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg); + if (ret < 0) { + return ret; + } + } + + /* If guest supports masking, irqfd is already setup, unmask it. + * Otherwise, set it up now. + */ + if (proxy->vdev->guest_notifier_mask) { + proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, false); + /* Test after unmasking to avoid losing events. */ + if (proxy->vdev->guest_notifier_pending && + proxy->vdev->guest_notifier_pending(proxy->vdev, queue_no)) { + event_notifier_set(n); + } + } else { + ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); } + return ret; } -static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector, +static void kvm_virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, + unsigned int queue_no, + unsigned int vector) +{ + /* If guest supports masking, keep irqfd but mask it. + * Otherwise, clean it up now. + */ + if (proxy->vdev->guest_notifier_mask) { + proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, true); + } else { + kvm_virtio_pci_irqfd_release(proxy, vector, queue_no); + } +} + +static int kvm_virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, MSIMessage msg) { VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); VirtIODevice *vdev = proxy->vdev; int ret, queue_no; - for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) { + for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { if (!virtio_queue_get_num(vdev, queue_no)) { break; } if (virtio_queue_vector(vdev, queue_no) != vector) { continue; } - ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg); + ret = kvm_virtio_pci_vq_vector_unmask(proxy, queue_no, vector, msg); if (ret < 0) { goto undo; } @@ -554,25 +681,25 @@ undo: if (virtio_queue_vector(vdev, queue_no) != vector) { continue; } - kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector); + kvm_virtio_pci_vq_vector_mask(proxy, queue_no, vector); } return ret; } -static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector) +static void kvm_virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) { VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); VirtIODevice *vdev = proxy->vdev; int queue_no; - for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) { + for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { if (!virtio_queue_get_num(vdev, queue_no)) { break; } if (virtio_queue_vector(vdev, queue_no) != vector) { continue; } - kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector); + kvm_virtio_pci_vq_vector_mask(proxy, queue_no, vector); } } @@ -587,7 +714,7 @@ static void kvm_virtio_pci_vector_poll(PCIDevice *dev, EventNotifier *notifier; VirtQueue *vq; - for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) { + for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { if (!virtio_queue_get_num(vdev, queue_no)) { break; } @@ -598,7 +725,11 @@ static void kvm_virtio_pci_vector_poll(PCIDevice *dev, } vq = virtio_get_queue(vdev, queue_no); notifier = virtio_queue_get_guest_notifier(vq); - if (event_notifier_test_and_clear(notifier)) { + if (vdev->guest_notifier_pending) { + if (vdev->guest_notifier_pending(vdev, queue_no)) { + msix_set_pending(dev, vector); + } + } else if (event_notifier_test_and_clear(notifier)) { msix_set_pending(dev, vector); } } @@ -631,7 +762,7 @@ static bool virtio_pci_query_guest_notifiers(DeviceState *d) return msix_enabled(&proxy->pci_dev); } -static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign) +static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) { VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); VirtIODevice *vdev = proxy->vdev; @@ -639,14 +770,24 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign) bool with_irqfd = msix_enabled(&proxy->pci_dev) && kvm_msi_via_irqfd_enabled(); + nvqs = MIN(nvqs, VIRTIO_PCI_QUEUE_MAX); + + /* When deassigning, pass a consistent nvqs value + * to avoid leaking notifiers. + */ + assert(assign || nvqs == proxy->nvqs_with_notifiers); + + proxy->nvqs_with_notifiers = nvqs; + /* Must unset vector notifier while guest notifier is still assigned */ if (proxy->vector_irqfd && !assign) { msix_unset_vector_notifiers(&proxy->pci_dev); + kvm_virtio_pci_vector_release(proxy, nvqs); g_free(proxy->vector_irqfd); proxy->vector_irqfd = NULL; } - for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { + for (n = 0; n < nvqs; n++) { if (!virtio_queue_get_num(vdev, n)) { break; } @@ -663,17 +804,25 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign) proxy->vector_irqfd = g_malloc0(sizeof(*proxy->vector_irqfd) * msix_nr_vectors_allocated(&proxy->pci_dev)); + r = kvm_virtio_pci_vector_use(proxy, nvqs); + if (r < 0) { + goto assign_error; + } r = msix_set_vector_notifiers(&proxy->pci_dev, - kvm_virtio_pci_vector_use, - kvm_virtio_pci_vector_release, + kvm_virtio_pci_vector_unmask, + kvm_virtio_pci_vector_mask, kvm_virtio_pci_vector_poll); if (r < 0) { - goto assign_error; + goto notifiers_error; } } return 0; +notifiers_error: + assert(assign); + kvm_virtio_pci_vector_release(proxy, nvqs); + assign_error: /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ assert(assign); diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h index b58d9a2d19..9ff3139fe9 100644 --- a/hw/virtio-pci.h +++ b/hw/virtio-pci.h @@ -27,6 +27,7 @@ #define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT) typedef struct { + MSIMessage msg; int virq; unsigned int users; } VirtIOIRQFD; @@ -51,6 +52,7 @@ typedef struct { bool ioeventfd_disabled; bool ioeventfd_started; VirtIOIRQFD *vector_irqfd; + int nvqs_with_notifiers; } VirtIOPCIProxy; void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev); diff --git a/hw/virtio.h b/hw/virtio.h index 1dec9dce07..b9f1873fd6 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -99,7 +99,7 @@ typedef struct { int (*load_done)(DeviceState *d, QEMUFile *f); unsigned (*get_features)(DeviceState *d); bool (*query_guest_notifiers)(DeviceState *d); - int (*set_guest_notifiers)(DeviceState *d, bool assigned); + int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assigned); int (*set_host_notifier)(DeviceState *d, int n, bool assigned); void (*vmstate_change)(DeviceState *d, bool running); } VirtIOBindings; @@ -126,6 +126,19 @@ struct VirtIODevice void (*set_config)(VirtIODevice *vdev, const uint8_t *config); void (*reset)(VirtIODevice *vdev); void (*set_status)(VirtIODevice *vdev, uint8_t val); + /* Test and clear event pending status. + * Should be called after unmask to avoid losing events. + * If backend does not support masking, + * must check in frontend instead. + */ + bool (*guest_notifier_pending)(VirtIODevice *vdev, int n); + /* Mask/unmask events from this vq. Any events reported + * while masked will become pending. + * If backend does not support masking, + * must mask in frontend instead. + */ + void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask); + VirtQueue *vq; const VirtIOBindings *binding; DeviceState *binding_opaque; diff --git a/include/block/block.h b/include/block/block.h index 0719339231..ffd193637d 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -349,6 +349,7 @@ void bdrv_img_create(const char *filename, const char *fmt, void bdrv_set_buffer_alignment(BlockDriverState *bs, int align); void *qemu_blockalign(BlockDriverState *bs, size_t size); +bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov); #define BDRV_SECTORS_PER_DIRTY_CHUNK 2048 diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h index 486c77cad4..ccfccae2b4 100644 --- a/include/qemu/config-file.h +++ b/include/qemu/config-file.h @@ -6,11 +6,6 @@ #include "qapi/error.h" #include "qemu/option.h" -extern QemuOptsList qemu_fsdev_opts; -extern QemuOptsList qemu_virtfs_opts; -extern QemuOptsList qemu_spice_opts; -extern QemuOptsList qemu_sandbox_opts; - QemuOptsList *qemu_find_opts(const char *group); QemuOptsList *qemu_find_opts_err(const char *group, Error **errp); void qemu_add_opts(QemuOptsList *list); diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 28a783e2be..c07d4ee458 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -183,4 +183,12 @@ char *get_boot_devices_list(uint32_t *size); bool usb_enabled(bool default_usb); +extern QemuOptsList qemu_drive_opts; +extern QemuOptsList qemu_chardev_opts; +extern QemuOptsList qemu_device_opts; +extern QemuOptsList qemu_netdev_opts; +extern QemuOptsList qemu_net_opts; +extern QemuOptsList qemu_global_opts; +extern QemuOptsList qemu_mon_opts; + #endif diff --git a/trace.h b/include/trace.h index c15f498128..c15f498128 100644 --- a/trace.h +++ b/include/trace.h diff --git a/kvm-stub.c b/kvm-stub.c index 5b971521cd..81f8967180 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -131,6 +131,11 @@ void kvm_irqchip_release_virq(KVMState *s, int virq) { } +int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) +{ + return -ENOSYS; +} + int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq) { return -ENOSYS; diff --git a/libcacard/Makefile b/libcacard/Makefile index c26aac65c3..47827a0eb8 100644 --- a/libcacard/Makefile +++ b/libcacard/Makefile @@ -1,63 +1,49 @@ --include ../config-host.mak --include $(SRC_PATH)/rules.mak --include $(SRC_PATH)/Makefile.objs - libcacard_includedir=$(includedir)/cacard -$(call set-vpath, $(SRC_PATH)) +TOOLS += vscclient$(EXESUF) # objects linked into a shared library, built with libtool with -fPIC if required -QEMU_OBJS=$(oslib-obj-y) qemu-timer-common.o $(trace-obj-y) $(stub-obj-y) -QEMU_OBJS_LIB=$(patsubst %.o,%.lo,$(QEMU_OBJS)) - -QEMU_CFLAGS+=-I../ - -libcacard.lib-y=$(patsubst %.o,%.lo,$(libcacard-y)) +libcacard-obj-y = $(stub-obj-y) $(libcacard-y) +libcacard-obj-y += util/osdep.o util/cutils.o util/qemu-timer-common.o util/error.o +libcacard-obj-$(CONFIG_WIN32) += util/oslib-win32.o util/qemu-thread-win32.o +libcacard-obj-$(CONFIG_POSIX) += util/oslib-posix.o util/qemu-thread-posix.o +libcacard-obj-y += $(filter trace/%, $(util-obj-y)) -vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o cutils.o - $(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS)," LINK $@") +libcacard-lobj-y=$(patsubst %.o,%.lo,$(libcacard-obj-y)) -clean: - rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient *.lo */*.lo .libs/* */.libs/* *.la */*.la *.pc - rm -Rf .libs */.libs +# libtool will build the .o files, too +$(libcacard-obj-y): | $(libcacard-lobj-y) all: libcacard.la libcacard.pc -# Dummy command so that make thinks it has done something - @true + +vscclient$(EXESUF): libcacard/vscclient.o libcacard.la + $(call LINK,$^) ######################################################################### # Rules for building libcacard standalone library -ifeq ($(LIBTOOL),) -libcacard.la: - @echo "libtool is missing, please install and rerun configure"; exit 1 - -install-libcacard: - @echo "libtool is missing, please install and rerun configure"; exit 1 -else -libcacard.la: $(libcacard.lib-y) $(QEMU_OBJS_LIB) - $(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs)," lt LINK $@") +libcacard.la: LDFLAGS += -rpath $(libdir) -no-undefined \ + -export-syms $(SRC_PATH)/libcacard/libcacard.syms +libcacard.la: LIBS += $(libcacard_libs) +libcacard.la: $(libcacard-lobj-y) + $(call LINK,$^) -libcacard_srcpath=$(SRC_PATH)/libcacard -libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in +libcacard.pc: $(SRC_PATH)/libcacard/libcacard.pc.in $(call quiet-command,sed -e 's|@LIBDIR@|$(libdir)|' \ -e 's|@INCLUDEDIR@|$(libcacard_includedir)|' \ -e 's|@VERSION@|$(shell cat $(SRC_PATH)/VERSION)|' \ - -e 's|@PREFIX@|$(prefix)|' \ - < $(libcacard_srcpath)/libcacard.pc.in > libcacard.pc,\ + -e 's|@PREFIX@|$(prefix)|' $< > libcacard.pc,\ " GEN $@") .PHONY: install-libcacard -install-libcacard: libcacard.pc libcacard.la vscclient +install: install-libcacard +install-libcacard: libcacard.pc libcacard.la $(INSTALL_DIR) "$(DESTDIR)$(libdir)" $(INSTALL_DIR) "$(DESTDIR)$(libdir)/pkgconfig" $(INSTALL_DIR) "$(DESTDIR)$(libcacard_includedir)" - $(INSTALL_DIR) "$(DESTDIR)$(bindir)" - $(LIBTOOL) --mode=install $(INSTALL_PROG) vscclient "$(DESTDIR)$(bindir)" - $(LIBTOOL) --mode=install $(INSTALL_DATA) libcacard.la "$(DESTDIR)$(libdir)" - $(LIBTOOL) --mode=install $(INSTALL_DATA) libcacard.pc "$(DESTDIR)$(libdir)/pkgconfig" - for inc in *.h; do \ - $(LIBTOOL) --mode=install $(INSTALL_DATA) $(libcacard_srcpath)/$$inc "$(DESTDIR)$(libcacard_includedir)"; \ + $(INSTALL_LIB) libcacard.la "$(DESTDIR)$(libdir)" + $(INSTALL_DATA) libcacard.pc "$(DESTDIR)$(libdir)/pkgconfig" + for inc in $(SRC_PATH)/libcacard/*.h; do \ + $(INSTALL_DATA) $$inc "$(DESTDIR)$(libcacard_includedir)"; \ done -endif diff --git a/libcacard/libcacard.syms b/libcacard/libcacard.syms new file mode 100644 index 0000000000..1697515a7f --- /dev/null +++ b/libcacard/libcacard.syms @@ -0,0 +1,77 @@ +cac_card_init +cac_is_cac_card +vcard_add_applet +vcard_apdu_delete +vcard_apdu_new +vcard_applet_get_aid +vcard_buffer_response_delete +vcard_buffer_response_new +vcard_delete_applet +vcard_emul_delete_key +vcard_emul_force_card_insert +vcard_emul_force_card_remove +vcard_emul_get_atr +vcard_emul_get_login_count +vcard_emul_init +vcard_emul_login +vcard_emul_options +vcard_emul_replay_insertion_events +vcard_emul_reset +vcard_emul_rsa_op +vcard_emul_type_from_string +vcard_emul_type_select +vcard_emul_usage +vcard_find_applet +vcard_free +vcard_get_atr +vcard_get_buffer_response +vcard_get_current_applet_private +vcard_get_private +vcard_get_type +vcard_init +vcard_make_response +vcard_new +vcard_new_applet +vcard_process_apdu +vcard_process_applet_apdu +vcard_reference +vcard_reset +vcard_response_delete +vcard_response_new +vcard_response_new_bytes +vcard_response_new_data +vcard_response_new_status_bytes +vcard_select_applet +vcard_set_applet_private +vcard_set_atr_func +vcard_set_buffer_response +vcard_set_type +vevent_delete +vevent_get_next_vevent +vevent_new +vevent_queue_init +vevent_queue_vevent +vevent_wait_next_vevent +vreader_add_reader +vreader_card_is_present +vreader_free +vreader_get_id +vreader_get_name +vreader_get_private +vreader_get_reader_by_id +vreader_get_reader_by_name +vreader_get_reader_list +vreader_init +vreader_insert_card +vreader_list_delete +vreader_list_get_first +vreader_list_get_next +vreader_list_get_reader +vreader_new +vreader_power_off +vreader_power_on +vreader_queue_card_event +vreader_reference +vreader_remove_reader +vreader_set_id +vreader_xfr_bytes @@ -270,6 +270,7 @@ static void monitor_puts(Monitor *mon, const char *str) char c; for(;;) { + assert(mon->outbuf_index < sizeof(mon->outbuf) - 1); c = *str++; if (c == '\0') break; @@ -4790,3 +4791,25 @@ int monitor_read_block_device_key(Monitor *mon, const char *device, return monitor_read_bdrv_key_start(mon, bs, completion_cb, opaque); } + +QemuOptsList qemu_mon_opts = { + .name = "mon", + .implied_opt_name = "chardev", + .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head), + .desc = { + { + .name = "mode", + .type = QEMU_OPT_STRING, + },{ + .name = "chardev", + .type = QEMU_OPT_STRING, + },{ + .name = "default", + .type = QEMU_OPT_BOOL, + },{ + .name = "pretty", + .type = QEMU_OPT_BOOL, + }, + { /* end of list */ } + }, +}; @@ -1054,3 +1054,29 @@ unsigned compute_mcast_idx(const uint8_t *ep) } return crc >> 26; } + +QemuOptsList qemu_netdev_opts = { + .name = "netdev", + .implied_opt_name = "type", + .head = QTAILQ_HEAD_INITIALIZER(qemu_netdev_opts.head), + .desc = { + /* + * no elements => accept any params + * validation will happen later + */ + { /* end of list */ } + }, +}; + +QemuOptsList qemu_net_opts = { + .name = "net", + .implied_opt_name = "type", + .head = QTAILQ_HEAD_INITIALIZER(qemu_net_opts.head), + .desc = { + /* + * no elements => accept any params + * validation will happen later + */ + { /* end of list */ } + }, +}; diff --git a/pci-ids.txt b/pci-ids.txt deleted file mode 100644 index 73125a8bd7..0000000000 --- a/pci-ids.txt +++ /dev/null @@ -1,31 +0,0 @@ - -PCI IDs for qemu -================ - -Red Hat, Inc. donates a part of its device ID range to qemu, to be used for -virtual devices. The vendor ID is 1af4 (formerly Qumranet ID). - -The 1000 -> 10ff device ID range is used for VirtIO devices. - -The 1100 device ID is used as PCI Subsystem ID for existing hardware -devices emulated by qemu. - -All other device IDs are reserved. - - -VirtIO Device IDs ------------------ - -1af4:1000 network device -1af4:1001 block device -1af4:1002 balloon device -1af4:1003 console device - -1af4:1004 Reserved. - to Contact Gerd Hoffmann <kraxel@redhat.com> to get a -1af4:10ef device ID assigned for your new virtio device. - -1af4:10f0 Available for experimental usage without registration. Must get - to official ID when the code leaves the test lab (i.e. when seeking -1af4:10ff upstream merge or shipping a distro/product) to avoid conflicts. - diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index f9bd3b9910..1f9c97342c 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -1,5 +1,5 @@ -qapi-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o -qapi-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o -qapi-obj-y += string-input-visitor.o string-output-visitor.o +util-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o +util-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o +util-obj-y += string-input-visitor.o string-output-visitor.o -common-obj-y += opts-visitor.o +util-obj-y += opts-visitor.o diff --git a/qemu-char.c b/qemu-char.c index f41788c9ef..3be4970423 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2924,3 +2924,75 @@ CharDriverState *qemu_char_get_next_serial(void) return serial_hds[next_serial++]; } +QemuOptsList qemu_chardev_opts = { + .name = "chardev", + .implied_opt_name = "backend", + .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head), + .desc = { + { + .name = "backend", + .type = QEMU_OPT_STRING, + },{ + .name = "path", + .type = QEMU_OPT_STRING, + },{ + .name = "host", + .type = QEMU_OPT_STRING, + },{ + .name = "port", + .type = QEMU_OPT_STRING, + },{ + .name = "localaddr", + .type = QEMU_OPT_STRING, + },{ + .name = "localport", + .type = QEMU_OPT_STRING, + },{ + .name = "to", + .type = QEMU_OPT_NUMBER, + },{ + .name = "ipv4", + .type = QEMU_OPT_BOOL, + },{ + .name = "ipv6", + .type = QEMU_OPT_BOOL, + },{ + .name = "wait", + .type = QEMU_OPT_BOOL, + },{ + .name = "server", + .type = QEMU_OPT_BOOL, + },{ + .name = "delay", + .type = QEMU_OPT_BOOL, + },{ + .name = "telnet", + .type = QEMU_OPT_BOOL, + },{ + .name = "width", + .type = QEMU_OPT_NUMBER, + },{ + .name = "height", + .type = QEMU_OPT_NUMBER, + },{ + .name = "cols", + .type = QEMU_OPT_NUMBER, + },{ + .name = "rows", + .type = QEMU_OPT_NUMBER, + },{ + .name = "mux", + .type = QEMU_OPT_BOOL, + },{ + .name = "signal", + .type = QEMU_OPT_BOOL, + },{ + .name = "name", + .type = QEMU_OPT_STRING, + },{ + .name = "debug", + .type = QEMU_OPT_NUMBER, + }, + { /* end of list */ } + }, +}; diff --git a/qemu-config.c b/qemu-config.c deleted file mode 100644 index 2188c3e5ec..0000000000 --- a/qemu-config.c +++ /dev/null @@ -1,894 +0,0 @@ -#include "qemu-common.h" -#include "qemu/error-report.h" -#include "qemu/option.h" -#include "qemu/config-file.h" -#include "hw/qdev.h" -#include "qapi/error.h" - -static QemuOptsList qemu_drive_opts = { - .name = "drive", - .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head), - .desc = { - { - .name = "bus", - .type = QEMU_OPT_NUMBER, - .help = "bus number", - },{ - .name = "unit", - .type = QEMU_OPT_NUMBER, - .help = "unit number (i.e. lun for scsi)", - },{ - .name = "if", - .type = QEMU_OPT_STRING, - .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)", - },{ - .name = "index", - .type = QEMU_OPT_NUMBER, - .help = "index number", - },{ - .name = "cyls", - .type = QEMU_OPT_NUMBER, - .help = "number of cylinders (ide disk geometry)", - },{ - .name = "heads", - .type = QEMU_OPT_NUMBER, - .help = "number of heads (ide disk geometry)", - },{ - .name = "secs", - .type = QEMU_OPT_NUMBER, - .help = "number of sectors (ide disk geometry)", - },{ - .name = "trans", - .type = QEMU_OPT_STRING, - .help = "chs translation (auto, lba. none)", - },{ - .name = "media", - .type = QEMU_OPT_STRING, - .help = "media type (disk, cdrom)", - },{ - .name = "snapshot", - .type = QEMU_OPT_BOOL, - .help = "enable/disable snapshot mode", - },{ - .name = "file", - .type = QEMU_OPT_STRING, - .help = "disk image", - },{ - .name = "cache", - .type = QEMU_OPT_STRING, - .help = "host cache usage (none, writeback, writethrough, " - "directsync, unsafe)", - },{ - .name = "aio", - .type = QEMU_OPT_STRING, - .help = "host AIO implementation (threads, native)", - },{ - .name = "format", - .type = QEMU_OPT_STRING, - .help = "disk format (raw, qcow2, ...)", - },{ - .name = "serial", - .type = QEMU_OPT_STRING, - .help = "disk serial number", - },{ - .name = "rerror", - .type = QEMU_OPT_STRING, - .help = "read error action", - },{ - .name = "werror", - .type = QEMU_OPT_STRING, - .help = "write error action", - },{ - .name = "addr", - .type = QEMU_OPT_STRING, - .help = "pci address (virtio only)", - },{ - .name = "readonly", - .type = QEMU_OPT_BOOL, - .help = "open drive file as read-only", - },{ - .name = "iops", - .type = QEMU_OPT_NUMBER, - .help = "limit total I/O operations per second", - },{ - .name = "iops_rd", - .type = QEMU_OPT_NUMBER, - .help = "limit read operations per second", - },{ - .name = "iops_wr", - .type = QEMU_OPT_NUMBER, - .help = "limit write operations per second", - },{ - .name = "bps", - .type = QEMU_OPT_NUMBER, - .help = "limit total bytes per second", - },{ - .name = "bps_rd", - .type = QEMU_OPT_NUMBER, - .help = "limit read bytes per second", - },{ - .name = "bps_wr", - .type = QEMU_OPT_NUMBER, - .help = "limit write bytes per second", - },{ - .name = "copy-on-read", - .type = QEMU_OPT_BOOL, - .help = "copy read data from backing file into image file", - },{ - .name = "boot", - .type = QEMU_OPT_BOOL, - .help = "(deprecated, ignored)", - }, - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_iscsi_opts = { - .name = "iscsi", - .head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head), - .desc = { - { - .name = "user", - .type = QEMU_OPT_STRING, - .help = "username for CHAP authentication to target", - },{ - .name = "password", - .type = QEMU_OPT_STRING, - .help = "password for CHAP authentication to target", - },{ - .name = "header-digest", - .type = QEMU_OPT_STRING, - .help = "HeaderDigest setting. " - "{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}", - },{ - .name = "initiator-name", - .type = QEMU_OPT_STRING, - .help = "Initiator iqn name to use when connecting", - }, - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_chardev_opts = { - .name = "chardev", - .implied_opt_name = "backend", - .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head), - .desc = { - { - .name = "backend", - .type = QEMU_OPT_STRING, - },{ - .name = "path", - .type = QEMU_OPT_STRING, - },{ - .name = "host", - .type = QEMU_OPT_STRING, - },{ - .name = "port", - .type = QEMU_OPT_STRING, - },{ - .name = "localaddr", - .type = QEMU_OPT_STRING, - },{ - .name = "localport", - .type = QEMU_OPT_STRING, - },{ - .name = "to", - .type = QEMU_OPT_NUMBER, - },{ - .name = "ipv4", - .type = QEMU_OPT_BOOL, - },{ - .name = "ipv6", - .type = QEMU_OPT_BOOL, - },{ - .name = "wait", - .type = QEMU_OPT_BOOL, - },{ - .name = "server", - .type = QEMU_OPT_BOOL, - },{ - .name = "delay", - .type = QEMU_OPT_BOOL, - },{ - .name = "telnet", - .type = QEMU_OPT_BOOL, - },{ - .name = "width", - .type = QEMU_OPT_NUMBER, - },{ - .name = "height", - .type = QEMU_OPT_NUMBER, - },{ - .name = "cols", - .type = QEMU_OPT_NUMBER, - },{ - .name = "rows", - .type = QEMU_OPT_NUMBER, - },{ - .name = "mux", - .type = QEMU_OPT_BOOL, - },{ - .name = "signal", - .type = QEMU_OPT_BOOL, - },{ - .name = "name", - .type = QEMU_OPT_STRING, - },{ - .name = "debug", - .type = QEMU_OPT_NUMBER, - }, - { /* end of list */ } - }, -}; - -QemuOptsList qemu_fsdev_opts = { - .name = "fsdev", - .implied_opt_name = "fsdriver", - .head = QTAILQ_HEAD_INITIALIZER(qemu_fsdev_opts.head), - .desc = { - { - .name = "fsdriver", - .type = QEMU_OPT_STRING, - }, { - .name = "path", - .type = QEMU_OPT_STRING, - }, { - .name = "security_model", - .type = QEMU_OPT_STRING, - }, { - .name = "writeout", - .type = QEMU_OPT_STRING, - }, { - .name = "readonly", - .type = QEMU_OPT_BOOL, - - }, { - .name = "socket", - .type = QEMU_OPT_STRING, - }, { - .name = "sock_fd", - .type = QEMU_OPT_NUMBER, - }, - - { /*End of list */ } - }, -}; - -QemuOptsList qemu_virtfs_opts = { - .name = "virtfs", - .implied_opt_name = "fsdriver", - .head = QTAILQ_HEAD_INITIALIZER(qemu_virtfs_opts.head), - .desc = { - { - .name = "fsdriver", - .type = QEMU_OPT_STRING, - }, { - .name = "path", - .type = QEMU_OPT_STRING, - }, { - .name = "mount_tag", - .type = QEMU_OPT_STRING, - }, { - .name = "security_model", - .type = QEMU_OPT_STRING, - }, { - .name = "writeout", - .type = QEMU_OPT_STRING, - }, { - .name = "readonly", - .type = QEMU_OPT_BOOL, - }, { - .name = "socket", - .type = QEMU_OPT_STRING, - }, { - .name = "sock_fd", - .type = QEMU_OPT_NUMBER, - }, - - { /*End of list */ } - }, -}; - -static QemuOptsList qemu_device_opts = { - .name = "device", - .implied_opt_name = "driver", - .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head), - .desc = { - /* - * no elements => accept any - * sanity checking will happen later - * when setting device properties - */ - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_netdev_opts = { - .name = "netdev", - .implied_opt_name = "type", - .head = QTAILQ_HEAD_INITIALIZER(qemu_netdev_opts.head), - .desc = { - /* - * no elements => accept any params - * validation will happen later - */ - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_net_opts = { - .name = "net", - .implied_opt_name = "type", - .head = QTAILQ_HEAD_INITIALIZER(qemu_net_opts.head), - .desc = { - /* - * no elements => accept any params - * validation will happen later - */ - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_rtc_opts = { - .name = "rtc", - .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head), - .desc = { - { - .name = "base", - .type = QEMU_OPT_STRING, - },{ - .name = "clock", - .type = QEMU_OPT_STRING, - },{ - .name = "driftfix", - .type = QEMU_OPT_STRING, - }, - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_global_opts = { - .name = "global", - .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head), - .desc = { - { - .name = "driver", - .type = QEMU_OPT_STRING, - },{ - .name = "property", - .type = QEMU_OPT_STRING, - },{ - .name = "value", - .type = QEMU_OPT_STRING, - }, - { /* end of list */ } - }, -}; - -QemuOptsList qemu_sandbox_opts = { - .name = "sandbox", - .implied_opt_name = "enable", - .head = QTAILQ_HEAD_INITIALIZER(qemu_sandbox_opts.head), - .desc = { - { - .name = "enable", - .type = QEMU_OPT_BOOL, - }, - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_mon_opts = { - .name = "mon", - .implied_opt_name = "chardev", - .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head), - .desc = { - { - .name = "mode", - .type = QEMU_OPT_STRING, - },{ - .name = "chardev", - .type = QEMU_OPT_STRING, - },{ - .name = "default", - .type = QEMU_OPT_BOOL, - },{ - .name = "pretty", - .type = QEMU_OPT_BOOL, - }, - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_trace_opts = { - .name = "trace", - .implied_opt_name = "trace", - .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head), - .desc = { - { - .name = "events", - .type = QEMU_OPT_STRING, - },{ - .name = "file", - .type = QEMU_OPT_STRING, - }, - { /* end of list */ } - }, -}; - -QemuOptsList qemu_spice_opts = { - .name = "spice", - .head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head), - .desc = { - { - .name = "port", - .type = QEMU_OPT_NUMBER, - },{ - .name = "tls-port", - .type = QEMU_OPT_NUMBER, - },{ - .name = "addr", - .type = QEMU_OPT_STRING, - },{ - .name = "ipv4", - .type = QEMU_OPT_BOOL, - },{ - .name = "ipv6", - .type = QEMU_OPT_BOOL, - },{ - .name = "password", - .type = QEMU_OPT_STRING, - },{ - .name = "disable-ticketing", - .type = QEMU_OPT_BOOL, - },{ - .name = "disable-copy-paste", - .type = QEMU_OPT_BOOL, - },{ - .name = "sasl", - .type = QEMU_OPT_BOOL, - },{ - .name = "x509-dir", - .type = QEMU_OPT_STRING, - },{ - .name = "x509-key-file", - .type = QEMU_OPT_STRING, - },{ - .name = "x509-key-password", - .type = QEMU_OPT_STRING, - },{ - .name = "x509-cert-file", - .type = QEMU_OPT_STRING, - },{ - .name = "x509-cacert-file", - .type = QEMU_OPT_STRING, - },{ - .name = "x509-dh-key-file", - .type = QEMU_OPT_STRING, - },{ - .name = "tls-ciphers", - .type = QEMU_OPT_STRING, - },{ - .name = "tls-channel", - .type = QEMU_OPT_STRING, - },{ - .name = "plaintext-channel", - .type = QEMU_OPT_STRING, - },{ - .name = "image-compression", - .type = QEMU_OPT_STRING, - },{ - .name = "jpeg-wan-compression", - .type = QEMU_OPT_STRING, - },{ - .name = "zlib-glz-wan-compression", - .type = QEMU_OPT_STRING, - },{ - .name = "streaming-video", - .type = QEMU_OPT_STRING, - },{ - .name = "agent-mouse", - .type = QEMU_OPT_BOOL, - },{ - .name = "playback-compression", - .type = QEMU_OPT_BOOL, - }, { - .name = "seamless-migration", - .type = QEMU_OPT_BOOL, - }, - { /* end of list */ } - }, -}; - -QemuOptsList qemu_option_rom_opts = { - .name = "option-rom", - .implied_opt_name = "romfile", - .head = QTAILQ_HEAD_INITIALIZER(qemu_option_rom_opts.head), - .desc = { - { - .name = "bootindex", - .type = QEMU_OPT_NUMBER, - }, { - .name = "romfile", - .type = QEMU_OPT_STRING, - }, - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_machine_opts = { - .name = "machine", - .implied_opt_name = "type", - .merge_lists = true, - .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head), - .desc = { - { - .name = "type", - .type = QEMU_OPT_STRING, - .help = "emulated machine" - }, { - .name = "accel", - .type = QEMU_OPT_STRING, - .help = "accelerator list", - }, { - .name = "kernel_irqchip", - .type = QEMU_OPT_BOOL, - .help = "use KVM in-kernel irqchip", - }, { - .name = "kvm_shadow_mem", - .type = QEMU_OPT_SIZE, - .help = "KVM shadow MMU size", - }, { - .name = "kernel", - .type = QEMU_OPT_STRING, - .help = "Linux kernel image file", - }, { - .name = "initrd", - .type = QEMU_OPT_STRING, - .help = "Linux initial ramdisk file", - }, { - .name = "append", - .type = QEMU_OPT_STRING, - .help = "Linux kernel command line", - }, { - .name = "dtb", - .type = QEMU_OPT_STRING, - .help = "Linux kernel device tree file", - }, { - .name = "dumpdtb", - .type = QEMU_OPT_STRING, - .help = "Dump current dtb to a file and quit", - }, { - .name = "phandle_start", - .type = QEMU_OPT_STRING, - .help = "The first phandle ID we may generate dynamically", - }, { - .name = "dt_compatible", - .type = QEMU_OPT_STRING, - .help = "Overrides the \"compatible\" property of the dt root node", - }, { - .name = "dump-guest-core", - .type = QEMU_OPT_BOOL, - .help = "Include guest memory in a core dump", - }, { - .name = "mem-merge", - .type = QEMU_OPT_BOOL, - .help = "enable/disable memory merge support", - },{ - .name = "usb", - .type = QEMU_OPT_BOOL, - .help = "Set on/off to enable/disable usb", - }, { - .name = "nvram", - .type = QEMU_OPT_STRING, - .help = "Drive backing persistent NVRAM", - }, - { /* End of list */ } - }, -}; - -QemuOptsList qemu_boot_opts = { - .name = "boot-opts", - .head = QTAILQ_HEAD_INITIALIZER(qemu_boot_opts.head), - .desc = { - /* the three names below are not used now */ - { - .name = "order", - .type = QEMU_OPT_STRING, - }, { - .name = "once", - .type = QEMU_OPT_STRING, - }, { - .name = "menu", - .type = QEMU_OPT_STRING, - /* following are really used */ - }, { - .name = "splash", - .type = QEMU_OPT_STRING, - }, { - .name = "splash-time", - .type = QEMU_OPT_STRING, - }, { - .name = "reboot-timeout", - .type = QEMU_OPT_STRING, - }, - { /*End of list */ } - }, -}; - -static QemuOptsList qemu_add_fd_opts = { - .name = "add-fd", - .head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head), - .desc = { - { - .name = "fd", - .type = QEMU_OPT_NUMBER, - .help = "file descriptor of which a duplicate is added to fd set", - },{ - .name = "set", - .type = QEMU_OPT_NUMBER, - .help = "ID of the fd set to add fd to", - },{ - .name = "opaque", - .type = QEMU_OPT_STRING, - .help = "free-form string used to describe fd", - }, - { /* end of list */ } - }, -}; - -static QemuOptsList qemu_object_opts = { - .name = "object", - .implied_opt_name = "qom-type", - .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head), - .desc = { - { } - }, -}; - -static QemuOptsList *vm_config_groups[32] = { - &qemu_drive_opts, - &qemu_chardev_opts, - &qemu_device_opts, - &qemu_netdev_opts, - &qemu_net_opts, - &qemu_rtc_opts, - &qemu_global_opts, - &qemu_mon_opts, - &qemu_trace_opts, - &qemu_option_rom_opts, - &qemu_machine_opts, - &qemu_boot_opts, - &qemu_iscsi_opts, - &qemu_sandbox_opts, - &qemu_add_fd_opts, - &qemu_object_opts, - NULL, -}; - -static QemuOptsList *find_list(QemuOptsList **lists, const char *group, - Error **errp) -{ - int i; - - for (i = 0; lists[i] != NULL; i++) { - if (strcmp(lists[i]->name, group) == 0) - break; - } - if (lists[i] == NULL) { - error_set(errp, QERR_INVALID_OPTION_GROUP, group); - } - return lists[i]; -} - -QemuOptsList *qemu_find_opts(const char *group) -{ - QemuOptsList *ret; - Error *local_err = NULL; - - ret = find_list(vm_config_groups, group, &local_err); - if (error_is_set(&local_err)) { - error_report("%s\n", error_get_pretty(local_err)); - error_free(local_err); - } - - return ret; -} - -QemuOptsList *qemu_find_opts_err(const char *group, Error **errp) -{ - return find_list(vm_config_groups, group, errp); -} - -void qemu_add_opts(QemuOptsList *list) -{ - int entries, i; - - entries = ARRAY_SIZE(vm_config_groups); - entries--; /* keep list NULL terminated */ - for (i = 0; i < entries; i++) { - if (vm_config_groups[i] == NULL) { - vm_config_groups[i] = list; - return; - } - } - fprintf(stderr, "ran out of space in vm_config_groups"); - abort(); -} - -int qemu_set_option(const char *str) -{ - char group[64], id[64], arg[64]; - QemuOptsList *list; - QemuOpts *opts; - int rc, offset; - - rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset); - if (rc < 3 || str[offset] != '=') { - error_report("can't parse: \"%s\"", str); - return -1; - } - - list = qemu_find_opts(group); - if (list == NULL) { - return -1; - } - - opts = qemu_opts_find(list, id); - if (!opts) { - error_report("there is no %s \"%s\" defined", - list->name, id); - return -1; - } - - if (qemu_opt_set(opts, arg, str+offset+1) == -1) { - return -1; - } - return 0; -} - -int qemu_global_option(const char *str) -{ - char driver[64], property[64]; - QemuOpts *opts; - int rc, offset; - - rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset); - if (rc < 2 || str[offset] != '=') { - error_report("can't parse: \"%s\"", str); - return -1; - } - - opts = qemu_opts_create_nofail(&qemu_global_opts); - qemu_opt_set(opts, "driver", driver); - qemu_opt_set(opts, "property", property); - qemu_opt_set(opts, "value", str+offset+1); - return 0; -} - -struct ConfigWriteData { - QemuOptsList *list; - FILE *fp; -}; - -static int config_write_opt(const char *name, const char *value, void *opaque) -{ - struct ConfigWriteData *data = opaque; - - fprintf(data->fp, " %s = \"%s\"\n", name, value); - return 0; -} - -static int config_write_opts(QemuOpts *opts, void *opaque) -{ - struct ConfigWriteData *data = opaque; - const char *id = qemu_opts_id(opts); - - if (id) { - fprintf(data->fp, "[%s \"%s\"]\n", data->list->name, id); - } else { - fprintf(data->fp, "[%s]\n", data->list->name); - } - qemu_opt_foreach(opts, config_write_opt, data, 0); - fprintf(data->fp, "\n"); - return 0; -} - -void qemu_config_write(FILE *fp) -{ - struct ConfigWriteData data = { .fp = fp }; - QemuOptsList **lists = vm_config_groups; - int i; - - fprintf(fp, "# qemu config file\n\n"); - for (i = 0; lists[i] != NULL; i++) { - data.list = lists[i]; - qemu_opts_foreach(data.list, config_write_opts, &data, 0); - } -} - -int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname) -{ - char line[1024], group[64], id[64], arg[64], value[1024]; - Location loc; - QemuOptsList *list = NULL; - Error *local_err = NULL; - QemuOpts *opts = NULL; - int res = -1, lno = 0; - - loc_push_none(&loc); - while (fgets(line, sizeof(line), fp) != NULL) { - loc_set_file(fname, ++lno); - if (line[0] == '\n') { - /* skip empty lines */ - continue; - } - if (line[0] == '#') { - /* comment */ - continue; - } - if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) { - /* group with id */ - list = find_list(lists, group, &local_err); - if (error_is_set(&local_err)) { - error_report("%s\n", error_get_pretty(local_err)); - error_free(local_err); - goto out; - } - opts = qemu_opts_create(list, id, 1, NULL); - continue; - } - if (sscanf(line, "[%63[^]]]", group) == 1) { - /* group without id */ - list = find_list(lists, group, &local_err); - if (error_is_set(&local_err)) { - error_report("%s\n", error_get_pretty(local_err)); - error_free(local_err); - goto out; - } - opts = qemu_opts_create_nofail(list); - continue; - } - if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) { - /* arg = value */ - if (opts == NULL) { - error_report("no group defined"); - goto out; - } - if (qemu_opt_set(opts, arg, value) != 0) { - goto out; - } - continue; - } - error_report("parse error"); - goto out; - } - if (ferror(fp)) { - error_report("error reading file"); - goto out; - } - res = 0; -out: - loc_pop(&loc); - return res; -} - -int qemu_read_config_file(const char *filename) -{ - FILE *f = fopen(filename, "r"); - int ret; - - if (f == NULL) { - return -errno; - } - - ret = qemu_config_parse(f, vm_config_groups, filename); - fclose(f); - - if (ret == 0) { - return 0; - } else { - return -EINVAL; - } -} diff --git a/qemu-tool.c b/qemu-tool.c deleted file mode 100644 index 1a474c45bc..0000000000 --- a/qemu-tool.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Compatibility for qemu-img/qemu-nbd - * - * Copyright IBM, Corp. 2008 - * - * Authors: - * Anthony Liguori <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. - */ - -#include "qemu-common.h" -#include "monitor/monitor.h" -#include "qemu/timer.h" -#include "qemu/log.h" -#include "migration/migration.h" -#include "qemu/main-loop.h" -#include "sysemu/sysemu.h" -#include "qemu/sockets.h" -#include "slirp/libslirp.h" - -#include <sys/time.h> - -struct QEMUBH -{ - QEMUBHFunc *cb; - void *opaque; -}; - -const char *qemu_get_vm_name(void) -{ - return NULL; -} - -Monitor *cur_mon; - -void vm_stop(RunState state) -{ - abort(); -} - -int monitor_cur_is_qmp(void) -{ - return 0; -} - -void monitor_set_error(Monitor *mon, QError *qerror) -{ -} - -void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) -{ -} - -void monitor_printf(Monitor *mon, const char *fmt, ...) -{ -} - -void monitor_print_filename(Monitor *mon, const char *filename) -{ -} - -void monitor_protocol_event(MonitorEvent event, QObject *data) -{ -} - -int64_t cpu_get_clock(void) -{ - return get_clock_realtime(); -} - -int64_t cpu_get_icount(void) -{ - abort(); -} - -void qemu_mutex_lock_iothread(void) -{ -} - -void qemu_mutex_unlock_iothread(void) -{ -} - -int use_icount; - -void qemu_clock_warp(QEMUClock *clock) -{ -} - -void slirp_update_timeout(uint32_t *timeout) -{ -} - -void slirp_select_fill(int *pnfds, fd_set *readfds, - fd_set *writefds, fd_set *xfds) -{ -} - -void slirp_select_poll(fd_set *readfds, fd_set *writefds, - fd_set *xfds, int select_error) -{ -} - -void migrate_add_blocker(Error *reason) -{ -} - -void migrate_del_blocker(Error *reason) -{ -} diff --git a/qemu-user.c b/qemu-user.c deleted file mode 100644 index f8b450c03d..0000000000 --- a/qemu-user.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Stubs for QEMU user emulation - * - * Copyright (c) 2012 SUSE LINUX Products GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see - * <http://www.gnu.org/licenses/gpl-2.0.html> - */ - -#include "qemu-common.h" -#include "monitor/monitor.h" - -Monitor *cur_mon; - -int monitor_cur_is_qmp(void) -{ - return 0; -} - -void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) -{ -} - -void monitor_set_error(Monitor *mon, QError *qerror) -{ -} diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs new file mode 100644 index 0000000000..c9ff59c6cc --- /dev/null +++ b/qobject/Makefile.objs @@ -0,0 +1,3 @@ +util-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o +util-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o +util-obj-y += qerror.o diff --git a/json-lexer.c b/qobject/json-lexer.c index 440df60392..440df60392 100644 --- a/json-lexer.c +++ b/qobject/json-lexer.c diff --git a/json-parser.c b/qobject/json-parser.c index 05279c11eb..05279c11eb 100644 --- a/json-parser.c +++ b/qobject/json-parser.c diff --git a/json-streamer.c b/qobject/json-streamer.c index 1b2f9b1d10..1b2f9b1d10 100644 --- a/json-streamer.c +++ b/qobject/json-streamer.c diff --git a/qbool.c b/qobject/qbool.c index a3d2afa827..a3d2afa827 100644 --- a/qbool.c +++ b/qobject/qbool.c diff --git a/qdict.c b/qobject/qdict.c index 7543ccc10f..7543ccc10f 100644 --- a/qdict.c +++ b/qobject/qdict.c diff --git a/qerror.c b/qobject/qerror.c index 3aee1cf6a6..3aee1cf6a6 100644 --- a/qerror.c +++ b/qobject/qerror.c diff --git a/qfloat.c b/qobject/qfloat.c index 7de0992dba..7de0992dba 100644 --- a/qfloat.c +++ b/qobject/qfloat.c diff --git a/qint.c b/qobject/qint.c index 86b9b04f0b..86b9b04f0b 100644 --- a/qint.c +++ b/qobject/qint.c diff --git a/qjson.c b/qobject/qjson.c index 83a6b4f7c1..83a6b4f7c1 100644 --- a/qjson.c +++ b/qobject/qjson.c diff --git a/qlist.c b/qobject/qlist.c index 1ced0de58e..1ced0de58e 100644 --- a/qlist.c +++ b/qobject/qlist.c diff --git a/qstring.c b/qobject/qstring.c index 5f7376c336..5f7376c336 100644 --- a/qstring.c +++ b/qobject/qstring.c diff --git a/qom/Makefile.objs b/qom/Makefile.objs index 5ef060a401..1899a4ce42 100644 --- a/qom/Makefile.objs +++ b/qom/Makefile.objs @@ -1,4 +1,2 @@ -qom-obj-y = object.o container.o qom-qobject.o -qom-obj-twice-y = cpu.o -common-obj-y = $(qom-obj-twice-y) -user-obj-y = $(qom-obj-twice-y) +universal-obj-y = object.o container.o qom-qobject.o +universal-obj-y += cpu.o @@ -21,11 +21,22 @@ QEMU_CFLAGS += -I$(<D) -I$(@D) $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," CC $(TARGET_DIR)$@") ifeq ($(LIBTOOL),) -%.lo: %.c - @echo "missing libtool. please install and rerun configure"; exit 1 +LIBTOOL = /bin/false +LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \ + $(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(version-obj-y) \ + $(LIBS)," LINK $(TARGET_DIR)$@") else +LIBTOOL += $(if $(V),,--quiet) %.lo: %.c - $(call quiet-command,$(LIBTOOL) --mode=compile --quiet --tag=CC $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," lt CC $@") + $(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," lt CC $@") +%.lo: %.dtrace + $(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC dtrace -o $@ -G -s $<, " lt GEN $(TARGET_DIR)$@") + +LINK = $(call quiet-command,\ + $(if $(filter %.lo %.la,$^),$(LIBTOOL) --mode=link --tag=CC \ + )$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \ + $(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(version-obj-y) \ + $(LIBS),$(if $(filter %.lo %.la,$^),"lt LINK ", " LINK ")"$(TARGET_DIR)$@") endif %.asm: %.S @@ -37,7 +48,8 @@ endif %.o: %.m $(call quiet-command,$(OBJCC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," OBJC $(TARGET_DIR)$@") -LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(LIBS)," LINK $(TARGET_DIR)$@") +%.o: %.dtrace + $(call quiet-command,dtrace -o $@ -G -s $<, " GEN $(TARGET_DIR)$@") %$(EXESUF): %.o $(call LINK,$^) diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 7672c69a29..a2603947db 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,11 +1,24 @@ stub-obj-y += arch-query-cpu-def.o +stub-obj-y += clock-warp.o +stub-obj-y += cpu-get-clock.o +stub-obj-y += cpu-get-icount.o stub-obj-y += fdset-add-fd.o stub-obj-y += fdset-find-fd.o stub-obj-y += fdset-get-fd.o stub-obj-y += fdset-remove-fd.o stub-obj-y += get-fd.o -stub-obj-y += set-fd-handler.o +stub-obj-y += get-vm-name.o +stub-obj-y += iothread-lock.o +stub-obj-y += migr-blocker.o +stub-obj-y += mon-is-qmp.o +stub-obj-y += mon-printf.o +stub-obj-y += mon-print-filename.o +stub-obj-y += mon-protocol-event.o +stub-obj-y += mon-set-error.o stub-obj-y += reset.o -stub-obj-y += vmstate.o +stub-obj-y += set-fd-handler.o +stub-obj-y += slirp.o stub-obj-y += sysbus.o +stub-obj-y += vm-stop.o +stub-obj-y += vmstate.o stub-obj-$(CONFIG_WIN32) += fd-register.o diff --git a/stubs/clock-warp.c b/stubs/clock-warp.c new file mode 100644 index 0000000000..b64c462e73 --- /dev/null +++ b/stubs/clock-warp.c @@ -0,0 +1,7 @@ +#include "qemu-common.h" +#include "qemu/timer.h" + +void qemu_clock_warp(QEMUClock *clock) +{ +} + diff --git a/stubs/cpu-get-clock.c b/stubs/cpu-get-clock.c new file mode 100644 index 0000000000..5b34c976d9 --- /dev/null +++ b/stubs/cpu-get-clock.c @@ -0,0 +1,7 @@ +#include "qemu-common.h" +#include "qemu/timer.h" + +int64_t cpu_get_clock(void) +{ + return get_clock_realtime(); +} diff --git a/stubs/cpu-get-icount.c b/stubs/cpu-get-icount.c new file mode 100644 index 0000000000..d68585965f --- /dev/null +++ b/stubs/cpu-get-icount.c @@ -0,0 +1,9 @@ +#include "qemu-common.h" +#include "qemu/timer.h" + +int use_icount; + +int64_t cpu_get_icount(void) +{ + abort(); +} diff --git a/stubs/get-vm-name.c b/stubs/get-vm-name.c new file mode 100644 index 0000000000..e5f619ffab --- /dev/null +++ b/stubs/get-vm-name.c @@ -0,0 +1,7 @@ +#include "qemu-common.h" + +const char *qemu_get_vm_name(void) +{ + return NULL; +} + diff --git a/stubs/iothread-lock.c b/stubs/iothread-lock.c new file mode 100644 index 0000000000..5d8aca1b37 --- /dev/null +++ b/stubs/iothread-lock.c @@ -0,0 +1,10 @@ +#include "qemu-common.h" +#include "qemu/main-loop.h" + +void qemu_mutex_lock_iothread(void) +{ +} + +void qemu_mutex_unlock_iothread(void) +{ +} diff --git a/stubs/migr-blocker.c b/stubs/migr-blocker.c new file mode 100644 index 0000000000..300df6e205 --- /dev/null +++ b/stubs/migr-blocker.c @@ -0,0 +1,10 @@ +#include "qemu-common.h" +#include "migration/migration.h" + +void migrate_add_blocker(Error *reason) +{ +} + +void migrate_del_blocker(Error *reason) +{ +} diff --git a/stubs/mon-is-qmp.c b/stubs/mon-is-qmp.c new file mode 100644 index 0000000000..1f0a8fd98a --- /dev/null +++ b/stubs/mon-is-qmp.c @@ -0,0 +1,7 @@ +#include "qemu-common.h" +#include "monitor/monitor.h" + +int monitor_cur_is_qmp(void) +{ + return 0; +} diff --git a/stubs/mon-print-filename.c b/stubs/mon-print-filename.c new file mode 100644 index 0000000000..9c939641ff --- /dev/null +++ b/stubs/mon-print-filename.c @@ -0,0 +1,6 @@ +#include "qemu-common.h" +#include "monitor/monitor.h" + +void monitor_print_filename(Monitor *mon, const char *filename) +{ +} diff --git a/stubs/mon-printf.c b/stubs/mon-printf.c new file mode 100644 index 0000000000..0ce2ca6925 --- /dev/null +++ b/stubs/mon-printf.c @@ -0,0 +1,10 @@ +#include "qemu-common.h" +#include "monitor/monitor.h" + +void monitor_printf(Monitor *mon, const char *fmt, ...) +{ +} + +void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) +{ +} diff --git a/stubs/mon-protocol-event.c b/stubs/mon-protocol-event.c new file mode 100644 index 0000000000..0946e94724 --- /dev/null +++ b/stubs/mon-protocol-event.c @@ -0,0 +1,6 @@ +#include "qemu-common.h" +#include "monitor/monitor.h" + +void monitor_protocol_event(MonitorEvent event, QObject *data) +{ +} diff --git a/stubs/mon-set-error.c b/stubs/mon-set-error.c new file mode 100644 index 0000000000..d0411f97fa --- /dev/null +++ b/stubs/mon-set-error.c @@ -0,0 +1,8 @@ +#include "qemu-common.h" +#include "monitor/monitor.h" + +Monitor *cur_mon; + +void monitor_set_error(Monitor *mon, QError *qerror) +{ +} diff --git a/stubs/slirp.c b/stubs/slirp.c new file mode 100644 index 0000000000..9a3309a2b9 --- /dev/null +++ b/stubs/slirp.c @@ -0,0 +1,17 @@ +#include "qemu-common.h" +#include "slirp/slirp.h" + +void slirp_update_timeout(uint32_t *timeout) +{ +} + +void slirp_select_fill(int *pnfds, fd_set *readfds, + fd_set *writefds, fd_set *xfds) +{ +} + +void slirp_select_poll(fd_set *readfds, fd_set *writefds, + fd_set *xfds, int select_error) +{ +} + diff --git a/stubs/vm-stop.c b/stubs/vm-stop.c new file mode 100644 index 0000000000..45689354f6 --- /dev/null +++ b/stubs/vm-stop.c @@ -0,0 +1,7 @@ +#include "qemu-common.h" +#include "sysemu/sysemu.h" + +void vm_stop(RunState state) +{ + abort(); +} diff --git a/target-i386/arch_memory_mapping.c b/target-i386/arch_memory_mapping.c index c6c7874474..844893f44d 100644 --- a/target-i386/arch_memory_mapping.c +++ b/target-i386/arch_memory_mapping.c @@ -115,7 +115,7 @@ static void walk_pde2(MemoryMappingList *list, hwaddr pde_start_addr, int32_t a20_mask, bool pse) { - hwaddr pde_addr, pte_start_addr, start_paddr; + hwaddr pde_addr, pte_start_addr, start_paddr, high_paddr; uint32_t pde; target_ulong line_addr, start_vaddr; int i; @@ -130,8 +130,13 @@ static void walk_pde2(MemoryMappingList *list, line_addr = (((unsigned int)i & 0x3ff) << 22); if ((pde & PG_PSE_MASK) && pse) { - /* 4 MB page */ - start_paddr = (pde & ~0x3fffff) | ((pde & 0x1fe000) << 19); + /* + * 4 MB page: + * bits 39:32 are bits 20:13 of the PDE + * bit3 31:22 are bits 31:22 of the PDE + */ + high_paddr = ((hwaddr)(pde & 0x1fe000) << 19); + start_paddr = (pde & ~0x3fffff) | high_paddr; if (cpu_physical_memory_is_io(start_paddr)) { /* I/O region */ continue; diff --git a/tests/Makefile b/tests/Makefile index b09a3437cd..d97a571c8b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -70,22 +70,20 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \ tests/test-qmp-commands.o tests/test-visitor-serialization.o -test-qapi-obj-y = $(qobject-obj-y) $(qapi-obj-y) qemu-tool.o -test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o -test-qapi-obj-y += module.o +test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o $(test-obj-y): QEMU_INCLUDES += -Itests -tests/check-qint$(EXESUF): tests/check-qint.o qint.o -tests/check-qstring$(EXESUF): tests/check-qstring.o qstring.o -tests/check-qdict$(EXESUF): tests/check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o -tests/check-qlist$(EXESUF): tests/check-qlist.o qlist.o qint.o -tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o -tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) qemu-tool.o -tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) iov.o libqemustub.a -tests/test-aio$(EXESUF): tests/test-aio.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) libqemustub.a -tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) libqemustub.a -tests/test-iov$(EXESUF): tests/test-iov.o iov.o +tests/check-qint$(EXESUF): tests/check-qint.o libqemuutil.a +tests/check-qstring$(EXESUF): tests/check-qstring.o libqemuutil.a +tests/check-qdict$(EXESUF): tests/check-qdict.o libqemuutil.a +tests/check-qlist$(EXESUF): tests/check-qlist.o libqemuutil.a +tests/check-qfloat$(EXESUF): tests/check-qfloat.o libqemuutil.a +tests/check-qjson$(EXESUF): tests/check-qjson.o libqemuutil.a libqemustub.a +tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil.a libqemustub.a +tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a libqemustub.a +tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(block-obj-y) libqemuutil.a libqemustub.a +tests/test-iov$(EXESUF): tests/test-iov.o libqemuutil.a tests/test-qapi-types.c tests/test-qapi-types.h :\ $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py @@ -98,18 +96,18 @@ $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@") -tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) -tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) -tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y) -tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y) -tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) -tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) -tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) +tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a +tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a +tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a +tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a +tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a +tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) qapi-types.o qapi-visit.o libqemuutil.a libqemustub.a +tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a -tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) -tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y) -tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y) -tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o $(trace-obj-y) +tests/rtc-test$(EXESUF): tests/rtc-test.o +tests/m48t59-test$(EXESUF): tests/m48t59-test.o +tests/fdc-test$(EXESUF): tests/fdc-test.o +tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o # QTest rules @@ -117,7 +115,7 @@ TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS))) QTEST_TARGETS=$(foreach TARGET,$(TARGETS), $(if $(check-qtest-$(TARGET)-y), $(TARGET),)) check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y)) -qtest-obj-y = tests/libqtest.o $(oslib-obj-y) libqemustub.a +qtest-obj-y = tests/libqtest.o libqemuutil.a libqemustub.a $(check-qtest-y): $(qtest-obj-y) .PHONY: check-help diff --git a/trace/Makefile.objs b/trace/Makefile.objs index b791723696..27fe26b5c2 100644 --- a/trace/Makefile.objs +++ b/trace/Makefile.objs @@ -1,12 +1,9 @@ # -*- mode: makefile -*- ###################################################################### -# Auto-generated tracing routines +# Auto-generated header for tracing routines -ifeq ($(TRACE_BACKEND),dtrace) -TRACE_H_EXTRA_DEPS=$(obj)/generated-tracers-dtrace.h -endif -$(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp $(TRACE_H_EXTRA_DEPS) +$(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=h \ @@ -14,6 +11,10 @@ $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) +###################################################################### +# Auto-generated tracing routines (non-DTrace) + +ifneq ($(TRACE_BACKEND),dtrace) $(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp $(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ @@ -23,9 +24,6 @@ $(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) $(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.h - -ifneq ($(TRACE_BACKEND),dtrace) -trace-obj-y += generated-tracers.o endif @@ -35,36 +33,26 @@ endif # Normal practice is to name DTrace probe file with a '.d' extension # but that gets picked up by QEMU's Makefile as an external dependency # rule file. So we use '.dtrace' instead -$(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp -$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak +ifeq ($(TRACE_BACKEND),dtrace) +$(obj)/generated-tracers.dtrace: $(obj)/generated-tracers.dtrace-timestamp +$(obj)/generated-tracers.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=d \ --backend=$(TRACE_BACKEND) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) -$(obj)/generated-tracers-dtrace.h: trace/generated-tracers-dtrace.dtrace +$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers.dtrace $(call quiet-command,dtrace -o $@ -h -s $<, " GEN $@") -$(obj)/generated-tracers-dtrace.o: trace/generated-tracers-dtrace.dtrace - $(call quiet-command,dtrace -o $@ -G -s $<, " GEN $@") - -trace-obj-$(CONFIG_TRACE_DTRACE) += generated-tracers-dtrace.o - - -ifeq ($(LIBTOOL),) -$(obj)/generated-tracers-dtrace.lo: $(obj)/generated-tracers-dtrace.dtrace - @echo "missing libtool. please install and rerun configure."; exit 1 -else -$(obj)/generated-tracers-dtrace.lo: $(obj)/generated-tracers-dtrace.dtrace - $(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC dtrace -o $@ -G -s $<, " lt GEN $@") +$(obj)/generated-tracers.o: $(obj)/generated-tracers.dtrace endif - ###################################################################### # Backend code -trace-obj-$(CONFIG_TRACE_DEFAULT) += default.o -trace-obj-$(CONFIG_TRACE_SIMPLE) += simple.o -trace-obj-$(CONFIG_TRACE_STDERR) += stderr.o -trace-obj-y += control.o +util-obj-$(CONFIG_TRACE_DEFAULT) += default.o +util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o +util-obj-$(CONFIG_TRACE_STDERR) += stderr.o +util-obj-y += control.o +util-obj-y += generated-tracers.o diff --git a/ui/spice-core.c b/ui/spice-core.c index d83de2a46e..3f2c5650cd 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -417,6 +417,90 @@ static SpiceChannelList *qmp_query_spice_channels(void) return head; } +static QemuOptsList qemu_spice_opts = { + .name = "spice", + .head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head), + .desc = { + { + .name = "port", + .type = QEMU_OPT_NUMBER, + },{ + .name = "tls-port", + .type = QEMU_OPT_NUMBER, + },{ + .name = "addr", + .type = QEMU_OPT_STRING, + },{ + .name = "ipv4", + .type = QEMU_OPT_BOOL, + },{ + .name = "ipv6", + .type = QEMU_OPT_BOOL, + },{ + .name = "password", + .type = QEMU_OPT_STRING, + },{ + .name = "disable-ticketing", + .type = QEMU_OPT_BOOL, + },{ + .name = "disable-copy-paste", + .type = QEMU_OPT_BOOL, + },{ + .name = "sasl", + .type = QEMU_OPT_BOOL, + },{ + .name = "x509-dir", + .type = QEMU_OPT_STRING, + },{ + .name = "x509-key-file", + .type = QEMU_OPT_STRING, + },{ + .name = "x509-key-password", + .type = QEMU_OPT_STRING, + },{ + .name = "x509-cert-file", + .type = QEMU_OPT_STRING, + },{ + .name = "x509-cacert-file", + .type = QEMU_OPT_STRING, + },{ + .name = "x509-dh-key-file", + .type = QEMU_OPT_STRING, + },{ + .name = "tls-ciphers", + .type = QEMU_OPT_STRING, + },{ + .name = "tls-channel", + .type = QEMU_OPT_STRING, + },{ + .name = "plaintext-channel", + .type = QEMU_OPT_STRING, + },{ + .name = "image-compression", + .type = QEMU_OPT_STRING, + },{ + .name = "jpeg-wan-compression", + .type = QEMU_OPT_STRING, + },{ + .name = "zlib-glz-wan-compression", + .type = QEMU_OPT_STRING, + },{ + .name = "streaming-video", + .type = QEMU_OPT_STRING, + },{ + .name = "agent-mouse", + .type = QEMU_OPT_BOOL, + },{ + .name = "playback-compression", + .type = QEMU_OPT_BOOL, + }, { + .name = "seamless-migration", + .type = QEMU_OPT_BOOL, + }, + { /* end of list */ } + }, +}; + SpiceInfo *qmp_query_spice(Error **errp) { QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head); diff --git a/util/Makefile.objs b/util/Makefile.objs new file mode 100644 index 0000000000..5baeb53af6 --- /dev/null +++ b/util/Makefile.objs @@ -0,0 +1,10 @@ +util-obj-y = osdep.o cutils.o qemu-timer-common.o +util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o event_notifier-win32.o +util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o +util-obj-y += envlist.o path.o host-utils.o cache-utils.o module.o +util-obj-y += bitmap.o bitops.o +util-obj-y += acl.o +util-obj-y += error.o qemu-error.o +util-obj-$(CONFIG_POSIX) += compatfd.o +util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o +util-obj-y += qemu-option.o qemu-progress.o diff --git a/bitmap.c b/util/bitmap.c index 687841dcec..687841dcec 100644 --- a/bitmap.c +++ b/util/bitmap.c diff --git a/bitops.c b/util/bitops.c index 4c3a836a01..4c3a836a01 100644 --- a/bitops.c +++ b/util/bitops.c diff --git a/cache-utils.c b/util/cache-utils.c index b94013a8cb..b94013a8cb 100644 --- a/cache-utils.c +++ b/util/cache-utils.c diff --git a/compatfd.c b/util/compatfd.c index 9cf3f2834d..9cf3f2834d 100644 --- a/compatfd.c +++ b/util/compatfd.c diff --git a/cutils.c b/util/cutils.c index 80bb1dcbf7..80bb1dcbf7 100644 --- a/cutils.c +++ b/util/cutils.c diff --git a/envlist.c b/util/envlist.c index ff99fc44e9..ff99fc44e9 100644 --- a/envlist.c +++ b/util/envlist.c diff --git a/error.c b/util/error.c index 519f6b6ce0..519f6b6ce0 100644 --- a/error.c +++ b/util/error.c diff --git a/event_notifier-posix.c b/util/event_notifier-posix.c index 713d7560d0..713d7560d0 100644 --- a/event_notifier-posix.c +++ b/util/event_notifier-posix.c diff --git a/event_notifier-win32.c b/util/event_notifier-win32.c index 6dbb530cfa..6dbb530cfa 100644 --- a/event_notifier-win32.c +++ b/util/event_notifier-win32.c diff --git a/host-utils.c b/util/host-utils.c index 5e3915abba..5e3915abba 100644 --- a/host-utils.c +++ b/util/host-utils.c diff --git a/module.c b/util/module.c index 7acc33d076..7acc33d076 100644 --- a/module.c +++ b/util/module.c diff --git a/notify.c b/util/notify.c index 7b7692acb2..7b7692acb2 100644 --- a/notify.c +++ b/util/notify.c diff --git a/osdep.c b/util/osdep.c index 5b51a0322e..5b51a0322e 100644 --- a/osdep.c +++ b/util/osdep.c diff --git a/oslib-posix.c b/util/oslib-posix.c index 4f5ec6788b..4f5ec6788b 100644 --- a/oslib-posix.c +++ b/util/oslib-posix.c diff --git a/oslib-win32.c b/util/oslib-win32.c index e7e283e875..e7e283e875 100644 --- a/oslib-win32.c +++ b/util/oslib-win32.c diff --git a/util/qemu-config.c b/util/qemu-config.c new file mode 100644 index 0000000000..47c81f72d3 --- /dev/null +++ b/util/qemu-config.c @@ -0,0 +1,215 @@ +#include "qemu-common.h" +#include "qemu/error-report.h" +#include "qemu/option.h" +#include "qemu/config-file.h" +#include "hw/qdev.h" +#include "qapi/error.h" + +static QemuOptsList *vm_config_groups[32]; + +static QemuOptsList *find_list(QemuOptsList **lists, const char *group, + Error **errp) +{ + int i; + + for (i = 0; lists[i] != NULL; i++) { + if (strcmp(lists[i]->name, group) == 0) + break; + } + if (lists[i] == NULL) { + error_set(errp, QERR_INVALID_OPTION_GROUP, group); + } + return lists[i]; +} + +QemuOptsList *qemu_find_opts(const char *group) +{ + QemuOptsList *ret; + Error *local_err = NULL; + + ret = find_list(vm_config_groups, group, &local_err); + if (error_is_set(&local_err)) { + error_report("%s\n", error_get_pretty(local_err)); + error_free(local_err); + } + + return ret; +} + +QemuOptsList *qemu_find_opts_err(const char *group, Error **errp) +{ + return find_list(vm_config_groups, group, errp); +} + +void qemu_add_opts(QemuOptsList *list) +{ + int entries, i; + + entries = ARRAY_SIZE(vm_config_groups); + entries--; /* keep list NULL terminated */ + for (i = 0; i < entries; i++) { + if (vm_config_groups[i] == NULL) { + vm_config_groups[i] = list; + return; + } + } + fprintf(stderr, "ran out of space in vm_config_groups"); + abort(); +} + +int qemu_set_option(const char *str) +{ + char group[64], id[64], arg[64]; + QemuOptsList *list; + QemuOpts *opts; + int rc, offset; + + rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset); + if (rc < 3 || str[offset] != '=') { + error_report("can't parse: \"%s\"", str); + return -1; + } + + list = qemu_find_opts(group); + if (list == NULL) { + return -1; + } + + opts = qemu_opts_find(list, id); + if (!opts) { + error_report("there is no %s \"%s\" defined", + list->name, id); + return -1; + } + + if (qemu_opt_set(opts, arg, str+offset+1) == -1) { + return -1; + } + return 0; +} + +struct ConfigWriteData { + QemuOptsList *list; + FILE *fp; +}; + +static int config_write_opt(const char *name, const char *value, void *opaque) +{ + struct ConfigWriteData *data = opaque; + + fprintf(data->fp, " %s = \"%s\"\n", name, value); + return 0; +} + +static int config_write_opts(QemuOpts *opts, void *opaque) +{ + struct ConfigWriteData *data = opaque; + const char *id = qemu_opts_id(opts); + + if (id) { + fprintf(data->fp, "[%s \"%s\"]\n", data->list->name, id); + } else { + fprintf(data->fp, "[%s]\n", data->list->name); + } + qemu_opt_foreach(opts, config_write_opt, data, 0); + fprintf(data->fp, "\n"); + return 0; +} + +void qemu_config_write(FILE *fp) +{ + struct ConfigWriteData data = { .fp = fp }; + QemuOptsList **lists = vm_config_groups; + int i; + + fprintf(fp, "# qemu config file\n\n"); + for (i = 0; lists[i] != NULL; i++) { + data.list = lists[i]; + qemu_opts_foreach(data.list, config_write_opts, &data, 0); + } +} + +int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname) +{ + char line[1024], group[64], id[64], arg[64], value[1024]; + Location loc; + QemuOptsList *list = NULL; + Error *local_err = NULL; + QemuOpts *opts = NULL; + int res = -1, lno = 0; + + loc_push_none(&loc); + while (fgets(line, sizeof(line), fp) != NULL) { + loc_set_file(fname, ++lno); + if (line[0] == '\n') { + /* skip empty lines */ + continue; + } + if (line[0] == '#') { + /* comment */ + continue; + } + if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) { + /* group with id */ + list = find_list(lists, group, &local_err); + if (error_is_set(&local_err)) { + error_report("%s\n", error_get_pretty(local_err)); + error_free(local_err); + goto out; + } + opts = qemu_opts_create(list, id, 1, NULL); + continue; + } + if (sscanf(line, "[%63[^]]]", group) == 1) { + /* group without id */ + list = find_list(lists, group, &local_err); + if (error_is_set(&local_err)) { + error_report("%s\n", error_get_pretty(local_err)); + error_free(local_err); + goto out; + } + opts = qemu_opts_create_nofail(list); + continue; + } + if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) { + /* arg = value */ + if (opts == NULL) { + error_report("no group defined"); + goto out; + } + if (qemu_opt_set(opts, arg, value) != 0) { + goto out; + } + continue; + } + error_report("parse error"); + goto out; + } + if (ferror(fp)) { + error_report("error reading file"); + goto out; + } + res = 0; +out: + loc_pop(&loc); + return res; +} + +int qemu_read_config_file(const char *filename) +{ + FILE *f = fopen(filename, "r"); + int ret; + + if (f == NULL) { + return -errno; + } + + ret = qemu_config_parse(f, vm_config_groups, filename); + fclose(f); + + if (ret == 0) { + return 0; + } else { + return -EINVAL; + } +} diff --git a/qemu-error.c b/util/qemu-error.c index 08a36f480c..08a36f480c 100644 --- a/qemu-error.c +++ b/util/qemu-error.c diff --git a/qemu-option.c b/util/qemu-option.c index f532b765a0..f532b765a0 100644 --- a/qemu-option.c +++ b/util/qemu-option.c diff --git a/qemu-progress.c b/util/qemu-progress.c index 9a3f96cd47..9a3f96cd47 100644 --- a/qemu-progress.c +++ b/util/qemu-progress.c diff --git a/qemu-sockets.c b/util/qemu-sockets.c index 3537bf3d45..3537bf3d45 100644 --- a/qemu-sockets.c +++ b/util/qemu-sockets.c diff --git a/qemu-thread-posix.c b/util/qemu-thread-posix.c index 4489abf1d8..4489abf1d8 100644 --- a/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c diff --git a/qemu-thread-win32.c b/util/qemu-thread-win32.c index 517878dcc1..517878dcc1 100644 --- a/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c diff --git a/qemu-timer-common.c b/util/qemu-timer-common.c index 16f5e758b2..16f5e758b2 100644 --- a/qemu-timer-common.c +++ b/util/qemu-timer-common.c @@ -299,6 +299,195 @@ static struct { { .driver = "qxl-vga", .flag = &default_vga }, }; +static QemuOptsList qemu_rtc_opts = { + .name = "rtc", + .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head), + .desc = { + { + .name = "base", + .type = QEMU_OPT_STRING, + },{ + .name = "clock", + .type = QEMU_OPT_STRING, + },{ + .name = "driftfix", + .type = QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +static QemuOptsList qemu_sandbox_opts = { + .name = "sandbox", + .implied_opt_name = "enable", + .head = QTAILQ_HEAD_INITIALIZER(qemu_sandbox_opts.head), + .desc = { + { + .name = "enable", + .type = QEMU_OPT_BOOL, + }, + { /* end of list */ } + }, +}; + +static QemuOptsList qemu_trace_opts = { + .name = "trace", + .implied_opt_name = "trace", + .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head), + .desc = { + { + .name = "events", + .type = QEMU_OPT_STRING, + },{ + .name = "file", + .type = QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +static QemuOptsList qemu_option_rom_opts = { + .name = "option-rom", + .implied_opt_name = "romfile", + .head = QTAILQ_HEAD_INITIALIZER(qemu_option_rom_opts.head), + .desc = { + { + .name = "bootindex", + .type = QEMU_OPT_NUMBER, + }, { + .name = "romfile", + .type = QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +static QemuOptsList qemu_machine_opts = { + .name = "machine", + .implied_opt_name = "type", + .merge_lists = true, + .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head), + .desc = { + { + .name = "type", + .type = QEMU_OPT_STRING, + .help = "emulated machine" + }, { + .name = "accel", + .type = QEMU_OPT_STRING, + .help = "accelerator list", + }, { + .name = "kernel_irqchip", + .type = QEMU_OPT_BOOL, + .help = "use KVM in-kernel irqchip", + }, { + .name = "kvm_shadow_mem", + .type = QEMU_OPT_SIZE, + .help = "KVM shadow MMU size", + }, { + .name = "kernel", + .type = QEMU_OPT_STRING, + .help = "Linux kernel image file", + }, { + .name = "initrd", + .type = QEMU_OPT_STRING, + .help = "Linux initial ramdisk file", + }, { + .name = "append", + .type = QEMU_OPT_STRING, + .help = "Linux kernel command line", + }, { + .name = "dtb", + .type = QEMU_OPT_STRING, + .help = "Linux kernel device tree file", + }, { + .name = "dumpdtb", + .type = QEMU_OPT_STRING, + .help = "Dump current dtb to a file and quit", + }, { + .name = "phandle_start", + .type = QEMU_OPT_STRING, + .help = "The first phandle ID we may generate dynamically", + }, { + .name = "dt_compatible", + .type = QEMU_OPT_STRING, + .help = "Overrides the \"compatible\" property of the dt root node", + }, { + .name = "dump-guest-core", + .type = QEMU_OPT_BOOL, + .help = "Include guest memory in a core dump", + }, { + .name = "mem-merge", + .type = QEMU_OPT_BOOL, + .help = "enable/disable memory merge support", + },{ + .name = "usb", + .type = QEMU_OPT_BOOL, + .help = "Set on/off to enable/disable usb", + }, + { /* End of list */ } + }, +}; + +static QemuOptsList qemu_boot_opts = { + .name = "boot-opts", + .head = QTAILQ_HEAD_INITIALIZER(qemu_boot_opts.head), + .desc = { + /* the three names below are not used now */ + { + .name = "order", + .type = QEMU_OPT_STRING, + }, { + .name = "once", + .type = QEMU_OPT_STRING, + }, { + .name = "menu", + .type = QEMU_OPT_STRING, + /* following are really used */ + }, { + .name = "splash", + .type = QEMU_OPT_STRING, + }, { + .name = "splash-time", + .type = QEMU_OPT_STRING, + }, { + .name = "reboot-timeout", + .type = QEMU_OPT_STRING, + }, + { /*End of list */ } + }, +}; + +static QemuOptsList qemu_add_fd_opts = { + .name = "add-fd", + .head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head), + .desc = { + { + .name = "fd", + .type = QEMU_OPT_NUMBER, + .help = "file descriptor of which a duplicate is added to fd set", + },{ + .name = "set", + .type = QEMU_OPT_NUMBER, + .help = "ID of the fd set to add fd to", + },{ + .name = "opaque", + .type = QEMU_OPT_STRING, + .help = "free-form string used to describe fd", + }, + { /* end of list */ } + }, +}; + +static QemuOptsList qemu_object_opts = { + .name = "object", + .implied_opt_name = "qom-type", + .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head), + .desc = { + { } + }, +}; + const char *qemu_get_vm_name(void) { return qemu_name; @@ -2566,6 +2755,22 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_QOM); + qemu_add_opts(&qemu_drive_opts); + qemu_add_opts(&qemu_chardev_opts); + qemu_add_opts(&qemu_device_opts); + qemu_add_opts(&qemu_netdev_opts); + qemu_add_opts(&qemu_net_opts); + qemu_add_opts(&qemu_rtc_opts); + qemu_add_opts(&qemu_global_opts); + qemu_add_opts(&qemu_mon_opts); + qemu_add_opts(&qemu_trace_opts); + qemu_add_opts(&qemu_option_rom_opts); + qemu_add_opts(&qemu_machine_opts); + qemu_add_opts(&qemu_boot_opts); + qemu_add_opts(&qemu_sandbox_opts); + qemu_add_opts(&qemu_add_fd_opts); + qemu_add_opts(&qemu_object_opts); + runstate_init(); init_clocks(); |