]> git.proxmox.com Git - mirror_qemu.git/commitdiff
Merge remote-tracking branch 'remotes/vivier/tags/q800-for-5.0-pull-request' into...
authorPeter Maydell <peter.maydell@linaro.org>
Thu, 12 Mar 2020 16:00:31 +0000 (16:00 +0000)
committerPeter Maydell <peter.maydell@linaro.org>
Thu, 12 Mar 2020 16:00:31 +0000 (16:00 +0000)
Fix Coverity CID 1412799 (Error handling issues)

# gpg: Signature made Thu 12 Mar 2020 15:15:01 GMT
# gpg:                using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg:                issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier/tags/q800-for-5.0-pull-request:
  q800: fix coverity warning CID 1412799

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
318 files changed:
.gitignore
.travis.yml
MAINTAINERS
Makefile
Makefile.objs
block.c
block/Makefile.objs
block/backup-top.c
block/backup.c
block/block-copy.c
block/crypto.c
block/curl.c
block/file-posix.c
block/monitor/Makefile.objs [new file with mode: 0644]
block/monitor/block-hmp-cmds.c [new file with mode: 0644]
block/qapi-sysemu.c [new file with mode: 0644]
block/qcow2-cluster.c
block/qcow2-threads.c
block/qcow2.c
block/rbd.c
block/stream.c
block/trace-events
blockdev-nbd.c
blockdev.c
blockjob.c
chardev/char-pipe.c
chardev/char-win.c
chardev/char.c
configure
crypto/block.c
default-configs/i386-softmmu.mak
device-hotplug.c [deleted file]
docs/arm-cpu-features.rst [deleted file]
docs/can.txt
docs/conf.py
docs/defs.rst.inc [new file with mode: 0644]
docs/devel/atomics.txt
docs/devel/kconfig.rst
docs/devel/loads-stores.rst
docs/devel/multi-thread-tcg.txt
docs/devel/tcg.rst
docs/index.html.in
docs/index.rst
docs/qemu-cpu-models.texi [deleted file]
docs/qemu-option-trace.rst.inc
docs/replay.txt
docs/security.texi [deleted file]
docs/specs/fw_cfg.txt
docs/specs/ivshmem-spec.txt
docs/specs/tpm.rst
docs/sphinx/hxtool.py
docs/system/arm/cpu-features.rst [new file with mode: 0644]
docs/system/arm/integratorcp.rst [new file with mode: 0644]
docs/system/arm/musicpal.rst [new file with mode: 0644]
docs/system/arm/nseries.rst [new file with mode: 0644]
docs/system/arm/palm.rst [new file with mode: 0644]
docs/system/arm/realview.rst [new file with mode: 0644]
docs/system/arm/stellaris.rst [new file with mode: 0644]
docs/system/arm/sx1.rst [new file with mode: 0644]
docs/system/arm/versatile.rst [new file with mode: 0644]
docs/system/arm/xscale.rst [new file with mode: 0644]
docs/system/build-platforms.rst [new file with mode: 0644]
docs/system/conf.py
docs/system/cpu-models-mips.rst.inc [new file with mode: 0644]
docs/system/cpu-models-x86.rst.inc [new file with mode: 0644]
docs/system/deprecated.rst [new file with mode: 0644]
docs/system/device-url-syntax.rst.inc [new file with mode: 0644]
docs/system/gdb.rst [new file with mode: 0644]
docs/system/images.rst [new file with mode: 0644]
docs/system/index.rst
docs/system/invocation.rst [new file with mode: 0644]
docs/system/ivshmem.rst [new file with mode: 0644]
docs/system/keys.rst [new file with mode: 0644]
docs/system/keys.rst.inc [new file with mode: 0644]
docs/system/license.rst [new file with mode: 0644]
docs/system/linuxboot.rst [new file with mode: 0644]
docs/system/managed-startup.rst [new file with mode: 0644]
docs/system/monitor.rst [new file with mode: 0644]
docs/system/mux-chardev.rst [new file with mode: 0644]
docs/system/mux-chardev.rst.inc [new file with mode: 0644]
docs/system/net.rst [new file with mode: 0644]
docs/system/qemu-block-drivers.rst
docs/system/qemu-block-drivers.rst.inc [new file with mode: 0644]
docs/system/qemu-cpu-models.rst [new file with mode: 0644]
docs/system/qemu-manpage.rst [new file with mode: 0644]
docs/system/quickstart.rst [new file with mode: 0644]
docs/system/security.rst [new file with mode: 0644]
docs/system/target-arm.rst [new file with mode: 0644]
docs/system/target-i386-desc.rst.inc [new file with mode: 0644]
docs/system/target-i386.rst [new file with mode: 0644]
docs/system/target-m68k.rst [new file with mode: 0644]
docs/system/target-mips.rst [new file with mode: 0644]
docs/system/target-ppc.rst [new file with mode: 0644]
docs/system/target-sparc.rst [new file with mode: 0644]
docs/system/target-sparc64.rst [new file with mode: 0644]
docs/system/target-xtensa.rst [new file with mode: 0644]
docs/system/targets.rst [new file with mode: 0644]
docs/system/tls.rst [new file with mode: 0644]
docs/system/usb.rst [new file with mode: 0644]
docs/system/vnc-security.rst [new file with mode: 0644]
docs/user/conf.py [new file with mode: 0644]
docs/user/index.rst [new file with mode: 0644]
docs/user/main.rst [new file with mode: 0644]
fsdev/virtfs-proxy-helper.c
gdbstub.c
hmp-commands-info.hx
hmp-commands.hx
hw/9pfs/9p-proxy.c
hw/acpi/cpu_hotplug.c
hw/acpi/ich9.c
hw/acpi/piix4.c
hw/alpha/alpha_sys.h
hw/alpha/dp264.c
hw/arm/Kconfig
hw/arm/cubieboard.c
hw/arm/gumstix.c
hw/arm/mainstone.c
hw/arm/musicpal.c
hw/arm/omap_sx1.c
hw/arm/pxa2xx.c
hw/arm/smmu-common.c
hw/arm/spitz.c
hw/arm/strongarm.c
hw/arm/sysbus-fdt.c
hw/arm/virt.c
hw/arm/xlnx-versal-virt.c
hw/arm/xlnx-versal.c
hw/arm/z2.c
hw/audio/fmopl.c
hw/block/xen-block.c
hw/core/qdev.c
hw/display/exynos4210_fimd.c
hw/display/pxa2xx_lcd.c
hw/dma/xlnx-zdma.c
hw/hppa/machine.c
hw/i2c/smbus_ich9.c
hw/i386/Kconfig
hw/i386/acpi-build.c
hw/i386/intel_iommu.c
hw/i386/pc.c
hw/i386/pc_piix.c
hw/i386/pc_q35.c
hw/isa/lpc_ich9.c
hw/net/dp8393x.c
hw/net/e1000.c
hw/net/e1000e_core.c
hw/pci-bridge/pcie_root_port.c
hw/pci-bridge/xio3130_downstream.c
hw/pci-host/i440fx.c
hw/pci-host/q35.c
hw/pci/pcie.c
hw/pci/pcie_port.c
hw/rtc/twl92230.c
hw/s390x/ipl.c
hw/s390x/ipl.h
hw/scsi/scsi-disk.c
hw/timer/cadence_ttc.c
hw/timer/hpet.c
hw/tpm/Kconfig
hw/tpm/Makefile.objs
hw/tpm/tpm_tis.c [deleted file]
hw/tpm/tpm_tis.h [new file with mode: 0644]
hw/tpm/tpm_tis_common.c [new file with mode: 0644]
hw/tpm/tpm_tis_isa.c [new file with mode: 0644]
hw/tpm/tpm_tis_sysbus.c [new file with mode: 0644]
hw/usb/dev-serial.c
hw/usb/dev-storage.c
hw/usb/hcd-ehci.c
hw/virtio/vhost-vsock.c
hw/virtio/vhost.c
include/block/aio.h
include/block/block-copy.h
include/block/block-hmp-cmds.h [new file with mode: 0644]
include/block/block_int.h
include/block/nbd.h
include/crypto/block.h
include/hw/arm/xlnx-versal.h
include/hw/i386/ich9.h
include/hw/i386/intel_iommu.h
include/hw/i386/ioapic_internal.h
include/hw/i386/pc.h
include/hw/pci-host/q35.h
include/hw/pci/pcie.h
include/hw/pci/pcie_port.h
include/monitor/hmp.h
include/monitor/monitor.h
include/qemu/job.h
include/qemu/progress_meter.h [new file with mode: 0644]
include/qemu/queue.h
include/qom/object_interfaces.h
include/sysemu/arch_init.h
include/sysemu/blockdev.h
include/sysemu/sysemu.h
include/sysemu/tpm.h
job-qmp.c
job.c
monitor/Makefile.objs
monitor/hmp-cmds.c
monitor/hmp.c
monitor/misc.c
monitor/monitor.c
monitor/qmp-cmds.c
monitor/qmp.c
net/hub.c
net/hub.h
net/slirp.c
pc-bios/s390-ccw.img
pc-bios/s390-ccw/jump2ipl.c
pc-bios/s390-ccw/main.c
pc-bios/s390-ccw/netmain.c
pc-bios/s390-ccw/s390-arch.h
pc-bios/s390-ccw/s390-ccw.h
qapi/Makefile.objs
qapi/block-core.json
qapi/block.json
qapi/control.json
qapi/pragma.json [new file with mode: 0644]
qapi/qapi-schema.json
qapi/qom.json
qapi/transaction.json
qemu-deprecated.texi [deleted file]
qemu-doc.texi [deleted file]
qemu-img.c
qemu-option-trace.texi [deleted file]
qemu-options.hx
qemu-storage-daemon.c [new file with mode: 0644]
qemu-tech.texi [deleted file]
qemu.nsi
qga/channel-win32.c
qga/commands-win32.c
qom/Makefile.objs
qom/qom-qmp-cmds.c
qtest.c
rules.mak
scripts/git.orderfile
scripts/hxtool
scripts/hxtool-conv.pl [new file with mode: 0755]
scripts/qapi/commands.py
scripts/qapi/common.py
scripts/qapi/error.py
scripts/qapi/events.py
scripts/qapi/expr.py
scripts/qapi/gen.py
scripts/qapi/introspect.py
scripts/qapi/parser.py
scripts/qapi/schema.py
scripts/qapi/source.py
scripts/qapi/types.py
scripts/qapi/visit.py
scripts/texi2pod.pl
softmmu/vl.c
storage-daemon/Makefile.objs [new file with mode: 0644]
storage-daemon/qapi/Makefile.objs [new file with mode: 0644]
storage-daemon/qapi/qapi-schema.json [new file with mode: 0644]
stubs/Makefile.objs
stubs/arch_type.c [new file with mode: 0644]
stubs/monitor-core.c [new file with mode: 0644]
stubs/monitor.c
target/arm/cpu.c
target/arm/cpu.h
target/arm/cpu64.c
target/arm/helper-a64.c
target/arm/helper-a64.h
target/arm/helper.c
target/arm/helper.h
target/arm/internals.h
target/arm/op_helper.c
target/arm/translate-a64.c
target/riscv/cpu.c
target/s390x/diag.c
tests/qapi-schema/test-qapi.py
tests/qemu-iotests/026
tests/qemu-iotests/026.out
tests/qemu-iotests/026.out.nocache
tests/qemu-iotests/178
tests/qemu-iotests/178.out.qcow2
tests/qemu-iotests/178.out.raw
tests/qemu-iotests/245
tests/qemu-iotests/245.out
tests/qemu-iotests/288 [new file with mode: 0755]
tests/qemu-iotests/288.out [new file with mode: 0644]
tests/qemu-iotests/common.rc
tests/qemu-iotests/group
tests/qtest/Makefile.include
tests/qtest/fuzz/fork_fuzz.ld
tests/qtest/fuzz/qos_fuzz.c
tests/qtest/tpm-crb-swtpm-test.c
tests/qtest/tpm-crb-test.c
tests/qtest/tpm-tests.c
tests/qtest/tpm-tests.h
tests/qtest/tpm-tis-device-swtpm-test.c [new file with mode: 0644]
tests/qtest/tpm-tis-device-test.c [new file with mode: 0644]
tests/qtest/tpm-tis-swtpm-test.c
tests/qtest/tpm-tis-test.c
tests/qtest/tpm-tis-util.c [new file with mode: 0644]
tests/qtest/tpm-tis-util.h [new file with mode: 0644]
tests/qtest/tpm-util.c
tests/qtest/tpm-util.h
tests/requirements.txt
tests/tcg/aarch64/pauth-1.c
tests/test-rcu-list.c
tests/test-util-sockets.c
tests/vm/Makefile.include
tests/vm/basevm.py
tests/vm/centos
tests/vm/ubuntu.i386
tools/virtiofsd/fuse_virtio.c
tools/virtiofsd/passthrough_ll.c
tools/virtiofsd/seccomp.c
ui/cocoa.m
util/Makefile.objs
util/aio-posix.c
util/aio-posix.h [new file with mode: 0644]
util/fdmon-epoll.c [new file with mode: 0644]
util/fdmon-io_uring.c [new file with mode: 0644]
util/fdmon-poll.c [new file with mode: 0644]
util/osdep.c
util/trace-events

index bc0a035f9cc098bd1cdc7f9f17d478d44205060f..0c5af83aa74548554e1a90d31518609546797713 100644 (file)
@@ -46,9 +46,6 @@
 !/qapi/qapi-visit-core.c
 /qapi/qapi-visit.[ch]
 /qapi/qapi-doc.texi
-/qemu-doc.html
-/qemu-doc.info
-/qemu-doc.txt
 /qemu-edid
 /qemu-img
 /qemu-nbd
index 9867272177d4cf3f8908a28ed68f7b2a1c8e9e25..b92798ac3b9dded0a9ce98a6b5cae19c37d8ca16 100644 (file)
@@ -273,6 +273,7 @@ jobs:
 
     - name: "OSX Xcode 10.3"
       env:
+        - BASE_CONFIG="--disable-docs --enable-tools"
         - CONFIG="--target-list=i386-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,x86_64-softmmu"
       os: osx
       osx_image: xcode10.3
@@ -312,6 +313,7 @@ jobs:
 
     # Acceptance (Functional) tests
     - name: "GCC check-acceptance"
+      dist: bionic
       env:
         - CONFIG="--target-list=aarch64-softmmu,alpha-softmmu,arm-softmmu,m68k-softmmu,microblaze-softmmu,mips-softmmu,mips64el-softmmu,nios2-softmmu,or1k-softmmu,ppc-softmmu,ppc64-softmmu,s390x-softmmu,sparc-softmmu,x86_64-softmmu,xtensa-softmmu"
         - TEST_CMD="make check-acceptance"
@@ -322,7 +324,9 @@ jobs:
           packages:
             - python3-pil
             - python3-pip
-            - python3.5-venv
+            - python3-numpy
+            - python3-opencv
+            - python3-venv
             - rpm2cpio
             - tesseract-ocr
             - tesseract-ocr-eng
index c258391cad8b6a020fb2ba534fa72cc402b10c9b..2903cbe564e048a833304906182bcc342ee84a6a 100644 (file)
@@ -155,6 +155,7 @@ F: include/hw/cpu/a*mpcore.h
 F: disas/arm.c
 F: disas/arm-a64.cc
 F: disas/libvixl/
+F: docs/system/target-arm.rst
 
 ARM SMMU
 M: Eric Auger <eric.auger@redhat.com>
@@ -215,6 +216,7 @@ S: Maintained
 F: target/mips/
 F: default-configs/*mips*
 F: disas/*mips*
+F: docs/system/cpu-models-mips.rst.inc
 F: hw/intc/mips_gic.c
 F: hw/mips/
 F: hw/misc/mips_*
@@ -319,7 +321,7 @@ F: tests/tcg/i386/
 F: tests/tcg/x86_64/
 F: hw/i386/
 F: disas/i386.c
-F: docs/qemu-cpu-models.texi
+F: docs/system/cpu-models-x86.rst.inc
 T: git https://github.com/ehabkost/qemu.git x86-next
 
 Xtensa TCG CPUs
@@ -614,6 +616,7 @@ F: hw/arm/integratorcp.c
 F: hw/misc/arm_integrator_debug.c
 F: include/hw/misc/arm_integrator_debug.h
 F: tests/acceptance/machine_arm_integratorcp.py
+F: docs/system/arm/integratorcp.rst
 
 MCIMX6UL EVK / i.MX6ul
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -672,6 +675,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
 L: qemu-arm@nongnu.org
 S: Odd Fixes
 F: hw/arm/musicpal.c
+F: docs/system/arm/musicpal.rst
 
 nSeries
 M: Andrzej Zaborowski <balrogg@gmail.com>
@@ -688,6 +692,7 @@ F: include/hw/display/blizzard.h
 F: include/hw/input/tsc2xxx.h
 F: include/hw/misc/cbus.h
 F: tests/acceptance/machine_arm_n8x0.py
+F: docs/system/arm/nseries.rst
 
 Palm
 M: Andrzej Zaborowski <balrogg@gmail.com>
@@ -697,6 +702,7 @@ S: Odd Fixes
 F: hw/arm/palm.c
 F: hw/input/tsc210x.c
 F: include/hw/input/tsc2xxx.h
+F: docs/system/arm/palm.rst
 
 Raspberry Pi
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -718,6 +724,7 @@ F: hw/arm/realview*
 F: hw/cpu/realview_mpcore.c
 F: hw/intc/realview_gic.c
 F: include/hw/intc/realview_gic.h
+F: docs/system/arm/realview.rst
 
 PXA2XX
 M: Andrzej Zaborowski <balrogg@gmail.com>
@@ -737,6 +744,7 @@ F: hw/misc/max111x.c
 F: include/hw/arm/pxa.h
 F: include/hw/arm/sharpsl.h
 F: include/hw/display/tc6393xb.h
+F: docs/system/arm/xscale.rst
 
 SABRELITE / i.MX6
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -772,6 +780,7 @@ L: qemu-arm@nongnu.org
 S: Maintained
 F: hw/*/stellaris*
 F: include/hw/input/gamepad.h
+F: docs/system/arm/stellaris.rst
 
 Versatile Express
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -785,6 +794,7 @@ L: qemu-arm@nongnu.org
 S: Maintained
 F: hw/*/versatile*
 F: hw/misc/arm_sysctl.c
+F: docs/system/arm/versatile.rst
 
 Virt
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -1884,6 +1894,8 @@ L: qemu-block@nongnu.org
 S: Supported
 F: util/async.c
 F: util/aio-*.c
+F: util/aio-*.h
+F: util/fdmon-*.c
 F: block/io.c
 F: migration/block*
 F: include/block/aio.h
@@ -1919,6 +1931,7 @@ Block QAPI, monitor, command line
 M: Markus Armbruster <armbru@redhat.com>
 S: Supported
 F: blockdev.c
+F: blockdev-hmp-cmds.c
 F: block/qapi.c
 F: qapi/block*.json
 F: qapi/transaction.json
@@ -2233,7 +2246,7 @@ M: Stefan Hajnoczi <stefanha@redhat.com>
 S: Maintained
 F: trace/
 F: trace-events
-F: qemu-option-trace.texi
+F: docs/qemu-option-trace.rst.inc
 F: scripts/tracetool.py
 F: scripts/tracetool/
 F: scripts/qemu-trace-stap*
@@ -2803,7 +2816,7 @@ F: contrib/gitdm/*
 
 Incompatible changes
 R: libvir-list@redhat.com
-F: qemu-deprecated.texi
+F: docs/system/deprecated.rst
 
 Build System
 ------------
index aa9cc0b5847561063c6bfb3af2bf2392408fb33a..7df22fcc5dac4133dba18c761052e1e234cac07a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,9 +15,6 @@ UNCHECKED_GOALS := %clean TAGS cscope ctags dist \
     help check-help print-% \
     docker docker-% vm-help vm-test vm-build-%
 
-print-%:
-       @echo '$*=$($*)'
-
 # All following code might depend on configuration variables
 ifneq ($(wildcard config-host.mak),)
 # Put the all: rule here so that config-host.mak can contain dependencies.
@@ -128,7 +125,28 @@ GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-events-%.c)
 GENERATED_QAPI_FILES += qapi/qapi-introspect.c qapi/qapi-introspect.h
 GENERATED_QAPI_FILES += qapi/qapi-doc.texi
 
+# The following list considers only the storage daemon main module. All other
+# modules are currently shared with the main schema, so we don't actually
+# generate additional files.
+
+GENERATED_STORAGE_DAEMON_QAPI_FILES = storage-daemon/qapi/qapi-commands.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-commands.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-emit-events.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-emit-events.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-events.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-events.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-init-commands.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-init-commands.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-introspect.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-introspect.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-types.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-types.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-visit.h
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-visit.c
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-doc.texi
+
 generated-files-y += $(GENERATED_QAPI_FILES)
+generated-files-y += $(GENERATED_STORAGE_DAEMON_QAPI_FILES)
 
 generated-files-y += trace/generated-tcg-tracers.h
 
@@ -344,7 +362,7 @@ MANUAL_BUILDDIR := docs
 endif
 
 ifdef BUILD_DOCS
-DOCS=qemu-doc.html qemu-doc.txt qemu.1
+DOCS+=$(MANUAL_BUILDDIR)/system/qemu.1
 DOCS+=$(MANUAL_BUILDDIR)/tools/qemu-img.1
 DOCS+=$(MANUAL_BUILDDIR)/tools/qemu-nbd.8
 DOCS+=$(MANUAL_BUILDDIR)/interop/qemu-ga.8
@@ -354,7 +372,7 @@ endif
 DOCS+=$(MANUAL_BUILDDIR)/system/qemu-block-drivers.7
 DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
 DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
-DOCS+=docs/qemu-cpu-models.7
+DOCS+=$(MANUAL_BUILDDIR)/system/qemu-cpu-models.7
 DOCS+=$(MANUAL_BUILDDIR)/index.html
 ifdef CONFIG_VIRTFS
 DOCS+=$(MANUAL_BUILDDIR)/tools/virtfs-proxy-helper.1
@@ -450,6 +468,8 @@ dummy := $(call unnest-vars,, \
                 qga-vss-dll-obj-y \
                 block-obj-y \
                 block-obj-m \
+                storage-daemon-obj-y \
+                storage-daemon-obj-m \
                 crypto-obj-y \
                 qom-obj-y \
                 io-obj-y \
@@ -482,6 +502,7 @@ TARGET_DIRS_RULES := $(foreach t, all fuzz clean install, $(addsuffix /$(t), $(T
 SOFTMMU_ALL_RULES=$(filter %-softmmu/all, $(TARGET_DIRS_RULES))
 $(SOFTMMU_ALL_RULES): $(authz-obj-y)
 $(SOFTMMU_ALL_RULES): $(block-obj-y)
+$(SOFTMMU_ALL_RULES): $(storage-daemon-obj-y)
 $(SOFTMMU_ALL_RULES): $(chardev-obj-y)
 $(SOFTMMU_ALL_RULES): $(crypto-obj-y)
 $(SOFTMMU_ALL_RULES): $(io-obj-y)
@@ -586,6 +607,7 @@ qemu-img.o: qemu-img-cmds.h
 qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
 qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
 qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(chardev-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
 
@@ -647,6 +669,17 @@ qapi-gen-timestamp: $(qapi-modules) $(qapi-py)
                "GEN","$(@:%-timestamp=%)")
        @>$@
 
+qapi-modules-storage-daemon = \
+       $(SRC_PATH)/storage-daemon/qapi/qapi-schema.json \
+    $(QAPI_MODULES_STORAGE_DAEMON:%=$(SRC_PATH)/qapi/%.json)
+
+$(GENERATED_STORAGE_DAEMON_QAPI_FILES): storage-daemon/qapi/qapi-gen-timestamp ;
+storage-daemon/qapi/qapi-gen-timestamp: $(qapi-modules-storage-daemon) $(qapi-py)
+       $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
+               -o "storage-daemon/qapi" $<, \
+               "GEN","$(@:%-timestamp=%)")
+       @>$@
+
 QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qapi-commands.h qga-qapi-init-commands.h)
 $(qga-obj-y): $(QGALIB_GEN)
 
@@ -745,6 +778,7 @@ clean: recurse-clean
        rm -f trace/generated-tracers-dtrace.h*
        rm -f $(foreach f,$(generated-files-y),$(f) $(f)-timestamp)
        rm -f qapi-gen-timestamp
+       rm -f storage-daemon/qapi/qapi-gen-timestamp
        rm -rf qga/qapi-generated
        rm -f config-all-devices.mak
 
@@ -761,16 +795,12 @@ rm -f $(MANUAL_BUILDDIR)/$1/objects.inv $(MANUAL_BUILDDIR)/$1/searchindex.js $(M
 endef
 
 distclean: clean
-       rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
+       rm -f config-host.mak config-host.h* config-host.ld $(DOCS)
        rm -f tests/tcg/config-*.mak
        rm -f config-all-devices.mak config-all-disas.mak config.status
        rm -f $(SUBDIR_DEVICES_MAK)
        rm -f po/*.mo tests/qemu-iotests/common.env
        rm -f roms/seabios/config.mak roms/vgabios/config.mak
-       rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.cps
-       rm -f qemu-doc.fn qemu-doc.fns qemu-doc.info qemu-doc.ky qemu-doc.kys
-       rm -f qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp
-       rm -f qemu-doc.vr qemu-doc.txt
        rm -f qemu-plugins-ld.symbols qemu-plugins-ld64.symbols
        rm -f config.log
        rm -f linux-headers/asm
@@ -780,13 +810,13 @@ distclean: clean
        rm -f docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
        rm -f docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
        rm -f docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
-       rm -f docs/qemu-cpu-models.7
        rm -rf .doctrees
        $(call clean-manual,devel)
        $(call clean-manual,interop)
        $(call clean-manual,specs)
        $(call clean-manual,system)
        $(call clean-manual,tools)
+       $(call clean-manual,user)
        for d in $(TARGET_DIRS); do \
        rm -rf $$d || exit 1 ; \
         done
@@ -845,21 +875,20 @@ install-sphinxdocs: sphinxdocs
        $(call install-manual,specs)
        $(call install-manual,system)
        $(call install-manual,tools)
+       $(call install-manual,user)
 
 install-doc: $(DOCS) install-sphinxdocs
        $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
        $(INSTALL_DATA) $(MANUAL_BUILDDIR)/index.html "$(DESTDIR)$(qemu_docdir)"
-       $(INSTALL_DATA) qemu-doc.html "$(DESTDIR)$(qemu_docdir)"
-       $(INSTALL_DATA) qemu-doc.txt "$(DESTDIR)$(qemu_docdir)"
        $(INSTALL_DATA) docs/interop/qemu-qmp-ref.html "$(DESTDIR)$(qemu_docdir)"
        $(INSTALL_DATA) docs/interop/qemu-qmp-ref.txt "$(DESTDIR)$(qemu_docdir)"
 ifdef CONFIG_POSIX
        $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
-       $(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
+       $(INSTALL_DATA) $(MANUAL_BUILDDIR)/system/qemu.1 "$(DESTDIR)$(mandir)/man1"
        $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man7"
        $(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
        $(INSTALL_DATA) $(MANUAL_BUILDDIR)/system/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
-       $(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7"
+       $(INSTALL_DATA) $(MANUAL_BUILDDIR)/system/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7"
 ifeq ($(CONFIG_TOOLS),y)
        $(INSTALL_DATA) $(MANUAL_BUILDDIR)/tools/qemu-img.1 "$(DESTDIR)$(mandir)/man1"
        $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
@@ -1039,7 +1068,8 @@ sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html \
             $(MANUAL_BUILDDIR)/interop/index.html \
             $(MANUAL_BUILDDIR)/specs/index.html \
             $(MANUAL_BUILDDIR)/system/index.html \
-            $(MANUAL_BUILDDIR)/tools/index.html
+            $(MANUAL_BUILDDIR)/tools/index.html \
+            $(MANUAL_BUILDDIR)/user/index.html
 
 # Canned command to build a single manual
 # Arguments: $1 = manual name, $2 = Sphinx builder ('html' or 'man')
@@ -1048,8 +1078,10 @@ sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html \
 # a single doctree: https://github.com/sphinx-doc/sphinx/issues/2946
 build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" $(SPHINX_BUILD) $(if $(V),,-q) -W -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
 # We assume all RST files in the manual's directory are used in it
-manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) \
-              $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
+manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst $(SRC_PATH)/docs/$1/*/*.rst) \
+              $(SRC_PATH)/docs/defs.rst.inc \
+              $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py \
+              $(SRC_PATH)/docs/sphinx/*.py
 # Macro to write out the rule and dependencies for building manpages
 # Usage: $(call define-manpage-rule,manualname,manpage1 manpage2...[,extradeps])
 # 'extradeps' is optional, and specifies extra files (eg .hx files) that
@@ -1068,15 +1100,18 @@ $(MANUAL_BUILDDIR)/interop/index.html: $(call manual-deps,interop)
 $(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
        $(call build-manual,specs,html)
 
-$(MANUAL_BUILDDIR)/system/index.html: $(call manual-deps,system)
+$(MANUAL_BUILDDIR)/system/index.html: $(call manual-deps,system) $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/qemu-options.hx
        $(call build-manual,system,html)
 
 $(MANUAL_BUILDDIR)/tools/index.html: $(call manual-deps,tools) $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/docs/qemu-option-trace.rst.inc
        $(call build-manual,tools,html)
 
+$(MANUAL_BUILDDIR)/user/index.html: $(call manual-deps,user)
+       $(call build-manual,user,html)
+
 $(call define-manpage-rule,interop,qemu-ga.8)
 
-$(call define-manpage-rule,system,qemu-block-drivers.7)
+$(call define-manpage-rule,system,qemu.1 qemu-block-drivers.7 qemu-cpu-models.7)
 
 $(call define-manpage-rule,tools,\
        qemu-img.1 qemu-nbd.8 qemu-trace-stap.1\
@@ -1088,36 +1123,16 @@ $(MANUAL_BUILDDIR)/index.html: $(SRC_PATH)/docs/index.html.in qemu-version.h
        $(call quiet-command, sed "s|@@VERSION@@|${VERSION}|g" $< >$@, \
              "GEN","$@")
 
-qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool
-       $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@")
-
-qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool
-       $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@")
-
-qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
-       $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@")
-
 docs/interop/qemu-qmp-qapi.texi: qapi/qapi-doc.texi
        @cp -p $< $@
 
 docs/interop/qemu-ga-qapi.texi: qga/qapi-generated/qga-qapi-doc.texi
        @cp -p $< $@
 
-qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
-qemu.1: qemu-option-trace.texi
-docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
-
-html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html sphinxdocs
-info: qemu-doc.info docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info
-pdf: qemu-doc.pdf docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
-txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
-
-qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
-       qemu-options.texi \
-       qemu-tech.texi qemu-option-trace.texi \
-       qemu-deprecated.texi qemu-monitor.texi \
-       qemu-monitor-info.texi \
-       docs/qemu-cpu-models.texi docs/security.texi
+html: docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html sphinxdocs
+info: docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info
+pdf: docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
+txt: docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
 
 docs/interop/qemu-ga-ref.dvi docs/interop/qemu-ga-ref.html \
     docs/interop/qemu-ga-ref.info docs/interop/qemu-ga-ref.pdf \
index 8a1cbe8000e6109f46a0308774e128e3cac7f59d..40d3a1696cb6f68b033c7ba2d03ae3b6b3c79cee 100644 (file)
@@ -27,6 +27,15 @@ io-obj-y = io/
 
 endif # CONFIG_SOFTMMU or CONFIG_TOOLS
 
+#######################################################################
+# storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are
+# used for system emulation, too, but specified separately there)
+
+storage-daemon-obj-y = block/ monitor/ qapi/ qom/ storage-daemon/
+storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o job-qmp.o
+storage-daemon-obj-$(CONFIG_WIN32) += os-win32.o
+storage-daemon-obj-$(CONFIG_POSIX) += os-posix.o
+
 ######################################################################
 # Target independent part of system emulation. The long term path is to
 # suppress *all* target specific code in case of system emulation, i.e. a
@@ -39,7 +48,7 @@ common-obj-y += dump/
 common-obj-y += job-qmp.o
 common-obj-y += monitor/
 common-obj-y += net/
-common-obj-y += qdev-monitor.o device-hotplug.o
+common-obj-y += qdev-monitor.o
 common-obj-$(CONFIG_WIN32) += os-win32.o
 common-obj-$(CONFIG_POSIX) += os-posix.o
 
diff --git a/block.c b/block.c
index 1bdb9c679d77557b244bc7dd3a9a87480f1e1ce6..957630b1c5d5b3ac8fca92537daec7b3f7131b34 100644 (file)
--- a/block.c
+++ b/block.c
@@ -600,7 +600,7 @@ static int bdrv_create_file_fallback(const char *filename, BlockDriver *drv,
                                      QemuOpts *opts, Error **errp)
 {
     BlockBackend *blk;
-    QDict *options = qdict_new();
+    QDict *options;
     int64_t size = 0;
     char *buf = NULL;
     PreallocMode prealloc;
@@ -623,6 +623,7 @@ static int bdrv_create_file_fallback(const char *filename, BlockDriver *drv,
         return -ENOTSUP;
     }
 
+    options = qdict_new();
     qdict_put_str(options, "driver", drv->format_name);
 
     blk = blk_new_open(filename, NULL, options,
@@ -3694,6 +3695,15 @@ cleanup_perm:
             }
         }
     }
+
+    if (ret == 0) {
+        QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) {
+            BlockDriverState *bs = bs_entry->state.bs;
+
+            if (bs->drv->bdrv_reopen_commit_post)
+                bs->drv->bdrv_reopen_commit_post(&bs_entry->state);
+        }
+    }
 cleanup:
     QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
         if (ret) {
@@ -3777,6 +3787,29 @@ static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
     *shared = cumulative_shared_perms;
 }
 
+static bool bdrv_reopen_can_attach(BlockDriverState *parent,
+                                   BdrvChild *child,
+                                   BlockDriverState *new_child,
+                                   Error **errp)
+{
+    AioContext *parent_ctx = bdrv_get_aio_context(parent);
+    AioContext *child_ctx = bdrv_get_aio_context(new_child);
+    GSList *ignore;
+    bool ret;
+
+    ignore = g_slist_prepend(NULL, child);
+    ret = bdrv_can_set_aio_context(new_child, parent_ctx, &ignore, NULL);
+    g_slist_free(ignore);
+    if (ret) {
+        return ret;
+    }
+
+    ignore = g_slist_prepend(NULL, child);
+    ret = bdrv_can_set_aio_context(parent, child_ctx, &ignore, errp);
+    g_slist_free(ignore);
+    return ret;
+}
+
 /*
  * Take a BDRVReopenState and check if the value of 'backing' in the
  * reopen_state->options QDict is valid or not.
@@ -3828,14 +3861,11 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
     }
 
     /*
-     * TODO: before removing the x- prefix from x-blockdev-reopen we
-     * should move the new backing file into the right AioContext
-     * instead of returning an error.
+     * Check AioContext compatibility so that the bdrv_set_backing_hd() call in
+     * bdrv_reopen_commit() won't fail.
      */
     if (new_backing_bs) {
-        if (bdrv_get_aio_context(new_backing_bs) != bdrv_get_aio_context(bs)) {
-            error_setg(errp, "Cannot use a new backing file "
-                       "with a different AioContext");
+        if (!bdrv_reopen_can_attach(bs, bs->backing, new_backing_bs, errp)) {
             return -EINVAL;
         }
     }
index 3bcb35c81d26068b679df8d8b52902c4743e188c..3635b6b4c18660e435598b0a4d43401041d7701b 100644 (file)
@@ -45,8 +45,11 @@ block-obj-y += crypto.o
 block-obj-y += aio_task.o
 block-obj-y += backup-top.o
 block-obj-y += filter-compress.o
+common-obj-y += monitor/
 
-common-obj-y += stream.o
+block-obj-y += stream.o
+
+common-obj-y += qapi-sysemu.o
 
 nfs.o-libs         := $(LIBNFS_LIBS)
 iscsi.o-cflags     := $(LIBISCSI_CFLAGS)
index 1bfb360bd34a5a6260350692fd973854dee49f44..3b50c06e2c1ae8bed21b5b85bd6d49e7ff5fde8a 100644 (file)
@@ -38,6 +38,7 @@ typedef struct BDRVBackupTopState {
     BlockCopyState *bcs;
     BdrvChild *target;
     bool active;
+    int64_t cluster_size;
 } BDRVBackupTopState;
 
 static coroutine_fn int backup_top_co_preadv(
@@ -57,8 +58,8 @@ static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
         return 0;
     }
 
-    off = QEMU_ALIGN_DOWN(offset, s->bcs->cluster_size);
-    end = QEMU_ALIGN_UP(offset + bytes, s->bcs->cluster_size);
+    off = QEMU_ALIGN_DOWN(offset, s->cluster_size);
+    end = QEMU_ALIGN_UP(offset + bytes, s->cluster_size);
 
     return block_copy(s->bcs, off, end - off, NULL);
 }
@@ -238,6 +239,7 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
         goto fail;
     }
 
+    state->cluster_size = cluster_size;
     state->bcs = block_copy_state_new(top->backing, state->target,
                                       cluster_size, write_flags, &local_err);
     if (local_err) {
index 1383e219f5db9f6a833c5b3407ed1190b2ce2186..7430ca5883006acf9f856f6ba9386fd571daf59c 100644 (file)
@@ -57,15 +57,6 @@ static void backup_progress_bytes_callback(int64_t bytes, void *opaque)
     BackupBlockJob *s = opaque;
 
     s->bytes_read += bytes;
-    job_progress_update(&s->common.job, bytes);
-}
-
-static void backup_progress_reset_callback(void *opaque)
-{
-    BackupBlockJob *s = opaque;
-    uint64_t estimate = bdrv_get_dirty_count(s->bcs->copy_bitmap);
-
-    job_progress_set_remaining(&s->common.job, estimate);
 }
 
 static int coroutine_fn backup_do_cow(BackupBlockJob *job,
@@ -111,7 +102,7 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
 
     if (ret < 0 && job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS) {
         /* If we failed and synced, merge in the bits we didn't copy: */
-        bdrv_dirty_bitmap_merge_internal(bm, job->bcs->copy_bitmap,
+        bdrv_dirty_bitmap_merge_internal(bm, block_copy_dirty_bitmap(job->bcs),
                                          NULL, true);
     }
 }
@@ -154,7 +145,8 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
         return;
     }
 
-    bdrv_set_dirty_bitmap(backup_job->bcs->copy_bitmap, 0, backup_job->len);
+    bdrv_set_dirty_bitmap(block_copy_dirty_bitmap(backup_job->bcs), 0,
+                          backup_job->len);
 }
 
 static BlockErrorAction backup_error_action(BackupBlockJob *job,
@@ -199,7 +191,7 @@ static int coroutine_fn backup_loop(BackupBlockJob *job)
     BdrvDirtyBitmapIter *bdbi;
     int ret = 0;
 
-    bdbi = bdrv_dirty_iter_new(job->bcs->copy_bitmap);
+    bdbi = bdrv_dirty_iter_new(block_copy_dirty_bitmap(job->bcs));
     while ((offset = bdrv_dirty_iter_next(bdbi)) != -1) {
         do {
             if (yield_and_check(job)) {
@@ -219,14 +211,14 @@ static int coroutine_fn backup_loop(BackupBlockJob *job)
     return ret;
 }
 
-static void backup_init_copy_bitmap(BackupBlockJob *job)
+static void backup_init_bcs_bitmap(BackupBlockJob *job)
 {
     bool ret;
     uint64_t estimate;
+    BdrvDirtyBitmap *bcs_bitmap = block_copy_dirty_bitmap(job->bcs);
 
     if (job->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
-        ret = bdrv_dirty_bitmap_merge_internal(job->bcs->copy_bitmap,
-                                               job->sync_bitmap,
+        ret = bdrv_dirty_bitmap_merge_internal(bcs_bitmap, job->sync_bitmap,
                                                NULL, true);
         assert(ret);
     } else {
@@ -235,12 +227,12 @@ static void backup_init_copy_bitmap(BackupBlockJob *job)
              * We can't hog the coroutine to initialize this thoroughly.
              * Set a flag and resume work when we are able to yield safely.
              */
-            job->bcs->skip_unallocated = true;
+            block_copy_set_skip_unallocated(job->bcs, true);
         }
-        bdrv_set_dirty_bitmap(job->bcs->copy_bitmap, 0, job->len);
+        bdrv_set_dirty_bitmap(bcs_bitmap, 0, job->len);
     }
 
-    estimate = bdrv_get_dirty_count(job->bcs->copy_bitmap);
+    estimate = bdrv_get_dirty_count(bcs_bitmap);
     job_progress_set_remaining(&job->common.job, estimate);
 }
 
@@ -249,7 +241,7 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
     BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
     int ret = 0;
 
-    backup_init_copy_bitmap(s);
+    backup_init_bcs_bitmap(s);
 
     if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
         int64_t offset = 0;
@@ -268,12 +260,12 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
 
             offset += count;
         }
-        s->bcs->skip_unallocated = false;
+        block_copy_set_skip_unallocated(s->bcs, false);
     }
 
     if (s->sync_mode == MIRROR_SYNC_MODE_NONE) {
         /*
-         * All bits are set in copy_bitmap to allow any cluster to be copied.
+         * All bits are set in bcs bitmap to allow any cluster to be copied.
          * This does not actually require them to be copied.
          */
         while (!job_is_cancelled(job)) {
@@ -464,8 +456,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
     job->cluster_size = cluster_size;
     job->len = len;
 
-    block_copy_set_callbacks(bcs, backup_progress_bytes_callback,
-                             backup_progress_reset_callback, job);
+    block_copy_set_progress_callback(bcs, backup_progress_bytes_callback, job);
+    block_copy_set_progress_meter(bcs, &job->common.job.progress);
 
     /* Required permissions are already taken by backup-top target */
     block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
index 79798a1567b10d8b59b6bb045ca499026e00a018..05227e18bf15a7ce237a53e90c0950720ac3725c 100644 (file)
 #define BLOCK_COPY_MAX_BUFFER (1 * MiB)
 #define BLOCK_COPY_MAX_MEM (128 * MiB)
 
-static void coroutine_fn block_copy_wait_inflight_reqs(BlockCopyState *s,
-                                                       int64_t start,
-                                                       int64_t end)
+typedef struct BlockCopyInFlightReq {
+    int64_t offset;
+    int64_t bytes;
+    QLIST_ENTRY(BlockCopyInFlightReq) list;
+    CoQueue wait_queue; /* coroutines blocked on this request */
+} BlockCopyInFlightReq;
+
+typedef struct BlockCopyState {
+    /*
+     * BdrvChild objects are not owned or managed by block-copy. They are
+     * provided by block-copy user and user is responsible for appropriate
+     * permissions on these children.
+     */
+    BdrvChild *source;
+    BdrvChild *target;
+    BdrvDirtyBitmap *copy_bitmap;
+    int64_t in_flight_bytes;
+    int64_t cluster_size;
+    bool use_copy_range;
+    int64_t copy_size;
+    uint64_t len;
+    QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs;
+
+    BdrvRequestFlags write_flags;
+
+    /*
+     * skip_unallocated:
+     *
+     * Used by sync=top jobs, which first scan the source node for unallocated
+     * areas and clear them in the copy_bitmap.  During this process, the bitmap
+     * is thus not fully initialized: It may still have bits set for areas that
+     * are unallocated and should actually not be copied.
+     *
+     * This is indicated by skip_unallocated.
+     *
+     * In this case, block_copy() will query the source’s allocation status,
+     * skip unallocated regions, clear them in the copy_bitmap, and invoke
+     * block_copy_reset_unallocated() every time it does.
+     */
+    bool skip_unallocated;
+
+    ProgressMeter *progress;
+    /* progress_bytes_callback: called when some copying progress is done. */
+    ProgressBytesCallbackFunc progress_bytes_callback;
+    void *progress_opaque;
+
+    SharedResource *mem;
+} BlockCopyState;
+
+static BlockCopyInFlightReq *find_conflicting_inflight_req(BlockCopyState *s,
+                                                           int64_t offset,
+                                                           int64_t bytes)
 {
     BlockCopyInFlightReq *req;
-    bool waited;
 
-    do {
-        waited = false;
-        QLIST_FOREACH(req, &s->inflight_reqs, list) {
-            if (end > req->start_byte && start < req->end_byte) {
-                qemu_co_queue_wait(&req->wait_queue, NULL);
-                waited = true;
-                break;
-            }
+    QLIST_FOREACH(req, &s->inflight_reqs, list) {
+        if (offset + bytes > req->offset && offset < req->offset + req->bytes) {
+            return req;
         }
-    } while (waited);
+    }
+
+    return NULL;
+}
+
+/*
+ * If there are no intersecting requests return false. Otherwise, wait for the
+ * first found intersecting request to finish and return true.
+ */
+static bool coroutine_fn block_copy_wait_one(BlockCopyState *s, int64_t offset,
+                                             int64_t bytes)
+{
+    BlockCopyInFlightReq *req = find_conflicting_inflight_req(s, offset, bytes);
+
+    if (!req) {
+        return false;
+    }
+
+    qemu_co_queue_wait(&req->wait_queue, NULL);
+
+    return true;
 }
 
+/* Called only on full-dirty region */
 static void block_copy_inflight_req_begin(BlockCopyState *s,
                                           BlockCopyInFlightReq *req,
-                                          int64_t start, int64_t end)
+                                          int64_t offset, int64_t bytes)
 {
-    req->start_byte = start;
-    req->end_byte = end;
+    assert(!find_conflicting_inflight_req(s, offset, bytes));
+
+    bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
+    s->in_flight_bytes += bytes;
+
+    req->offset = offset;
+    req->bytes = bytes;
     qemu_co_queue_init(&req->wait_queue);
     QLIST_INSERT_HEAD(&s->inflight_reqs, req, list);
 }
 
-static void coroutine_fn block_copy_inflight_req_end(BlockCopyInFlightReq *req)
+/*
+ * block_copy_inflight_req_shrink
+ *
+ * Drop the tail of the request to be handled later. Set dirty bits back and
+ * wake up all requests waiting for us (may be some of them are not intersecting
+ * with shrunk request)
+ */
+static void coroutine_fn block_copy_inflight_req_shrink(BlockCopyState *s,
+        BlockCopyInFlightReq *req, int64_t new_bytes)
+{
+    if (new_bytes == req->bytes) {
+        return;
+    }
+
+    assert(new_bytes > 0 && new_bytes < req->bytes);
+
+    s->in_flight_bytes -= req->bytes - new_bytes;
+    bdrv_set_dirty_bitmap(s->copy_bitmap,
+                          req->offset + new_bytes, req->bytes - new_bytes);
+
+    req->bytes = new_bytes;
+    qemu_co_queue_restart_all(&req->wait_queue);
+}
+
+static void coroutine_fn block_copy_inflight_req_end(BlockCopyState *s,
+                                                     BlockCopyInFlightReq *req,
+                                                     int ret)
 {
+    s->in_flight_bytes -= req->bytes;
+    if (ret < 0) {
+        bdrv_set_dirty_bitmap(s->copy_bitmap, req->offset, req->bytes);
+    }
     QLIST_REMOVE(req, list);
     qemu_co_queue_restart_all(&req->wait_queue);
 }
@@ -70,16 +169,19 @@ void block_copy_state_free(BlockCopyState *s)
     g_free(s);
 }
 
+static uint32_t block_copy_max_transfer(BdrvChild *source, BdrvChild *target)
+{
+    return MIN_NON_ZERO(INT_MAX,
+                        MIN_NON_ZERO(source->bs->bl.max_transfer,
+                                     target->bs->bl.max_transfer));
+}
+
 BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
                                      int64_t cluster_size,
                                      BdrvRequestFlags write_flags, Error **errp)
 {
     BlockCopyState *s;
     BdrvDirtyBitmap *copy_bitmap;
-    uint32_t max_transfer =
-            MIN_NON_ZERO(INT_MAX,
-                         MIN_NON_ZERO(source->bs->bl.max_transfer,
-                                      target->bs->bl.max_transfer));
 
     copy_bitmap = bdrv_create_dirty_bitmap(source->bs, cluster_size, NULL,
                                            errp);
@@ -99,7 +201,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
         .mem = shres_create(BLOCK_COPY_MAX_MEM),
     };
 
-    if (max_transfer < cluster_size) {
+    if (block_copy_max_transfer(source, target) < cluster_size) {
         /*
          * copy_range does not respect max_transfer. We don't want to bother
          * with requests smaller than block-copy cluster size, so fallback to
@@ -114,12 +216,11 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
         s->copy_size = cluster_size;
     } else {
         /*
-         * copy_range does not respect max_transfer (it's a TODO), so we factor
-         * that in here.
+         * We enable copy-range, but keep small copy_size, until first
+         * successful copy_range (look at block_copy_do_copy).
          */
         s->use_copy_range = true;
-        s->copy_size = MIN(MAX(cluster_size, BLOCK_COPY_MAX_COPY_RANGE),
-                           QEMU_ALIGN_DOWN(max_transfer, cluster_size));
+        s->copy_size = MAX(s->cluster_size, BLOCK_COPY_MAX_BUFFER);
     }
 
     QLIST_INIT(&s->inflight_reqs);
@@ -127,48 +228,83 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
     return s;
 }
 
-void block_copy_set_callbacks(
+void block_copy_set_progress_callback(
         BlockCopyState *s,
         ProgressBytesCallbackFunc progress_bytes_callback,
-        ProgressResetCallbackFunc progress_reset_callback,
         void *progress_opaque)
 {
     s->progress_bytes_callback = progress_bytes_callback;
-    s->progress_reset_callback = progress_reset_callback;
     s->progress_opaque = progress_opaque;
 }
 
+void block_copy_set_progress_meter(BlockCopyState *s, ProgressMeter *pm)
+{
+    s->progress = pm;
+}
+
 /*
  * block_copy_do_copy
  *
- * Do copy of cluser-aligned chunk. @end is allowed to exceed s->len only to
- * cover last cluster when s->len is not aligned to clusters.
+ * Do copy of cluster-aligned chunk. Requested region is allowed to exceed
+ * s->len only to cover last cluster when s->len is not aligned to clusters.
  *
  * No sync here: nor bitmap neighter intersecting requests handling, only copy.
  *
  * Returns 0 on success.
  */
 static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
-                                           int64_t start, int64_t end,
-                                           bool *error_is_read)
+                                           int64_t offset, int64_t bytes,
+                                           bool zeroes, bool *error_is_read)
 {
     int ret;
-    int nbytes = MIN(end, s->len) - start;
+    int64_t nbytes = MIN(offset + bytes, s->len) - offset;
     void *bounce_buffer = NULL;
 
-    assert(QEMU_IS_ALIGNED(start, s->cluster_size));
-    assert(QEMU_IS_ALIGNED(end, s->cluster_size));
-    assert(end < s->len || end == QEMU_ALIGN_UP(s->len, s->cluster_size));
+    assert(offset >= 0 && bytes > 0 && INT64_MAX - offset >= bytes);
+    assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
+    assert(QEMU_IS_ALIGNED(bytes, s->cluster_size));
+    assert(offset < s->len);
+    assert(offset + bytes <= s->len ||
+           offset + bytes == QEMU_ALIGN_UP(s->len, s->cluster_size));
+    assert(nbytes < INT_MAX);
+
+    if (zeroes) {
+        ret = bdrv_co_pwrite_zeroes(s->target, offset, nbytes, s->write_flags &
+                                    ~BDRV_REQ_WRITE_COMPRESSED);
+        if (ret < 0) {
+            trace_block_copy_write_zeroes_fail(s, offset, ret);
+            if (error_is_read) {
+                *error_is_read = false;
+            }
+        }
+        return ret;
+    }
 
     if (s->use_copy_range) {
-        ret = bdrv_co_copy_range(s->source, start, s->target, start, nbytes,
+        ret = bdrv_co_copy_range(s->source, offset, s->target, offset, nbytes,
                                  0, s->write_flags);
         if (ret < 0) {
-            trace_block_copy_copy_range_fail(s, start, ret);
+            trace_block_copy_copy_range_fail(s, offset, ret);
             s->use_copy_range = false;
             s->copy_size = MAX(s->cluster_size, BLOCK_COPY_MAX_BUFFER);
             /* Fallback to read+write with allocated buffer */
         } else {
+            if (s->use_copy_range) {
+                /*
+                 * Successful copy-range. Now increase copy_size.  copy_range
+                 * does not respect max_transfer (it's a TODO), so we factor
+                 * that in here.
+                 *
+                 * Note: we double-check s->use_copy_range for the case when
+                 * parallel block-copy request unsets it during previous
+                 * bdrv_co_copy_range call.
+                 */
+                s->copy_size =
+                        MIN(MAX(s->cluster_size, BLOCK_COPY_MAX_COPY_RANGE),
+                            QEMU_ALIGN_DOWN(block_copy_max_transfer(s->source,
+                                                                    s->target),
+                                            s->cluster_size));
+            }
             goto out;
         }
     }
@@ -176,24 +312,27 @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
     /*
      * In case of failed copy_range request above, we may proceed with buffered
      * request larger than BLOCK_COPY_MAX_BUFFER. Still, further requests will
-     * be properly limited, so don't care too much.
+     * be properly limited, so don't care too much. Moreover the most likely
+     * case (copy_range is unsupported for the configuration, so the very first
+     * copy_range request fails) is handled by setting large copy_size only
+     * after first successful copy_range.
      */
 
     bounce_buffer = qemu_blockalign(s->source->bs, nbytes);
 
-    ret = bdrv_co_pread(s->source, start, nbytes, bounce_buffer, 0);
+    ret = bdrv_co_pread(s->source, offset, nbytes, bounce_buffer, 0);
     if (ret < 0) {
-        trace_block_copy_read_fail(s, start, ret);
+        trace_block_copy_read_fail(s, offset, ret);
         if (error_is_read) {
             *error_is_read = true;
         }
         goto out;
     }
 
-    ret = bdrv_co_pwrite(s->target, start, nbytes, bounce_buffer,
+    ret = bdrv_co_pwrite(s->target, offset, nbytes, bounce_buffer,
                          s->write_flags);
     if (ret < 0) {
-        trace_block_copy_write_fail(s, start, ret);
+        trace_block_copy_write_fail(s, offset, ret);
         if (error_is_read) {
             *error_is_read = false;
         }
@@ -206,6 +345,38 @@ out:
     return ret;
 }
 
+static int block_copy_block_status(BlockCopyState *s, int64_t offset,
+                                   int64_t bytes, int64_t *pnum)
+{
+    int64_t num;
+    BlockDriverState *base;
+    int ret;
+
+    if (s->skip_unallocated && s->source->bs->backing) {
+        base = s->source->bs->backing->bs;
+    } else {
+        base = NULL;
+    }
+
+    ret = bdrv_block_status_above(s->source->bs, base, offset, bytes, &num,
+                                  NULL, NULL);
+    if (ret < 0 || num < s->cluster_size) {
+        /*
+         * On error or if failed to obtain large enough chunk just fallback to
+         * copy one cluster.
+         */
+        num = s->cluster_size;
+        ret = BDRV_BLOCK_ALLOCATED | BDRV_BLOCK_DATA;
+    } else if (offset + num == s->len) {
+        num = QEMU_ALIGN_UP(num, s->cluster_size);
+    } else {
+        num = QEMU_ALIGN_DOWN(num, s->cluster_size);
+    }
+
+    *pnum = num;
+    return ret;
+}
+
 /*
  * Check if the cluster starting at offset is allocated or not.
  * return via pnum the number of contiguous clusters sharing this allocation.
@@ -269,21 +440,28 @@ int64_t block_copy_reset_unallocated(BlockCopyState *s,
 
     if (!ret) {
         bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
-        s->progress_reset_callback(s->progress_opaque);
+        progress_set_remaining(s->progress,
+                               bdrv_get_dirty_count(s->copy_bitmap) +
+                               s->in_flight_bytes);
     }
 
     *count = bytes;
     return ret;
 }
 
-int coroutine_fn block_copy(BlockCopyState *s,
-                            int64_t start, uint64_t bytes,
-                            bool *error_is_read)
+/*
+ * block_copy_dirty_clusters
+ *
+ * Copy dirty clusters in @offset/@bytes range.
+ * Returns 1 if dirty clusters found and successfully copied, 0 if no dirty
+ * clusters found and -errno on failure.
+ */
+static int coroutine_fn block_copy_dirty_clusters(BlockCopyState *s,
+                                                  int64_t offset, int64_t bytes,
+                                                  bool *error_is_read)
 {
     int ret = 0;
-    int64_t end = bytes + start; /* bytes */
-    int64_t status_bytes;
-    BlockCopyInFlightReq req;
+    bool found_dirty = false;
 
     /*
      * block_copy() user is responsible for keeping source and target in same
@@ -292,60 +470,109 @@ int coroutine_fn block_copy(BlockCopyState *s,
     assert(bdrv_get_aio_context(s->source->bs) ==
            bdrv_get_aio_context(s->target->bs));
 
-    assert(QEMU_IS_ALIGNED(start, s->cluster_size));
-    assert(QEMU_IS_ALIGNED(end, s->cluster_size));
-
-    block_copy_wait_inflight_reqs(s, start, bytes);
-    block_copy_inflight_req_begin(s, &req, start, end);
+    assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
+    assert(QEMU_IS_ALIGNED(bytes, s->cluster_size));
 
-    while (start < end) {
-        int64_t next_zero, chunk_end;
+    while (bytes) {
+        BlockCopyInFlightReq req;
+        int64_t next_zero, cur_bytes, status_bytes;
 
-        if (!bdrv_dirty_bitmap_get(s->copy_bitmap, start)) {
-            trace_block_copy_skip(s, start);
-            start += s->cluster_size;
+        if (!bdrv_dirty_bitmap_get(s->copy_bitmap, offset)) {
+            trace_block_copy_skip(s, offset);
+            offset += s->cluster_size;
+            bytes -= s->cluster_size;
             continue; /* already copied */
         }
 
-        chunk_end = MIN(end, start + s->copy_size);
+        found_dirty = true;
+
+        cur_bytes = MIN(bytes, s->copy_size);
 
-        next_zero = bdrv_dirty_bitmap_next_zero(s->copy_bitmap, start,
-                                                chunk_end - start);
+        next_zero = bdrv_dirty_bitmap_next_zero(s->copy_bitmap, offset,
+                                                cur_bytes);
         if (next_zero >= 0) {
-            assert(next_zero > start); /* start is dirty */
-            assert(next_zero < chunk_end); /* no need to do MIN() */
-            chunk_end = next_zero;
+            assert(next_zero > offset); /* offset is dirty */
+            assert(next_zero < offset + cur_bytes); /* no need to do MIN() */
+            cur_bytes = next_zero - offset;
         }
-
-        if (s->skip_unallocated) {
-            ret = block_copy_reset_unallocated(s, start, &status_bytes);
-            if (ret == 0) {
-                trace_block_copy_skip_range(s, start, status_bytes);
-                start += status_bytes;
-                continue;
-            }
-            /* Clamp to known allocated region */
-            chunk_end = MIN(chunk_end, start + status_bytes);
+        block_copy_inflight_req_begin(s, &req, offset, cur_bytes);
+
+        ret = block_copy_block_status(s, offset, cur_bytes, &status_bytes);
+        assert(ret >= 0); /* never fail */
+        cur_bytes = MIN(cur_bytes, status_bytes);
+        block_copy_inflight_req_shrink(s, &req, cur_bytes);
+        if (s->skip_unallocated && !(ret & BDRV_BLOCK_ALLOCATED)) {
+            block_copy_inflight_req_end(s, &req, 0);
+            progress_set_remaining(s->progress,
+                                   bdrv_get_dirty_count(s->copy_bitmap) +
+                                   s->in_flight_bytes);
+            trace_block_copy_skip_range(s, offset, status_bytes);
+            offset += status_bytes;
+            bytes -= status_bytes;
+            continue;
         }
 
-        trace_block_copy_process(s, start);
-
-        bdrv_reset_dirty_bitmap(s->copy_bitmap, start, chunk_end - start);
+        trace_block_copy_process(s, offset);
 
-        co_get_from_shres(s->mem, chunk_end - start);
-        ret = block_copy_do_copy(s, start, chunk_end, error_is_read);
-        co_put_to_shres(s->mem, chunk_end - start);
+        co_get_from_shres(s->mem, cur_bytes);
+        ret = block_copy_do_copy(s, offset, cur_bytes, ret & BDRV_BLOCK_ZERO,
+                                 error_is_read);
+        co_put_to_shres(s->mem, cur_bytes);
+        block_copy_inflight_req_end(s, &req, ret);
         if (ret < 0) {
-            bdrv_set_dirty_bitmap(s->copy_bitmap, start, chunk_end - start);
-            break;
+            return ret;
         }
 
-        s->progress_bytes_callback(chunk_end - start, s->progress_opaque);
-        start = chunk_end;
-        ret = 0;
+        progress_work_done(s->progress, cur_bytes);
+        s->progress_bytes_callback(cur_bytes, s->progress_opaque);
+        offset += cur_bytes;
+        bytes -= cur_bytes;
     }
 
-    block_copy_inflight_req_end(&req);
+    return found_dirty;
+}
+
+/*
+ * block_copy
+ *
+ * Copy requested region, accordingly to dirty bitmap.
+ * Collaborate with parallel block_copy requests: if they succeed it will help
+ * us. If they fail, we will retry not-copied regions. So, if we return error,
+ * it means that some I/O operation failed in context of _this_ block_copy call,
+ * not some parallel operation.
+ */
+int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
+                            bool *error_is_read)
+{
+    int ret;
+
+    do {
+        ret = block_copy_dirty_clusters(s, offset, bytes, error_is_read);
+
+        if (ret == 0) {
+            ret = block_copy_wait_one(s, offset, bytes);
+        }
+
+        /*
+         * We retry in two cases:
+         * 1. Some progress done
+         *    Something was copied, which means that there were yield points
+         *    and some new dirty bits may have appeared (due to failed parallel
+         *    block-copy requests).
+         * 2. We have waited for some intersecting block-copy request
+         *    It may have failed and produced new dirty bits.
+         */
+    } while (ret > 0);
 
     return ret;
 }
+
+BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s)
+{
+    return s->copy_bitmap;
+}
+
+void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip)
+{
+    s->skip_unallocated = skip;
+}
index 24823835c1c228d8b1f0456681c80551587ba9b3..23e9c74d6f516ed817c5770518f93fa9a8b532c7 100644 (file)
@@ -484,6 +484,67 @@ static int64_t block_crypto_getlength(BlockDriverState *bs)
 }
 
 
+static BlockMeasureInfo *block_crypto_measure(QemuOpts *opts,
+                                              BlockDriverState *in_bs,
+                                              Error **errp)
+{
+    g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
+    Error *local_err = NULL;
+    BlockMeasureInfo *info;
+    uint64_t size;
+    size_t luks_payload_size;
+    QDict *cryptoopts;
+
+    /*
+     * Preallocation mode doesn't affect size requirements but we must consume
+     * the option.
+     */
+    g_free(qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC));
+
+    size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+
+    if (in_bs) {
+        int64_t ssize = bdrv_getlength(in_bs);
+
+        if (ssize < 0) {
+            error_setg_errno(&local_err, -ssize,
+                             "Unable to get image virtual_size");
+            goto err;
+        }
+
+        size = ssize;
+    }
+
+    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
+            &block_crypto_create_opts_luks, true);
+    qdict_put_str(cryptoopts, "format", "luks");
+    create_opts = block_crypto_create_opts_init(cryptoopts, &local_err);
+    qobject_unref(cryptoopts);
+    if (!create_opts) {
+        goto err;
+    }
+
+    if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
+                                                &luks_payload_size,
+                                                &local_err)) {
+        goto err;
+    }
+
+    /*
+     * Unallocated blocks are still encrypted so allocation status makes no
+     * difference to the file size.
+     */
+    info = g_new(BlockMeasureInfo, 1);
+    info->fully_allocated = luks_payload_size + size;
+    info->required = luks_payload_size + size;
+    return info;
+
+err:
+    error_propagate(errp, local_err);
+    return NULL;
+}
+
+
 static int block_crypto_probe_luks(const uint8_t *buf,
                                    int buf_size,
                                    const char *filename) {
@@ -670,6 +731,7 @@ static BlockDriver bdrv_crypto_luks = {
     .bdrv_co_preadv     = block_crypto_co_preadv,
     .bdrv_co_pwritev    = block_crypto_co_pwritev,
     .bdrv_getlength     = block_crypto_getlength,
+    .bdrv_measure       = block_crypto_measure,
     .bdrv_get_info      = block_crypto_get_info_luks,
     .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
 
index f86299378e38d0e1c9f12fc3e69d06a55845217b..6e325901dc68e4a12a76047a52b550bf498e5702 100644 (file)
@@ -214,11 +214,35 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
 {
     BDRVCURLState *s = opaque;
     size_t realsize = size * nmemb;
-    const char *accept_line = "Accept-Ranges: bytes";
+    const char *header = (char *)ptr;
+    const char *end = header + realsize;
+    const char *accept_ranges = "accept-ranges:";
+    const char *bytes = "bytes";
 
-    if (realsize >= strlen(accept_line)
-        && strncmp((char *)ptr, accept_line, strlen(accept_line)) == 0) {
-        s->accept_range = true;
+    if (realsize >= strlen(accept_ranges)
+        && g_ascii_strncasecmp(header, accept_ranges,
+                               strlen(accept_ranges)) == 0) {
+
+        char *p = strchr(header, ':') + 1;
+
+        /* Skip whitespace between the header name and value. */
+        while (p < end && *p && g_ascii_isspace(*p)) {
+            p++;
+        }
+
+        if (end - p >= strlen(bytes)
+            && strncmp(p, bytes, strlen(bytes)) == 0) {
+
+            /* Check that there is nothing but whitespace after the value. */
+            p += strlen(bytes);
+            while (p < end && *p && g_ascii_isspace(*p)) {
+                p++;
+            }
+
+            if (p == end || !*p) {
+                s->accept_range = true;
+            }
+        }
     }
 
     return realsize;
index 634547711297d6b6f78f9f4cca4d9b0a1a983c25..0f77447a25df87642136f34b0290b1379b27d210 100644 (file)
@@ -888,7 +888,6 @@ static int raw_handle_perm_lock(BlockDriverState *bs,
                               "Is another process using the image [%s]?\n",
                               bs->filename);
         }
-        op = RAW_PL_ABORT;
         /* fall through to unlock bytes. */
     case RAW_PL_ABORT:
         raw_apply_lock_bytes(s, s->fd, s->perm, ~s->shared_perm,
diff --git a/block/monitor/Makefile.objs b/block/monitor/Makefile.objs
new file mode 100644 (file)
index 0000000..0a74f9a
--- /dev/null
@@ -0,0 +1 @@
+common-obj-y += block-hmp-cmds.o
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
new file mode 100644 (file)
index 0000000..c3a6368
--- /dev/null
@@ -0,0 +1,1015 @@
+/*
+ * Blockdev HMP commands
+ *
+ *  Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/boards.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/blockdev.h"
+#include "qapi/qapi-commands-block.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/config-file.h"
+#include "qemu/option.h"
+#include "qemu/sockets.h"
+#include "qemu/cutils.h"
+#include "sysemu/sysemu.h"
+#include "monitor/monitor.h"
+#include "monitor/hmp.h"
+#include "block/nbd.h"
+#include "block/qapi.h"
+#include "block/block_int.h"
+#include "block/block-hmp-cmds.h"
+#include "qemu-io.h"
+
+static void hmp_drive_add_node(Monitor *mon, const char *optstr)
+{
+    QemuOpts *opts;
+    QDict *qdict;
+    Error *local_err = NULL;
+
+    opts = qemu_opts_parse_noisily(&qemu_drive_opts, optstr, false);
+    if (!opts) {
+        return;
+    }
+
+    qdict = qemu_opts_to_qdict(opts, NULL);
+
+    if (!qdict_get_try_str(qdict, "node-name")) {
+        qobject_unref(qdict);
+        error_report("'node-name' needs to be specified");
+        goto out;
+    }
+
+    BlockDriverState *bs = bds_tree_init(qdict, &local_err);
+    if (!bs) {
+        error_report_err(local_err);
+        goto out;
+    }
+
+    bdrv_set_monitor_owned(bs);
+out:
+    qemu_opts_del(opts);
+}
+
+void hmp_drive_add(Monitor *mon, const QDict *qdict)
+{
+    Error *err = NULL;
+    DriveInfo *dinfo;
+    QemuOpts *opts;
+    MachineClass *mc;
+    const char *optstr = qdict_get_str(qdict, "opts");
+    bool node = qdict_get_try_bool(qdict, "node", false);
+
+    if (node) {
+        hmp_drive_add_node(mon, optstr);
+        return;
+    }
+
+    opts = drive_def(optstr);
+    if (!opts)
+        return;
+
+    mc = MACHINE_GET_CLASS(current_machine);
+    dinfo = drive_new(opts, mc->block_default_type, &err);
+    if (err) {
+        error_report_err(err);
+        qemu_opts_del(opts);
+        goto err;
+    }
+
+    if (!dinfo) {
+        return;
+    }
+
+    switch (dinfo->type) {
+    case IF_NONE:
+        monitor_printf(mon, "OK\n");
+        break;
+    default:
+        monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
+        goto err;
+    }
+    return;
+
+err:
+    if (dinfo) {
+        BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+        monitor_remove_blk(blk);
+        blk_unref(blk);
+    }
+}
+
+void hmp_drive_del(Monitor *mon, const QDict *qdict)
+{
+    const char *id = qdict_get_str(qdict, "id");
+    BlockBackend *blk;
+    BlockDriverState *bs;
+    AioContext *aio_context;
+    Error *local_err = NULL;
+
+    bs = bdrv_find_node(id);
+    if (bs) {
+        qmp_blockdev_del(id, &local_err);
+        if (local_err) {
+            error_report_err(local_err);
+        }
+        return;
+    }
+
+    blk = blk_by_name(id);
+    if (!blk) {
+        error_report("Device '%s' not found", id);
+        return;
+    }
+
+    if (!blk_legacy_dinfo(blk)) {
+        error_report("Deleting device added with blockdev-add"
+                     " is not supported");
+        return;
+    }
+
+    aio_context = blk_get_aio_context(blk);
+    aio_context_acquire(aio_context);
+
+    bs = blk_bs(blk);
+    if (bs) {
+        if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
+            error_report_err(local_err);
+            aio_context_release(aio_context);
+            return;
+        }
+
+        blk_remove_bs(blk);
+    }
+
+    /* Make the BlockBackend and the attached BlockDriverState anonymous */
+    monitor_remove_blk(blk);
+
+    /*
+     * If this BlockBackend has a device attached to it, its refcount will be
+     * decremented when the device is removed; otherwise we have to do so here.
+     */
+    if (blk_get_attached_dev(blk)) {
+        /* Further I/O must not pause the guest */
+        blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT,
+                         BLOCKDEV_ON_ERROR_REPORT);
+    } else {
+        blk_unref(blk);
+    }
+
+    aio_context_release(aio_context);
+}
+
+void hmp_commit(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    BlockBackend *blk;
+    int ret;
+
+    if (!strcmp(device, "all")) {
+        ret = blk_commit_all();
+    } else {
+        BlockDriverState *bs;
+        AioContext *aio_context;
+
+        blk = blk_by_name(device);
+        if (!blk) {
+            error_report("Device '%s' not found", device);
+            return;
+        }
+        if (!blk_is_available(blk)) {
+            error_report("Device '%s' has no medium", device);
+            return;
+        }
+
+        bs = blk_bs(blk);
+        aio_context = bdrv_get_aio_context(bs);
+        aio_context_acquire(aio_context);
+
+        ret = bdrv_commit(bs);
+
+        aio_context_release(aio_context);
+    }
+    if (ret < 0) {
+        error_report("'commit' error for '%s': %s", device, strerror(-ret));
+    }
+}
+
+void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
+{
+    const char *filename = qdict_get_str(qdict, "target");
+    const char *format = qdict_get_try_str(qdict, "format");
+    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
+    bool full = qdict_get_try_bool(qdict, "full", false);
+    Error *err = NULL;
+    DriveMirror mirror = {
+        .device = (char *)qdict_get_str(qdict, "device"),
+        .target = (char *)filename,
+        .has_format = !!format,
+        .format = (char *)format,
+        .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
+        .has_mode = true,
+        .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
+        .unmap = true,
+    };
+
+    if (!filename) {
+        error_setg(&err, QERR_MISSING_PARAMETER, "target");
+        hmp_handle_error(mon, err);
+        return;
+    }
+    qmp_drive_mirror(&mirror, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_drive_backup(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    const char *filename = qdict_get_str(qdict, "target");
+    const char *format = qdict_get_try_str(qdict, "format");
+    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
+    bool full = qdict_get_try_bool(qdict, "full", false);
+    bool compress = qdict_get_try_bool(qdict, "compress", false);
+    Error *err = NULL;
+    DriveBackup backup = {
+        .device = (char *)device,
+        .target = (char *)filename,
+        .has_format = !!format,
+        .format = (char *)format,
+        .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
+        .has_mode = true,
+        .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
+        .has_compress = !!compress,
+        .compress = compress,
+    };
+
+    if (!filename) {
+        error_setg(&err, QERR_MISSING_PARAMETER, "target");
+        hmp_handle_error(mon, err);
+        return;
+    }
+
+    qmp_drive_backup(&backup, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
+{
+    Error *error = NULL;
+    const char *device = qdict_get_str(qdict, "device");
+    int64_t value = qdict_get_int(qdict, "speed");
+
+    qmp_block_job_set_speed(device, value, &error);
+
+    hmp_handle_error(mon, error);
+}
+
+void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
+{
+    Error *error = NULL;
+    const char *device = qdict_get_str(qdict, "device");
+    bool force = qdict_get_try_bool(qdict, "force", false);
+
+    qmp_block_job_cancel(device, true, force, &error);
+
+    hmp_handle_error(mon, error);
+}
+
+void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
+{
+    Error *error = NULL;
+    const char *device = qdict_get_str(qdict, "device");
+
+    qmp_block_job_pause(device, &error);
+
+    hmp_handle_error(mon, error);
+}
+
+void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
+{
+    Error *error = NULL;
+    const char *device = qdict_get_str(qdict, "device");
+
+    qmp_block_job_resume(device, &error);
+
+    hmp_handle_error(mon, error);
+}
+
+void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
+{
+    Error *error = NULL;
+    const char *device = qdict_get_str(qdict, "device");
+
+    qmp_block_job_complete(device, &error);
+
+    hmp_handle_error(mon, error);
+}
+
+void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    const char *filename = qdict_get_try_str(qdict, "snapshot-file");
+    const char *format = qdict_get_try_str(qdict, "format");
+    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
+    enum NewImageMode mode;
+    Error *err = NULL;
+
+    if (!filename) {
+        /*
+         * In the future, if 'snapshot-file' is not specified, the snapshot
+         * will be taken internally. Today it's actually required.
+         */
+        error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file");
+        hmp_handle_error(mon, err);
+        return;
+    }
+
+    mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+    qmp_blockdev_snapshot_sync(true, device, false, NULL,
+                               filename, false, NULL,
+                               !!format, format,
+                               true, mode, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    const char *name = qdict_get_str(qdict, "name");
+    Error *err = NULL;
+
+    qmp_blockdev_snapshot_internal_sync(device, name, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    const char *name = qdict_get_str(qdict, "name");
+    const char *id = qdict_get_try_str(qdict, "id");
+    Error *err = NULL;
+
+    qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
+                                               true, name, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
+{
+    const char *uri = qdict_get_str(qdict, "uri");
+    bool writable = qdict_get_try_bool(qdict, "writable", false);
+    bool all = qdict_get_try_bool(qdict, "all", false);
+    Error *local_err = NULL;
+    BlockInfoList *block_list, *info;
+    SocketAddress *addr;
+    BlockExportNbd export;
+
+    if (writable && !all) {
+        error_setg(&local_err, "-w only valid together with -a");
+        goto exit;
+    }
+
+    /* First check if the address is valid and start the server.  */
+    addr = socket_parse(uri, &local_err);
+    if (local_err != NULL) {
+        goto exit;
+    }
+
+    nbd_server_start(addr, NULL, NULL, &local_err);
+    qapi_free_SocketAddress(addr);
+    if (local_err != NULL) {
+        goto exit;
+    }
+
+    if (!all) {
+        return;
+    }
+
+    /* Then try adding all block devices.  If one fails, close all and
+     * exit.
+     */
+    block_list = qmp_query_block(NULL);
+
+    for (info = block_list; info; info = info->next) {
+        if (!info->value->has_inserted) {
+            continue;
+        }
+
+        export = (BlockExportNbd) {
+            .device         = info->value->device,
+            .has_writable   = true,
+            .writable       = writable,
+        };
+
+        qmp_nbd_server_add(&export, &local_err);
+
+        if (local_err != NULL) {
+            qmp_nbd_server_stop(NULL);
+            break;
+        }
+    }
+
+    qapi_free_BlockInfoList(block_list);
+
+exit:
+    hmp_handle_error(mon, local_err);
+}
+
+void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    const char *name = qdict_get_try_str(qdict, "name");
+    bool writable = qdict_get_try_bool(qdict, "writable", false);
+    Error *local_err = NULL;
+
+    BlockExportNbd export = {
+        .device         = (char *) device,
+        .has_name       = !!name,
+        .name           = (char *) name,
+        .has_writable   = true,
+        .writable       = writable,
+    };
+
+    qmp_nbd_server_add(&export, &local_err);
+    hmp_handle_error(mon, local_err);
+}
+
+void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
+{
+    const char *name = qdict_get_str(qdict, "name");
+    bool force = qdict_get_try_bool(qdict, "force", false);
+    Error *err = NULL;
+
+    /* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */
+    qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
+{
+    Error *err = NULL;
+
+    qmp_nbd_server_stop(&err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_block_resize(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    int64_t size = qdict_get_int(qdict, "size");
+    Error *err = NULL;
+
+    qmp_block_resize(true, device, false, NULL, size, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_block_stream(Monitor *mon, const QDict *qdict)
+{
+    Error *error = NULL;
+    const char *device = qdict_get_str(qdict, "device");
+    const char *base = qdict_get_try_str(qdict, "base");
+    int64_t speed = qdict_get_try_int(qdict, "speed", 0);
+
+    qmp_block_stream(true, device, device, base != NULL, base, false, NULL,
+                     false, NULL, qdict_haskey(qdict, "speed"), speed, true,
+                     BLOCKDEV_ON_ERROR_REPORT, false, false, false, false,
+                     &error);
+
+    hmp_handle_error(mon, error);
+}
+
+void hmp_block_passwd(Monitor *mon, const QDict *qdict)
+{
+    const char *device = qdict_get_str(qdict, "device");
+    const char *password = qdict_get_str(qdict, "password");
+    Error *err = NULL;
+
+    qmp_block_passwd(true, device, false, NULL, password, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
+{
+    Error *err = NULL;
+    char *device = (char *) qdict_get_str(qdict, "device");
+    BlockIOThrottle throttle = {
+        .bps = qdict_get_int(qdict, "bps"),
+        .bps_rd = qdict_get_int(qdict, "bps_rd"),
+        .bps_wr = qdict_get_int(qdict, "bps_wr"),
+        .iops = qdict_get_int(qdict, "iops"),
+        .iops_rd = qdict_get_int(qdict, "iops_rd"),
+        .iops_wr = qdict_get_int(qdict, "iops_wr"),
+    };
+
+    /*
+     * qmp_block_set_io_throttle has separate parameters for the
+     * (deprecated) block device name and the qdev ID but the HMP
+     * version has only one, so we must decide which one to pass.
+     */
+    if (blk_by_name(device)) {
+        throttle.has_device = true;
+        throttle.device = device;
+    } else {
+        throttle.has_id = true;
+        throttle.id = device;
+    }
+
+    qmp_block_set_io_throttle(&throttle, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_eject(Monitor *mon, const QDict *qdict)
+{
+    bool force = qdict_get_try_bool(qdict, "force", false);
+    const char *device = qdict_get_str(qdict, "device");
+    Error *err = NULL;
+
+    qmp_eject(true, device, false, NULL, true, force, &err);
+    hmp_handle_error(mon, err);
+}
+
+void hmp_qemu_io(Monitor *mon, const QDict *qdict)
+{
+    BlockBackend *blk;
+    BlockBackend *local_blk = NULL;
+    bool qdev = qdict_get_try_bool(qdict, "qdev", false);
+    const char *device = qdict_get_str(qdict, "device");
+    const char *command = qdict_get_str(qdict, "command");
+    Error *err = NULL;
+    int ret;
+
+    if (qdev) {
+        blk = blk_by_qdev_id(device, &err);
+        if (!blk) {
+            goto fail;
+        }
+    } else {
+        blk = blk_by_name(device);
+        if (!blk) {
+            BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
+            if (bs) {
+                blk = local_blk = blk_new(bdrv_get_aio_context(bs),
+                                          0, BLK_PERM_ALL);
+                ret = blk_insert_bs(blk, bs, &err);
+                if (ret < 0) {
+                    goto fail;
+                }
+            } else {
+                goto fail;
+            }
+        }
+    }
+
+    /*
+     * Notably absent: Proper permission management. This is sad, but it seems
+     * almost impossible to achieve without changing the semantics and thereby
+     * limiting the use cases of the qemu-io HMP command.
+     *
+     * In an ideal world we would unconditionally create a new BlockBackend for
+     * qemuio_command(), but we have commands like 'reopen' and want them to
+     * take effect on the exact BlockBackend whose name the user passed instead
+     * of just on a temporary copy of it.
+     *
+     * Another problem is that deleting the temporary BlockBackend involves
+     * draining all requests on it first, but some qemu-iotests cases want to
+     * issue multiple aio_read/write requests and expect them to complete in
+     * the background while the monitor has already returned.
+     *
+     * This is also what prevents us from saving the original permissions and
+     * restoring them later: We can't revoke permissions until all requests
+     * have completed, and we don't know when that is nor can we really let
+     * anything else run before we have revoken them to avoid race conditions.
+     *
+     * What happens now is that command() in qemu-io-cmds.c can extend the
+     * permissions if necessary for the qemu-io command. And they simply stay
+     * extended, possibly resulting in a read-only guest device keeping write
+     * permissions. Ugly, but it appears to be the lesser evil.
+     */
+    qemuio_command(blk, command);
+
+fail:
+    blk_unref(local_blk);
+    hmp_handle_error(mon, err);
+}
+
+static void print_block_info(Monitor *mon, BlockInfo *info,
+                             BlockDeviceInfo *inserted, bool verbose)
+{
+    ImageInfo *image_info;
+
+    assert(!info || !info->has_inserted || info->inserted == inserted);
+
+    if (info && *info->device) {
+        monitor_printf(mon, "%s", info->device);
+        if (inserted && inserted->has_node_name) {
+            monitor_printf(mon, " (%s)", inserted->node_name);
+        }
+    } else {
+        assert(info || inserted);
+        monitor_printf(mon, "%s",
+                       inserted && inserted->has_node_name ? inserted->node_name
+                       : info && info->has_qdev ? info->qdev
+                       : "<anonymous>");
+    }
+
+    if (inserted) {
+        monitor_printf(mon, ": %s (%s%s%s)\n",
+                       inserted->file,
+                       inserted->drv,
+                       inserted->ro ? ", read-only" : "",
+                       inserted->encrypted ? ", encrypted" : "");
+    } else {
+        monitor_printf(mon, ": [not inserted]\n");
+    }
+
+    if (info) {
+        if (info->has_qdev) {
+            monitor_printf(mon, "    Attached to:      %s\n", info->qdev);
+        }
+        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
+            monitor_printf(mon, "    I/O status:       %s\n",
+                           BlockDeviceIoStatus_str(info->io_status));
+        }
+
+        if (info->removable) {
+            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
+                           info->locked ? "" : "not ",
+                           info->tray_open ? "open" : "closed");
+        }
+    }
+
+
+    if (!inserted) {
+        return;
+    }
+
+    monitor_printf(mon, "    Cache mode:       %s%s%s\n",
+                   inserted->cache->writeback ? "writeback" : "writethrough",
+                   inserted->cache->direct ? ", direct" : "",
+                   inserted->cache->no_flush ? ", ignore flushes" : "");
+
+    if (inserted->has_backing_file) {
+        monitor_printf(mon,
+                       "    Backing file:     %s "
+                       "(chain depth: %" PRId64 ")\n",
+                       inserted->backing_file,
+                       inserted->backing_file_depth);
+    }
+
+    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
+        monitor_printf(mon, "    Detect zeroes:    %s\n",
+                BlockdevDetectZeroesOptions_str(inserted->detect_zeroes));
+    }
+
+    if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
+        inserted->iops || inserted->iops_rd || inserted->iops_wr)
+    {
+        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
+                        " bps_rd=%" PRId64  " bps_wr=%" PRId64
+                        " bps_max=%" PRId64
+                        " bps_rd_max=%" PRId64
+                        " bps_wr_max=%" PRId64
+                        " iops=%" PRId64 " iops_rd=%" PRId64
+                        " iops_wr=%" PRId64
+                        " iops_max=%" PRId64
+                        " iops_rd_max=%" PRId64
+                        " iops_wr_max=%" PRId64
+                        " iops_size=%" PRId64
+                        " group=%s\n",
+                        inserted->bps,
+                        inserted->bps_rd,
+                        inserted->bps_wr,
+                        inserted->bps_max,
+                        inserted->bps_rd_max,
+                        inserted->bps_wr_max,
+                        inserted->iops,
+                        inserted->iops_rd,
+                        inserted->iops_wr,
+                        inserted->iops_max,
+                        inserted->iops_rd_max,
+                        inserted->iops_wr_max,
+                        inserted->iops_size,
+                        inserted->group);
+    }
+
+    if (verbose) {
+        monitor_printf(mon, "\nImages:\n");
+        image_info = inserted->image;
+        while (1) {
+                bdrv_image_info_dump(image_info);
+            if (image_info->has_backing_image) {
+                image_info = image_info->backing_image;
+            } else {
+                break;
+            }
+        }
+    }
+}
+
+void hmp_info_block(Monitor *mon, const QDict *qdict)
+{
+    BlockInfoList *block_list, *info;
+    BlockDeviceInfoList *blockdev_list, *blockdev;
+    const char *device = qdict_get_try_str(qdict, "device");
+    bool verbose = qdict_get_try_bool(qdict, "verbose", false);
+    bool nodes = qdict_get_try_bool(qdict, "nodes", false);
+    bool printed = false;
+
+    /* Print BlockBackend information */
+    if (!nodes) {
+        block_list = qmp_query_block(NULL);
+    } else {
+        block_list = NULL;
+    }
+
+    for (info = block_list; info; info = info->next) {
+        if (device && strcmp(device, info->value->device)) {
+            continue;
+        }
+
+        if (info != block_list) {
+            monitor_printf(mon, "\n");
+        }
+
+        print_block_info(mon, info->value, info->value->has_inserted
+                                           ? info->value->inserted : NULL,
+                         verbose);
+        printed = true;
+    }
+
+    qapi_free_BlockInfoList(block_list);
+
+    if ((!device && !nodes) || printed) {
+        return;
+    }
+
+    /* Print node information */
+    blockdev_list = qmp_query_named_block_nodes(false, false, NULL);
+    for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
+        assert(blockdev->value->has_node_name);
+        if (device && strcmp(device, blockdev->value->node_name)) {
+            continue;
+        }
+
+        if (blockdev != blockdev_list) {
+            monitor_printf(mon, "\n");
+        }
+
+        print_block_info(mon, NULL, blockdev->value, verbose);
+    }
+    qapi_free_BlockDeviceInfoList(blockdev_list);
+}
+
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
+{
+    BlockStatsList *stats_list, *stats;
+
+    stats_list = qmp_query_blockstats(false, false, NULL);
+
+    for (stats = stats_list; stats; stats = stats->next) {
+        if (!stats->value->has_device) {
+            continue;
+        }
+
+        monitor_printf(mon, "%s:", stats->value->device);
+        monitor_printf(mon, " rd_bytes=%" PRId64
+                       " wr_bytes=%" PRId64
+                       " rd_operations=%" PRId64
+                       " wr_operations=%" PRId64
+                       " flush_operations=%" PRId64
+                       " wr_total_time_ns=%" PRId64
+                       " rd_total_time_ns=%" PRId64
+                       " flush_total_time_ns=%" PRId64
+                       " rd_merged=%" PRId64
+                       " wr_merged=%" PRId64
+                       " idle_time_ns=%" PRId64
+                       "\n",
+                       stats->value->stats->rd_bytes,
+                       stats->value->stats->wr_bytes,
+                       stats->value->stats->rd_operations,
+                       stats->value->stats->wr_operations,
+                       stats->value->stats->flush_operations,
+                       stats->value->stats->wr_total_time_ns,
+                       stats->value->stats->rd_total_time_ns,
+                       stats->value->stats->flush_total_time_ns,
+                       stats->value->stats->rd_merged,
+                       stats->value->stats->wr_merged,
+                       stats->value->stats->idle_time_ns);
+    }
+
+    qapi_free_BlockStatsList(stats_list);
+}
+
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
+{
+    BlockJobInfoList *list;
+    Error *err = NULL;
+
+    list = qmp_query_block_jobs(&err);
+    assert(!err);
+
+    if (!list) {
+        monitor_printf(mon, "No active jobs\n");
+        return;
+    }
+
+    while (list) {
+        if (strcmp(list->value->type, "stream") == 0) {
+            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
+                           " of %" PRId64 " bytes, speed limit %" PRId64
+                           " bytes/s\n",
+                           list->value->device,
+                           list->value->offset,
+                           list->value->len,
+                           list->value->speed);
+        } else {
+            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
+                           " of %" PRId64 " bytes, speed limit %" PRId64
+                           " bytes/s\n",
+                           list->value->type,
+                           list->value->device,
+                           list->value->offset,
+                           list->value->len,
+                           list->value->speed);
+        }
+        list = list->next;
+    }
+
+    qapi_free_BlockJobInfoList(list);
+}
+
+void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
+{
+    BlockDriverState *bs, *bs1;
+    BdrvNextIterator it1;
+    QEMUSnapshotInfo *sn_tab, *sn;
+    bool no_snapshot = true;
+    int nb_sns, i;
+    int total;
+    int *global_snapshots;
+    AioContext *aio_context;
+
+    typedef struct SnapshotEntry {
+        QEMUSnapshotInfo sn;
+        QTAILQ_ENTRY(SnapshotEntry) next;
+    } SnapshotEntry;
+
+    typedef struct ImageEntry {
+        const char *imagename;
+        QTAILQ_ENTRY(ImageEntry) next;
+        QTAILQ_HEAD(, SnapshotEntry) snapshots;
+    } ImageEntry;
+
+    QTAILQ_HEAD(, ImageEntry) image_list =
+        QTAILQ_HEAD_INITIALIZER(image_list);
+
+    ImageEntry *image_entry, *next_ie;
+    SnapshotEntry *snapshot_entry;
+
+    bs = bdrv_all_find_vmstate_bs();
+    if (!bs) {
+        monitor_printf(mon, "No available block device supports snapshots\n");
+        return;
+    }
+    aio_context = bdrv_get_aio_context(bs);
+
+    aio_context_acquire(aio_context);
+    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
+    aio_context_release(aio_context);
+
+    if (nb_sns < 0) {
+        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
+        return;
+    }
+
+    for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) {
+        int bs1_nb_sns = 0;
+        ImageEntry *ie;
+        SnapshotEntry *se;
+        AioContext *ctx = bdrv_get_aio_context(bs1);
+
+        aio_context_acquire(ctx);
+        if (bdrv_can_snapshot(bs1)) {
+            sn = NULL;
+            bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
+            if (bs1_nb_sns > 0) {
+                no_snapshot = false;
+                ie = g_new0(ImageEntry, 1);
+                ie->imagename = bdrv_get_device_name(bs1);
+                QTAILQ_INIT(&ie->snapshots);
+                QTAILQ_INSERT_TAIL(&image_list, ie, next);
+                for (i = 0; i < bs1_nb_sns; i++) {
+                    se = g_new0(SnapshotEntry, 1);
+                    se->sn = sn[i];
+                    QTAILQ_INSERT_TAIL(&ie->snapshots, se, next);
+                }
+            }
+            g_free(sn);
+        }
+        aio_context_release(ctx);
+    }
+
+    if (no_snapshot) {
+        monitor_printf(mon, "There is no snapshot available.\n");
+        return;
+    }
+
+    global_snapshots = g_new0(int, nb_sns);
+    total = 0;
+    for (i = 0; i < nb_sns; i++) {
+        SnapshotEntry *next_sn;
+        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) {
+            global_snapshots[total] = i;
+            total++;
+            QTAILQ_FOREACH(image_entry, &image_list, next) {
+                QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots,
+                                    next, next_sn) {
+                    if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) {
+                        QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry,
+                                      next);
+                        g_free(snapshot_entry);
+                    }
+                }
+            }
+        }
+    }
+    monitor_printf(mon, "List of snapshots present on all disks:\n");
+
+    if (total > 0) {
+        bdrv_snapshot_dump(NULL);
+        monitor_printf(mon, "\n");
+        for (i = 0; i < total; i++) {
+            sn = &sn_tab[global_snapshots[i]];
+            /*
+             * The ID is not guaranteed to be the same on all images, so
+             * overwrite it.
+             */
+            pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
+            bdrv_snapshot_dump(sn);
+            monitor_printf(mon, "\n");
+        }
+    } else {
+        monitor_printf(mon, "None\n");
+    }
+
+    QTAILQ_FOREACH(image_entry, &image_list, next) {
+        if (QTAILQ_EMPTY(&image_entry->snapshots)) {
+            continue;
+        }
+        monitor_printf(mon,
+                       "\nList of partial (non-loadable) snapshots on '%s':\n",
+                       image_entry->imagename);
+        bdrv_snapshot_dump(NULL);
+        monitor_printf(mon, "\n");
+        QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
+            bdrv_snapshot_dump(&snapshot_entry->sn);
+            monitor_printf(mon, "\n");
+        }
+    }
+
+    QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) {
+        SnapshotEntry *next_sn;
+        QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next,
+                            next_sn) {
+            g_free(snapshot_entry);
+        }
+        g_free(image_entry);
+    }
+    g_free(sn_tab);
+    g_free(global_snapshots);
+}
diff --git a/block/qapi-sysemu.c b/block/qapi-sysemu.c
new file mode 100644 (file)
index 0000000..8498402
--- /dev/null
@@ -0,0 +1,590 @@
+/*
+ * QMP command handlers specific to the system emulators
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qapi/qapi-commands-block.h"
+#include "qapi/qmp/qdict.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/blockdev.h"
+
+static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
+                                 Error **errp)
+{
+    BlockBackend *blk;
+
+    if (!blk_name == !qdev_id) {
+        error_setg(errp, "Need exactly one of 'device' and 'id'");
+        return NULL;
+    }
+
+    if (qdev_id) {
+        blk = blk_by_qdev_id(qdev_id, errp);
+    } else {
+        blk = blk_by_name(blk_name);
+        if (blk == NULL) {
+            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+                      "Device '%s' not found", blk_name);
+        }
+    }
+
+    return blk;
+}
+
+/*
+ * Attempt to open the tray of @device.
+ * If @force, ignore its tray lock.
+ * Else, if the tray is locked, don't open it, but ask the guest to open it.
+ * On error, store an error through @errp and return -errno.
+ * If @device does not exist, return -ENODEV.
+ * If it has no removable media, return -ENOTSUP.
+ * If it has no tray, return -ENOSYS.
+ * If the guest was asked to open the tray, return -EINPROGRESS.
+ * Else, return 0.
+ */
+static int do_open_tray(const char *blk_name, const char *qdev_id,
+                        bool force, Error **errp)
+{
+    BlockBackend *blk;
+    const char *device = qdev_id ?: blk_name;
+    bool locked;
+
+    blk = qmp_get_blk(blk_name, qdev_id, errp);
+    if (!blk) {
+        return -ENODEV;
+    }
+
+    if (!blk_dev_has_removable_media(blk)) {
+        error_setg(errp, "Device '%s' is not removable", device);
+        return -ENOTSUP;
+    }
+
+    if (!blk_dev_has_tray(blk)) {
+        error_setg(errp, "Device '%s' does not have a tray", device);
+        return -ENOSYS;
+    }
+
+    if (blk_dev_is_tray_open(blk)) {
+        return 0;
+    }
+
+    locked = blk_dev_is_medium_locked(blk);
+    if (locked) {
+        blk_dev_eject_request(blk, force);
+    }
+
+    if (!locked || force) {
+        blk_dev_change_media_cb(blk, false, &error_abort);
+    }
+
+    if (locked && !force) {
+        error_setg(errp, "Device '%s' is locked and force was not specified, "
+                   "wait for tray to open and try again", device);
+        return -EINPROGRESS;
+    }
+
+    return 0;
+}
+
+void qmp_blockdev_open_tray(bool has_device, const char *device,
+                            bool has_id, const char *id,
+                            bool has_force, bool force,
+                            Error **errp)
+{
+    Error *local_err = NULL;
+    int rc;
+
+    if (!has_force) {
+        force = false;
+    }
+    rc = do_open_tray(has_device ? device : NULL,
+                      has_id ? id : NULL,
+                      force, &local_err);
+    if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    error_free(local_err);
+}
+
+void qmp_blockdev_close_tray(bool has_device, const char *device,
+                             bool has_id, const char *id,
+                             Error **errp)
+{
+    BlockBackend *blk;
+    Error *local_err = NULL;
+
+    device = has_device ? device : NULL;
+    id = has_id ? id : NULL;
+
+    blk = qmp_get_blk(device, id, errp);
+    if (!blk) {
+        return;
+    }
+
+    if (!blk_dev_has_removable_media(blk)) {
+        error_setg(errp, "Device '%s' is not removable", device ?: id);
+        return;
+    }
+
+    if (!blk_dev_has_tray(blk)) {
+        /* Ignore this command on tray-less devices */
+        return;
+    }
+
+    if (!blk_dev_is_tray_open(blk)) {
+        return;
+    }
+
+    blk_dev_change_media_cb(blk, true, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+}
+
+static void blockdev_remove_medium(bool has_device, const char *device,
+                                   bool has_id, const char *id, Error **errp)
+{
+    BlockBackend *blk;
+    BlockDriverState *bs;
+    AioContext *aio_context;
+    bool has_attached_device;
+
+    device = has_device ? device : NULL;
+    id = has_id ? id : NULL;
+
+    blk = qmp_get_blk(device, id, errp);
+    if (!blk) {
+        return;
+    }
+
+    /* For BBs without a device, we can exchange the BDS tree at will */
+    has_attached_device = blk_get_attached_dev(blk);
+
+    if (has_attached_device && !blk_dev_has_removable_media(blk)) {
+        error_setg(errp, "Device '%s' is not removable", device ?: id);
+        return;
+    }
+
+    if (has_attached_device && blk_dev_has_tray(blk) &&
+        !blk_dev_is_tray_open(blk))
+    {
+        error_setg(errp, "Tray of device '%s' is not open", device ?: id);
+        return;
+    }
+
+    bs = blk_bs(blk);
+    if (!bs) {
+        return;
+    }
+
+    aio_context = bdrv_get_aio_context(bs);
+    aio_context_acquire(aio_context);
+
+    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
+        goto out;
+    }
+
+    blk_remove_bs(blk);
+
+    if (!blk_dev_has_tray(blk)) {
+        /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
+         * called at all); therefore, the medium needs to be ejected here.
+         * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
+         * value passed here (i.e. false). */
+        blk_dev_change_media_cb(blk, false, &error_abort);
+    }
+
+out:
+    aio_context_release(aio_context);
+}
+
+void qmp_blockdev_remove_medium(const char *id, Error **errp)
+{
+    blockdev_remove_medium(false, NULL, true, id, errp);
+}
+
+static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
+                                            BlockDriverState *bs, Error **errp)
+{
+    Error *local_err = NULL;
+    bool has_device;
+    int ret;
+
+    /* For BBs without a device, we can exchange the BDS tree at will */
+    has_device = blk_get_attached_dev(blk);
+
+    if (has_device && !blk_dev_has_removable_media(blk)) {
+        error_setg(errp, "Device is not removable");
+        return;
+    }
+
+    if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
+        error_setg(errp, "Tray of the device is not open");
+        return;
+    }
+
+    if (blk_bs(blk)) {
+        error_setg(errp, "There already is a medium in the device");
+        return;
+    }
+
+    ret = blk_insert_bs(blk, bs, errp);
+    if (ret < 0) {
+        return;
+    }
+
+    if (!blk_dev_has_tray(blk)) {
+        /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
+         * called at all); therefore, the medium needs to be pushed into the
+         * slot here.
+         * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
+         * value passed here (i.e. true). */
+        blk_dev_change_media_cb(blk, true, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            blk_remove_bs(blk);
+            return;
+        }
+    }
+}
+
+static void blockdev_insert_medium(bool has_device, const char *device,
+                                   bool has_id, const char *id,
+                                   const char *node_name, Error **errp)
+{
+    BlockBackend *blk;
+    BlockDriverState *bs;
+
+    blk = qmp_get_blk(has_device ? device : NULL,
+                      has_id ? id : NULL,
+                      errp);
+    if (!blk) {
+        return;
+    }
+
+    bs = bdrv_find_node(node_name);
+    if (!bs) {
+        error_setg(errp, "Node '%s' not found", node_name);
+        return;
+    }
+
+    if (bdrv_has_blk(bs)) {
+        error_setg(errp, "Node '%s' is already in use", node_name);
+        return;
+    }
+
+    qmp_blockdev_insert_anon_medium(blk, bs, errp);
+}
+
+void qmp_blockdev_insert_medium(const char *id, const char *node_name,
+                                Error **errp)
+{
+    blockdev_insert_medium(false, NULL, true, id, node_name, errp);
+}
+
+void qmp_blockdev_change_medium(bool has_device, const char *device,
+                                bool has_id, const char *id,
+                                const char *filename,
+                                bool has_format, const char *format,
+                                bool has_read_only,
+                                BlockdevChangeReadOnlyMode read_only,
+                                Error **errp)
+{
+    BlockBackend *blk;
+    BlockDriverState *medium_bs = NULL;
+    int bdrv_flags;
+    bool detect_zeroes;
+    int rc;
+    QDict *options = NULL;
+    Error *err = NULL;
+
+    blk = qmp_get_blk(has_device ? device : NULL,
+                      has_id ? id : NULL,
+                      errp);
+    if (!blk) {
+        goto fail;
+    }
+
+    if (blk_bs(blk)) {
+        blk_update_root_state(blk);
+    }
+
+    bdrv_flags = blk_get_open_flags_from_root_state(blk);
+    bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
+        BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
+
+    if (!has_read_only) {
+        read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
+    }
+
+    switch (read_only) {
+    case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
+        break;
+
+    case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
+        bdrv_flags &= ~BDRV_O_RDWR;
+        break;
+
+    case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
+        bdrv_flags |= BDRV_O_RDWR;
+        break;
+
+    default:
+        abort();
+    }
+
+    options = qdict_new();
+    detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
+    qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
+
+    if (has_format) {
+        qdict_put_str(options, "driver", format);
+    }
+
+    medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
+    if (!medium_bs) {
+        goto fail;
+    }
+
+    rc = do_open_tray(has_device ? device : NULL,
+                      has_id ? id : NULL,
+                      false, &err);
+    if (rc && rc != -ENOSYS) {
+        error_propagate(errp, err);
+        goto fail;
+    }
+    error_free(err);
+    err = NULL;
+
+    blockdev_remove_medium(has_device, device, has_id, id, &err);
+    if (err) {
+        error_propagate(errp, err);
+        goto fail;
+    }
+
+    qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
+    if (err) {
+        error_propagate(errp, err);
+        goto fail;
+    }
+
+    qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
+
+fail:
+    /* If the medium has been inserted, the device has its own reference, so
+     * ours must be relinquished; and if it has not been inserted successfully,
+     * the reference must be relinquished anyway */
+    bdrv_unref(medium_bs);
+}
+
+void qmp_eject(bool has_device, const char *device,
+               bool has_id, const char *id,
+               bool has_force, bool force, Error **errp)
+{
+    Error *local_err = NULL;
+    int rc;
+
+    if (!has_force) {
+        force = false;
+    }
+
+    rc = do_open_tray(has_device ? device : NULL,
+                      has_id ? id : NULL,
+                      force, &local_err);
+    if (rc && rc != -ENOSYS) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    error_free(local_err);
+
+    blockdev_remove_medium(has_device, device, has_id, id, errp);
+}
+
+/* throttling disk I/O limits */
+void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
+{
+    ThrottleConfig cfg;
+    BlockDriverState *bs;
+    BlockBackend *blk;
+    AioContext *aio_context;
+
+    blk = qmp_get_blk(arg->has_device ? arg->device : NULL,
+                      arg->has_id ? arg->id : NULL,
+                      errp);
+    if (!blk) {
+        return;
+    }
+
+    aio_context = blk_get_aio_context(blk);
+    aio_context_acquire(aio_context);
+
+    bs = blk_bs(blk);
+    if (!bs) {
+        error_setg(errp, "Device has no medium");
+        goto out;
+    }
+
+    throttle_config_init(&cfg);
+    cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
+    cfg.buckets[THROTTLE_BPS_READ].avg  = arg->bps_rd;
+    cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
+
+    cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
+    cfg.buckets[THROTTLE_OPS_READ].avg  = arg->iops_rd;
+    cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
+
+    if (arg->has_bps_max) {
+        cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
+    }
+    if (arg->has_bps_rd_max) {
+        cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
+    }
+    if (arg->has_bps_wr_max) {
+        cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
+    }
+    if (arg->has_iops_max) {
+        cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
+    }
+    if (arg->has_iops_rd_max) {
+        cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
+    }
+    if (arg->has_iops_wr_max) {
+        cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
+    }
+
+    if (arg->has_bps_max_length) {
+        cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
+    }
+    if (arg->has_bps_rd_max_length) {
+        cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
+    }
+    if (arg->has_bps_wr_max_length) {
+        cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
+    }
+    if (arg->has_iops_max_length) {
+        cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
+    }
+    if (arg->has_iops_rd_max_length) {
+        cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
+    }
+    if (arg->has_iops_wr_max_length) {
+        cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
+    }
+
+    if (arg->has_iops_size) {
+        cfg.op_size = arg->iops_size;
+    }
+
+    if (!throttle_is_valid(&cfg, errp)) {
+        goto out;
+    }
+
+    if (throttle_enabled(&cfg)) {
+        /* Enable I/O limits if they're not enabled yet, otherwise
+         * just update the throttling group. */
+        if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
+            blk_io_limits_enable(blk,
+                                 arg->has_group ? arg->group :
+                                 arg->has_device ? arg->device :
+                                 arg->id);
+        } else if (arg->has_group) {
+            blk_io_limits_update_group(blk, arg->group);
+        }
+        /* Set the new throttling configuration */
+        blk_set_io_limits(blk, &cfg);
+    } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
+        /* If all throttling settings are set to 0, disable I/O limits */
+        blk_io_limits_disable(blk);
+    }
+
+out:
+    aio_context_release(aio_context);
+}
+
+void qmp_block_latency_histogram_set(
+    const char *id,
+    bool has_boundaries, uint64List *boundaries,
+    bool has_boundaries_read, uint64List *boundaries_read,
+    bool has_boundaries_write, uint64List *boundaries_write,
+    bool has_boundaries_flush, uint64List *boundaries_flush,
+    Error **errp)
+{
+    BlockBackend *blk = qmp_get_blk(NULL, id, errp);
+    BlockAcctStats *stats;
+    int ret;
+
+    if (!blk) {
+        return;
+    }
+
+    stats = blk_get_stats(blk);
+
+    if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
+        !has_boundaries_flush)
+    {
+        block_latency_histograms_clear(stats);
+        return;
+    }
+
+    if (has_boundaries || has_boundaries_read) {
+        ret = block_latency_histogram_set(
+            stats, BLOCK_ACCT_READ,
+            has_boundaries_read ? boundaries_read : boundaries);
+        if (ret) {
+            error_setg(errp, "Device '%s' set read boundaries fail", id);
+            return;
+        }
+    }
+
+    if (has_boundaries || has_boundaries_write) {
+        ret = block_latency_histogram_set(
+            stats, BLOCK_ACCT_WRITE,
+            has_boundaries_write ? boundaries_write : boundaries);
+        if (ret) {
+            error_setg(errp, "Device '%s' set write boundaries fail", id);
+            return;
+        }
+    }
+
+    if (has_boundaries || has_boundaries_flush) {
+        ret = block_latency_histogram_set(
+            stats, BLOCK_ACCT_FLUSH,
+            has_boundaries_flush ? boundaries_flush : boundaries);
+        if (ret) {
+            error_setg(errp, "Device '%s' set flush boundaries fail", id);
+            return;
+        }
+    }
+}
index 78c95dfa16278f169627ce0313e4e754c918e068..17f13632797d04c142fc74ff104c9a966fef9e11 100644 (file)
@@ -1026,7 +1026,7 @@ err:
 void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
 {
     BDRVQcow2State *s = bs->opaque;
-    if (!has_data_file(bs)) {
+    if (!has_data_file(bs) && !m->keep_old_clusters) {
         qcow2_free_clusters(bs, m->alloc_offset,
                             m->nb_clusters << s->cluster_bits,
                             QCOW2_DISCARD_NEVER);
index 77bb578cdf61f4f5d4f6521e33a18f05b057c78b..a68126f291ab35889b5f9e32b2fe9335c7f65b62 100644 (file)
@@ -128,12 +128,12 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
  * @src - source buffer, @src_size bytes
  *
  * Returns: 0 on success
- *          -1 on fail
+ *          -EIO on fail
  */
 static ssize_t qcow2_decompress(void *dest, size_t dest_size,
                                 const void *src, size_t src_size)
 {
-    int ret = 0;
+    int ret;
     z_stream strm;
 
     memset(&strm, 0, sizeof(strm));
@@ -144,17 +144,19 @@ static ssize_t qcow2_decompress(void *dest, size_t dest_size,
 
     ret = inflateInit2(&strm, -12);
     if (ret != Z_OK) {
-        return -1;
+        return -EIO;
     }
 
     ret = inflate(&strm, Z_FINISH);
-    if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || strm.avail_out != 0) {
+    if ((ret == Z_STREAM_END || ret == Z_BUF_ERROR) && strm.avail_out == 0) {
         /*
          * We approve Z_BUF_ERROR because we need @dest buffer to be filled, but
          * @src buffer may be processed partly (because in qcow2 we know size of
          * compressed data with precision of one sector)
          */
-        ret = -1;
+        ret = 0;
+    } else {
+        ret = -EIO;
     }
 
     inflateEnd(&strm);
index 3c754f616bf86c95ea07224eef204c05cc565617..d44b45633dbbceebb224395131609abb3adec169 100644 (file)
@@ -1884,6 +1884,11 @@ fail:
 static void qcow2_reopen_commit(BDRVReopenState *state)
 {
     qcow2_update_options_commit(state->bs, state->opaque);
+    g_free(state->opaque);
+}
+
+static void qcow2_reopen_commit_post(BDRVReopenState *state)
+{
     if (state->flags & BDRV_O_RDWR) {
         Error *local_err = NULL;
 
@@ -1898,7 +1903,6 @@ static void qcow2_reopen_commit(BDRVReopenState *state)
                               bdrv_get_node_name(state->bs));
         }
     }
-    g_free(state->opaque);
 }
 
 static void qcow2_reopen_abort(BDRVReopenState *state)
@@ -2606,6 +2610,7 @@ static void qcow2_close(BlockDriverState *bs)
 
     qcrypto_block_free(s->crypto);
     s->crypto = NULL;
+    qapi_free_QCryptoBlockOpenOptions(s->crypto_opts);
 
     g_free(s->unknown_header_fields);
     cleanup_unknown_header_ext(bs);
@@ -4604,60 +4609,6 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
     return ret;
 }
 
-static ssize_t qcow2_measure_crypto_hdr_init_func(QCryptoBlock *block,
-        size_t headerlen, void *opaque, Error **errp)
-{
-    size_t *headerlenp = opaque;
-
-    /* Stash away the payload size */
-    *headerlenp = headerlen;
-    return 0;
-}
-
-static ssize_t qcow2_measure_crypto_hdr_write_func(QCryptoBlock *block,
-        size_t offset, const uint8_t *buf, size_t buflen,
-        void *opaque, Error **errp)
-{
-    /* Discard the bytes, we're not actually writing to an image */
-    return buflen;
-}
-
-/* Determine the number of bytes for the LUKS payload */
-static bool qcow2_measure_luks_headerlen(QemuOpts *opts, size_t *len,
-                                         Error **errp)
-{
-    QDict *opts_qdict;
-    QDict *cryptoopts_qdict;
-    QCryptoBlockCreateOptions *cryptoopts;
-    QCryptoBlock *crypto;
-
-    /* Extract "encrypt." options into a qdict */
-    opts_qdict = qemu_opts_to_qdict(opts, NULL);
-    qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, "encrypt.");
-    qobject_unref(opts_qdict);
-
-    /* Build QCryptoBlockCreateOptions object from qdict */
-    qdict_put_str(cryptoopts_qdict, "format", "luks");
-    cryptoopts = block_crypto_create_opts_init(cryptoopts_qdict, errp);
-    qobject_unref(cryptoopts_qdict);
-    if (!cryptoopts) {
-        return false;
-    }
-
-    /* Fake LUKS creation in order to determine the payload size */
-    crypto = qcrypto_block_create(cryptoopts, "encrypt.",
-                                  qcow2_measure_crypto_hdr_init_func,
-                                  qcow2_measure_crypto_hdr_write_func,
-                                  len, errp);
-    qapi_free_QCryptoBlockCreateOptions(cryptoopts);
-    if (!crypto) {
-        return false;
-    }
-
-    qcrypto_block_free(crypto);
-    return true;
-}
-
 static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
                                        Error **errp)
 {
@@ -4708,9 +4659,27 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
     g_free(optstr);
 
     if (has_luks) {
+        g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
+        QDict *opts_qdict;
+        QDict *cryptoopts;
         size_t headerlen;
 
-        if (!qcow2_measure_luks_headerlen(opts, &headerlen, &local_err)) {
+        opts_qdict = qemu_opts_to_qdict(opts, NULL);
+        qdict_extract_subqdict(opts_qdict, &cryptoopts, "encrypt.");
+        qobject_unref(opts_qdict);
+
+        qdict_put_str(cryptoopts, "format", "luks");
+
+        create_opts = block_crypto_create_opts_init(cryptoopts, errp);
+        qobject_unref(cryptoopts);
+        if (!create_opts) {
+            goto err;
+        }
+
+        if (!qcrypto_block_calculate_payload_offset(create_opts,
+                                                    "encrypt.",
+                                                    &headerlen,
+                                                    &local_err)) {
             goto err;
         }
 
@@ -5534,6 +5503,7 @@ BlockDriver bdrv_qcow2 = {
     .bdrv_close         = qcow2_close,
     .bdrv_reopen_prepare  = qcow2_reopen_prepare,
     .bdrv_reopen_commit   = qcow2_reopen_commit,
+    .bdrv_reopen_commit_post = qcow2_reopen_commit_post,
     .bdrv_reopen_abort    = qcow2_reopen_abort,
     .bdrv_join_options    = qcow2_join_options,
     .bdrv_child_perm      = bdrv_format_default_perms,
index 027cbcc695202db27d1cb17bd573bd0f2ca10b7e..84115d34b4fac1f117e3e52f30b6d24aaa35f68a 100644 (file)
@@ -104,6 +104,7 @@ typedef struct BDRVRBDState {
     rbd_image_t image;
     char *image_name;
     char *snap;
+    char *namespace;
     uint64_t image_size;
 } BDRVRBDState;
 
@@ -152,7 +153,7 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
     const char *start;
     char *p, *buf;
     QList *keypairs = NULL;
-    char *found_str;
+    char *found_str, *image_name;
 
     if (!strstart(filename, "rbd:", &start)) {
         error_setg(errp, "File name must start with 'rbd:'");
@@ -171,18 +172,24 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
     qdict_put_str(options, "pool", found_str);
 
     if (strchr(p, '@')) {
-        found_str = qemu_rbd_next_tok(p, '@', &p);
-        qemu_rbd_unescape(found_str);
-        qdict_put_str(options, "image", found_str);
+        image_name = qemu_rbd_next_tok(p, '@', &p);
 
         found_str = qemu_rbd_next_tok(p, ':', &p);
         qemu_rbd_unescape(found_str);
         qdict_put_str(options, "snapshot", found_str);
     } else {
-        found_str = qemu_rbd_next_tok(p, ':', &p);
+        image_name = qemu_rbd_next_tok(p, ':', &p);
+    }
+    /* Check for namespace in the image_name */
+    if (strchr(image_name, '/')) {
+        found_str = qemu_rbd_next_tok(image_name, '/', &image_name);
         qemu_rbd_unescape(found_str);
-        qdict_put_str(options, "image", found_str);
+        qdict_put_str(options, "namespace", found_str);
+    } else {
+        qdict_put_str(options, "namespace", "");
     }
+    qemu_rbd_unescape(image_name);
+    qdict_put_str(options, "image", image_name);
     if (!p) {
         goto done;
     }
@@ -343,6 +350,11 @@ static QemuOptsList runtime_opts = {
             .type = QEMU_OPT_STRING,
             .help = "Rados pool name",
         },
+        {
+            .name = "namespace",
+            .type = QEMU_OPT_STRING,
+            .help = "Rados namespace name in the pool",
+        },
         {
             .name = "image",
             .type = QEMU_OPT_STRING,
@@ -467,13 +479,14 @@ static int coroutine_fn qemu_rbd_co_create_opts(const char *filename,
      * schema, but when they come from -drive, they're all QString.
      */
     loc = rbd_opts->location;
-    loc->pool     = g_strdup(qdict_get_try_str(options, "pool"));
-    loc->conf     = g_strdup(qdict_get_try_str(options, "conf"));
-    loc->has_conf = !!loc->conf;
-    loc->user     = g_strdup(qdict_get_try_str(options, "user"));
-    loc->has_user = !!loc->user;
-    loc->image    = g_strdup(qdict_get_try_str(options, "image"));
-    keypairs      = qdict_get_try_str(options, "=keyvalue-pairs");
+    loc->pool        = g_strdup(qdict_get_try_str(options, "pool"));
+    loc->conf        = g_strdup(qdict_get_try_str(options, "conf"));
+    loc->has_conf    = !!loc->conf;
+    loc->user        = g_strdup(qdict_get_try_str(options, "user"));
+    loc->has_user    = !!loc->user;
+    loc->q_namespace = g_strdup(qdict_get_try_str(options, "namespace"));
+    loc->image       = g_strdup(qdict_get_try_str(options, "image"));
+    keypairs         = qdict_get_try_str(options, "=keyvalue-pairs");
 
     ret = qemu_rbd_do_create(create_options, keypairs, password_secret, errp);
     if (ret < 0) {
@@ -648,6 +661,11 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
         error_setg_errno(errp, -r, "error opening pool %s", opts->pool);
         goto failed_shutdown;
     }
+    /*
+     * Set the namespace after opening the io context on the pool,
+     * if nspace == NULL or if nspace == "", it is just as we did nothing
+     */
+    rados_ioctx_set_namespace(*io_ctx, opts->q_namespace);
 
     return 0;
 
index 5562ccbf577a20ddd520ec080c2608763109f997..aa2e7af98e37747526efbba6ef1120294e6abc55 100644 (file)
@@ -114,7 +114,6 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
     int64_t offset = 0;
     uint64_t delay_ns = 0;
     int error = 0;
-    int ret = 0;
     int64_t n = 0; /* bytes */
 
     if (bs == s->bottom) {
@@ -139,6 +138,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 
     for ( ; offset < len; offset += n) {
         bool copy;
+        int ret;
 
         /* Note that even when no rate limit is applied we need to yield
          * with no pending I/O here so that bdrv_drain_all() returns.
@@ -183,7 +183,6 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
                 break;
             }
         }
-        ret = 0;
 
         /* Publish progress */
         job_progress_update(&s->common.job, n);
index 1a7329b736f3cecca0c927f50992e25dd905a153..29dff8881cca9f89cb00d4c773fae042b284880b 100644 (file)
@@ -48,6 +48,7 @@ block_copy_process(void *bcs, int64_t start) "bcs %p start %"PRId64
 block_copy_copy_range_fail(void *bcs, int64_t start, int ret) "bcs %p start %"PRId64" ret %d"
 block_copy_read_fail(void *bcs, int64_t start, int ret) "bcs %p start %"PRId64" ret %d"
 block_copy_write_fail(void *bcs, int64_t start, int ret) "bcs %p start %"PRId64" ret %d"
+block_copy_write_zeroes_fail(void *bcs, int64_t start, int ret) "bcs %p start %"PRId64" ret %d"
 
 # ../blockdev.c
 qmp_block_job_cancel(void *job) "job %p"
index de2f2ff7132043be323ffb578c53e42033b2241a..1a95d89f0096a848eab3d2a1d13daade6b0d2227 100644 (file)
@@ -132,6 +132,11 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
     nbd_server = NULL;
 }
 
+void nbd_server_start_options(NbdServerOptions *arg, Error **errp)
+{
+    nbd_server_start(arg->addr, arg->tls_creds, arg->tls_authz, errp);
+}
+
 void qmp_nbd_server_start(SocketAddressLegacy *addr,
                           bool has_tls_creds, const char *tls_creds,
                           bool has_tls_authz, const char *tls_authz,
@@ -143,10 +148,7 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr,
     qapi_free_SocketAddress(addr_flat);
 }
 
-void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
-                        bool has_description, const char *description,
-                        bool has_writable, bool writable,
-                        bool has_bitmap, const char *bitmap, Error **errp)
+void qmp_nbd_server_add(BlockExportNbd *arg, Error **errp)
 {
     BlockDriverState *bs = NULL;
     BlockBackend *on_eject_blk;
@@ -159,28 +161,28 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
         return;
     }
 
-    if (!has_name) {
-        name = device;
+    if (!arg->has_name) {
+        arg->name = arg->device;
     }
 
-    if (strlen(name) > NBD_MAX_STRING_SIZE) {
-        error_setg(errp, "export name '%s' too long", name);
+    if (strlen(arg->name) > NBD_MAX_STRING_SIZE) {
+        error_setg(errp, "export name '%s' too long", arg->name);
         return;
     }
 
-    if (has_description && strlen(description) > NBD_MAX_STRING_SIZE) {
-        error_setg(errp, "description '%s' too long", description);
+    if (arg->description && strlen(arg->description) > NBD_MAX_STRING_SIZE) {
+        error_setg(errp, "description '%s' too long", arg->description);
         return;
     }
 
-    if (nbd_export_find(name)) {
-        error_setg(errp, "NBD server already has export named '%s'", name);
+    if (nbd_export_find(arg->name)) {
+        error_setg(errp, "NBD server already has export named '%s'", arg->name);
         return;
     }
 
-    on_eject_blk = blk_by_name(device);
+    on_eject_blk = blk_by_name(arg->device);
 
-    bs = bdrv_lookup_bs(device, device, errp);
+    bs = bdrv_lookup_bs(arg->device, arg->device, errp);
     if (!bs) {
         return;
     }
@@ -194,15 +196,15 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
         goto out;
     }
 
-    if (!has_writable) {
-        writable = false;
+    if (!arg->has_writable) {
+        arg->writable = false;
     }
     if (bdrv_is_read_only(bs)) {
-        writable = false;
+        arg->writable = false;
     }
 
-    exp = nbd_export_new(bs, 0, len, name, description, bitmap,
-                         !writable, !writable,
+    exp = nbd_export_new(bs, 0, len, arg->name, arg->description, arg->bitmap,
+                         !arg->writable, !arg->writable,
                          NULL, false, on_eject_blk, errp);
     if (!exp) {
         goto out;
index 011dcfec27704514884b7a5684bbc97d57d0772b..257cb376825e6e386f41247ae922238f7d652c83 100644 (file)
 #include "qemu/main-loop.h"
 #include "qemu/throttle-options.h"
 
-static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
+QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
     QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
 
-static int do_open_tray(const char *blk_name, const char *qdev_id,
-                        bool force, Error **errp);
-static void blockdev_remove_medium(bool has_device, const char *device,
-                                   bool has_id, const char *id, Error **errp);
-static void blockdev_insert_medium(bool has_device, const char *device,
-                                   bool has_id, const char *id,
-                                   const char *node_name, Error **errp);
+void bdrv_set_monitor_owned(BlockDriverState *bs)
+{
+    QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
+}
 
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
@@ -648,7 +645,7 @@ err_no_opts:
 }
 
 /* Takes the ownership of bs_opts */
-static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
+BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
 {
     int bdrv_flags = 0;
 
@@ -1047,64 +1044,6 @@ static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp)
     return bs;
 }
 
-static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
-                                 Error **errp)
-{
-    BlockBackend *blk;
-
-    if (!blk_name == !qdev_id) {
-        error_setg(errp, "Need exactly one of 'device' and 'id'");
-        return NULL;
-    }
-
-    if (qdev_id) {
-        blk = blk_by_qdev_id(qdev_id, errp);
-    } else {
-        blk = blk_by_name(blk_name);
-        if (blk == NULL) {
-            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
-                      "Device '%s' not found", blk_name);
-        }
-    }
-
-    return blk;
-}
-
-void hmp_commit(Monitor *mon, const QDict *qdict)
-{
-    const char *device = qdict_get_str(qdict, "device");
-    BlockBackend *blk;
-    int ret;
-
-    if (!strcmp(device, "all")) {
-        ret = blk_commit_all();
-    } else {
-        BlockDriverState *bs;
-        AioContext *aio_context;
-
-        blk = blk_by_name(device);
-        if (!blk) {
-            error_report("Device '%s' not found", device);
-            return;
-        }
-        if (!blk_is_available(blk)) {
-            error_report("Device '%s' has no medium", device);
-            return;
-        }
-
-        bs = blk_bs(blk);
-        aio_context = bdrv_get_aio_context(bs);
-        aio_context_acquire(aio_context);
-
-        ret = bdrv_commit(bs);
-
-        aio_context_release(aio_context);
-    }
-    if (ret < 0) {
-        error_report("'commit' error for '%s': %s", device, strerror(-ret));
-    }
-}
-
 static void blockdev_do_action(TransactionAction *action, Error **errp)
 {
     TransactionActionList list;
@@ -2508,29 +2447,6 @@ exit:
     job_txn_unref(block_job_txn);
 }
 
-void qmp_eject(bool has_device, const char *device,
-               bool has_id, const char *id,
-               bool has_force, bool force, Error **errp)
-{
-    Error *local_err = NULL;
-    int rc;
-
-    if (!has_force) {
-        force = false;
-    }
-
-    rc = do_open_tray(has_device ? device : NULL,
-                      has_id ? id : NULL,
-                      force, &local_err);
-    if (rc && rc != -ENOSYS) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    error_free(local_err);
-
-    blockdev_remove_medium(has_device, device, has_id, id, errp);
-}
-
 void qmp_block_passwd(bool has_device, const char *device,
                       bool has_node_name, const char *node_name,
                       const char *password, Error **errp)
@@ -2539,455 +2455,6 @@ void qmp_block_passwd(bool has_device, const char *device,
                "Setting block passwords directly is no longer supported");
 }
 
-/*
- * Attempt to open the tray of @device.
- * If @force, ignore its tray lock.
- * Else, if the tray is locked, don't open it, but ask the guest to open it.
- * On error, store an error through @errp and return -errno.
- * If @device does not exist, return -ENODEV.
- * If it has no removable media, return -ENOTSUP.
- * If it has no tray, return -ENOSYS.
- * If the guest was asked to open the tray, return -EINPROGRESS.
- * Else, return 0.
- */
-static int do_open_tray(const char *blk_name, const char *qdev_id,
-                        bool force, Error **errp)
-{
-    BlockBackend *blk;
-    const char *device = qdev_id ?: blk_name;
-    bool locked;
-
-    blk = qmp_get_blk(blk_name, qdev_id, errp);
-    if (!blk) {
-        return -ENODEV;
-    }
-
-    if (!blk_dev_has_removable_media(blk)) {
-        error_setg(errp, "Device '%s' is not removable", device);
-        return -ENOTSUP;
-    }
-
-    if (!blk_dev_has_tray(blk)) {
-        error_setg(errp, "Device '%s' does not have a tray", device);
-        return -ENOSYS;
-    }
-
-    if (blk_dev_is_tray_open(blk)) {
-        return 0;
-    }
-
-    locked = blk_dev_is_medium_locked(blk);
-    if (locked) {
-        blk_dev_eject_request(blk, force);
-    }
-
-    if (!locked || force) {
-        blk_dev_change_media_cb(blk, false, &error_abort);
-    }
-
-    if (locked && !force) {
-        error_setg(errp, "Device '%s' is locked and force was not specified, "
-                   "wait for tray to open and try again", device);
-        return -EINPROGRESS;
-    }
-
-    return 0;
-}
-
-void qmp_blockdev_open_tray(bool has_device, const char *device,
-                            bool has_id, const char *id,
-                            bool has_force, bool force,
-                            Error **errp)
-{
-    Error *local_err = NULL;
-    int rc;
-
-    if (!has_force) {
-        force = false;
-    }
-    rc = do_open_tray(has_device ? device : NULL,
-                      has_id ? id : NULL,
-                      force, &local_err);
-    if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    error_free(local_err);
-}
-
-void qmp_blockdev_close_tray(bool has_device, const char *device,
-                             bool has_id, const char *id,
-                             Error **errp)
-{
-    BlockBackend *blk;
-    Error *local_err = NULL;
-
-    device = has_device ? device : NULL;
-    id = has_id ? id : NULL;
-
-    blk = qmp_get_blk(device, id, errp);
-    if (!blk) {
-        return;
-    }
-
-    if (!blk_dev_has_removable_media(blk)) {
-        error_setg(errp, "Device '%s' is not removable", device ?: id);
-        return;
-    }
-
-    if (!blk_dev_has_tray(blk)) {
-        /* Ignore this command on tray-less devices */
-        return;
-    }
-
-    if (!blk_dev_is_tray_open(blk)) {
-        return;
-    }
-
-    blk_dev_change_media_cb(blk, true, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-}
-
-static void blockdev_remove_medium(bool has_device, const char *device,
-                                   bool has_id, const char *id, Error **errp)
-{
-    BlockBackend *blk;
-    BlockDriverState *bs;
-    AioContext *aio_context;
-    bool has_attached_device;
-
-    device = has_device ? device : NULL;
-    id = has_id ? id : NULL;
-
-    blk = qmp_get_blk(device, id, errp);
-    if (!blk) {
-        return;
-    }
-
-    /* For BBs without a device, we can exchange the BDS tree at will */
-    has_attached_device = blk_get_attached_dev(blk);
-
-    if (has_attached_device && !blk_dev_has_removable_media(blk)) {
-        error_setg(errp, "Device '%s' is not removable", device ?: id);
-        return;
-    }
-
-    if (has_attached_device && blk_dev_has_tray(blk) &&
-        !blk_dev_is_tray_open(blk))
-    {
-        error_setg(errp, "Tray of device '%s' is not open", device ?: id);
-        return;
-    }
-
-    bs = blk_bs(blk);
-    if (!bs) {
-        return;
-    }
-
-    aio_context = bdrv_get_aio_context(bs);
-    aio_context_acquire(aio_context);
-
-    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
-        goto out;
-    }
-
-    blk_remove_bs(blk);
-
-    if (!blk_dev_has_tray(blk)) {
-        /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
-         * called at all); therefore, the medium needs to be ejected here.
-         * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
-         * value passed here (i.e. false). */
-        blk_dev_change_media_cb(blk, false, &error_abort);
-    }
-
-out:
-    aio_context_release(aio_context);
-}
-
-void qmp_blockdev_remove_medium(const char *id, Error **errp)
-{
-    blockdev_remove_medium(false, NULL, true, id, errp);
-}
-
-static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
-                                            BlockDriverState *bs, Error **errp)
-{
-    Error *local_err = NULL;
-    bool has_device;
-    int ret;
-
-    /* For BBs without a device, we can exchange the BDS tree at will */
-    has_device = blk_get_attached_dev(blk);
-
-    if (has_device && !blk_dev_has_removable_media(blk)) {
-        error_setg(errp, "Device is not removable");
-        return;
-    }
-
-    if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
-        error_setg(errp, "Tray of the device is not open");
-        return;
-    }
-
-    if (blk_bs(blk)) {
-        error_setg(errp, "There already is a medium in the device");
-        return;
-    }
-
-    ret = blk_insert_bs(blk, bs, errp);
-    if (ret < 0) {
-        return;
-    }
-
-    if (!blk_dev_has_tray(blk)) {
-        /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
-         * called at all); therefore, the medium needs to be pushed into the
-         * slot here.
-         * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
-         * value passed here (i.e. true). */
-        blk_dev_change_media_cb(blk, true, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            blk_remove_bs(blk);
-            return;
-        }
-    }
-}
-
-static void blockdev_insert_medium(bool has_device, const char *device,
-                                   bool has_id, const char *id,
-                                   const char *node_name, Error **errp)
-{
-    BlockBackend *blk;
-    BlockDriverState *bs;
-
-    blk = qmp_get_blk(has_device ? device : NULL,
-                      has_id ? id : NULL,
-                      errp);
-    if (!blk) {
-        return;
-    }
-
-    bs = bdrv_find_node(node_name);
-    if (!bs) {
-        error_setg(errp, "Node '%s' not found", node_name);
-        return;
-    }
-
-    if (bdrv_has_blk(bs)) {
-        error_setg(errp, "Node '%s' is already in use", node_name);
-        return;
-    }
-
-    qmp_blockdev_insert_anon_medium(blk, bs, errp);
-}
-
-void qmp_blockdev_insert_medium(const char *id, const char *node_name,
-                                Error **errp)
-{
-    blockdev_insert_medium(false, NULL, true, id, node_name, errp);
-}
-
-void qmp_blockdev_change_medium(bool has_device, const char *device,
-                                bool has_id, const char *id,
-                                const char *filename,
-                                bool has_format, const char *format,
-                                bool has_read_only,
-                                BlockdevChangeReadOnlyMode read_only,
-                                Error **errp)
-{
-    BlockBackend *blk;
-    BlockDriverState *medium_bs = NULL;
-    int bdrv_flags;
-    bool detect_zeroes;
-    int rc;
-    QDict *options = NULL;
-    Error *err = NULL;
-
-    blk = qmp_get_blk(has_device ? device : NULL,
-                      has_id ? id : NULL,
-                      errp);
-    if (!blk) {
-        goto fail;
-    }
-
-    if (blk_bs(blk)) {
-        blk_update_root_state(blk);
-    }
-
-    bdrv_flags = blk_get_open_flags_from_root_state(blk);
-    bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
-        BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
-
-    if (!has_read_only) {
-        read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
-    }
-
-    switch (read_only) {
-    case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
-        break;
-
-    case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
-        bdrv_flags &= ~BDRV_O_RDWR;
-        break;
-
-    case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
-        bdrv_flags |= BDRV_O_RDWR;
-        break;
-
-    default:
-        abort();
-    }
-
-    options = qdict_new();
-    detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
-    qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
-
-    if (has_format) {
-        qdict_put_str(options, "driver", format);
-    }
-
-    medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
-    if (!medium_bs) {
-        goto fail;
-    }
-
-    rc = do_open_tray(has_device ? device : NULL,
-                      has_id ? id : NULL,
-                      false, &err);
-    if (rc && rc != -ENOSYS) {
-        error_propagate(errp, err);
-        goto fail;
-    }
-    error_free(err);
-    err = NULL;
-
-    blockdev_remove_medium(has_device, device, has_id, id, &err);
-    if (err) {
-        error_propagate(errp, err);
-        goto fail;
-    }
-
-    qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
-    if (err) {
-        error_propagate(errp, err);
-        goto fail;
-    }
-
-    qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
-
-fail:
-    /* If the medium has been inserted, the device has its own reference, so
-     * ours must be relinquished; and if it has not been inserted successfully,
-     * the reference must be relinquished anyway */
-    bdrv_unref(medium_bs);
-}
-
-/* throttling disk I/O limits */
-void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
-{
-    ThrottleConfig cfg;
-    BlockDriverState *bs;
-    BlockBackend *blk;
-    AioContext *aio_context;
-
-    blk = qmp_get_blk(arg->has_device ? arg->device : NULL,
-                      arg->has_id ? arg->id : NULL,
-                      errp);
-    if (!blk) {
-        return;
-    }
-
-    aio_context = blk_get_aio_context(blk);
-    aio_context_acquire(aio_context);
-
-    bs = blk_bs(blk);
-    if (!bs) {
-        error_setg(errp, "Device has no medium");
-        goto out;
-    }
-
-    throttle_config_init(&cfg);
-    cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
-    cfg.buckets[THROTTLE_BPS_READ].avg  = arg->bps_rd;
-    cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
-
-    cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
-    cfg.buckets[THROTTLE_OPS_READ].avg  = arg->iops_rd;
-    cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
-
-    if (arg->has_bps_max) {
-        cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
-    }
-    if (arg->has_bps_rd_max) {
-        cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
-    }
-    if (arg->has_bps_wr_max) {
-        cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
-    }
-    if (arg->has_iops_max) {
-        cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
-    }
-    if (arg->has_iops_rd_max) {
-        cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
-    }
-    if (arg->has_iops_wr_max) {
-        cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
-    }
-
-    if (arg->has_bps_max_length) {
-        cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
-    }
-    if (arg->has_bps_rd_max_length) {
-        cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
-    }
-    if (arg->has_bps_wr_max_length) {
-        cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
-    }
-    if (arg->has_iops_max_length) {
-        cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
-    }
-    if (arg->has_iops_rd_max_length) {
-        cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
-    }
-    if (arg->has_iops_wr_max_length) {
-        cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
-    }
-
-    if (arg->has_iops_size) {
-        cfg.op_size = arg->iops_size;
-    }
-
-    if (!throttle_is_valid(&cfg, errp)) {
-        goto out;
-    }
-
-    if (throttle_enabled(&cfg)) {
-        /* Enable I/O limits if they're not enabled yet, otherwise
-         * just update the throttling group. */
-        if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
-            blk_io_limits_enable(blk,
-                                 arg->has_group ? arg->group :
-                                 arg->has_device ? arg->device :
-                                 arg->id);
-        } else if (arg->has_group) {
-            blk_io_limits_update_group(blk, arg->group);
-        }
-        /* Set the new throttling configuration */
-        blk_set_io_limits(blk, &cfg);
-    } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
-        /* If all throttling settings are set to 0, disable I/O limits */
-        blk_io_limits_disable(blk);
-    }
-
-out:
-    aio_context_release(aio_context);
-}
-
 void qmp_block_dirty_bitmap_add(const char *node, const char *name,
                                 bool has_granularity, uint32_t granularity,
                                 bool has_persistent, bool persistent,
@@ -3250,66 +2717,6 @@ BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
     return ret;
 }
 
-void hmp_drive_del(Monitor *mon, const QDict *qdict)
-{
-    const char *id = qdict_get_str(qdict, "id");
-    BlockBackend *blk;
-    BlockDriverState *bs;
-    AioContext *aio_context;
-    Error *local_err = NULL;
-
-    bs = bdrv_find_node(id);
-    if (bs) {
-        qmp_blockdev_del(id, &local_err);
-        if (local_err) {
-            error_report_err(local_err);
-        }
-        return;
-    }
-
-    blk = blk_by_name(id);
-    if (!blk) {
-        error_report("Device '%s' not found", id);
-        return;
-    }
-
-    if (!blk_legacy_dinfo(blk)) {
-        error_report("Deleting device added with blockdev-add"
-                     " is not supported");
-        return;
-    }
-
-    aio_context = blk_get_aio_context(blk);
-    aio_context_acquire(aio_context);
-
-    bs = blk_bs(blk);
-    if (bs) {
-        if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
-            error_report_err(local_err);
-            aio_context_release(aio_context);
-            return;
-        }
-
-        blk_remove_bs(blk);
-    }
-
-    /* Make the BlockBackend and the attached BlockDriverState anonymous */
-    monitor_remove_blk(blk);
-
-    /* If this BlockBackend has a device attached to it, its refcount will be
-     * decremented when the device is removed; otherwise we have to do so here.
-     */
-    if (blk_get_attached_dev(blk)) {
-        /* Further I/O must not pause the guest */
-        blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT,
-                         BLOCKDEV_ON_ERROR_REPORT);
-    } else {
-        blk_unref(blk);
-    }
-
-    aio_context_release(aio_context);
-}
-
 void qmp_block_resize(bool has_device, const char *device,
                       bool has_node_name, const char *node_name,
                       int64_t size, Error **errp)
@@ -4317,37 +3724,6 @@ out:
     aio_context_release(aio_context);
 }
 
-void hmp_drive_add_node(Monitor *mon, const char *optstr)
-{
-    QemuOpts *opts;
-    QDict *qdict;
-    Error *local_err = NULL;
-
-    opts = qemu_opts_parse_noisily(&qemu_drive_opts, optstr, false);
-    if (!opts) {
-        return;
-    }
-
-    qdict = qemu_opts_to_qdict(opts, NULL);
-
-    if (!qdict_get_try_str(qdict, "node-name")) {
-        qobject_unref(qdict);
-        error_report("'node-name' needs to be specified");
-        goto out;
-    }
-
-    BlockDriverState *bs = bds_tree_init(qdict, &local_err);
-    if (!bs) {
-        error_report_err(local_err);
-        goto out;
-    }
-
-    QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
-
-out:
-    qemu_opts_del(opts);
-}
-
 void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
 {
     BlockDriverState *bs;
@@ -4377,7 +3753,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
         goto fail;
     }
 
-    QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
+    bdrv_set_monitor_owned(bs);
 
 fail:
     visit_free(v);
@@ -4595,62 +3971,6 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
     aio_context_release(old_context);
 }
 
-void qmp_block_latency_histogram_set(
-    const char *id,
-    bool has_boundaries, uint64List *boundaries,
-    bool has_boundaries_read, uint64List *boundaries_read,
-    bool has_boundaries_write, uint64List *boundaries_write,
-    bool has_boundaries_flush, uint64List *boundaries_flush,
-    Error **errp)
-{
-    BlockBackend *blk = qmp_get_blk(NULL, id, errp);
-    BlockAcctStats *stats;
-    int ret;
-
-    if (!blk) {
-        return;
-    }
-
-    stats = blk_get_stats(blk);
-
-    if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
-        !has_boundaries_flush)
-    {
-        block_latency_histograms_clear(stats);
-        return;
-    }
-
-    if (has_boundaries || has_boundaries_read) {
-        ret = block_latency_histogram_set(
-            stats, BLOCK_ACCT_READ,
-            has_boundaries_read ? boundaries_read : boundaries);
-        if (ret) {
-            error_setg(errp, "Device '%s' set read boundaries fail", id);
-            return;
-        }
-    }
-
-    if (has_boundaries || has_boundaries_write) {
-        ret = block_latency_histogram_set(
-            stats, BLOCK_ACCT_WRITE,
-            has_boundaries_write ? boundaries_write : boundaries);
-        if (ret) {
-            error_setg(errp, "Device '%s' set write boundaries fail", id);
-            return;
-        }
-    }
-
-    if (has_boundaries || has_boundaries_flush) {
-        ret = block_latency_histogram_set(
-            stats, BLOCK_ACCT_FLUSH,
-            has_boundaries_flush ? boundaries_flush : boundaries);
-        if (ret) {
-            error_setg(errp, "Device '%s' set flush boundaries fail", id);
-            return;
-        }
-    }
-}
-
 QemuOptsList qemu_common_drive_opts = {
     .name = "drive",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
index 5d63b1e89dfc39d8887bc76405841b20ac41a8d0..fc850312c124ea62fdbf83f4f2ba7320b2ae406a 100644 (file)
@@ -299,8 +299,8 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
     info->device    = g_strdup(job->job.id);
     info->busy      = atomic_read(&job->job.busy);
     info->paused    = job->job.pause_count > 0;
-    info->offset    = job->job.progress_current;
-    info->len       = job->job.progress_total;
+    info->offset    = job->job.progress.current;
+    info->len       = job->job.progress.total;
     info->speed     = job->speed;
     info->io_status = job->iostatus;
     info->ready     = job_is_ready(&job->job),
@@ -330,8 +330,8 @@ static void block_job_event_cancelled(Notifier *n, void *opaque)
 
     qapi_event_send_block_job_cancelled(job_type(&job->job),
                                         job->job.id,
-                                        job->job.progress_total,
-                                        job->job.progress_current,
+                                        job->job.progress.total,
+                                        job->job.progress.current,
                                         job->speed);
 }
 
@@ -350,8 +350,8 @@ static void block_job_event_completed(Notifier *n, void *opaque)
 
     qapi_event_send_block_job_completed(job_type(&job->job),
                                         job->job.id,
-                                        job->job.progress_total,
-                                        job->job.progress_current,
+                                        job->job.progress.total,
+                                        job->job.progress.current,
                                         job->speed,
                                         !!msg,
                                         msg);
@@ -379,8 +379,8 @@ static void block_job_event_ready(Notifier *n, void *opaque)
 
     qapi_event_send_block_job_ready(job_type(&job->job),
                                     job->job.id,
-                                    job->job.progress_total,
-                                    job->job.progress_current,
+                                    job->job.progress.total,
+                                    job->job.progress.current,
                                     job->speed);
 }
 
index 94d714ffcd0ab1914b1b97fb53436e4535b1d3e1..fd12c9e63b5313cdfd972aa815b7db4ae659dff7 100644 (file)
@@ -70,7 +70,7 @@ static int win_chr_pipe_init(Chardev *chr, const char *filename,
                               MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
     g_free(openname);
     if (s->file == INVALID_HANDLE_VALUE) {
-        error_setg(errp, "Failed CreateNamedPipe (%lu)", GetLastError());
+        error_setg_win32(errp, GetLastError(), "Failed CreateNamedPipe");
         s->file = NULL;
         goto fail;
     }
index 34825f683dbaa752fcfd6168916d142489a280a5..d4fb44c4dcc5faefd8abc8e699324e9b6874022b 100644 (file)
@@ -96,7 +96,7 @@ int win_chr_serial_init(Chardev *chr, const char *filename, Error **errp)
     s->file = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                       OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
     if (s->file == INVALID_HANDLE_VALUE) {
-        error_setg(errp, "Failed CreateFile (%lu)", GetLastError());
+        error_setg_win32(errp, GetLastError(), "Failed CreateFile");
         s->file = NULL;
         goto fail;
     }
index 87237568dff3725295a69aa531789f83b50077f6..e77564060dbc8d60e964787b91501ff9dc77c53b 100644 (file)
@@ -737,7 +737,13 @@ Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
 
     if (qemu_opt_get_bool(opts, "mux", 0)) {
         assert(permit_mux_mon);
-        monitor_init_hmp(chr, true);
+        monitor_init_hmp(chr, true, &err);
+        if (err) {
+            error_report_err(err);
+            object_unparent(OBJECT(chr));
+            chr = NULL;
+            goto out;
+        }
     }
 
 out:
index 7b373bc0bb846da54286213b9650c3a2b7ff98d2..3c7470096ffb4fc9b68475c2eb8b306027c8cf30 100755 (executable)
--- a/configure
+++ b/configure
@@ -936,6 +936,17 @@ do
     fi
 done
 
+# Check for ancillary tools used in testing
+genisoimage=
+for binary in genisoimage
+do
+    if has $binary
+    then
+        genisoimage=$(command -v "$binary")
+        break
+    fi
+done
+
 : ${smbd=${SMBD-/usr/sbin/smbd}}
 
 # Default objcc to clang if available, otherwise use CC
@@ -4082,6 +4093,11 @@ if test "$linux_io_uring" != "no" ; then
     linux_io_uring_cflags=$($pkg_config --cflags liburing)
     linux_io_uring_libs=$($pkg_config --libs liburing)
     linux_io_uring=yes
+
+    # io_uring is used in libqemuutil.a where per-file -libs variables are not
+    # seen by programs linking the archive.  It's not ideal, but just add the
+    # library dependency globally.
+    LIBS="$linux_io_uring_libs $LIBS"
   else
     if test "$linux_io_uring" = "yes" ; then
       feature_not_found "linux io_uring" "Install liburing devel"
@@ -6305,7 +6321,7 @@ tools=""
 if test "$want_tools" = "yes" ; then
   tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) qemu-edid\$(EXESUF) $tools"
   if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
-    tools="qemu-nbd\$(EXESUF) $tools"
+    tools="qemu-nbd\$(EXESUF) qemu-storage-daemon\$(EXESUF) $tools"
   fi
   if [ "$ivshmem" = "yes" ]; then
     tools="ivshmem-client\$(EXESUF) ivshmem-server\$(EXESUF) $tools"
@@ -6567,6 +6583,7 @@ echo "python            $python ($python_version)"
 if test "$docs" != "no"; then
     echo "sphinx-build      $sphinx_build"
 fi
+echo "genisoimage       $genisoimage"
 echo "slirp support     $slirp $(echo_version $slirp $slirp_version)"
 if test "$slirp" != "no" ; then
     echo "smbd              $smbd"
@@ -7616,6 +7633,7 @@ echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
 echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak
 echo "PYTHON=$python" >> $config_host_mak
 echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak
+echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 if $iasl -h > /dev/null 2>&1; then
   echo "IASL=$iasl" >> $config_host_mak
index 325752871cde1e91511c9a03329e6023a396236c..6f42b32f1edbcbd4d40f7433b7af1e5588805b03 100644 (file)
@@ -115,6 +115,42 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
 }
 
 
+static ssize_t qcrypto_block_headerlen_hdr_init_func(QCryptoBlock *block,
+        size_t headerlen, void *opaque, Error **errp)
+{
+    size_t *headerlenp = opaque;
+
+    /* Stash away the payload size */
+    *headerlenp = headerlen;
+    return 0;
+}
+
+
+static ssize_t qcrypto_block_headerlen_hdr_write_func(QCryptoBlock *block,
+        size_t offset, const uint8_t *buf, size_t buflen,
+        void *opaque, Error **errp)
+{
+    /* Discard the bytes, we're not actually writing to an image */
+    return buflen;
+}
+
+
+bool
+qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts,
+                                       const char *optprefix,
+                                       size_t *len,
+                                       Error **errp)
+{
+    /* Fake LUKS creation in order to determine the payload size */
+    g_autoptr(QCryptoBlock) crypto =
+        qcrypto_block_create(create_opts, optprefix,
+                             qcrypto_block_headerlen_hdr_init_func,
+                             qcrypto_block_headerlen_hdr_write_func,
+                             len, errp);
+    return crypto != NULL;
+}
+
+
 QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
                                          Error **errp)
 {
index 4cc64dafa2d20ab26f29374bb7198174e7e09223..84d1a2487cdd654ac8d9827a7155c1c586dfa34b 100644 (file)
@@ -20,7 +20,7 @@
 #CONFIG_SGA=n
 #CONFIG_TEST_DEVICES=n
 #CONFIG_TPM_CRB=n
-#CONFIG_TPM_TIS=n
+#CONFIG_TPM_TIS_ISA=n
 #CONFIG_VTD=n
 
 # Boards:
diff --git a/device-hotplug.c b/device-hotplug.c
deleted file mode 100644 (file)
index f01d537..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * QEMU device hotplug helpers
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "hw/boards.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/error.h"
-#include "qemu/config-file.h"
-#include "qemu/option.h"
-#include "sysemu/sysemu.h"
-#include "monitor/monitor.h"
-#include "block/block_int.h"
-
-static DriveInfo *add_init_drive(const char *optstr)
-{
-    Error *err = NULL;
-    DriveInfo *dinfo;
-    QemuOpts *opts;
-    MachineClass *mc;
-
-    opts = drive_def(optstr);
-    if (!opts)
-        return NULL;
-
-    mc = MACHINE_GET_CLASS(current_machine);
-    dinfo = drive_new(opts, mc->block_default_type, &err);
-    if (err) {
-        error_report_err(err);
-        qemu_opts_del(opts);
-        return NULL;
-    }
-
-    return dinfo;
-}
-
-void hmp_drive_add(Monitor *mon, const QDict *qdict)
-{
-    DriveInfo *dinfo = NULL;
-    const char *opts = qdict_get_str(qdict, "opts");
-    bool node = qdict_get_try_bool(qdict, "node", false);
-
-    if (node) {
-        hmp_drive_add_node(mon, opts);
-        return;
-    }
-
-    dinfo = add_init_drive(opts);
-    if (!dinfo) {
-        goto err;
-    }
-
-    switch (dinfo->type) {
-    case IF_NONE:
-        monitor_printf(mon, "OK\n");
-        break;
-    default:
-        monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
-        goto err;
-    }
-    return;
-
-err:
-    if (dinfo) {
-        BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-        monitor_remove_blk(blk);
-        blk_unref(blk);
-    }
-}
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
deleted file mode 100644 (file)
index fc1623a..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-================
-ARM CPU Features
-================
-
-Examples of probing and using ARM CPU features
-
-Introduction
-============
-
-CPU features are optional features that a CPU of supporting type may
-choose to implement or not.  In QEMU, optional CPU features have
-corresponding boolean CPU proprieties that, when enabled, indicate
-that the feature is implemented, and, conversely, when disabled,
-indicate that it is not implemented. An example of an ARM CPU feature
-is the Performance Monitoring Unit (PMU).  CPU types such as the
-Cortex-A15 and the Cortex-A57, which respectively implement ARM
-architecture reference manuals ARMv7-A and ARMv8-A, may both optionally
-implement PMUs.  For example, if a user wants to use a Cortex-A15 without
-a PMU, then the `-cpu` parameter should contain `pmu=off` on the QEMU
-command line, i.e. `-cpu cortex-a15,pmu=off`.
-
-As not all CPU types support all optional CPU features, then whether or
-not a CPU property exists depends on the CPU type.  For example, CPUs
-that implement the ARMv8-A architecture reference manual may optionally
-support the AArch32 CPU feature, which may be enabled by disabling the
-`aarch64` CPU property.  A CPU type such as the Cortex-A15, which does
-not implement ARMv8-A, will not have the `aarch64` CPU property.
-
-QEMU's support may be limited for some CPU features, only partially
-supporting the feature or only supporting the feature under certain
-configurations.  For example, the `aarch64` CPU feature, which, when
-disabled, enables the optional AArch32 CPU feature, is only supported
-when using the KVM accelerator and when running on a host CPU type that
-supports the feature.  While `aarch64` currently only works with KVM,
-it could work with TCG.  CPU features that are specific to KVM are
-prefixed with "kvm-" and are described in "KVM VCPU Features".
-
-CPU Feature Probing
-===================
-
-Determining which CPU features are available and functional for a given
-CPU type is possible with the `query-cpu-model-expansion` QMP command.
-Below are some examples where `scripts/qmp/qmp-shell` (see the top comment
-block in the script for usage) is used to issue the QMP commands.
-
-1. Determine which CPU features are available for the `max` CPU type
-   (Note, we started QEMU with qemu-system-aarch64, so `max` is
-   implementing the ARMv8-A reference manual in this case)::
-
-      (QEMU) query-cpu-model-expansion type=full model={"name":"max"}
-      { "return": {
-        "model": { "name": "max", "props": {
-        "sve1664": true, "pmu": true, "sve1792": true, "sve1920": true,
-        "sve128": true, "aarch64": true, "sve1024": true, "sve": true,
-        "sve640": true, "sve768": true, "sve1408": true, "sve256": true,
-        "sve1152": true, "sve512": true, "sve384": true, "sve1536": true,
-        "sve896": true, "sve1280": true, "sve2048": true
-      }}}}
-
-We see that the `max` CPU type has the `pmu`, `aarch64`, `sve`, and many
-`sve<N>` CPU features.  We also see that all the CPU features are
-enabled, as they are all `true`.  (The `sve<N>` CPU features are all
-optional SVE vector lengths (see "SVE CPU Properties").  While with TCG
-all SVE vector lengths can be supported, when KVM is in use it's more
-likely that only a few lengths will be supported, if SVE is supported at
-all.)
-
-(2) Let's try to disable the PMU::
-
-      (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"pmu":false}}
-      { "return": {
-        "model": { "name": "max", "props": {
-        "sve1664": true, "pmu": false, "sve1792": true, "sve1920": true,
-        "sve128": true, "aarch64": true, "sve1024": true, "sve": true,
-        "sve640": true, "sve768": true, "sve1408": true, "sve256": true,
-        "sve1152": true, "sve512": true, "sve384": true, "sve1536": true,
-        "sve896": true, "sve1280": true, "sve2048": true
-      }}}}
-
-We see it worked, as `pmu` is now `false`.
-
-(3) Let's try to disable `aarch64`, which enables the AArch32 CPU feature::
-
-      (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"aarch64":false}}
-      {"error": {
-       "class": "GenericError", "desc":
-       "'aarch64' feature cannot be disabled unless KVM is enabled and 32-bit EL1 is supported"
-      }}
-
-It looks like this feature is limited to a configuration we do not
-currently have.
-
-(4) Let's disable `sve` and see what happens to all the optional SVE
-    vector lengths::
-
-      (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"sve":false}}
-      { "return": {
-        "model": { "name": "max", "props": {
-        "sve1664": false, "pmu": true, "sve1792": false, "sve1920": false,
-        "sve128": false, "aarch64": true, "sve1024": false, "sve": false,
-        "sve640": false, "sve768": false, "sve1408": false, "sve256": false,
-        "sve1152": false, "sve512": false, "sve384": false, "sve1536": false,
-        "sve896": false, "sve1280": false, "sve2048": false
-      }}}}
-
-As expected they are now all `false`.
-
-(5) Let's try probing CPU features for the Cortex-A15 CPU type::
-
-      (QEMU) query-cpu-model-expansion type=full model={"name":"cortex-a15"}
-      {"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}}
-
-Only the `pmu` CPU feature is available.
-
-A note about CPU feature dependencies
--------------------------------------
-
-It's possible for features to have dependencies on other features. I.e.
-it may be possible to change one feature at a time without error, but
-when attempting to change all features at once an error could occur
-depending on the order they are processed.  It's also possible changing
-all at once doesn't generate an error, because a feature's dependencies
-are satisfied with other features, but the same feature cannot be changed
-independently without error.  For these reasons callers should always
-attempt to make their desired changes all at once in order to ensure the
-collection is valid.
-
-A note about CPU models and KVM
--------------------------------
-
-Named CPU models generally do not work with KVM.  There are a few cases
-that do work, e.g. using the named CPU model `cortex-a57` with KVM on a
-seattle host, but mostly if KVM is enabled the `host` CPU type must be
-used.  This means the guest is provided all the same CPU features as the
-host CPU type has.  And, for this reason, the `host` CPU type should
-enable all CPU features that the host has by default.  Indeed it's even
-a bit strange to allow disabling CPU features that the host has when using
-the `host` CPU type, but in the absence of CPU models it's the best we can
-do if we want to launch guests without all the host's CPU features enabled.
-
-Enabling KVM also affects the `query-cpu-model-expansion` QMP command.  The
-affect is not only limited to specific features, as pointed out in example
-(3) of "CPU Feature Probing", but also to which CPU types may be expanded.
-When KVM is enabled, only the `max`, `host`, and current CPU type may be
-expanded.  This restriction is necessary as it's not possible to know all
-CPU types that may work with KVM, but it does impose a small risk of users
-experiencing unexpected errors.  For example on a seattle, as mentioned
-above, the `cortex-a57` CPU type is also valid when KVM is enabled.
-Therefore a user could use the `host` CPU type for the current type, but
-then attempt to query `cortex-a57`, however that query will fail with our
-restrictions.  This shouldn't be an issue though as management layers and
-users have been preferring the `host` CPU type for use with KVM for quite
-some time.  Additionally, if the KVM-enabled QEMU instance running on a
-seattle host is using the `cortex-a57` CPU type, then querying `cortex-a57`
-will work.
-
-Using CPU Features
-==================
-
-After determining which CPU features are available and supported for a
-given CPU type, then they may be selectively enabled or disabled on the
-QEMU command line with that CPU type::
-
-  $ qemu-system-aarch64 -M virt -cpu max,pmu=off,sve=on,sve128=on,sve256=on
-
-The example above disables the PMU and enables the first two SVE vector
-lengths for the `max` CPU type.  Note, the `sve=on` isn't actually
-necessary, because, as we observed above with our probe of the `max` CPU
-type, `sve` is already on by default.  Also, based on our probe of
-defaults, it would seem we need to disable many SVE vector lengths, rather
-than only enabling the two we want.  This isn't the case, because, as
-disabling many SVE vector lengths would be quite verbose, the `sve<N>` CPU
-properties have special semantics (see "SVE CPU Property Parsing
-Semantics").
-
-KVM VCPU Features
-=================
-
-KVM VCPU features are CPU features that are specific to KVM, such as
-paravirt features or features that enable CPU virtualization extensions.
-The features' CPU properties are only available when KVM is enabled and
-are named with the prefix "kvm-".  KVM VCPU features may be probed,
-enabled, and disabled in the same way as other CPU features.  Below is
-the list of KVM VCPU features and their descriptions.
-
-  kvm-no-adjvtime          By default kvm-no-adjvtime is disabled.  This
-                           means that by default the virtual time
-                           adjustment is enabled (vtime is not *not*
-                           adjusted).
-
-                           When virtual time adjustment is enabled each
-                           time the VM transitions back to running state
-                           the VCPU's virtual counter is updated to ensure
-                           stopped time is not counted.  This avoids time
-                           jumps surprising guest OSes and applications,
-                           as long as they use the virtual counter for
-                           timekeeping.  However it has the side effect of
-                           the virtual and physical counters diverging.
-                           All timekeeping based on the virtual counter
-                           will appear to lag behind any timekeeping that
-                           does not subtract VM stopped time.  The guest
-                           may resynchronize its virtual counter with
-                           other time sources as needed.
-
-                           Enable kvm-no-adjvtime to disable virtual time
-                           adjustment, also restoring the legacy (pre-5.0)
-                           behavior.
-
-SVE CPU Properties
-==================
-
-There are two types of SVE CPU properties: `sve` and `sve<N>`.  The first
-is used to enable or disable the entire SVE feature, just as the `pmu`
-CPU property completely enables or disables the PMU.  The second type
-is used to enable or disable specific vector lengths, where `N` is the
-number of bits of the length.  The `sve<N>` CPU properties have special
-dependencies and constraints, see "SVE CPU Property Dependencies and
-Constraints" below.  Additionally, as we want all supported vector lengths
-to be enabled by default, then, in order to avoid overly verbose command
-lines (command lines full of `sve<N>=off`, for all `N` not wanted), we
-provide the parsing semantics listed in "SVE CPU Property Parsing
-Semantics".
-
-SVE CPU Property Dependencies and Constraints
----------------------------------------------
-
-  1) At least one vector length must be enabled when `sve` is enabled.
-
-  2) If a vector length `N` is enabled, then, when KVM is enabled, all
-     smaller, host supported vector lengths must also be enabled.  If
-     KVM is not enabled, then only all the smaller, power-of-two vector
-     lengths must be enabled.  E.g. with KVM if the host supports all
-     vector lengths up to 512-bits (128, 256, 384, 512), then if `sve512`
-     is enabled, the 128-bit vector length, 256-bit vector length, and
-     384-bit vector length must also be enabled. Without KVM, the 384-bit
-     vector length would not be required.
-
-  3) If KVM is enabled then only vector lengths that the host CPU type
-     support may be enabled.  If SVE is not supported by the host, then
-     no `sve*` properties may be enabled.
-
-SVE CPU Property Parsing Semantics
-----------------------------------
-
-  1) If SVE is disabled (`sve=off`), then which SVE vector lengths
-     are enabled or disabled is irrelevant to the guest, as the entire
-     SVE feature is disabled and that disables all vector lengths for
-     the guest.  However QEMU will still track any `sve<N>` CPU
-     properties provided by the user.  If later an `sve=on` is provided,
-     then the guest will get only the enabled lengths.  If no `sve=on`
-     is provided and there are explicitly enabled vector lengths, then
-     an error is generated.
-
-  2) If SVE is enabled (`sve=on`), but no `sve<N>` CPU properties are
-     provided, then all supported vector lengths are enabled, which when
-     KVM is not in use means including the non-power-of-two lengths, and,
-     when KVM is in use, it means all vector lengths supported by the host
-     processor.
-
-  3) If SVE is enabled, then an error is generated when attempting to
-     disable the last enabled vector length (see constraint (1) of "SVE
-     CPU Property Dependencies and Constraints").
-
-  4) If one or more vector lengths have been explicitly enabled and at
-     at least one of the dependency lengths of the maximum enabled length
-     has been explicitly disabled, then an error is generated (see
-     constraint (2) of "SVE CPU Property Dependencies and Constraints").
-
-  5) When KVM is enabled, if the host does not support SVE, then an error
-     is generated when attempting to enable any `sve*` properties (see
-     constraint (3) of "SVE CPU Property Dependencies and Constraints").
-
-  6) When KVM is enabled, if the host does support SVE, then an error is
-     generated when attempting to enable any vector lengths not supported
-     by the host (see constraint (3) of "SVE CPU Property Dependencies and
-     Constraints").
-
-  7) If one or more `sve<N>` CPU properties are set `off`, but no `sve<N>`,
-     CPU properties are set `on`, then the specified vector lengths are
-     disabled but the default for any unspecified lengths remains enabled.
-     When KVM is not enabled, disabling a power-of-two vector length also
-     disables all vector lengths larger than the power-of-two length.
-     When KVM is enabled, then disabling any supported vector length also
-     disables all larger vector lengths (see constraint (2) of "SVE CPU
-     Property Dependencies and Constraints").
-
-  8) If one or more `sve<N>` CPU properties are set to `on`, then they
-     are enabled and all unspecified lengths default to disabled, except
-     for the required lengths per constraint (2) of "SVE CPU Property
-     Dependencies and Constraints", which will even be auto-enabled if
-     they were not explicitly enabled.
-
-  9) If SVE was disabled (`sve=off`), allowing all vector lengths to be
-     explicitly disabled (i.e. avoiding the error specified in (3) of
-     "SVE CPU Property Parsing Semantics"), then if later an `sve=on` is
-     provided an error will be generated.  To avoid this error, one must
-     enable at least one vector length prior to enabling SVE.
-
-SVE CPU Property Examples
--------------------------
-
-  1) Disable SVE::
-
-     $ qemu-system-aarch64 -M virt -cpu max,sve=off
-
-  2) Implicitly enable all vector lengths for the `max` CPU type::
-
-     $ qemu-system-aarch64 -M virt -cpu max
-
-  3) When KVM is enabled, implicitly enable all host CPU supported vector
-     lengths with the `host` CPU type::
-
-     $ qemu-system-aarch64 -M virt,accel=kvm -cpu host
-
-  4) Only enable the 128-bit vector length::
-
-     $ qemu-system-aarch64 -M virt -cpu max,sve128=on
-
-  5) Disable the 512-bit vector length and all larger vector lengths,
-     since 512 is a power-of-two.  This results in all the smaller,
-     uninitialized lengths (128, 256, and 384) defaulting to enabled::
-
-     $ qemu-system-aarch64 -M virt -cpu max,sve512=off
-
-  6) Enable the 128-bit, 256-bit, and 512-bit vector lengths::
-
-     $ qemu-system-aarch64 -M virt -cpu max,sve128=on,sve256=on,sve512=on
-
-  7) The same as (6), but since the 128-bit and 256-bit vector
-     lengths are required for the 512-bit vector length to be enabled,
-     then allow them to be auto-enabled::
-
-     $ qemu-system-aarch64 -M virt -cpu max,sve512=on
-
-  8) Do the same as (7), but by first disabling SVE and then re-enabling it::
-
-     $ qemu-system-aarch64 -M virt -cpu max,sve=off,sve512=on,sve=on
-
-  9) Force errors regarding the last vector length::
-
-     $ qemu-system-aarch64 -M virt -cpu max,sve128=off
-     $ qemu-system-aarch64 -M virt -cpu max,sve=off,sve128=off,sve=on
-
-SVE CPU Property Recommendations
---------------------------------
-
-The examples in "SVE CPU Property Examples" exhibit many ways to select
-vector lengths which developers may find useful in order to avoid overly
-verbose command lines.  However, the recommended way to select vector
-lengths is to explicitly enable each desired length.  Therefore only
-example's (1), (4), and (6) exhibit recommended uses of the properties.
-
index 9fa6ed51c82351240bdbb8777fe141f846edb201..11ed8f2d68b1c1bc11534ce0cc9eeb64ea6bafa7 100644 (file)
@@ -13,7 +13,7 @@ controller is implemented.
 
 The PCI addon card hardware has been selected as the first CAN
 interface to implement because such device can be easily connected
-to systems with different CPU architectures (x86, PowerPC, ARM, etc.).
+to systems with different CPU architectures (x86, PowerPC, Arm, etc.).
 
 The project has been initially started in frame of RTEMS GSoC 2013
 slot by Jin Yang under our mentoring  The initial idea was to provide generic
index 7588bf192eecf67898575e6e5c06f7099c9f2cf4..960043cb8603f0e911f75a7f6e6ecc47ff61c302 100644 (file)
@@ -132,6 +132,12 @@ suppress_warnings = ["ref.option"]
 # style document building; our Makefile always sets the variable.
 confdir = os.getenv('CONFDIR', "/etc/qemu")
 rst_epilog = ".. |CONFDIR| replace:: ``" + confdir + "``\n"
+# We slurp in the defs.rst.inc and literally include it into rst_epilog,
+# because Sphinx's include:: directive doesn't work with absolute paths
+# and there isn't any one single relative path that will work for all
+# documents and for both via-make and direct sphinx-build invocation.
+with open(os.path.join(qemu_docdir, 'defs.rst.inc')) as f:
+    rst_epilog += f.read()
 
 # -- Options for HTML output ----------------------------------------------
 
diff --git a/docs/defs.rst.inc b/docs/defs.rst.inc
new file mode 100644 (file)
index 0000000..48d05aa
--- /dev/null
@@ -0,0 +1,15 @@
+..
+   Generally useful rST substitution definitions. This is included for
+   all rST files as part of the epilogue by docs/conf.py.  conf.py
+   also defines some dynamically generated substitutions like CONFDIR.
+
+   Note that |qemu_system| and |qemu_system_x86| are intended to be
+   used inside a parsed-literal block: the definition must not include
+   extra literal formatting with ``..``: this works in the HTML output
+   but the manpages will end up misrendered with following normal text
+   incorrectly in boldface.
+
+.. |qemu_system| replace:: qemu-system-x86_64
+.. |qemu_system_x86| replace:: qemu_system-x86_64
+.. |I2C| replace:: I\ :sup:`2`\ C
+.. |I2S| replace:: I\ :sup:`2`\ S
index a4db3a4aaadb943337a56e166cd8556cbc3db099..67bdf8262808f9c90777641848b82d88a648886d 100644 (file)
@@ -87,7 +87,7 @@ Sequentially consistent loads and stores can be done using:
     atomic_xchg(ptr, val) for stores
 
 However, they are quite expensive on some platforms, notably POWER and
-ARM.  Therefore, qemu/atomic.h provides two primitives with slightly
+Arm.  Therefore, qemu/atomic.h provides two primitives with slightly
 weaker constraints:
 
     typeof(*ptr) atomic_mb_read(ptr)
index b7bca4470467b0a4c1cbfa0e92bccca362ce5d31..e5df72b34228ffb38a937d53a157f413e6aa8c5c 100644 (file)
@@ -8,7 +8,7 @@ time different targets can share large amounts of code.  For example,
 a POWER and an x86 board can run the same code to emulate a PCI network
 card, even though the boards use different PCI host bridges, and they
 can run the same code to emulate a SCSI disk while using different
-SCSI adapters.  ARM, s390 and x86 boards can all present a virtio-blk
+SCSI adapters.  Arm, s390 and x86 boards can all present a virtio-blk
 disk to their guests, but with three different virtio guest interfaces.
 
 Each QEMU target enables a subset of the boards, devices and buses that
index 03aa9e7ff8043adae9ee3a2d5b228b3e23fec76c..0d99eb24c1bb853c44165d009afec3ffadb301ea 100644 (file)
@@ -302,7 +302,7 @@ way QEMU defines the view of memory that a device or CPU has.
 or bus fabric.)
 
 Each CPU has an AddressSpace. Some kinds of CPU have more than
-one AddressSpace (for instance ARM guest CPUs have an AddressSpace
+one AddressSpace (for instance Arm guest CPUs have an AddressSpace
 for the Secure world and one for NonSecure if they implement TrustZone).
 Devices which can do DMA-type operations should generally have an
 AddressSpace. There is also a "system address space" which typically
index 782bebc28b41f7b209dbdefc82c3dc348d12a060..3c85ac0eab9b8febfa420c83e04df5bbf74dd779 100644 (file)
@@ -227,7 +227,7 @@ minimise contention.
 (Current solution)
 
 MMIO access automatically serialises hardware emulation by way of the
-BQL. Currently ARM targets serialise all ARM_CP_IO register accesses
+BQL. Currently Arm targets serialise all ARM_CP_IO register accesses
 and also defer the reset/startup of vCPUs to the vCPU context by way
 of async_run_on_cpu().
 
@@ -268,7 +268,7 @@ ordered backends this could become a NOP.
 Aside from explicit standalone memory barrier instructions there are
 also implicit memory ordering semantics which comes with each guest
 memory access instruction. For example all x86 load/stores come with
-fairly strong guarantees of sequential consistency where as ARM has
+fairly strong guarantees of sequential consistency whereas Arm has
 special variants of load/store instructions that imply acquire/release
 semantics.
 
@@ -317,7 +317,7 @@ x86 cmpxchg instruction.
 
 The second type offer a pair of load/store instructions which offer a
 guarantee that a region of memory has not been touched between the
-load and store instructions. An example of this is ARM's ldrex/strex
+load and store instructions. An example of this is Arm's ldrex/strex
 pair where the strex instruction will return a flag indicating a
 successful store only if no other CPU has accessed the memory region
 since the ldrex.
@@ -339,7 +339,7 @@ CURRENT OPEN QUESTIONS:
 
 The TCG provides a number of atomic helpers (tcg_gen_atomic_*) which
 can be used directly or combined to emulate other instructions like
-ARM's ldrex/strex instructions. While they are susceptible to the ABA
+Arm's ldrex/strex instructions. While they are susceptible to the ABA
 problem so far common guests have not implemented patterns where
 this may be a problem - typically presenting a locking ABI which
 assumes cmpxchg like semantics.
index 4956a30a4e6f387bb1c3d8777ad9ecd6be029b45..4ebde44b9d72b2b007a612983877d1456d1981db 100644 (file)
@@ -83,7 +83,7 @@ memory until the end of the translation block.  This is done for internal
 emulation state that is rarely accessed directly by the program and/or changes
 very often throughout the execution of a translation block---this includes
 condition codes on x86, delay slots on SPARC, conditional execution on
-ARM, and so on.  This state is stored for each target instruction, and
+Arm, and so on.  This state is stored for each target instruction, and
 looked up on exceptions.
 
 MMU emulation
index cf61b1cf4488b8b3af95f857d082d6f4863d0022..e9a160384cfe939a3bccc51e5da9052130e381a8 100644 (file)
@@ -7,13 +7,13 @@
     <body>
         <h1>QEMU @@VERSION@@ Documentation</h1>
         <ul>
-            <li><a href="qemu-doc.html">User Documentation</a></li>
-            <li><a href="qemu-qmp-ref.html">QMP Reference Manual</a></li>
-            <li><a href="qemu-ga-ref.html">Guest Agent Protocol Reference</a></li>
-            <li><a href="interop/index.html">System Emulation Management and Interoperability Guide</a></li>
-            <li><a href="specs/index.html">System Emulation Guest Hardware Specifications</a></li>
             <li><a href="system/index.html">System Emulation User's Guide</a></li>
+            <li><a href="user/index.html">User Mode Emulation User's Guide</a></li>
             <li><a href="tools/index.html">Tools Guide</a></li>
+            <li><a href="interop/index.html">System Emulation Management and Interoperability Guide</a></li>
+            <li><a href="specs/index.html">System Emulation Guest Hardware Specifications</a></li>
+            <li><a href="qemu-qmp-ref.html">QMP Reference Manual</a></li>
+            <li><a href="qemu-ga-ref.html">Guest Agent Protocol Reference</a></li>
         </ul>
     </body>
 </html>
index acd604fa8a9683dc1eedef15f6874c5ffe8c69fe..763e3d0426e8b15245b6ff0d0611a4396b1730ae 100644 (file)
@@ -10,8 +10,9 @@ Welcome to QEMU's documentation!
    :maxdepth: 2
    :caption: Contents:
 
-   interop/index
-   devel/index
-   specs/index
    system/index
+   user/index
    tools/index
+   interop/index
+   specs/index
+   devel/index
diff --git a/docs/qemu-cpu-models.texi b/docs/qemu-cpu-models.texi
deleted file mode 100644 (file)
index f88a1de..0000000
+++ /dev/null
@@ -1,677 +0,0 @@
-@c man begin SYNOPSIS
-QEMU / KVM CPU model configuration
-@c man end
-
-@set qemu_system_x86 qemu-system-x86_64
-
-@c man begin DESCRIPTION
-
-@menu
-* recommendations_cpu_models_x86::  Recommendations for KVM CPU model configuration on x86 hosts
-* recommendations_cpu_models_MIPS:: Supported CPU model configurations on MIPS hosts
-* cpu_model_syntax_apps::           Syntax for configuring CPU models
-@end menu
-
-QEMU / KVM virtualization supports two ways to configure CPU models
-
-@table @option
-
-@item Host passthrough
-
-This passes the host CPU model features, model, stepping, exactly to the
-guest. Note that KVM may filter out some host CPU model features if they
-cannot be supported with virtualization. Live migration is unsafe when
-this mode is used as libvirt / QEMU cannot guarantee a stable CPU is
-exposed to the guest across hosts. This is the recommended CPU to use,
-provided live migration is not required.
-
-@item Named model
-
-QEMU comes with a number of predefined named CPU models, that typically
-refer to specific generations of hardware released by Intel and AMD.
-These allow the guest VMs to have a degree of isolation from the host CPU,
-allowing greater flexibility in live migrating between hosts with differing
-hardware.
-@end table
-
-In both cases, it is possible to optionally add or remove individual CPU
-features, to alter what is presented to the guest by default.
-
-Libvirt supports a third way to configure CPU models known as "Host model".
-This uses the QEMU "Named model" feature, automatically picking a CPU model
-that is similar the host CPU, and then adding extra features to approximate
-the host model as closely as possible. This does not guarantee the CPU family,
-stepping, etc will precisely match the host CPU, as they would with "Host
-passthrough", but gives much of the benefit of passthrough, while making
-live migration safe.
-
-@node recommendations_cpu_models_x86
-@subsection Recommendations for KVM CPU model configuration on x86 hosts
-
-The information that follows provides recommendations for configuring
-CPU models on x86 hosts. The goals are to maximise performance, while
-protecting guest OS against various CPU hardware flaws, and optionally
-enabling live migration between hosts with heterogeneous CPU models.
-
-@menu
-* preferred_cpu_models_intel_x86::       Preferred CPU models for Intel x86 hosts
-* important_cpu_features_intel_x86::     Important CPU features for Intel x86 hosts
-* preferred_cpu_models_amd_x86::         Preferred CPU models for AMD x86 hosts
-* important_cpu_features_amd_x86::       Important CPU features for AMD x86 hosts
-* default_cpu_models_x86::               Default x86 CPU models
-* other_non_recommended_cpu_models_x86:: Other non-recommended x86 CPUs
-@end menu
-
-@node preferred_cpu_models_intel_x86
-@subsubsection Preferred CPU models for Intel x86 hosts
-
-The following CPU models are preferred for use on Intel hosts. Administrators /
-applications are recommended to use the CPU model that matches the generation
-of the host CPUs in use. In a deployment with a mixture of host CPU models
-between machines, if live migration compatibility is required, use the newest
-CPU model that is compatible across all desired hosts.
-
-@table @option
-@item @code{Skylake-Server}
-@item @code{Skylake-Server-IBRS}
-
-Intel Xeon Processor (Skylake, 2016)
-
-
-@item @code{Skylake-Client}
-@item @code{Skylake-Client-IBRS}
-
-Intel Core Processor (Skylake, 2015)
-
-
-@item @code{Broadwell}
-@item @code{Broadwell-IBRS}
-@item @code{Broadwell-noTSX}
-@item @code{Broadwell-noTSX-IBRS}
-
-Intel Core Processor (Broadwell, 2014)
-
-
-@item @code{Haswell}
-@item @code{Haswell-IBRS}
-@item @code{Haswell-noTSX}
-@item @code{Haswell-noTSX-IBRS}
-
-Intel Core Processor (Haswell, 2013)
-
-
-@item @code{IvyBridge}
-@item @code{IvyBridge-IBRS}
-
-Intel Xeon E3-12xx v2 (Ivy Bridge, 2012)
-
-
-@item @code{SandyBridge}
-@item @code{SandyBridge-IBRS}
-
-Intel Xeon E312xx (Sandy Bridge, 2011)
-
-
-@item @code{Westmere}
-@item @code{Westmere-IBRS}
-
-Westmere E56xx/L56xx/X56xx (Nehalem-C, 2010)
-
-
-@item @code{Nehalem}
-@item @code{Nehalem-IBRS}
-
-Intel Core i7 9xx (Nehalem Class Core i7, 2008)
-
-
-@item @code{Penryn}
-
-Intel Core 2 Duo P9xxx (Penryn Class Core 2, 2007)
-
-
-@item @code{Conroe}
-
-Intel Celeron_4x0 (Conroe/Merom Class Core 2, 2006)
-
-@end table
-
-@node important_cpu_features_intel_x86
-@subsubsection Important CPU features for Intel x86 hosts
-
-The following are important CPU features that should be used on Intel x86
-hosts, when available in the host CPU. Some of them require explicit
-configuration to enable, as they are not included by default in some, or all,
-of the named CPU models listed above. In general all of these features are
-included if using "Host passthrough" or "Host model".
-
-
-@table @option
-
-@item @code{pcid}
-
-Recommended to mitigate the cost of the Meltdown (CVE-2017-5754) fix
-
-Included by default in Haswell, Broadwell & Skylake Intel CPU models.
-
-Should be explicitly turned on for Westmere, SandyBridge, and IvyBridge
-Intel CPU models. Note that some desktop/mobile Westmere CPUs cannot
-support this feature.
-
-
-@item @code{spec-ctrl}
-
-Required to enable the Spectre v2 (CVE-2017-5715) fix.
-
-Included by default in Intel CPU models with -IBRS suffix.
-
-Must be explicitly turned on for Intel CPU models without -IBRS suffix.
-
-Requires the host CPU microcode to support this feature before it
-can be used for guest CPUs.
-
-
-@item @code{stibp}
-
-Required to enable stronger Spectre v2 (CVE-2017-5715) fixes in some
-operating systems.
-
-Must be explicitly turned on for all Intel CPU models.
-
-Requires the host CPU microcode to support this feature before it
-can be used for guest CPUs.
-
-
-@item @code{ssbd}
-
-Required to enable the CVE-2018-3639 fix
-
-Not included by default in any Intel CPU model.
-
-Must be explicitly turned on for all Intel CPU models.
-
-Requires the host CPU microcode to support this feature before it
-can be used for guest CPUs.
-
-
-@item @code{pdpe1gb}
-
-Recommended to allow guest OS to use 1GB size pages
-
-Not included by default in any Intel CPU model.
-
-Should be explicitly turned on for all Intel CPU models.
-
-Note that not all CPU hardware will support this feature.
-
-@item @code{md-clear}
-
-Required to confirm the MDS (CVE-2018-12126, CVE-2018-12127, CVE-2018-12130,
-CVE-2019-11091) fixes.
-
-Not included by default in any Intel CPU model.
-
-Must be explicitly turned on for all Intel CPU models.
-
-Requires the host CPU microcode to support this feature before it
-can be used for guest CPUs.
-@end table
-
-
-@node preferred_cpu_models_amd_x86
-@subsubsection Preferred CPU models for AMD x86 hosts
-
-The following CPU models are preferred for use on Intel hosts. Administrators /
-applications are recommended to use the CPU model that matches the generation
-of the host CPUs in use. In a deployment with a mixture of host CPU models
-between machines, if live migration compatibility is required, use the newest
-CPU model that is compatible across all desired hosts.
-
-@table @option
-
-@item @code{EPYC}
-@item @code{EPYC-IBPB}
-
-AMD EPYC Processor (2017)
-
-
-@item @code{Opteron_G5}
-
-AMD Opteron 63xx class CPU (2012)
-
-
-@item @code{Opteron_G4}
-
-AMD Opteron 62xx class CPU (2011)
-
-
-@item @code{Opteron_G3}
-
-AMD Opteron 23xx (Gen 3 Class Opteron, 2009)
-
-
-@item @code{Opteron_G2}
-
-AMD Opteron 22xx (Gen 2 Class Opteron, 2006)
-
-
-@item @code{Opteron_G1}
-
-AMD Opteron 240 (Gen 1 Class Opteron, 2004)
-@end table
-
-@node important_cpu_features_amd_x86
-@subsubsection Important CPU features for AMD x86 hosts
-
-The following are important CPU features that should be used on AMD x86
-hosts, when available in the host CPU. Some of them require explicit
-configuration to enable, as they are not included by default in some, or all,
-of the named CPU models listed above. In general all of these features are
-included if using "Host passthrough" or "Host model".
-
-
-@table @option
-
-@item @code{ibpb}
-
-Required to enable the Spectre v2 (CVE-2017-5715) fix.
-
-Included by default in AMD CPU models with -IBPB suffix.
-
-Must be explicitly turned on for AMD CPU models without -IBPB suffix.
-
-Requires the host CPU microcode to support this feature before it
-can be used for guest CPUs.
-
-
-@item @code{stibp}
-
-Required to enable stronger Spectre v2 (CVE-2017-5715) fixes in some
-operating systems.
-
-Must be explicitly turned on for all AMD CPU models.
-
-Requires the host CPU microcode to support this feature before it
-can be used for guest CPUs.
-
-
-@item @code{virt-ssbd}
-
-Required to enable the CVE-2018-3639 fix
-
-Not included by default in any AMD CPU model.
-
-Must be explicitly turned on for all AMD CPU models.
-
-This should be provided to guests, even if amd-ssbd is also
-provided, for maximum guest compatibility.
-
-Note for some QEMU / libvirt versions, this must be force enabled
-when when using "Host model", because this is a virtual feature
-that doesn't exist in the physical host CPUs.
-
-
-@item @code{amd-ssbd}
-
-Required to enable the CVE-2018-3639 fix
-
-Not included by default in any AMD CPU model.
-
-Must be explicitly turned on for all AMD CPU models.
-
-This provides higher performance than virt-ssbd so should be
-exposed to guests whenever available in the host. virt-ssbd
-should none the less also be exposed for maximum guest
-compatibility as some kernels only know about virt-ssbd.
-
-
-@item @code{amd-no-ssb}
-
-Recommended to indicate the host is not vulnerable CVE-2018-3639
-
-Not included by default in any AMD CPU model.
-
-Future hardware generations of CPU will not be vulnerable to
-CVE-2018-3639, and thus the guest should be told not to enable
-its mitigations, by exposing amd-no-ssb. This is mutually
-exclusive with virt-ssbd and amd-ssbd.
-
-
-@item @code{pdpe1gb}
-
-Recommended to allow guest OS to use 1GB size pages
-
-Not included by default in any AMD CPU model.
-
-Should be explicitly turned on for all AMD CPU models.
-
-Note that not all CPU hardware will support this feature.
-@end table
-
-
-@node default_cpu_models_x86
-@subsubsection Default x86 CPU models
-
-The default QEMU CPU models are designed such that they can run on all hosts.
-If an application does not wish to do perform any host compatibility checks
-before launching guests, the default is guaranteed to work.
-
-The default CPU models will, however, leave the guest OS vulnerable to various
-CPU hardware flaws, so their use is strongly discouraged. Applications should
-follow the earlier guidance to setup a better CPU configuration, with host
-passthrough recommended if live migration is not needed.
-
-@table @option
-@item @code{qemu32}
-@item @code{qemu64}
-
-QEMU Virtual CPU version 2.5+ (32 & 64 bit variants)
-
-qemu64 is used for x86_64 guests and qemu32 is used for i686 guests, when no
--cpu argument is given to QEMU, or no <cpu> is provided in libvirt XML.
-@end table
-
-
-@node other_non_recommended_cpu_models_x86
-@subsubsection Other non-recommended x86 CPUs
-
-The following CPUs models are compatible with most AMD and Intel x86 hosts, but
-their usage is discouraged, as they expose a very limited featureset, which
-prevents guests having optimal performance.
-
-@table @option
-
-@item @code{kvm32}
-@item @code{kvm64}
-
-Common KVM processor (32 & 64 bit variants)
-
-Legacy models just for historical compatibility with ancient QEMU versions.
-
-
-@item @code{486}
-@item @code{athlon}
-@item @code{phenom}
-@item @code{coreduo}
-@item @code{core2duo}
-@item @code{n270}
-@item @code{pentium}
-@item @code{pentium2}
-@item @code{pentium3}
-
-Various very old x86 CPU models, mostly predating the introduction of
-hardware assisted virtualization, that should thus not be required for
-running virtual machines.
-@end table
-
-@node recommendations_cpu_models_MIPS
-@subsection Supported CPU model configurations on MIPS hosts
-
-QEMU supports variety of MIPS CPU models:
-
-@menu
-* cpu_models_MIPS32::               Supported CPU models for MIPS32 hosts
-* cpu_models_MIPS64::               Supported CPU models for MIPS64 hosts
-* cpu_models_nanoMIPS::             Supported CPU models for nanoMIPS hosts
-* preferred_cpu_models_MIPS::       Preferred CPU models for MIPS hosts
-@end menu
-
-@node cpu_models_MIPS32
-@subsubsection Supported CPU models for MIPS32 hosts
-
-The following CPU models are supported for use on MIPS32 hosts. Administrators /
-applications are recommended to use the CPU model that matches the generation
-of the host CPUs in use. In a deployment with a mixture of host CPU models
-between machines, if live migration compatibility is required, use the newest
-CPU model that is compatible across all desired hosts.
-
-@table @option
-@item @code{mips32r6-generic}
-
-MIPS32 Processor (Release 6, 2015)
-
-
-@item @code{P5600}
-
-MIPS32 Processor (P5600, 2014)
-
-
-@item @code{M14K}
-@item @code{M14Kc}
-
-MIPS32 Processor (M14K, 2009)
-
-
-@item @code{74Kf}
-
-MIPS32 Processor (74K, 2007)
-
-
-@item @code{34Kf}
-
-MIPS32 Processor (34K, 2006)
-
-
-@item @code{24Kc}
-@item @code{24KEc}
-@item @code{24Kf}
-
-MIPS32 Processor (24K, 2003)
-
-
-@item @code{4Kc}
-@item @code{4Km}
-@item @code{4KEcR1}
-@item @code{4KEmR1}
-@item @code{4KEc}
-@item @code{4KEm}
-
-MIPS32 Processor (4K, 1999)
-@end table
-
-@node cpu_models_MIPS64
-@subsubsection Supported CPU models for MIPS64 hosts
-
-The following CPU models are supported for use on MIPS64 hosts. Administrators /
-applications are recommended to use the CPU model that matches the generation
-of the host CPUs in use. In a deployment with a mixture of host CPU models
-between machines, if live migration compatibility is required, use the newest
-CPU model that is compatible across all desired hosts.
-
-@table @option
-@item @code{I6400}
-
-MIPS64 Processor (Release 6, 2014)
-
-
-@item @code{Loongson-2F}
-
-MIPS64 Processor (Loongson 2, 2008)
-
-
-@item @code{Loongson-2E}
-
-MIPS64 Processor (Loongson 2, 2006)
-
-
-@item @code{mips64dspr2}
-
-MIPS64 Processor (Release 2, 2006)
-
-
-@item @code{MIPS64R2-generic}
-@item @code{5KEc}
-@item @code{5KEf}
-
-MIPS64 Processor (Release 2, 2002)
-
-
-@item @code{20Kc}
-
-MIPS64 Processor (20K, 2000)
-
-
-@item @code{5Kc}
-@item @code{5Kf}
-
-MIPS64 Processor (5K, 1999)
-
-
-@item @code{VR5432}
-
-MIPS64 Processor (VR, 1998)
-
-
-@item @code{R4000}
-
-MIPS64 Processor (MIPS III, 1991)
-@end table
-
-@node cpu_models_nanoMIPS
-@subsubsection Supported CPU models for nanoMIPS hosts
-
-The following CPU models are supported for use on nanoMIPS hosts. Administrators /
-applications are recommended to use the CPU model that matches the generation
-of the host CPUs in use. In a deployment with a mixture of host CPU models
-between machines, if live migration compatibility is required, use the newest
-CPU model that is compatible across all desired hosts.
-
-@table @option
-@item @code{I7200}
-
-MIPS I7200 (nanoMIPS, 2018)
-
-@end table
-
-@node preferred_cpu_models_MIPS
-@subsubsection Preferred CPU models for MIPS hosts
-
-The following CPU models are preferred for use on different MIPS hosts:
-
-@table @option
-@item @code{MIPS III}
-R4000
-
-@item @code{MIPS32R2}
-34Kf
-
-@item @code{MIPS64R6}
-I6400
-
-@item @code{nanoMIPS}
-I7200
-@end table
-
-@node cpu_model_syntax_apps
-@subsection Syntax for configuring CPU models
-
-The example below illustrate the approach to configuring the various
-CPU models / features in QEMU and libvirt
-
-@menu
-* cpu_model_syntax_qemu::    QEMU command line
-* cpu_model_syntax_libvirt:: Libvirt guest XML
-@end menu
-
-@node cpu_model_syntax_qemu
-@subsubsection QEMU command line
-
-@table @option
-
-@item Host passthrough
-
-@example
-   $ @value{qemu_system_x86} -cpu host
-@end example
-
-With feature customization:
-
-@example
-   $ @value{qemu_system_x86} -cpu host,-vmx,...
-@end example
-
-@item Named CPU models
-
-@example
-   $ @value{qemu_system_x86} -cpu Westmere
-@end example
-
-With feature customization:
-
-@example
-   $ @value{qemu_system_x86} -cpu Westmere,+pcid,...
-@end example
-
-@end table
-
-@node cpu_model_syntax_libvirt
-@subsubsection Libvirt guest XML
-
-@table @option
-
-@item Host passthrough
-
-@example
-   <cpu mode='host-passthrough'/>
-@end example
-
-With feature customization:
-
-@example
-   <cpu mode='host-passthrough'>
-       <feature name="vmx" policy="disable"/>
-       ...
-   </cpu>
-@end example
-
-@item Host model
-
-@example
-   <cpu mode='host-model'/>
-@end example
-
-With feature customization:
-
-@example
-   <cpu mode='host-model'>
-       <feature name="vmx" policy="disable"/>
-       ...
-   </cpu>
-@end example
-
-@item Named model
-
-@example
-   <cpu mode='custom'>
-       <model name="Westmere"/>
-   </cpu>
-@end example
-
-With feature customization:
-
-@example
-   <cpu mode='custom'>
-       <model name="Westmere"/>
-       <feature name="pcid" policy="require"/>
-       ...
-   </cpu>
-@end example
-
-@end table
-
-@c man end
-
-@ignore
-
-@setfilename qemu-cpu-models
-@settitle QEMU / KVM CPU model configuration
-
-@c man begin SEEALSO
-The HTML documentation of QEMU for more precise information and Linux
-user mode emulator invocation.
-@c man end
-
-@c man begin AUTHOR
-Daniel P. Berrange
-@c man end
-
-@end ignore
index 23cfcb48537d0dddf36ffaf0f6ce9289fc34e6f8..7e09773a9c518f6a47e9262b66c6016b21a61762 100644 (file)
@@ -1,7 +1,3 @@
-..
-  The contents of this file must be kept in sync with qemu-option-trace.texi
-  until all the users of the texi file have been converted to rst and
-  the texi file can be removed.
 
 Specify tracing options.
 
index f4619a62a3d3ec31b3e5f1ddb5c565f5adbf8c6b..70c27edb362105cf5886141d048f6b885763c244 100644 (file)
@@ -19,7 +19,7 @@ Deterministic replay has the following features:
    the memory, state of the hardware devices, clocks, and screen of the VM.
  * Writes execution log into the file for later replaying for multiple times
    on different machines.
- * Supports i386, x86_64, and ARM hardware platforms.
+ * Supports i386, x86_64, and Arm hardware platforms.
  * Performs deterministic replay of all operations with keyboard and mouse
    input devices.
 
diff --git a/docs/security.texi b/docs/security.texi
deleted file mode 100644 (file)
index 0d6b30e..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-@node Security
-@chapter Security
-
-@section Overview
-
-This chapter explains the security requirements that QEMU is designed to meet
-and principles for securely deploying QEMU.
-
-@section Security Requirements
-
-QEMU supports many different use cases, some of which have stricter security
-requirements than others.  The community has agreed on the overall security
-requirements that users may depend on.  These requirements define what is
-considered supported from a security perspective.
-
-@subsection Virtualization Use Case
-
-The virtualization use case covers cloud and virtual private server (VPS)
-hosting, as well as traditional data center and desktop virtualization.  These
-use cases rely on hardware virtualization extensions to execute guest code
-safely on the physical CPU at close-to-native speed.
-
-The following entities are untrusted, meaning that they may be buggy or
-malicious:
-
-@itemize
-@item Guest
-@item User-facing interfaces (e.g. VNC, SPICE, WebSocket)
-@item Network protocols (e.g. NBD, live migration)
-@item User-supplied files (e.g. disk images, kernels, device trees)
-@item Passthrough devices (e.g. PCI, USB)
-@end itemize
-
-Bugs affecting these entities are evaluated on whether they can cause damage in
-real-world use cases and treated as security bugs if this is the case.
-
-@subsection Non-virtualization Use Case
-
-The non-virtualization use case covers emulation using the Tiny Code Generator
-(TCG).  In principle the TCG and device emulation code used in conjunction with
-the non-virtualization use case should meet the same security requirements as
-the virtualization use case.  However, for historical reasons much of the
-non-virtualization use case code was not written with these security
-requirements in mind.
-
-Bugs affecting the non-virtualization use case are not considered security
-bugs at this time.  Users with non-virtualization use cases must not rely on
-QEMU to provide guest isolation or any security guarantees.
-
-@section Architecture
-
-This section describes the design principles that ensure the security
-requirements are met.
-
-@subsection Guest Isolation
-
-Guest isolation is the confinement of guest code to the virtual machine.  When
-guest code gains control of execution on the host this is called escaping the
-virtual machine.  Isolation also includes resource limits such as throttling of
-CPU, memory, disk, or network.  Guests must be unable to exceed their resource
-limits.
-
-QEMU presents an attack surface to the guest in the form of emulated devices.
-The guest must not be able to gain control of QEMU.  Bugs in emulated devices
-could allow malicious guests to gain code execution in QEMU.  At this point the
-guest has escaped the virtual machine and is able to act in the context of the
-QEMU process on the host.
-
-Guests often interact with other guests and share resources with them.  A
-malicious guest must not gain control of other guests or access their data.
-Disk image files and network traffic must be protected from other guests unless
-explicitly shared between them by the user.
-
-@subsection Principle of Least Privilege
-
-The principle of least privilege states that each component only has access to
-the privileges necessary for its function.  In the case of QEMU this means that
-each process only has access to resources belonging to the guest.
-
-The QEMU process should not have access to any resources that are inaccessible
-to the guest.  This way the guest does not gain anything by escaping into the
-QEMU process since it already has access to those same resources from within
-the guest.
-
-Following the principle of least privilege immediately fulfills guest isolation
-requirements.  For example, guest A only has access to its own disk image file
-@code{a.img} and not guest B's disk image file @code{b.img}.
-
-In reality certain resources are inaccessible to the guest but must be
-available to QEMU to perform its function.  For example, host system calls are
-necessary for QEMU but are not exposed to guests.  A guest that escapes into
-the QEMU process can then begin invoking host system calls.
-
-New features must be designed to follow the principle of least privilege.
-Should this not be possible for technical reasons, the security risk must be
-clearly documented so users are aware of the trade-off of enabling the feature.
-
-@subsection Isolation mechanisms
-
-Several isolation mechanisms are available to realize this architecture of
-guest isolation and the principle of least privilege.  With the exception of
-Linux seccomp, these mechanisms are all deployed by management tools that
-launch QEMU, such as libvirt.  They are also platform-specific so they are only
-described briefly for Linux here.
-
-The fundamental isolation mechanism is that QEMU processes must run as
-unprivileged users.  Sometimes it seems more convenient to launch QEMU as
-root to give it access to host devices (e.g. @code{/dev/net/tun}) but this poses a
-huge security risk.  File descriptor passing can be used to give an otherwise
-unprivileged QEMU process access to host devices without running QEMU as root.
-It is also possible to launch QEMU as a non-root user and configure UNIX groups
-for access to @code{/dev/kvm}, @code{/dev/net/tun}, and other device nodes.
-Some Linux distros already ship with UNIX groups for these devices by default.
-
-@itemize
-@item SELinux and AppArmor make it possible to confine processes beyond the
-traditional UNIX process and file permissions model.  They restrict the QEMU
-process from accessing processes and files on the host system that are not
-needed by QEMU.
-
-@item Resource limits and cgroup controllers provide throughput and utilization
-limits on key resources such as CPU time, memory, and I/O bandwidth.
-
-@item Linux namespaces can be used to make process, file system, and other system
-resources unavailable to QEMU.  A namespaced QEMU process is restricted to only
-those resources that were granted to it.
-
-@item Linux seccomp is available via the QEMU @option{--sandbox} option.  It disables
-system calls that are not needed by QEMU, thereby reducing the host kernel
-attack surface.
-@end itemize
-
-@section Sensitive configurations
-
-There are aspects of QEMU that can have security implications which users &
-management applications must be aware of.
-
-@subsection Monitor console (QMP and HMP)
-
-The monitor console (whether used with QMP or HMP) provides an interface
-to dynamically control many aspects of QEMU's runtime operation. Many of the
-commands exposed will instruct QEMU to access content on the host file system
-and/or trigger spawning of external processes.
-
-For example, the @code{migrate} command allows for the spawning of arbitrary
-processes for the purpose of tunnelling the migration data stream. The
-@code{blockdev-add} command instructs QEMU to open arbitrary files, exposing
-their content to the guest as a virtual disk.
-
-Unless QEMU is otherwise confined using technologies such as SELinux, AppArmor,
-or Linux namespaces, the monitor console should be considered to have privileges
-equivalent to those of the user account QEMU is running under.
-
-It is further important to consider the security of the character device backend
-over which the monitor console is exposed. It needs to have protection against
-malicious third parties which might try to make unauthorized connections, or
-perform man-in-the-middle attacks. Many of the character device backends do not
-satisfy this requirement and so must not be used for the monitor console.
-
-The general recommendation is that the monitor console should be exposed over
-a UNIX domain socket backend to the local host only. Use of the TCP based
-character device backend is inappropriate unless configured to use both TLS
-encryption and authorization control policy on client connections.
-
-In summary, the monitor console is considered a privileged control interface to
-QEMU and as such should only be made accessible to a trusted management
-application or user.
index 08c00bdf44a2cca1064356470af2d5438d44e3c9..8f1ebc66fa4a3fe04f898597a58f1c96576d9d30 100644 (file)
@@ -82,7 +82,7 @@ Selector Register IOport: 0x510
 Data Register IOport:     0x511
 DMA Address IOport:       0x514
 
-=== ARM Register Locations ===
+=== Arm Register Locations ===
 
 Selector Register address: Base + 8 (2 bytes)
 Data Register address:     Base + 0 (8 bytes)
index 042f7eae22512acfb89ea6dd97c39b63112d4ee9..1beb3a01ec3f4594df4441a7e0950ff7e7a487c2 100644 (file)
@@ -38,8 +38,8 @@ There are two basic configurations:
   Interrupts are message-signaled (MSI-X).  vectors=N configures the
   number of vectors to use.
 
-For more details on ivshmem device properties, see The QEMU Emulator
-User Documentation (qemu-doc.*).
+For more details on ivshmem device properties, see the QEMU Emulator
+user documentation.
 
 
 == The ivshmem PCI device's guest interface ==
index 2bdf637f55230d76d400d3868f7365473e449533..5e61238bc5fe3c74a11ecd8b0202ef13d7fb83b9 100644 (file)
@@ -18,9 +18,15 @@ The TIS interface makes a memory mapped IO region in the area
 0xfed40000-0xfed44fff available to the guest operating system.
 
 QEMU files related to TPM TIS interface:
- - ``hw/tpm/tpm_tis.c``
+ - ``hw/tpm/tpm_tis_common.c``
+ - ``hw/tpm/tpm_tis_isa.c``
+ - ``hw/tpm/tpm_tis_sysbus.c``
  - ``hw/tpm/tpm_tis.h``
 
+Both an ISA device and a sysbus device are available. The former is
+used with pc/q35 machine while the latter can be instantiated in the
+Arm virt machine.
+
 CRB interface
 -------------
 
@@ -325,6 +331,23 @@ In case a pSeries machine is emulated, use the following command line:
     -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0 \
     -drive file=test.img,format=raw,if=none,id=drive-virtio-disk0
 
+In case an Arm virt machine is emulated, use the following command line:
+
+.. code-block:: console
+
+  qemu-system-aarch64 -machine virt,gic-version=3,accel=kvm \
+    -cpu host -m 4G \
+    -nographic -no-acpi \
+    -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+    -tpmdev emulator,id=tpm0,chardev=chrtpm \
+    -device tpm-tis-device,tpmdev=tpm0 \
+    -device virtio-blk-pci,drive=drv0 \
+    -drive format=qcow2,file=hda.qcow2,if=none,id=drv0 \
+    -drive if=pflash,format=raw,file=flash0.img,readonly \
+    -drive if=pflash,format=raw,file=flash1.img
+
+  On Arm, ACPI boot with TPM is not yet supported.
+
 In case SeaBIOS is used as firmware, it should show the TPM menu item
 after entering the menu with 'ESC'.
 
index 5d6736f30027eaa06be112cafddd579085fb07a4..fb0649a3d5bc1012cad8233cff6692f16fc50a72 100644 (file)
@@ -37,13 +37,11 @@ else:
 
 __version__ = '1.0'
 
-# We parse hx files with a state machine which may be in one of three
-# states: reading the C code fragment, inside a texi fragment,
-# or inside a rST fragment.
+# We parse hx files with a state machine which may be in one of two
+# states: reading the C code fragment, or inside a rST fragment.
 class HxState(Enum):
     CTEXT = 1
-    TEXI = 2
-    RST = 3
+    RST = 2
 
 def serror(file, lnum, errtext):
     """Raise an exception giving a user-friendly syntax error message"""
@@ -60,8 +58,9 @@ def parse_defheading(file, lnum, line):
     # empty we ignore the directive -- these are used only to add
     # blank lines in the plain-text content of the --help output.
     #
-    # Return the heading text
-    match = re.match(r'DEFHEADING\((.*)\)', line)
+    # Return the heading text. We strip out any trailing ':' for
+    # consistency with other headings in the rST documentation.
+    match = re.match(r'DEFHEADING\((.*?):?\)', line)
     if match is None:
         serror(file, lnum, "Invalid DEFHEADING line")
     return match.group(1)
@@ -72,8 +71,9 @@ def parse_archheading(file, lnum, line):
     # though note that the 'some string' could be the empty string.
     # As with DEFHEADING, empty string ARCHHEADINGs will be ignored.
     #
-    # Return the heading text
-    match = re.match(r'ARCHHEADING\((.*),.*\)', line)
+    # Return the heading text. We strip out any trailing ':' for
+    # consistency with other headings in the rST documentation.
+    match = re.match(r'ARCHHEADING\((.*?):?,.*\)', line)
     if match is None:
         serror(file, lnum, "Invalid ARCHHEADING line")
     return match.group(1)
@@ -108,31 +108,13 @@ class HxtoolDocDirective(Directive):
 
                 if directive == 'HXCOMM':
                     pass
-                elif directive == 'STEXI':
-                    if state == HxState.RST:
-                        serror(hxfile, lnum, 'expected ERST, found STEXI')
-                    elif state == HxState.TEXI:
-                        serror(hxfile, lnum, 'expected ETEXI, found STEXI')
-                    else:
-                        state = HxState.TEXI
-                elif directive == 'ETEXI':
-                    if state == HxState.RST:
-                        serror(hxfile, lnum, 'expected ERST, found ETEXI')
-                    elif state == HxState.CTEXT:
-                        serror(hxfile, lnum, 'expected STEXI, found ETEXI')
-                    else:
-                        state = HxState.CTEXT
                 elif directive == 'SRST':
                     if state == HxState.RST:
                         serror(hxfile, lnum, 'expected ERST, found SRST')
-                    elif state == HxState.TEXI:
-                        serror(hxfile, lnum, 'expected ETEXI, found SRST')
                     else:
                         state = HxState.RST
                 elif directive == 'ERST':
-                    if state == HxState.TEXI:
-                        serror(hxfile, lnum, 'expected ETEXI, found ERST')
-                    elif state == HxState.CTEXT:
+                    if state == HxState.CTEXT:
                         serror(hxfile, lnum, 'expected SRST, found ERST')
                     else:
                         state = HxState.CTEXT
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
new file mode 100644 (file)
index 0000000..2d5c06c
--- /dev/null
@@ -0,0 +1,346 @@
+Arm CPU Features
+================
+
+CPU features are optional features that a CPU of supporting type may
+choose to implement or not.  In QEMU, optional CPU features have
+corresponding boolean CPU proprieties that, when enabled, indicate
+that the feature is implemented, and, conversely, when disabled,
+indicate that it is not implemented. An example of an Arm CPU feature
+is the Performance Monitoring Unit (PMU).  CPU types such as the
+Cortex-A15 and the Cortex-A57, which respectively implement Arm
+architecture reference manuals ARMv7-A and ARMv8-A, may both optionally
+implement PMUs.  For example, if a user wants to use a Cortex-A15 without
+a PMU, then the `-cpu` parameter should contain `pmu=off` on the QEMU
+command line, i.e. `-cpu cortex-a15,pmu=off`.
+
+As not all CPU types support all optional CPU features, then whether or
+not a CPU property exists depends on the CPU type.  For example, CPUs
+that implement the ARMv8-A architecture reference manual may optionally
+support the AArch32 CPU feature, which may be enabled by disabling the
+`aarch64` CPU property.  A CPU type such as the Cortex-A15, which does
+not implement ARMv8-A, will not have the `aarch64` CPU property.
+
+QEMU's support may be limited for some CPU features, only partially
+supporting the feature or only supporting the feature under certain
+configurations.  For example, the `aarch64` CPU feature, which, when
+disabled, enables the optional AArch32 CPU feature, is only supported
+when using the KVM accelerator and when running on a host CPU type that
+supports the feature.  While `aarch64` currently only works with KVM,
+it could work with TCG.  CPU features that are specific to KVM are
+prefixed with "kvm-" and are described in "KVM VCPU Features".
+
+CPU Feature Probing
+===================
+
+Determining which CPU features are available and functional for a given
+CPU type is possible with the `query-cpu-model-expansion` QMP command.
+Below are some examples where `scripts/qmp/qmp-shell` (see the top comment
+block in the script for usage) is used to issue the QMP commands.
+
+1. Determine which CPU features are available for the `max` CPU type
+   (Note, we started QEMU with qemu-system-aarch64, so `max` is
+   implementing the ARMv8-A reference manual in this case)::
+
+      (QEMU) query-cpu-model-expansion type=full model={"name":"max"}
+      { "return": {
+        "model": { "name": "max", "props": {
+        "sve1664": true, "pmu": true, "sve1792": true, "sve1920": true,
+        "sve128": true, "aarch64": true, "sve1024": true, "sve": true,
+        "sve640": true, "sve768": true, "sve1408": true, "sve256": true,
+        "sve1152": true, "sve512": true, "sve384": true, "sve1536": true,
+        "sve896": true, "sve1280": true, "sve2048": true
+      }}}}
+
+We see that the `max` CPU type has the `pmu`, `aarch64`, `sve`, and many
+`sve<N>` CPU features.  We also see that all the CPU features are
+enabled, as they are all `true`.  (The `sve<N>` CPU features are all
+optional SVE vector lengths (see "SVE CPU Properties").  While with TCG
+all SVE vector lengths can be supported, when KVM is in use it's more
+likely that only a few lengths will be supported, if SVE is supported at
+all.)
+
+(2) Let's try to disable the PMU::
+
+      (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"pmu":false}}
+      { "return": {
+        "model": { "name": "max", "props": {
+        "sve1664": true, "pmu": false, "sve1792": true, "sve1920": true,
+        "sve128": true, "aarch64": true, "sve1024": true, "sve": true,
+        "sve640": true, "sve768": true, "sve1408": true, "sve256": true,
+        "sve1152": true, "sve512": true, "sve384": true, "sve1536": true,
+        "sve896": true, "sve1280": true, "sve2048": true
+      }}}}
+
+We see it worked, as `pmu` is now `false`.
+
+(3) Let's try to disable `aarch64`, which enables the AArch32 CPU feature::
+
+      (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"aarch64":false}}
+      {"error": {
+       "class": "GenericError", "desc":
+       "'aarch64' feature cannot be disabled unless KVM is enabled and 32-bit EL1 is supported"
+      }}
+
+It looks like this feature is limited to a configuration we do not
+currently have.
+
+(4) Let's disable `sve` and see what happens to all the optional SVE
+    vector lengths::
+
+      (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"sve":false}}
+      { "return": {
+        "model": { "name": "max", "props": {
+        "sve1664": false, "pmu": true, "sve1792": false, "sve1920": false,
+        "sve128": false, "aarch64": true, "sve1024": false, "sve": false,
+        "sve640": false, "sve768": false, "sve1408": false, "sve256": false,
+        "sve1152": false, "sve512": false, "sve384": false, "sve1536": false,
+        "sve896": false, "sve1280": false, "sve2048": false
+      }}}}
+
+As expected they are now all `false`.
+
+(5) Let's try probing CPU features for the Cortex-A15 CPU type::
+
+      (QEMU) query-cpu-model-expansion type=full model={"name":"cortex-a15"}
+      {"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}}
+
+Only the `pmu` CPU feature is available.
+
+A note about CPU feature dependencies
+-------------------------------------
+
+It's possible for features to have dependencies on other features. I.e.
+it may be possible to change one feature at a time without error, but
+when attempting to change all features at once an error could occur
+depending on the order they are processed.  It's also possible changing
+all at once doesn't generate an error, because a feature's dependencies
+are satisfied with other features, but the same feature cannot be changed
+independently without error.  For these reasons callers should always
+attempt to make their desired changes all at once in order to ensure the
+collection is valid.
+
+A note about CPU models and KVM
+-------------------------------
+
+Named CPU models generally do not work with KVM.  There are a few cases
+that do work, e.g. using the named CPU model `cortex-a57` with KVM on a
+seattle host, but mostly if KVM is enabled the `host` CPU type must be
+used.  This means the guest is provided all the same CPU features as the
+host CPU type has.  And, for this reason, the `host` CPU type should
+enable all CPU features that the host has by default.  Indeed it's even
+a bit strange to allow disabling CPU features that the host has when using
+the `host` CPU type, but in the absence of CPU models it's the best we can
+do if we want to launch guests without all the host's CPU features enabled.
+
+Enabling KVM also affects the `query-cpu-model-expansion` QMP command.  The
+affect is not only limited to specific features, as pointed out in example
+(3) of "CPU Feature Probing", but also to which CPU types may be expanded.
+When KVM is enabled, only the `max`, `host`, and current CPU type may be
+expanded.  This restriction is necessary as it's not possible to know all
+CPU types that may work with KVM, but it does impose a small risk of users
+experiencing unexpected errors.  For example on a seattle, as mentioned
+above, the `cortex-a57` CPU type is also valid when KVM is enabled.
+Therefore a user could use the `host` CPU type for the current type, but
+then attempt to query `cortex-a57`, however that query will fail with our
+restrictions.  This shouldn't be an issue though as management layers and
+users have been preferring the `host` CPU type for use with KVM for quite
+some time.  Additionally, if the KVM-enabled QEMU instance running on a
+seattle host is using the `cortex-a57` CPU type, then querying `cortex-a57`
+will work.
+
+Using CPU Features
+==================
+
+After determining which CPU features are available and supported for a
+given CPU type, then they may be selectively enabled or disabled on the
+QEMU command line with that CPU type::
+
+  $ qemu-system-aarch64 -M virt -cpu max,pmu=off,sve=on,sve128=on,sve256=on
+
+The example above disables the PMU and enables the first two SVE vector
+lengths for the `max` CPU type.  Note, the `sve=on` isn't actually
+necessary, because, as we observed above with our probe of the `max` CPU
+type, `sve` is already on by default.  Also, based on our probe of
+defaults, it would seem we need to disable many SVE vector lengths, rather
+than only enabling the two we want.  This isn't the case, because, as
+disabling many SVE vector lengths would be quite verbose, the `sve<N>` CPU
+properties have special semantics (see "SVE CPU Property Parsing
+Semantics").
+
+KVM VCPU Features
+=================
+
+KVM VCPU features are CPU features that are specific to KVM, such as
+paravirt features or features that enable CPU virtualization extensions.
+The features' CPU properties are only available when KVM is enabled and
+are named with the prefix "kvm-".  KVM VCPU features may be probed,
+enabled, and disabled in the same way as other CPU features.  Below is
+the list of KVM VCPU features and their descriptions.
+
+  kvm-no-adjvtime          By default kvm-no-adjvtime is disabled.  This
+                           means that by default the virtual time
+                           adjustment is enabled (vtime is not *not*
+                           adjusted).
+
+                           When virtual time adjustment is enabled each
+                           time the VM transitions back to running state
+                           the VCPU's virtual counter is updated to ensure
+                           stopped time is not counted.  This avoids time
+                           jumps surprising guest OSes and applications,
+                           as long as they use the virtual counter for
+                           timekeeping.  However it has the side effect of
+                           the virtual and physical counters diverging.
+                           All timekeeping based on the virtual counter
+                           will appear to lag behind any timekeeping that
+                           does not subtract VM stopped time.  The guest
+                           may resynchronize its virtual counter with
+                           other time sources as needed.
+
+                           Enable kvm-no-adjvtime to disable virtual time
+                           adjustment, also restoring the legacy (pre-5.0)
+                           behavior.
+
+SVE CPU Properties
+==================
+
+There are two types of SVE CPU properties: `sve` and `sve<N>`.  The first
+is used to enable or disable the entire SVE feature, just as the `pmu`
+CPU property completely enables or disables the PMU.  The second type
+is used to enable or disable specific vector lengths, where `N` is the
+number of bits of the length.  The `sve<N>` CPU properties have special
+dependencies and constraints, see "SVE CPU Property Dependencies and
+Constraints" below.  Additionally, as we want all supported vector lengths
+to be enabled by default, then, in order to avoid overly verbose command
+lines (command lines full of `sve<N>=off`, for all `N` not wanted), we
+provide the parsing semantics listed in "SVE CPU Property Parsing
+Semantics".
+
+SVE CPU Property Dependencies and Constraints
+---------------------------------------------
+
+  1) At least one vector length must be enabled when `sve` is enabled.
+
+  2) If a vector length `N` is enabled, then, when KVM is enabled, all
+     smaller, host supported vector lengths must also be enabled.  If
+     KVM is not enabled, then only all the smaller, power-of-two vector
+     lengths must be enabled.  E.g. with KVM if the host supports all
+     vector lengths up to 512-bits (128, 256, 384, 512), then if `sve512`
+     is enabled, the 128-bit vector length, 256-bit vector length, and
+     384-bit vector length must also be enabled. Without KVM, the 384-bit
+     vector length would not be required.
+
+  3) If KVM is enabled then only vector lengths that the host CPU type
+     support may be enabled.  If SVE is not supported by the host, then
+     no `sve*` properties may be enabled.
+
+SVE CPU Property Parsing Semantics
+----------------------------------
+
+  1) If SVE is disabled (`sve=off`), then which SVE vector lengths
+     are enabled or disabled is irrelevant to the guest, as the entire
+     SVE feature is disabled and that disables all vector lengths for
+     the guest.  However QEMU will still track any `sve<N>` CPU
+     properties provided by the user.  If later an `sve=on` is provided,
+     then the guest will get only the enabled lengths.  If no `sve=on`
+     is provided and there are explicitly enabled vector lengths, then
+     an error is generated.
+
+  2) If SVE is enabled (`sve=on`), but no `sve<N>` CPU properties are
+     provided, then all supported vector lengths are enabled, which when
+     KVM is not in use means including the non-power-of-two lengths, and,
+     when KVM is in use, it means all vector lengths supported by the host
+     processor.
+
+  3) If SVE is enabled, then an error is generated when attempting to
+     disable the last enabled vector length (see constraint (1) of "SVE
+     CPU Property Dependencies and Constraints").
+
+  4) If one or more vector lengths have been explicitly enabled and at
+     at least one of the dependency lengths of the maximum enabled length
+     has been explicitly disabled, then an error is generated (see
+     constraint (2) of "SVE CPU Property Dependencies and Constraints").
+
+  5) When KVM is enabled, if the host does not support SVE, then an error
+     is generated when attempting to enable any `sve*` properties (see
+     constraint (3) of "SVE CPU Property Dependencies and Constraints").
+
+  6) When KVM is enabled, if the host does support SVE, then an error is
+     generated when attempting to enable any vector lengths not supported
+     by the host (see constraint (3) of "SVE CPU Property Dependencies and
+     Constraints").
+
+  7) If one or more `sve<N>` CPU properties are set `off`, but no `sve<N>`,
+     CPU properties are set `on`, then the specified vector lengths are
+     disabled but the default for any unspecified lengths remains enabled.
+     When KVM is not enabled, disabling a power-of-two vector length also
+     disables all vector lengths larger than the power-of-two length.
+     When KVM is enabled, then disabling any supported vector length also
+     disables all larger vector lengths (see constraint (2) of "SVE CPU
+     Property Dependencies and Constraints").
+
+  8) If one or more `sve<N>` CPU properties are set to `on`, then they
+     are enabled and all unspecified lengths default to disabled, except
+     for the required lengths per constraint (2) of "SVE CPU Property
+     Dependencies and Constraints", which will even be auto-enabled if
+     they were not explicitly enabled.
+
+  9) If SVE was disabled (`sve=off`), allowing all vector lengths to be
+     explicitly disabled (i.e. avoiding the error specified in (3) of
+     "SVE CPU Property Parsing Semantics"), then if later an `sve=on` is
+     provided an error will be generated.  To avoid this error, one must
+     enable at least one vector length prior to enabling SVE.
+
+SVE CPU Property Examples
+-------------------------
+
+  1) Disable SVE::
+
+     $ qemu-system-aarch64 -M virt -cpu max,sve=off
+
+  2) Implicitly enable all vector lengths for the `max` CPU type::
+
+     $ qemu-system-aarch64 -M virt -cpu max
+
+  3) When KVM is enabled, implicitly enable all host CPU supported vector
+     lengths with the `host` CPU type::
+
+     $ qemu-system-aarch64 -M virt,accel=kvm -cpu host
+
+  4) Only enable the 128-bit vector length::
+
+     $ qemu-system-aarch64 -M virt -cpu max,sve128=on
+
+  5) Disable the 512-bit vector length and all larger vector lengths,
+     since 512 is a power-of-two.  This results in all the smaller,
+     uninitialized lengths (128, 256, and 384) defaulting to enabled::
+
+     $ qemu-system-aarch64 -M virt -cpu max,sve512=off
+
+  6) Enable the 128-bit, 256-bit, and 512-bit vector lengths::
+
+     $ qemu-system-aarch64 -M virt -cpu max,sve128=on,sve256=on,sve512=on
+
+  7) The same as (6), but since the 128-bit and 256-bit vector
+     lengths are required for the 512-bit vector length to be enabled,
+     then allow them to be auto-enabled::
+
+     $ qemu-system-aarch64 -M virt -cpu max,sve512=on
+
+  8) Do the same as (7), but by first disabling SVE and then re-enabling it::
+
+     $ qemu-system-aarch64 -M virt -cpu max,sve=off,sve512=on,sve=on
+
+  9) Force errors regarding the last vector length::
+
+     $ qemu-system-aarch64 -M virt -cpu max,sve128=off
+     $ qemu-system-aarch64 -M virt -cpu max,sve=off,sve128=off,sve=on
+
+SVE CPU Property Recommendations
+--------------------------------
+
+The examples in "SVE CPU Property Examples" exhibit many ways to select
+vector lengths which developers may find useful in order to avoid overly
+verbose command lines.  However, the recommended way to select vector
+lengths is to explicitly enable each desired length.  Therefore only
+example's (1), (4), and (6) exhibit recommended uses of the properties.
+
diff --git a/docs/system/arm/integratorcp.rst b/docs/system/arm/integratorcp.rst
new file mode 100644 (file)
index 0000000..e6f050f
--- /dev/null
@@ -0,0 +1,16 @@
+Integrator/CP (``integratorcp``)
+================================
+
+The Arm Integrator/CP board is emulated with the following devices:
+
+-  ARM926E, ARM1026E, ARM946E, ARM1136 or Cortex-A8 CPU
+
+-  Two PL011 UARTs
+
+-  SMC 91c111 Ethernet adapter
+
+-  PL110 LCD controller
+
+-  PL050 KMI with PS/2 keyboard and mouse.
+
+-  PL181 MultiMedia Card Interface with SD card.
diff --git a/docs/system/arm/musicpal.rst b/docs/system/arm/musicpal.rst
new file mode 100644 (file)
index 0000000..9de380e
--- /dev/null
@@ -0,0 +1,19 @@
+Freecom MusicPal (``musicpal``)
+===============================
+
+The Freecom MusicPal internet radio emulation includes the following
+elements:
+
+-  Marvell MV88W8618 Arm core.
+
+-  32 MB RAM, 256 KB SRAM, 8 MB flash.
+
+-  Up to 2 16550 UARTs
+
+-  MV88W8xx8 Ethernet controller
+
+-  MV88W8618 audio controller, WM8750 CODEC and mixer
+
+-  128x64 display with brightness control
+
+-  2 buttons, 2 navigation wheels with button function
diff --git a/docs/system/arm/nseries.rst b/docs/system/arm/nseries.rst
new file mode 100644 (file)
index 0000000..cd9edf5
--- /dev/null
@@ -0,0 +1,33 @@
+Nokia N800 and N810 tablets (``n800``, ``n810``)
+================================================
+
+Nokia N800 and N810 internet tablets (known also as RX-34 and RX-44 /
+48) emulation supports the following elements:
+
+-  Texas Instruments OMAP2420 System-on-chip (ARM1136 core)
+
+-  RAM and non-volatile OneNAND Flash memories
+
+-  Display connected to EPSON remote framebuffer chip and OMAP on-chip
+   display controller and a LS041y3 MIPI DBI-C controller
+
+-  TI TSC2301 (in N800) and TI TSC2005 (in N810) touchscreen
+   controllers driven through SPI bus
+
+-  National Semiconductor LM8323-controlled qwerty keyboard driven
+   through |I2C| bus
+
+-  Secure Digital card connected to OMAP MMC/SD host
+
+-  Three OMAP on-chip UARTs and on-chip STI debugging console
+
+-  Mentor Graphics \"Inventra\" dual-role USB controller embedded in a
+   TI TUSB6010 chip - only USB host mode is supported
+
+-  TI TMP105 temperature sensor driven through |I2C| bus
+
+-  TI TWL92230C power management companion with an RTC on
+   |I2C| bus
+
+-  Nokia RETU and TAHVO multi-purpose chips with an RTC, connected
+   through CBUS
diff --git a/docs/system/arm/palm.rst b/docs/system/arm/palm.rst
new file mode 100644 (file)
index 0000000..47ff9b3
--- /dev/null
@@ -0,0 +1,23 @@
+Palm Tungsten|E PDA (``cheetah``)
+=================================
+
+The Palm Tungsten|E PDA (codename \"Cheetah\") emulation includes the
+following elements:
+
+-  Texas Instruments OMAP310 System-on-chip (ARM925T core)
+
+-  ROM and RAM memories (ROM firmware image can be loaded with
+   -option-rom)
+
+-  On-chip LCD controller
+
+-  On-chip Real Time Clock
+
+-  TI TSC2102i touchscreen controller / analog-digital converter /
+   Audio CODEC, connected through MicroWire and |I2S| busses
+
+-  GPIO-connected matrix keypad
+
+-  Secure Digital card connected to OMAP MMC/SD host
+
+-  Three on-chip UARTs
diff --git a/docs/system/arm/realview.rst b/docs/system/arm/realview.rst
new file mode 100644 (file)
index 0000000..65f5be3
--- /dev/null
@@ -0,0 +1,34 @@
+Arm Realview boards (``realview-eb``, ``realview-eb-mpcore``, ``realview-pb-a8``, ``realview-pbx-a9``)
+======================================================================================================
+
+Several variants of the Arm RealView baseboard are emulated, including
+the EB, PB-A8 and PBX-A9. Due to interactions with the bootloader, only
+certain Linux kernel configurations work out of the box on these boards.
+
+Kernels for the PB-A8 board should have CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+enabled in the kernel, and expect 512M RAM. Kernels for The PBX-A9 board
+should have CONFIG_SPARSEMEM enabled, CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+disabled and expect 1024M RAM.
+
+The following devices are emulated:
+
+-  ARM926E, ARM1136, ARM11MPCore, Cortex-A8 or Cortex-A9 MPCore CPU
+
+-  Arm AMBA Generic/Distributed Interrupt Controller
+
+-  Four PL011 UARTs
+
+-  SMC 91c111 or SMSC LAN9118 Ethernet adapter
+
+-  PL110 LCD controller
+
+-  PL050 KMI with PS/2 keyboard and mouse
+
+-  PCI host bridge
+
+-  PCI OHCI USB controller
+
+-  LSI53C895A PCI SCSI Host Bus Adapter with hard disk and CD-ROM
+   devices
+
+-  PL181 MultiMedia Card Interface with SD card.
diff --git a/docs/system/arm/stellaris.rst b/docs/system/arm/stellaris.rst
new file mode 100644 (file)
index 0000000..8af4ad7
--- /dev/null
@@ -0,0 +1,26 @@
+Stellaris boards (``lm3s6965evb``, ``lm3s811evb``)
+==================================================
+
+The Luminary Micro Stellaris LM3S811EVB emulation includes the following
+devices:
+
+-  Cortex-M3 CPU core.
+
+-  64k Flash and 8k SRAM.
+
+-  Timers, UARTs, ADC and |I2C| interface.
+
+-  OSRAM Pictiva 96x16 OLED with SSD0303 controller on
+   |I2C| bus.
+
+The Luminary Micro Stellaris LM3S6965EVB emulation includes the
+following devices:
+
+-  Cortex-M3 CPU core.
+
+-  256k Flash and 64k SRAM.
+
+-  Timers, UARTs, ADC, |I2C| and SSI interfaces.
+
+-  OSRAM Pictiva 128x64 OLED with SSD0323 controller connected via
+   SSI.
diff --git a/docs/system/arm/sx1.rst b/docs/system/arm/sx1.rst
new file mode 100644 (file)
index 0000000..8bce30d
--- /dev/null
@@ -0,0 +1,18 @@
+Siemens SX1 (``sx1``, ``sx1-v1``)
+=================================
+
+The Siemens SX1 models v1 and v2 (default) basic emulation. The
+emulation includes the following elements:
+
+-  Texas Instruments OMAP310 System-on-chip (ARM925T core)
+
+-  ROM and RAM memories (ROM firmware image can be loaded with
+   -pflash) V1 1 Flash of 16MB and 1 Flash of 8MB V2 1 Flash of 32MB
+
+-  On-chip LCD controller
+
+-  On-chip Real Time Clock
+
+-  Secure Digital card connected to OMAP MMC/SD host
+
+-  Three on-chip UARTs
diff --git a/docs/system/arm/versatile.rst b/docs/system/arm/versatile.rst
new file mode 100644 (file)
index 0000000..51221c3
--- /dev/null
@@ -0,0 +1,29 @@
+Arm Versatile boards (``versatileab``, ``versatilepb``)
+=======================================================
+
+The Arm Versatile baseboard is emulated with the following devices:
+
+-  ARM926E, ARM1136 or Cortex-A8 CPU
+
+-  PL190 Vectored Interrupt Controller
+
+-  Four PL011 UARTs
+
+-  SMC 91c111 Ethernet adapter
+
+-  PL110 LCD controller
+
+-  PL050 KMI with PS/2 keyboard and mouse.
+
+-  PCI host bridge. Note the emulated PCI bridge only provides access
+   to PCI memory space. It does not provide access to PCI IO space. This
+   means some devices (eg. ne2k_pci NIC) are not usable, and others (eg.
+   rtl8139 NIC) are only usable when the guest drivers use the memory
+   mapped control registers.
+
+-  PCI OHCI USB controller.
+
+-  LSI53C895A PCI SCSI Host Bus Adapter with hard disk and CD-ROM
+   devices.
+
+-  PL181 MultiMedia Card Interface with SD card.
diff --git a/docs/system/arm/xscale.rst b/docs/system/arm/xscale.rst
new file mode 100644 (file)
index 0000000..89ec93e
--- /dev/null
@@ -0,0 +1,29 @@
+Sharp XScale-based PDA models (``akita``, ``borzoi``, ``spitz``, ``terrier``)
+=============================================================================
+
+The XScale-based clamshell PDA models (\"Spitz\", \"Akita\", \"Borzoi\"
+and \"Terrier\") emulation includes the following peripherals:
+
+-  Intel PXA270 System-on-chip (ARMv5TE core)
+
+-  NAND Flash memory
+
+-  IBM/Hitachi DSCM microdrive in a PXA PCMCIA slot - not in \"Akita\"
+
+-  On-chip OHCI USB controller
+
+-  On-chip LCD controller
+
+-  On-chip Real Time Clock
+
+-  TI ADS7846 touchscreen controller on SSP bus
+
+-  Maxim MAX1111 analog-digital converter on |I2C| bus
+
+-  GPIO-connected keyboard controller and LEDs
+
+-  Secure Digital card connected to PXA MMC/SD host
+
+-  Three on-chip UARTs
+
+-  WM8750 audio CODEC on |I2C| and |I2S| busses
diff --git a/docs/system/build-platforms.rst b/docs/system/build-platforms.rst
new file mode 100644 (file)
index 0000000..c2b92a9
--- /dev/null
@@ -0,0 +1,79 @@
+.. _Supported-build-platforms:
+
+Supported build platforms
+=========================
+
+QEMU aims to support building and executing on multiple host OS
+platforms. This appendix outlines which platforms are the major build
+targets. These platforms are used as the basis for deciding upon the
+minimum required versions of 3rd party software QEMU depends on. The
+supported platforms are the targets for automated testing performed by
+the project when patches are submitted for review, and tested before and
+after merge.
+
+If a platform is not listed here, it does not imply that QEMU won't
+work. If an unlisted platform has comparable software versions to a
+listed platform, there is every expectation that it will work. Bug
+reports are welcome for problems encountered on unlisted platforms
+unless they are clearly older vintage than what is described here.
+
+Note that when considering software versions shipped in distros as
+support targets, QEMU considers only the version number, and assumes the
+features in that distro match the upstream release with the same
+version. In other words, if a distro backports extra features to the
+software in their distro, QEMU upstream code will not add explicit
+support for those backports, unless the feature is auto-detectable in a
+manner that works for the upstream releases too.
+
+The Repology site https://repology.org is a useful resource to identify
+currently shipped versions of software in various operating systems,
+though it does not cover all distros listed below.
+
+Linux OS
+--------
+
+For distributions with frequent, short-lifetime releases, the project
+will aim to support all versions that are not end of life by their
+respective vendors. For the purposes of identifying supported software
+versions, the project will look at Fedora, Ubuntu, and openSUSE distros.
+Other short- lifetime distros will be assumed to ship similar software
+versions.
+
+For distributions with long-lifetime releases, the project will aim to
+support the most recent major version at all times. Support for the
+previous major version will be dropped 2 years after the new major
+version is released, or when it reaches "end of life". For the purposes
+of identifying supported software versions, the project will look at
+RHEL, Debian, Ubuntu LTS, and SLES distros. Other long-lifetime distros
+will be assumed to ship similar software versions.
+
+Windows
+-------
+
+The project supports building with current versions of the MinGW
+toolchain, hosted on Linux.
+
+macOS
+-----
+
+The project supports building with the two most recent versions of
+macOS, with the current homebrew package set available.
+
+FreeBSD
+-------
+
+The project aims to support the all the versions which are not end of
+life.
+
+NetBSD
+------
+
+The project aims to support the most recent major version at all times.
+Support for the previous major version will be dropped 2 years after the
+new major version is released.
+
+OpenBSD
+-------
+
+The project aims to support the all the versions which are not end of
+life.
index 7ca115f5e03e4de8cad9ac9edfc49bf22a593b6c..6251849fefcb723c9badd8fa9484d342077139cd 100644 (file)
@@ -13,10 +13,16 @@ exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
 # This slightly misuses the 'description', but is the best way to get
 # the manual title to appear in the sidebar.
 html_theme_options['description'] = u'System Emulation User''s Guide'
+
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
+    ('qemu-manpage', 'qemu', u'QEMU User Documentation',
+     ['Fabrice Bellard'], 1),
     ('qemu-block-drivers', 'qemu-block-drivers',
      u'QEMU block drivers reference',
-     ['Fabrice Bellard and the QEMU Project developers'], 7)
+     ['Fabrice Bellard and the QEMU Project developers'], 7),
+    ('qemu-cpu-models', 'qemu-cpu-models',
+     u'QEMU CPU Models',
+     ['The QEMU Project developers'], 7)
 ]
diff --git a/docs/system/cpu-models-mips.rst.inc b/docs/system/cpu-models-mips.rst.inc
new file mode 100644 (file)
index 0000000..499b5b6
--- /dev/null
@@ -0,0 +1,105 @@
+Supported CPU model configurations on MIPS hosts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+QEMU supports variety of MIPS CPU models:
+
+Supported CPU models for MIPS32 hosts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following CPU models are supported for use on MIPS32 hosts.
+Administrators / applications are recommended to use the CPU model that
+matches the generation of the host CPUs in use. In a deployment with a
+mixture of host CPU models between machines, if live migration
+compatibility is required, use the newest CPU model that is compatible
+across all desired hosts.
+
+``mips32r6-generic``
+    MIPS32 Processor (Release 6, 2015)
+
+``P5600``
+    MIPS32 Processor (P5600, 2014)
+
+``M14K``, ``M14Kc``
+    MIPS32 Processor (M14K, 2009)
+
+``74Kf``
+    MIPS32 Processor (74K, 2007)
+
+``34Kf``
+    MIPS32 Processor (34K, 2006)
+
+``24Kc``, ``24KEc``, ``24Kf``
+    MIPS32 Processor (24K, 2003)
+
+``4Kc``, ``4Km``, ``4KEcR1``, ``4KEmR1``, ``4KEc``, ``4KEm``
+    MIPS32 Processor (4K, 1999)
+
+
+Supported CPU models for MIPS64 hosts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following CPU models are supported for use on MIPS64 hosts.
+Administrators / applications are recommended to use the CPU model that
+matches the generation of the host CPUs in use. In a deployment with a
+mixture of host CPU models between machines, if live migration
+compatibility is required, use the newest CPU model that is compatible
+across all desired hosts.
+
+``I6400``
+    MIPS64 Processor (Release 6, 2014)
+
+``Loongson-2F``
+    MIPS64 Processor (Loongson 2, 2008)
+
+``Loongson-2E``
+    MIPS64 Processor (Loongson 2, 2006)
+
+``mips64dspr2``
+    MIPS64 Processor (Release 2, 2006)
+
+``MIPS64R2-generic``, ``5KEc``, ``5KEf``
+    MIPS64 Processor (Release 2, 2002)
+
+``20Kc``
+    MIPS64 Processor (20K, 2000
+
+``5Kc``, ``5Kf``
+    MIPS64 Processor (5K, 1999)
+
+``VR5432``
+    MIPS64 Processor (VR, 1998)
+
+``R4000``
+    MIPS64 Processor (MIPS III, 1991)
+
+
+Supported CPU models for nanoMIPS hosts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following CPU models are supported for use on nanoMIPS hosts.
+Administrators / applications are recommended to use the CPU model that
+matches the generation of the host CPUs in use. In a deployment with a
+mixture of host CPU models between machines, if live migration
+compatibility is required, use the newest CPU model that is compatible
+across all desired hosts.
+
+``I7200``
+    MIPS I7200 (nanoMIPS, 2018)
+
+Preferred CPU models for MIPS hosts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following CPU models are preferred for use on different MIPS hosts:
+
+``MIPS III``
+    R4000
+
+``MIPS32R2``
+    34Kf
+
+``MIPS64R6``
+    I6400
+
+``nanoMIPS``
+    I7200
+
diff --git a/docs/system/cpu-models-x86.rst.inc b/docs/system/cpu-models-x86.rst.inc
new file mode 100644 (file)
index 0000000..cbad930
--- /dev/null
@@ -0,0 +1,365 @@
+Recommendations for KVM CPU model configuration on x86 hosts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The information that follows provides recommendations for configuring
+CPU models on x86 hosts. The goals are to maximise performance, while
+protecting guest OS against various CPU hardware flaws, and optionally
+enabling live migration between hosts with heterogeneous CPU models.
+
+
+Two ways to configure CPU models with QEMU / KVM
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(1) **Host passthrough**
+
+    This passes the host CPU model features, model, stepping, exactly to
+    the guest. Note that KVM may filter out some host CPU model features
+    if they cannot be supported with virtualization. Live migration is
+    unsafe when this mode is used as libvirt / QEMU cannot guarantee a
+    stable CPU is exposed to the guest across hosts. This is the
+    recommended CPU to use, provided live migration is not required.
+
+(2) **Named model**
+
+    QEMU comes with a number of predefined named CPU models, that
+    typically refer to specific generations of hardware released by
+    Intel and AMD.  These allow the guest VMs to have a degree of
+    isolation from the host CPU, allowing greater flexibility in live
+    migrating between hosts with differing hardware.  @end table
+
+In both cases, it is possible to optionally add or remove individual CPU
+features, to alter what is presented to the guest by default.
+
+Libvirt supports a third way to configure CPU models known as "Host
+model".  This uses the QEMU "Named model" feature, automatically picking
+a CPU model that is similar the host CPU, and then adding extra features
+to approximate the host model as closely as possible. This does not
+guarantee the CPU family, stepping, etc will precisely match the host
+CPU, as they would with "Host passthrough", but gives much of the
+benefit of passthrough, while making live migration safe.
+
+
+Preferred CPU models for Intel x86 hosts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following CPU models are preferred for use on Intel hosts.
+Administrators / applications are recommended to use the CPU model that
+matches the generation of the host CPUs in use. In a deployment with a
+mixture of host CPU models between machines, if live migration
+compatibility is required, use the newest CPU model that is compatible
+across all desired hosts.
+
+``Skylake-Server``, ``Skylake-Server-IBRS``
+    Intel Xeon Processor (Skylake, 2016)
+
+``Skylake-Client``, ``Skylake-Client-IBRS``
+    Intel Core Processor (Skylake, 2015)
+
+``Broadwell``, ``Broadwell-IBRS``, ``Broadwell-noTSX``, ``Broadwell-noTSX-IBRS``
+    Intel Core Processor (Broadwell, 2014)
+
+``Haswell``, ``Haswell-IBRS``, ``Haswell-noTSX``, ``Haswell-noTSX-IBRS``
+    Intel Core Processor (Haswell, 2013)
+
+``IvyBridge``, ``IvyBridge-IBR``
+    Intel Xeon E3-12xx v2 (Ivy Bridge, 2012)
+
+``SandyBridge``, ``SandyBridge-IBRS``
+    Intel Xeon E312xx (Sandy Bridge, 2011)
+
+``Westmere``, ``Westmere-IBRS``
+    Westmere E56xx/L56xx/X56xx (Nehalem-C, 2010)
+
+``Nehalem``, ``Nehalem-IBRS``
+    Intel Core i7 9xx (Nehalem Class Core i7, 2008)
+
+``Penryn``
+    Intel Core 2 Duo P9xxx (Penryn Class Core 2, 2007)
+
+``Conroe``
+    Intel Celeron_4x0 (Conroe/Merom Class Core 2, 2006)
+
+
+Important CPU features for Intel x86 hosts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following are important CPU features that should be used on Intel
+x86 hosts, when available in the host CPU. Some of them require explicit
+configuration to enable, as they are not included by default in some, or
+all, of the named CPU models listed above. In general all of these
+features are included if using "Host passthrough" or "Host model".
+
+``pcid``
+  Recommended to mitigate the cost of the Meltdown (CVE-2017-5754) fix.
+
+  Included by default in Haswell, Broadwell & Skylake Intel CPU models.
+
+  Should be explicitly turned on for Westmere, SandyBridge, and
+  IvyBridge Intel CPU models. Note that some desktop/mobile Westmere
+  CPUs cannot support this feature.
+
+``spec-ctrl``
+  Required to enable the Spectre v2 (CVE-2017-5715) fix.
+
+  Included by default in Intel CPU models with -IBRS suffix.
+
+  Must be explicitly turned on for Intel CPU models without -IBRS
+  suffix.
+
+  Requires the host CPU microcode to support this feature before it
+  can be used for guest CPUs.
+
+``stibp``
+  Required to enable stronger Spectre v2 (CVE-2017-5715) fixes in some
+  operating systems.
+
+  Must be explicitly turned on for all Intel CPU models.
+
+  Requires the host CPU microcode to support this feature before it can
+  be used for guest CPUs.
+
+``ssbd``
+  Required to enable the CVE-2018-3639 fix.
+
+  Not included by default in any Intel CPU model.
+
+  Must be explicitly turned on for all Intel CPU models.
+
+  Requires the host CPU microcode to support this feature before it
+  can be used for guest CPUs.
+
+``pdpe1gb``
+  Recommended to allow guest OS to use 1GB size pages.
+
+  Not included by default in any Intel CPU model.
+
+  Should be explicitly turned on for all Intel CPU models.
+
+  Note that not all CPU hardware will support this feature.
+
+``md-clear``
+  Required to confirm the MDS (CVE-2018-12126, CVE-2018-12127,
+  CVE-2018-12130, CVE-2019-11091) fixes.
+
+  Not included by default in any Intel CPU model.
+
+  Must be explicitly turned on for all Intel CPU models.
+
+  Requires the host CPU microcode to support this feature before it
+  can be used for guest CPUs.
+
+
+Preferred CPU models for AMD x86 hosts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following CPU models are preferred for use on Intel hosts.
+Administrators / applications are recommended to use the CPU model that
+matches the generation of the host CPUs in use. In a deployment with a
+mixture of host CPU models between machines, if live migration
+compatibility is required, use the newest CPU model that is compatible
+across all desired hosts.
+
+``EPYC``, ``EPYC-IBPB``
+    AMD EPYC Processor (2017)
+
+``Opteron_G5``
+    AMD Opteron 63xx class CPU (2012)
+
+``Opteron_G4``
+    AMD Opteron 62xx class CPU (2011)
+
+``Opteron_G3``
+    AMD Opteron 23xx (Gen 3 Class Opteron, 2009)
+
+``Opteron_G2``
+    AMD Opteron 22xx (Gen 2 Class Opteron, 2006)
+
+``Opteron_G1``
+    AMD Opteron 240 (Gen 1 Class Opteron, 2004)
+
+
+Important CPU features for AMD x86 hosts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following are important CPU features that should be used on AMD x86
+hosts, when available in the host CPU. Some of them require explicit
+configuration to enable, as they are not included by default in some, or
+all, of the named CPU models listed above. In general all of these
+features are included if using "Host passthrough" or "Host model".
+
+``ibpb``
+  Required to enable the Spectre v2 (CVE-2017-5715) fix.
+
+  Included by default in AMD CPU models with -IBPB suffix.
+
+  Must be explicitly turned on for AMD CPU models without -IBPB suffix.
+
+  Requires the host CPU microcode to support this feature before it
+  can be used for guest CPUs.
+
+``stibp``
+  Required to enable stronger Spectre v2 (CVE-2017-5715) fixes in some
+  operating systems.
+
+  Must be explicitly turned on for all AMD CPU models.
+
+  Requires the host CPU microcode to support this feature before it
+  can be used for guest CPUs.
+
+``virt-ssbd``
+  Required to enable the CVE-2018-3639 fix
+
+  Not included by default in any AMD CPU model.
+
+  Must be explicitly turned on for all AMD CPU models.
+
+  This should be provided to guests, even if amd-ssbd is also provided,
+  for maximum guest compatibility.
+
+  Note for some QEMU / libvirt versions, this must be force enabled when
+  when using "Host model", because this is a virtual feature that
+  doesn't exist in the physical host CPUs.
+
+``amd-ssbd``
+  Required to enable the CVE-2018-3639 fix
+
+  Not included by default in any AMD CPU model.
+
+  Must be explicitly turned on for all AMD CPU models.
+
+  This provides higher performance than ``virt-ssbd`` so should be
+  exposed to guests whenever available in the host. ``virt-ssbd`` should
+  none the less also be exposed for maximum guest compatibility as some
+  kernels only know about ``virt-ssbd``.
+
+``amd-no-ssb``
+  Recommended to indicate the host is not vulnerable CVE-2018-3639
+
+  Not included by default in any AMD CPU model.
+
+  Future hardware generations of CPU will not be vulnerable to
+  CVE-2018-3639, and thus the guest should be told not to enable
+  its mitigations, by exposing amd-no-ssb. This is mutually
+  exclusive with virt-ssbd and amd-ssbd.
+
+``pdpe1gb``
+  Recommended to allow guest OS to use 1GB size pages
+
+  Not included by default in any AMD CPU model.
+
+  Should be explicitly turned on for all AMD CPU models.
+
+  Note that not all CPU hardware will support this feature.
+
+
+Default x86 CPU models
+^^^^^^^^^^^^^^^^^^^^^^
+
+The default QEMU CPU models are designed such that they can run on all
+hosts.  If an application does not wish to do perform any host
+compatibility checks before launching guests, the default is guaranteed
+to work.
+
+The default CPU models will, however, leave the guest OS vulnerable to
+various CPU hardware flaws, so their use is strongly discouraged.
+Applications should follow the earlier guidance to setup a better CPU
+configuration, with host passthrough recommended if live migration is
+not needed.
+
+``qemu32``, ``qemu64``
+    QEMU Virtual CPU version 2.5+ (32 & 64 bit variants)
+
+``qemu64`` is used for x86_64 guests and ``qemu32`` is used for i686
+guests, when no ``-cpu`` argument is given to QEMU, or no ``<cpu>`` is
+provided in libvirt XML.
+
+Other non-recommended x86 CPUs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following CPUs models are compatible with most AMD and Intel x86
+hosts, but their usage is discouraged, as they expose a very limited
+featureset, which prevents guests having optimal performance.
+
+``kvm32``, ``kvm64``
+    Common KVM processor (32 & 64 bit variants).
+
+    Legacy models just for historical compatibility with ancient QEMU
+    versions.
+
+``486``, ``athlon``, ``phenom``, ``coreduo``, ``core2duo``, ``n270``, ``pentium``, ``pentium2``, ``pentium3``
+    Various very old x86 CPU models, mostly predating the introduction
+    of hardware assisted virtualization, that should thus not be
+    required for running virtual machines.
+
+
+Syntax for configuring CPU models
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The examples below illustrate the approach to configuring the various
+CPU models / features in QEMU and libvirt.
+
+QEMU command line
+^^^^^^^^^^^^^^^^^
+
+Host passthrough:
+
+.. parsed-literal::
+
+  |qemu_system| -cpu host
+
+Host passthrough with feature customization:
+
+.. parsed-literal::
+
+  |qemu_system| -cpu host,-vmx,...
+
+Named CPU models:
+
+.. parsed-literal::
+
+  |qemu_system| -cpu Westmere
+
+Named CPU models with feature customization:
+
+.. parsed-literal::
+
+  |qemu_system| -cpu Westmere,+pcid,...
+
+Libvirt guest XML
+^^^^^^^^^^^^^^^^^
+
+Host passthrough::
+
+    <cpu mode='host-passthrough'/>
+
+Host passthrough with feature customization::
+
+    <cpu mode='host-passthrough'>
+        <feature name="vmx" policy="disable"/>
+        ...
+    </cpu>
+
+Host model::
+
+    <cpu mode='host-model'/>
+
+Host model with feature customization::
+
+    <cpu mode='host-model'>
+        <feature name="vmx" policy="disable"/>
+        ...
+    </cpu>
+
+Named model::
+
+    <cpu mode='custom'>
+        <model name="Westmere"/>
+    </cpu>
+
+Named model with feature customization::
+
+    <cpu mode='custom'>
+        <model name="Westmere"/>
+        <feature name="pcid" policy="require"/>
+        ...
+    </cpu>
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
new file mode 100644 (file)
index 0000000..0838338
--- /dev/null
@@ -0,0 +1,454 @@
+Deprecated features
+===================
+
+In general features are intended to be supported indefinitely once
+introduced into QEMU. In the event that a feature needs to be removed,
+it will be listed in this section. The feature will remain functional
+for 2 releases prior to actual removal. Deprecated features may also
+generate warnings on the console when QEMU starts up, or if activated
+via a monitor command, however, this is not a mandatory requirement.
+
+Prior to the 2.10.0 release there was no official policy on how
+long features would be deprecated prior to their removal, nor
+any documented list of which features were deprecated. Thus
+any features deprecated prior to 2.10.0 will be treated as if
+they were first deprecated in the 2.10.0 release.
+
+What follows is a list of all features currently marked as
+deprecated.
+
+System emulator command line arguments
+--------------------------------------
+
+``-machine enforce-config-section=on|off`` (since 3.1)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``enforce-config-section`` parameter is replaced by the
+``-global migration.send-configuration={on|off}`` option.
+
+``-no-kvm`` (since 1.3.0)
+'''''''''''''''''''''''''
+
+The ``-no-kvm`` argument is now a synonym for setting ``-accel tcg``.
+
+``-usbdevice`` (since 2.10.0)
+'''''''''''''''''''''''''''''
+
+The ``-usbdevice DEV`` argument is now a synonym for setting
+the ``-device usb-DEV`` argument instead. The deprecated syntax
+would automatically enable USB support on the machine type.
+If using the new syntax, USB support must be explicitly
+enabled via the ``-machine usb=on`` argument.
+
+``-drive file=json:{...{'driver':'file'}}`` (since 3.0)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The 'file' driver for drives is no longer appropriate for character or host
+devices and will only accept regular files (S_IFREG). The correct driver
+for these file types is 'host_cdrom' or 'host_device' as appropriate.
+
+``-net ...,name=``\ *name* (since 3.1)
+''''''''''''''''''''''''''''''''''''''
+
+The ``name`` parameter of the ``-net`` option is a synonym
+for the ``id`` parameter, which should now be used instead.
+
+``-smp`` (invalid topologies) (since 3.1)
+'''''''''''''''''''''''''''''''''''''''''
+
+CPU topology properties should describe whole machine topology including
+possible CPUs.
+
+However, historically it was possible to start QEMU with an incorrect topology
+where *n* <= *sockets* * *cores* * *threads* < *maxcpus*,
+which could lead to an incorrect topology enumeration by the guest.
+Support for invalid topologies will be removed, the user must ensure
+topologies described with -smp include all possible cpus, i.e.
+*sockets* * *cores* * *threads* = *maxcpus*.
+
+``-vnc acl`` (since 4.0.0)
+''''''''''''''''''''''''''
+
+The ``acl`` option to the ``-vnc`` argument has been replaced
+by the ``tls-authz`` and ``sasl-authz`` options.
+
+``QEMU_AUDIO_`` environment variables and ``-audio-help`` (since 4.0)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``-audiodev`` argument is now the preferred way to specify audio
+backend settings instead of environment variables.  To ease migration to
+the new format, the ``-audiodev-help`` option can be used to convert
+the current values of the environment variables to ``-audiodev`` options.
+
+Creating sound card devices and vnc without ``audiodev=`` property (since 4.2)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+When not using the deprecated legacy audio config, each sound card
+should specify an ``audiodev=`` property.  Additionally, when using
+vnc, you should specify an ``audiodev=`` propery if you plan to
+transmit audio through the VNC protocol.
+
+``-mon ...,control=readline,pretty=on|off`` (since 4.1)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``pretty=on|off`` switch has no effect for HMP monitors, but is
+silently ignored. Using the switch with HMP monitors will become an
+error in the future.
+
+``-realtime`` (since 4.1)
+'''''''''''''''''''''''''
+
+The ``-realtime mlock=on|off`` argument has been replaced by the
+``-overcommit mem-lock=on|off`` argument.
+
+``-numa node,mem=``\ *size* (since 4.1)
+'''''''''''''''''''''''''''''''''''''''
+
+The parameter ``mem`` of ``-numa node`` is used to assign a part of
+guest RAM to a NUMA node. But when using it, it's impossible to manage specified
+RAM chunk on the host side (like bind it to a host node, setting bind policy, ...),
+so guest end-ups with the fake NUMA configuration with suboptiomal performance.
+However since 2014 there is an alternative way to assign RAM to a NUMA node
+using parameter ``memdev``, which does the same as ``mem`` and adds
+means to actualy manage node RAM on the host side. Use parameter ``memdev``
+with *memory-backend-ram* backend as an replacement for parameter ``mem``
+to achieve the same fake NUMA effect or a properly configured
+*memory-backend-file* backend to actually benefit from NUMA configuration.
+In future new machine versions will not accept the option but it will still
+work with old machine types. User can check QAPI schema to see if the legacy
+option is supported by looking at MachineInfo::numa-mem-supported property.
+
+``-numa`` node (without memory specified) (since 4.1)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Splitting RAM by default between NUMA nodes has the same issues as ``mem``
+parameter described above with the difference that the role of the user plays
+QEMU using implicit generic or board specific splitting rule.
+Use ``memdev`` with *memory-backend-ram* backend or ``mem`` (if
+it's supported by used machine type) to define mapping explictly instead.
+
+``-mem-path`` fallback to RAM (since 4.1)
+'''''''''''''''''''''''''''''''''''''''''
+
+Currently if guest RAM allocation from file pointed by ``mem-path``
+fails, QEMU falls back to allocating from RAM, which might result
+in unpredictable behavior since the backing file specified by the user
+is ignored. In the future, users will be responsible for making sure
+the backing storage specified with ``-mem-path`` can actually provide
+the guest RAM configured with ``-m`` and QEMU will fail to start up if
+RAM allocation is unsuccessful.
+
+RISC-V ``-bios`` (since 4.1)
+''''''''''''''''''''''''''''
+
+QEMU 4.1 introduced support for the -bios option in QEMU for RISC-V for the
+RISC-V virt machine and sifive_u machine.
+
+QEMU 4.1 has no changes to the default behaviour to avoid breakages. This
+default will change in a future QEMU release, so please prepare now. All users
+of the virt or sifive_u machine must change their command line usage.
+
+QEMU 4.1 has three options, please migrate to one of these three:
+ 1. ``-bios none`` - This is the current default behavior if no -bios option
+      is included. QEMU will not automatically load any firmware. It is up
+      to the user to load all the images they need.
+ 2. ``-bios default`` - In a future QEMU release this will become the default
+      behaviour if no -bios option is specified. This option will load the
+      default OpenSBI firmware automatically. The firmware is included with
+      the QEMU release and no user interaction is required. All a user needs
+      to do is specify the kernel they want to boot with the -kernel option
+ 3. ``-bios <file>`` - Tells QEMU to load the specified file as the firmwrae.
+
+``-tb-size`` option (since 5.0)
+'''''''''''''''''''''''''''''''
+
+QEMU 5.0 introduced an alternative syntax to specify the size of the translation
+block cache, ``-accel tcg,tb-size=``.  The new syntax deprecates the
+previously available ``-tb-size`` option.
+
+``-show-cursor`` option (since 5.0)
+'''''''''''''''''''''''''''''''''''
+
+Use ``-display sdl,show-cursor=on`` or
+ ``-display gtk,show-cursor=on`` instead.
+
+QEMU Machine Protocol (QMP) commands
+------------------------------------
+
+``change`` (since 2.5.0)
+''''''''''''''''''''''''
+
+Use ``blockdev-change-medium`` or ``change-vnc-password`` instead.
+
+``migrate_set_downtime`` and ``migrate_set_speed`` (since 2.8.0)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Use ``migrate-set-parameters`` instead.
+
+``migrate-set-cache-size`` and ``query-migrate-cache-size`` (since 2.11.0)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Use ``migrate-set-parameters`` and ``query-migrate-parameters`` instead.
+
+``object-add`` option ``props`` (since 5.0)
+'''''''''''''''''''''''''''''''''''''''''''
+
+Specify the properties for the object as top-level arguments instead.
+
+``query-block`` result field ``dirty-bitmaps[i].status`` (since 4.0)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``status`` field of the ``BlockDirtyInfo`` structure, returned by
+the query-block command is deprecated. Two new boolean fields,
+``recording`` and ``busy`` effectively replace it.
+
+``query-block`` result field ``dirty-bitmaps`` (Since 4.2)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``dirty-bitmaps`` field of the ``BlockInfo`` structure, returned by
+the query-block command is itself now deprecated. The ``dirty-bitmaps``
+field of the ``BlockDeviceInfo`` struct should be used instead, which is the
+type of the ``inserted`` field in query-block replies, as well as the
+type of array items in query-named-block-nodes.
+
+Since the ``dirty-bitmaps`` field is optionally present in both the old and
+new locations, clients must use introspection to learn where to anticipate
+the field if/when it does appear in command output.
+
+``query-cpus`` (since 2.12.0)
+'''''''''''''''''''''''''''''
+
+The ``query-cpus`` command is replaced by the ``query-cpus-fast`` command.
+
+``query-cpus-fast`` ``arch`` output member (since 3.0.0)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``arch`` output member of the ``query-cpus-fast`` command is
+replaced by the ``target`` output member.
+
+``cpu-add`` (since 4.0)
+'''''''''''''''''''''''
+
+Use ``device_add`` for hotplugging vCPUs instead of ``cpu-add``.  See
+documentation of ``query-hotpluggable-cpus`` for additional
+details.
+
+``query-events`` (since 4.0)
+''''''''''''''''''''''''''''
+
+The ``query-events`` command has been superseded by the more powerful
+and accurate ``query-qmp-schema`` command.
+
+chardev client socket with ``wait`` option (since 4.0)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Character devices creating sockets in client mode should not specify
+the 'wait' field, which is only applicable to sockets in server mode
+
+Human Monitor Protocol (HMP) commands
+-------------------------------------
+
+``cpu-add`` (since 4.0)
+'''''''''''''''''''''''
+
+Use ``device_add`` for hotplugging vCPUs instead of ``cpu-add``.  See
+documentation of ``query-hotpluggable-cpus`` for additional details.
+
+``acl_show``, ``acl_reset``, ``acl_policy``, ``acl_add``, ``acl_remove`` (since 4.0.0)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``acl_show``, ``acl_reset``, ``acl_policy``, ``acl_add``, and
+``acl_remove`` commands are deprecated with no replacement. Authorization
+for VNC should be performed using the pluggable QAuthZ objects.
+
+Guest Emulator ISAs
+-------------------
+
+RISC-V ISA privledge specification version 1.09.1 (since 4.1)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The RISC-V ISA privledge specification version 1.09.1 has been deprecated.
+QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
+should be used instead of the 1.09.1 version.
+
+System emulator CPUS
+--------------------
+
+RISC-V ISA CPUs (since 4.1)
+'''''''''''''''''''''''''''
+
+The RISC-V cpus with the ISA version in the CPU name have been depcreated. The
+four CPUs are: ``rv32gcsu-v1.9.1``, ``rv32gcsu-v1.10.0``, ``rv64gcsu-v1.9.1`` and
+``rv64gcsu-v1.10.0``. Instead the version can be specified via the CPU ``priv_spec``
+option when using the ``rv32`` or ``rv64`` CPUs.
+
+RISC-V ISA CPUs (since 4.1)
+'''''''''''''''''''''''''''
+
+The RISC-V no MMU cpus have been depcreated. The two CPUs: ``rv32imacu-nommu`` and
+``rv64imacu-nommu`` should no longer be used. Instead the MMU status can be specified
+via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
+
+System emulator devices
+-----------------------
+
+``ide-drive`` (since 4.2)
+'''''''''''''''''''''''''
+
+The 'ide-drive' device is deprecated. Users should use 'ide-hd' or
+'ide-cd' as appropriate to get an IDE hard disk or CD-ROM as needed.
+
+``scsi-disk`` (since 4.2)
+'''''''''''''''''''''''''
+
+The 'scsi-disk' device is deprecated. Users should use 'scsi-hd' or
+'scsi-cd' as appropriate to get a SCSI hard disk or CD-ROM as needed.
+
+System emulator machines
+------------------------
+
+mips ``r4k`` platform (since 5.0)
+'''''''''''''''''''''''''''''''''
+
+This machine type is very old and unmaintained. Users should use the ``malta``
+machine type instead.
+
+``pc-1.0``, ``pc-1.1``, ``pc-1.2`` and ``pc-1.3`` (since 5.0)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+These machine types are very old and likely can not be used for live migration
+from old QEMU versions anymore. A newer machine type should be used instead.
+
+``spike_v1.9.1`` and ``spike_v1.10`` (since 4.1)
+''''''''''''''''''''''''''''''''''''''''''''''''
+
+The version specific Spike machines have been deprecated in favour of the
+generic ``spike`` machine. If you need to specify an older version of the RISC-V
+spec you can use the ``-cpu rv64gcsu,priv_spec=v1.9.1`` command line argument.
+
+Device options
+--------------
+
+Emulated device options
+'''''''''''''''''''''''
+
+``-device virtio-blk,scsi=on|off`` (since 5.0.0)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The virtio-blk SCSI passthrough feature is a legacy VIRTIO feature.  VIRTIO 1.0
+and later do not support it because the virtio-scsi device was introduced for
+full SCSI support.  Use virtio-scsi instead when SCSI passthrough is required.
+
+Note this also applies to ``-device virtio-blk-pci,scsi=on|off``, which is an
+alias.
+
+Block device options
+''''''''''''''''''''
+
+``"backing": ""`` (since 2.12.0)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In order to prevent QEMU from automatically opening an image's backing
+chain, use ``"backing": null`` instead.
+
+``rbd`` keyvalue pair encoded filenames: ``""`` (since 3.1.0)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Options for ``rbd`` should be specified according to its runtime options,
+like other block drivers.  Legacy parsing of keyvalue pair encoded
+filenames is useful to open images with the old format for backing files;
+These image files should be updated to use the current format.
+
+Example of legacy encoding::
+
+  json:{"file.driver":"rbd", "file.filename":"rbd:rbd/name"}
+
+The above, converted to the current supported format::
+
+  json:{"file.driver":"rbd", "file.pool":"rbd", "file.image":"name"}
+
+Related binaries
+----------------
+
+``qemu-img convert -n -o`` (since 4.2.0)
+''''''''''''''''''''''''''''''''''''''''
+
+All options specified in ``-o`` are image creation options, so
+they have no effect when used with ``-n`` to skip image creation.
+Silently ignored options can be confusing, so this combination of
+options will be made an error in future versions.
+
+Backwards compatibility
+-----------------------
+
+Runnability guarantee of CPU models (since 4.1.0)
+'''''''''''''''''''''''''''''''''''''''''''''''''
+
+Previous versions of QEMU never changed existing CPU models in
+ways that introduced additional host software or hardware
+requirements to the VM.  This allowed management software to
+safely change the machine type of an existing VM without
+introducing new requirements ("runnability guarantee").  This
+prevented CPU models from being updated to include CPU
+vulnerability mitigations, leaving guests vulnerable in the
+default configuration.
+
+The CPU model runnability guarantee won't apply anymore to
+existing CPU models.  Management software that needs runnability
+guarantees must resolve the CPU model aliases using te
+``alias-of`` field returned by the ``query-cpu-definitions`` QMP
+command.
+
+While those guarantees are kept, the return value of
+``query-cpu-definitions`` will have existing CPU model aliases
+point to a version that doesn't break runnability guarantees
+(specifically, version 1 of those CPU models).  In future QEMU
+versions, aliases will point to newer CPU model versions
+depending on the machine type, so management software must
+resolve CPU model aliases before starting a virtual machine.
+
+
+Recently removed features
+=========================
+
+What follows is a record of recently removed, formerly deprecated
+features that serves as a record for users who have encountered
+trouble after a recent upgrade.
+
+QEMU Machine Protocol (QMP) commands
+------------------------------------
+
+``block-dirty-bitmap-add`` "autoload" parameter (since 4.2.0)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The "autoload" parameter has been ignored since 2.12.0. All bitmaps
+are automatically loaded from qcow2 images.
+
+Human Monitor Protocol (HMP) commands
+-------------------------------------
+
+The ``hub_id`` parameter of ``hostfwd_add`` / ``hostfwd_remove`` (removed in 5.0)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and
+'hostfwd_remove' HMP commands has been replaced by ``netdev_id``.
+
+Related binaries
+----------------
+
+``qemu-nbd --partition`` (removed in 5.0.0)
+'''''''''''''''''''''''''''''''''''''''''''
+
+The ``qemu-nbd --partition $digit`` code (also spelled ``-P``)
+could only handle MBR partitions, and never correctly handled logical
+partitions beyond partition 5.  Exporting a partition can still be
+done by utilizing the ``--image-opts`` option with a raw blockdev
+using the ``offset`` and ``size`` parameters layered on top of
+any other existing blockdev. For example, if partition 1 is 100MiB
+long starting at 1MiB, the old command::
+
+  qemu-nbd -t -P 1 -f qcow2 file.qcow2
+
+can be rewritten as::
+
+  qemu-nbd -t --image-opts driver=raw,offset=1M,size=100M,file.driver=qcow2,file.file.driver=file,file.file.filename=file.qcow2
diff --git a/docs/system/device-url-syntax.rst.inc b/docs/system/device-url-syntax.rst.inc
new file mode 100644 (file)
index 0000000..88d7a37
--- /dev/null
@@ -0,0 +1,228 @@
+
+In addition to using normal file images for the emulated storage
+devices, QEMU can also use networked resources such as iSCSI devices.
+These are specified using a special URL syntax.
+
+``iSCSI``
+   iSCSI support allows QEMU to access iSCSI resources directly and use
+   as images for the guest storage. Both disk and cdrom images are
+   supported.
+
+   Syntax for specifying iSCSI LUNs is
+   "iscsi://<target-ip>[:<port>]/<target-iqn>/<lun>"
+
+   By default qemu will use the iSCSI initiator-name
+   'iqn.2008-11.org.linux-kvm[:<name>]' but this can also be set from
+   the command line or a configuration file.
+
+   Since version Qemu 2.4 it is possible to specify a iSCSI request
+   timeout to detect stalled requests and force a reestablishment of the
+   session. The timeout is specified in seconds. The default is 0 which
+   means no timeout. Libiscsi 1.15.0 or greater is required for this
+   feature.
+
+   Example (without authentication):
+
+   .. parsed-literal::
+
+      |qemu_system| -iscsi initiator-name=iqn.2001-04.com.example:my-initiator \
+                       -cdrom iscsi://192.0.2.1/iqn.2001-04.com.example/2 \
+                       -drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1
+
+   Example (CHAP username/password via URL):
+
+   .. parsed-literal::
+
+      |qemu_system| -drive file=iscsi://user%password@192.0.2.1/iqn.2001-04.com.example/1
+
+   Example (CHAP username/password via environment variables):
+
+   .. parsed-literal::
+
+      LIBISCSI_CHAP_USERNAME="user" \
+      LIBISCSI_CHAP_PASSWORD="password" \
+      |qemu_system| -drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1
+
+``NBD``
+   QEMU supports NBD (Network Block Devices) both using TCP protocol as
+   well as Unix Domain Sockets. With TCP, the default port is 10809.
+
+   Syntax for specifying a NBD device using TCP, in preferred URI form:
+   "nbd://<server-ip>[:<port>]/[<export>]"
+
+   Syntax for specifying a NBD device using Unix Domain Sockets;
+   remember that '?' is a shell glob character and may need quoting:
+   "nbd+unix:///[<export>]?socket=<domain-socket>"
+
+   Older syntax that is also recognized:
+   "nbd:<server-ip>:<port>[:exportname=<export>]"
+
+   Syntax for specifying a NBD device using Unix Domain Sockets
+   "nbd:unix:<domain-socket>[:exportname=<export>]"
+
+   Example for TCP
+
+   .. parsed-literal::
+
+      |qemu_system| --drive file=nbd:192.0.2.1:30000
+
+   Example for Unix Domain Sockets
+
+   .. parsed-literal::
+
+      |qemu_system| --drive file=nbd:unix:/tmp/nbd-socket
+
+``SSH``
+   QEMU supports SSH (Secure Shell) access to remote disks.
+
+   Examples:
+
+   .. parsed-literal::
+
+      |qemu_system| -drive file=ssh://user@host/path/to/disk.img
+      |qemu_system| -drive file.driver=ssh,file.user=user,file.host=host,file.port=22,file.path=/path/to/disk.img
+
+   Currently authentication must be done using ssh-agent. Other
+   authentication methods may be supported in future.
+
+``Sheepdog``
+   Sheepdog is a distributed storage system for QEMU. QEMU supports
+   using either local sheepdog devices or remote networked devices.
+
+   Syntax for specifying a sheepdog device
+
+   ::
+
+      sheepdog[+tcp|+unix]://[host:port]/vdiname[?socket=path][#snapid|#tag]
+
+   Example
+
+   .. parsed-literal::
+
+      |qemu_system| --drive file=sheepdog://192.0.2.1:30000/MyVirtualMachine
+
+   See also https://sheepdog.github.io/sheepdog/.
+
+``GlusterFS``
+   GlusterFS is a user space distributed file system. QEMU supports the
+   use of GlusterFS volumes for hosting VM disk images using TCP, Unix
+   Domain Sockets and RDMA transport protocols.
+
+   Syntax for specifying a VM disk image on GlusterFS volume is
+
+   .. parsed-literal::
+
+      URI:
+      gluster[+type]://[host[:port]]/volume/path[?socket=...][,debug=N][,logfile=...]
+
+      JSON:
+      'json:{"driver":"qcow2","file":{"driver":"gluster","volume":"testvol","path":"a.img","debug":N,"logfile":"...",
+                                       "server":[{"type":"tcp","host":"...","port":"..."},
+                                                 {"type":"unix","socket":"..."}]}}'
+
+   Example
+
+   .. parsed-literal::
+
+      URI:
+      |qemu_system| --drive file=gluster://192.0.2.1/testvol/a.img,
+                                     file.debug=9,file.logfile=/var/log/qemu-gluster.log
+
+      JSON:
+      |qemu_system| 'json:{"driver":"qcow2",
+                                "file":{"driver":"gluster",
+                                         "volume":"testvol","path":"a.img",
+                                         "debug":9,"logfile":"/var/log/qemu-gluster.log",
+                                         "server":[{"type":"tcp","host":"1.2.3.4","port":24007},
+                                                   {"type":"unix","socket":"/var/run/glusterd.socket"}]}}'
+      |qemu_system| -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
+                                            file.debug=9,file.logfile=/var/log/qemu-gluster.log,
+                                            file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
+                                            file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
+
+   See also http://www.gluster.org.
+
+``HTTP/HTTPS/FTP/FTPS``
+   QEMU supports read-only access to files accessed over http(s) and
+   ftp(s).
+
+   Syntax using a single filename:
+
+   ::
+
+      <protocol>://[<username>[:<password>]@]<host>/<path>
+
+   where:
+
+   ``protocol``
+      'http', 'https', 'ftp', or 'ftps'.
+
+   ``username``
+      Optional username for authentication to the remote server.
+
+   ``password``
+      Optional password for authentication to the remote server.
+
+   ``host``
+      Address of the remote server.
+
+   ``path``
+      Path on the remote server, including any query string.
+
+   The following options are also supported:
+
+   ``url``
+      The full URL when passing options to the driver explicitly.
+
+   ``readahead``
+      The amount of data to read ahead with each range request to the
+      remote server. This value may optionally have the suffix 'T', 'G',
+      'M', 'K', 'k' or 'b'. If it does not have a suffix, it will be
+      assumed to be in bytes. The value must be a multiple of 512 bytes.
+      It defaults to 256k.
+
+   ``sslverify``
+      Whether to verify the remote server's certificate when connecting
+      over SSL. It can have the value 'on' or 'off'. It defaults to
+      'on'.
+
+   ``cookie``
+      Send this cookie (it can also be a list of cookies separated by
+      ';') with each outgoing request. Only supported when using
+      protocols such as HTTP which support cookies, otherwise ignored.
+
+   ``timeout``
+      Set the timeout in seconds of the CURL connection. This timeout is
+      the time that CURL waits for a response from the remote server to
+      get the size of the image to be downloaded. If not set, the
+      default timeout of 5 seconds is used.
+
+   Note that when passing options to qemu explicitly, ``driver`` is the
+   value of <protocol>.
+
+   Example: boot from a remote Fedora 20 live ISO image
+
+   .. parsed-literal::
+
+      |qemu_system_x86| --drive media=cdrom,file=https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
+
+      |qemu_system_x86| --drive media=cdrom,file.driver=http,file.url=http://archives.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
+
+   Example: boot from a remote Fedora 20 cloud image using a local
+   overlay for writes, copy-on-read, and a readahead of 64k
+
+   .. parsed-literal::
+
+      qemu-img create -f qcow2 -o backing_file='json:{"file.driver":"http",, "file.url":"http://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Images/x86_64/Fedora-x86_64-20-20131211.1-sda.qcow2",, "file.readahead":"64k"}' /tmp/Fedora-x86_64-20-20131211.1-sda.qcow2
+
+      |qemu_system_x86| -drive file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-on-read=on
+
+   Example: boot from an image stored on a VMware vSphere server with a
+   self-signed certificate using a local overlay for writes, a readahead
+   of 64k and a timeout of 10 seconds.
+
+   .. parsed-literal::
+
+      qemu-img create -f qcow2 -o backing_file='json:{"file.driver":"https",, "file.url":"https://user:password@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=Datacenter&dsName=datastore1",, "file.sslverify":"off",, "file.readahead":"64k",, "file.timeout":10}' /tmp/test.qcow2
+
+      |qemu_system_x86| -drive file=/tmp/test.qcow2
diff --git a/docs/system/gdb.rst b/docs/system/gdb.rst
new file mode 100644 (file)
index 0000000..639f814
--- /dev/null
@@ -0,0 +1,81 @@
+.. _gdb_005fusage:
+
+GDB usage
+---------
+
+QEMU has a primitive support to work with gdb, so that you can do
+'Ctrl-C' while the virtual machine is running and inspect its state.
+
+In order to use gdb, launch QEMU with the '-s' option. It will wait for
+a gdb connection:
+
+.. parsed-literal::
+
+   |qemu_system| -s -kernel bzImage -hda rootdisk.img -append "root=/dev/hda"
+   Connected to host network interface: tun0
+   Waiting gdb connection on port 1234
+
+Then launch gdb on the 'vmlinux' executable::
+
+   > gdb vmlinux
+
+In gdb, connect to QEMU::
+
+   (gdb) target remote localhost:1234
+
+Then you can use gdb normally. For example, type 'c' to launch the
+kernel::
+
+   (gdb) c
+
+Here are some useful tips in order to use gdb on system code:
+
+1. Use ``info reg`` to display all the CPU registers.
+
+2. Use ``x/10i $eip`` to display the code at the PC position.
+
+3. Use ``set architecture i8086`` to dump 16 bit code. Then use
+   ``x/10i $cs*16+$eip`` to dump the code at the PC position.
+
+Advanced debugging options:
+
+The default single stepping behavior is step with the IRQs and timer
+service routines off. It is set this way because when gdb executes a
+single step it expects to advance beyond the current instruction. With
+the IRQs and timer service routines on, a single step might jump into
+the one of the interrupt or exception vectors instead of executing the
+current instruction. This means you may hit the same breakpoint a number
+of times before executing the instruction gdb wants to have executed.
+Because there are rare circumstances where you want to single step into
+an interrupt vector the behavior can be controlled from GDB. There are
+three commands you can query and set the single step behavior:
+
+``maintenance packet qqemu.sstepbits``
+   This will display the MASK bits used to control the single stepping
+   IE:
+
+   ::
+
+      (gdb) maintenance packet qqemu.sstepbits
+      sending: "qqemu.sstepbits"
+      received: "ENABLE=1,NOIRQ=2,NOTIMER=4"
+
+``maintenance packet qqemu.sstep``
+   This will display the current value of the mask used when single
+   stepping IE:
+
+   ::
+
+      (gdb) maintenance packet qqemu.sstep
+      sending: "qqemu.sstep"
+      received: "0x7"
+
+``maintenance packet Qqemu.sstep=HEX_VALUE``
+   This will change the single step mask, so if wanted to enable IRQs on
+   the single step, but not timers, you would use:
+
+   ::
+
+      (gdb) maintenance packet Qqemu.sstep=0x5
+      sending: "qemu.sstep=0x5"
+      received: "OK"
diff --git a/docs/system/images.rst b/docs/system/images.rst
new file mode 100644 (file)
index 0000000..ff26bf9
--- /dev/null
@@ -0,0 +1,85 @@
+.. _disk_005fimages:
+
+Disk Images
+-----------
+
+QEMU supports many disk image formats, including growable disk images
+(their size increase as non empty sectors are written), compressed and
+encrypted disk images.
+
+.. _disk_005fimages_005fquickstart:
+
+Quick start for disk image creation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can create a disk image with the command::
+
+   qemu-img create myimage.img mysize
+
+where myimage.img is the disk image filename and mysize is its size in
+kilobytes. You can add an ``M`` suffix to give the size in megabytes and
+a ``G`` suffix for gigabytes.
+
+See the qemu-img invocation documentation for more information.
+
+.. _disk_005fimages_005fsnapshot_005fmode:
+
+Snapshot mode
+~~~~~~~~~~~~~
+
+If you use the option ``-snapshot``, all disk images are considered as
+read only. When sectors in written, they are written in a temporary file
+created in ``/tmp``. You can however force the write back to the raw
+disk images by using the ``commit`` monitor command (or C-a s in the
+serial console).
+
+.. _vm_005fsnapshots:
+
+VM snapshots
+~~~~~~~~~~~~
+
+VM snapshots are snapshots of the complete virtual machine including CPU
+state, RAM, device state and the content of all the writable disks. In
+order to use VM snapshots, you must have at least one non removable and
+writable block device using the ``qcow2`` disk image format. Normally
+this device is the first virtual hard drive.
+
+Use the monitor command ``savevm`` to create a new VM snapshot or
+replace an existing one. A human readable name can be assigned to each
+snapshot in addition to its numerical ID.
+
+Use ``loadvm`` to restore a VM snapshot and ``delvm`` to remove a VM
+snapshot. ``info snapshots`` lists the available snapshots with their
+associated information::
+
+   (qemu) info snapshots
+   Snapshot devices: hda
+   Snapshot list (from hda):
+   ID        TAG                 VM SIZE                DATE       VM CLOCK
+   1         start                   41M 2006-08-06 12:38:02   00:00:14.954
+   2                                 40M 2006-08-06 12:43:29   00:00:18.633
+   3         msys                    40M 2006-08-06 12:44:04   00:00:23.514
+
+A VM snapshot is made of a VM state info (its size is shown in
+``info snapshots``) and a snapshot of every writable disk image. The VM
+state info is stored in the first ``qcow2`` non removable and writable
+block device. The disk image snapshots are stored in every disk image.
+The size of a snapshot in a disk image is difficult to evaluate and is
+not shown by ``info snapshots`` because the associated disk sectors are
+shared among all the snapshots to save disk space (otherwise each
+snapshot would need a full copy of all the disk images).
+
+When using the (unrelated) ``-snapshot`` option
+(:ref:`disk_005fimages_005fsnapshot_005fmode`),
+you can always make VM snapshots, but they are deleted as soon as you
+exit QEMU.
+
+VM snapshots currently have the following known limitations:
+
+-  They cannot cope with removable devices if they are removed or
+   inserted after a snapshot is done.
+
+-  A few device drivers still have incomplete snapshot support so their
+   state is not saved or restored properly (in particular USB).
+
+.. include:: qemu-block-drivers.rst.inc
index 1a4b2c82acef661fd22417e285eb471f66af305c..6e5f20fa1333ce238e7de8322987d288cb4288f8 100644 (file)
@@ -12,7 +12,25 @@ or Hypervisor.Framework.
 Contents:
 
 .. toctree::
-   :maxdepth: 2
+   :maxdepth: 3
 
-   qemu-block-drivers
+   quickstart
+   invocation
+   keys
+   mux-chardev
+   monitor
+   images
+   net
+   usb
+   ivshmem
+   linuxboot
+   vnc-security
+   tls
+   gdb
+   managed-startup
+   targets
+   security
    vfio-ap
+   deprecated
+   build-platforms
+   license
diff --git a/docs/system/invocation.rst b/docs/system/invocation.rst
new file mode 100644 (file)
index 0000000..4ba38fc
--- /dev/null
@@ -0,0 +1,18 @@
+.. _sec_005finvocation:
+
+Invocation
+----------
+
+.. parsed-literal::
+
+   |qemu_system| [options] [disk_image]
+
+disk_image is a raw hard disk image for IDE hard disk 0. Some targets do
+not need a disk image.
+
+.. hxtool-doc:: qemu-options.hx
+
+Device URL Syntax
+~~~~~~~~~~~~~~~~~
+
+.. include:: device-url-syntax.rst.inc
diff --git a/docs/system/ivshmem.rst b/docs/system/ivshmem.rst
new file mode 100644 (file)
index 0000000..b03a48a
--- /dev/null
@@ -0,0 +1,64 @@
+.. _pcsys_005fivshmem:
+
+Inter-VM Shared Memory device
+-----------------------------
+
+On Linux hosts, a shared memory device is available. The basic syntax
+is:
+
+.. parsed-literal::
+
+   |qemu_system_x86| -device ivshmem-plain,memdev=hostmem
+
+where hostmem names a host memory backend. For a POSIX shared memory
+backend, use something like
+
+::
+
+   -object memory-backend-file,size=1M,share,mem-path=/dev/shm/ivshmem,id=hostmem
+
+If desired, interrupts can be sent between guest VMs accessing the same
+shared memory region. Interrupt support requires using a shared memory
+server and using a chardev socket to connect to it. The code for the
+shared memory server is qemu.git/contrib/ivshmem-server. An example
+syntax when using the shared memory server is:
+
+.. parsed-literal::
+
+   # First start the ivshmem server once and for all
+   ivshmem-server -p pidfile -S path -m shm-name -l shm-size -n vectors
+
+   # Then start your qemu instances with matching arguments
+   |qemu_system_x86| -device ivshmem-doorbell,vectors=vectors,chardev=id
+                    -chardev socket,path=path,id=id
+
+When using the server, the guest will be assigned a VM ID (>=0) that
+allows guests using the same server to communicate via interrupts.
+Guests can read their VM ID from a device register (see
+ivshmem-spec.txt).
+
+Migration with ivshmem
+~~~~~~~~~~~~~~~~~~~~~~
+
+With device property ``master=on``, the guest will copy the shared
+memory on migration to the destination host. With ``master=off``, the
+guest will not be able to migrate with the device attached. In the
+latter case, the device should be detached and then reattached after
+migration using the PCI hotplug support.
+
+At most one of the devices sharing the same memory can be master. The
+master must complete migration before you plug back the other devices.
+
+ivshmem and hugepages
+~~~~~~~~~~~~~~~~~~~~~
+
+Instead of specifying the <shm size> using POSIX shm, you may specify a
+memory backend that has hugepage support:
+
+.. parsed-literal::
+
+   |qemu_system_x86| -object memory-backend-file,size=1G,mem-path=/dev/hugepages/my-shmem-file,share,id=mb1
+                    -device ivshmem-plain,memdev=mb1
+
+ivshmem-server also supports hugepages mount points with the ``-m``
+memory path argument.
diff --git a/docs/system/keys.rst b/docs/system/keys.rst
new file mode 100644 (file)
index 0000000..e596ae6
--- /dev/null
@@ -0,0 +1,6 @@
+.. _pcsys_005fkeys:
+
+Keys in the graphical frontends
+-------------------------------
+
+.. include:: keys.rst.inc
diff --git a/docs/system/keys.rst.inc b/docs/system/keys.rst.inc
new file mode 100644 (file)
index 0000000..bd9b8e5
--- /dev/null
@@ -0,0 +1,35 @@
+During the graphical emulation, you can use special key combinations to
+change modes. The default key mappings are shown below, but if you use
+``-alt-grab`` then the modifier is Ctrl-Alt-Shift (instead of Ctrl-Alt)
+and if you use ``-ctrl-grab`` then the modifier is the right Ctrl key
+(instead of Ctrl-Alt):
+
+Ctrl-Alt-f
+   Toggle full screen
+
+Ctrl-Alt-+
+   Enlarge the screen
+
+Ctrl-Alt\--
+   Shrink the screen
+
+Ctrl-Alt-u
+   Restore the screen's un-scaled dimensions
+
+Ctrl-Alt-n
+   Switch to virtual console 'n'. Standard console mappings are:
+
+   *1*
+      Target system display
+
+   *2*
+      Monitor
+
+   *3*
+      Serial port
+
+Ctrl-Alt
+   Toggle mouse and keyboard grab.
+
+In the virtual consoles, you can use Ctrl-Up, Ctrl-Down, Ctrl-PageUp and
+Ctrl-PageDown to move in the back log.
diff --git a/docs/system/license.rst b/docs/system/license.rst
new file mode 100644 (file)
index 0000000..cde3d2d
--- /dev/null
@@ -0,0 +1,11 @@
+.. _License:
+
+License
+=======
+
+QEMU is a trademark of Fabrice Bellard.
+
+QEMU is released under the `GNU General Public
+License <https://www.gnu.org/licenses/gpl-2.0.txt>`__, version 2. Parts
+of QEMU have specific licenses, see file
+`LICENSE <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=LICENSE>`__.
diff --git a/docs/system/linuxboot.rst b/docs/system/linuxboot.rst
new file mode 100644 (file)
index 0000000..228650a
--- /dev/null
@@ -0,0 +1,30 @@
+.. _direct_005flinux_005fboot:
+
+Direct Linux Boot
+-----------------
+
+This section explains how to launch a Linux kernel inside QEMU without
+having to make a full bootable image. It is very useful for fast Linux
+kernel testing.
+
+The syntax is:
+
+.. parsed-literal::
+
+   |qemu_system| -kernel bzImage -hda rootdisk.img -append "root=/dev/hda"
+
+Use ``-kernel`` to provide the Linux kernel image and ``-append`` to
+give the kernel command line arguments. The ``-initrd`` option can be
+used to provide an INITRD image.
+
+If you do not need graphical output, you can disable it and redirect the
+virtual serial port and the QEMU monitor to the console with the
+``-nographic`` option. The typical command line is:
+
+.. parsed-literal::
+
+   |qemu_system| -kernel bzImage -hda rootdisk.img \
+                    -append "root=/dev/hda console=ttyS0" -nographic
+
+Use Ctrl-a c to switch between the serial console and the monitor (see
+:ref:`pcsys_005fkeys`).
diff --git a/docs/system/managed-startup.rst b/docs/system/managed-startup.rst
new file mode 100644 (file)
index 0000000..9bcf98e
--- /dev/null
@@ -0,0 +1,35 @@
+Managed start up options
+========================
+
+In system mode emulation, it's possible to create a VM in a paused
+state using the ``-S`` command line option. In this state the machine
+is completely initialized according to command line options and ready
+to execute VM code but VCPU threads are not executing any code. The VM
+state in this paused state depends on the way QEMU was started. It
+could be in:
+
+- initial state (after reset/power on state)
+- with direct kernel loading, the initial state could be amended to execute
+  code loaded by QEMU in the VM's RAM and with incoming migration
+- with incoming migration, initial state will be amended with the migrated
+  machine state after migration completes
+
+This paused state is typically used by users to query machine state and/or
+additionally configure the machine (by hotplugging devices) in runtime before
+allowing VM code to run.
+
+However, at the ``-S`` pause point, it's impossible to configure options
+that affect initial VM creation (like: ``-smp``/``-m``/``-numa`` ...) or
+cold plug devices. The experimental ``--preconfig`` command line option
+allows pausing QEMU before the initial VM creation, in a "preconfig" state,
+where additional queries and configuration can be performed via QMP
+before moving on to the resulting configuration startup. In the
+preconfig state, QEMU only allows a limited set of commands over the
+QMP monitor, where the commands do not depend on an initialized
+machine, including but not limited to:
+
+- ``qmp_capabilities``
+- ``query-qmp-schema``
+- ``query-commands``
+- ``query-status``
+- ``x-exit-preconfig``
diff --git a/docs/system/monitor.rst b/docs/system/monitor.rst
new file mode 100644 (file)
index 0000000..0bcd5da
--- /dev/null
@@ -0,0 +1,31 @@
+.. _pcsys_005fmonitor:
+
+QEMU Monitor
+------------
+
+The QEMU monitor is used to give complex commands to the QEMU emulator.
+You can use it to:
+
+-  Remove or insert removable media images (such as CD-ROM or
+   floppies).
+
+-  Freeze/unfreeze the Virtual Machine (VM) and save or restore its
+   state from a disk file.
+
+-  Inspect the VM state without an external debugger.
+
+Commands
+~~~~~~~~
+
+The following commands are available:
+
+.. hxtool-doc:: hmp-commands.hx
+
+.. hxtool-doc:: hmp-commands-info.hx
+
+Integer expressions
+~~~~~~~~~~~~~~~~~~~
+
+The monitor understands integers expressions for every integer argument.
+You can use register names to get the value of specifics CPU registers
+by prefixing them with *$*.
diff --git a/docs/system/mux-chardev.rst b/docs/system/mux-chardev.rst
new file mode 100644 (file)
index 0000000..413a6b3
--- /dev/null
@@ -0,0 +1,6 @@
+.. _mux_005fkeys:
+
+Keys in the character backend multiplexer
+-----------------------------------------
+
+.. include:: mux-chardev.rst.inc
diff --git a/docs/system/mux-chardev.rst.inc b/docs/system/mux-chardev.rst.inc
new file mode 100644 (file)
index 0000000..84ea12c
--- /dev/null
@@ -0,0 +1,27 @@
+During emulation, if you are using a character backend multiplexer
+(which is the default if you are using ``-nographic``) then several
+commands are available via an escape sequence. These key sequences all
+start with an escape character, which is Ctrl-a by default, but can be
+changed with ``-echr``. The list below assumes you're using the default.
+
+Ctrl-a h
+   Print this help
+
+Ctrl-a x
+   Exit emulator
+
+Ctrl-a s
+   Save disk data back to file (if -snapshot)
+
+Ctrl-a t
+   Toggle console timestamps
+
+Ctrl-a b
+   Send break (magic sysrq in Linux)
+
+Ctrl-a c
+   Rotate between the frontends connected to the multiplexer (usually
+   this switches between the monitor and the console)
+
+Ctrl-a Ctrl-a
+   Send the escape character to the frontend
diff --git a/docs/system/net.rst b/docs/system/net.rst
new file mode 100644 (file)
index 0000000..4b2640c
--- /dev/null
@@ -0,0 +1,100 @@
+.. _pcsys_005fnetwork:
+
+Network emulation
+-----------------
+
+QEMU can simulate several network cards (e.g. PCI or ISA cards on the PC
+target) and can connect them to a network backend on the host or an
+emulated hub. The various host network backends can either be used to
+connect the NIC of the guest to a real network (e.g. by using a TAP
+devices or the non-privileged user mode network stack), or to other
+guest instances running in another QEMU process (e.g. by using the
+socket host network backend).
+
+Using TAP network interfaces
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is the standard way to connect QEMU to a real network. QEMU adds a
+virtual network device on your host (called ``tapN``), and you can then
+configure it as if it was a real ethernet card.
+
+Linux host
+^^^^^^^^^^
+
+As an example, you can download the ``linux-test-xxx.tar.gz`` archive
+and copy the script ``qemu-ifup`` in ``/etc`` and configure properly
+``sudo`` so that the command ``ifconfig`` contained in ``qemu-ifup`` can
+be executed as root. You must verify that your host kernel supports the
+TAP network interfaces: the device ``/dev/net/tun`` must be present.
+
+See :ref:`sec_005finvocation` to have examples of command
+lines using the TAP network interfaces.
+
+Windows host
+^^^^^^^^^^^^
+
+There is a virtual ethernet driver for Windows 2000/XP systems, called
+TAP-Win32. But it is not included in standard QEMU for Windows, so you
+will need to get it separately. It is part of OpenVPN package, so
+download OpenVPN from : https://openvpn.net/.
+
+Using the user mode network stack
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By using the option ``-net user`` (default configuration if no ``-net``
+option is specified), QEMU uses a completely user mode network stack
+(you don't need root privilege to use the virtual network). The virtual
+network configuration is the following::
+
+        guest (10.0.2.15)  <------>  Firewall/DHCP server <-----> Internet
+                              |          (10.0.2.2)
+                              |
+                              ---->  DNS server (10.0.2.3)
+                              |
+                              ---->  SMB server (10.0.2.4)
+
+The QEMU VM behaves as if it was behind a firewall which blocks all
+incoming connections. You can use a DHCP client to automatically
+configure the network in the QEMU VM. The DHCP server assign addresses
+to the hosts starting from 10.0.2.15.
+
+In order to check that the user mode network is working, you can ping
+the address 10.0.2.2 and verify that you got an address in the range
+10.0.2.x from the QEMU virtual DHCP server.
+
+Note that ICMP traffic in general does not work with user mode
+networking. ``ping``, aka. ICMP echo, to the local router (10.0.2.2)
+shall work, however. If you're using QEMU on Linux >= 3.0, it can use
+unprivileged ICMP ping sockets to allow ``ping`` to the Internet. The
+host admin has to set the ping_group_range in order to grant access to
+those sockets. To allow ping for GID 100 (usually users group)::
+
+   echo 100 100 > /proc/sys/net/ipv4/ping_group_range
+
+When using the built-in TFTP server, the router is also the TFTP server.
+
+When using the ``'-netdev user,hostfwd=...'`` option, TCP or UDP
+connections can be redirected from the host to the guest. It allows for
+example to redirect X11, telnet or SSH connections.
+
+Hubs
+~~~~
+
+QEMU can simulate several hubs. A hub can be thought of as a virtual
+connection between several network devices. These devices can be for
+example QEMU virtual ethernet cards or virtual Host ethernet devices
+(TAP devices). You can connect guest NICs or host network backends to
+such a hub using the ``-netdev
+hubport`` or ``-nic hubport`` options. The legacy ``-net`` option also
+connects the given device to the emulated hub with ID 0 (i.e. the
+default hub) unless you specify a netdev with ``-net nic,netdev=xxx``
+here.
+
+Connecting emulated networks between QEMU instances
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Using the ``-netdev socket`` (or ``-nic socket`` or ``-net socket``)
+option, it is possible to create emulated networks that span several
+QEMU instances. See the description of the ``-netdev socket`` option in
+:ref:`sec_005finvocation` to have a basic
+example.
index 388adbefbf42101c123324f18ec46869318580f4..bd99d4fa8eba9e2306d81ff3675cea2f00296a46 100644 (file)
+:orphan:
+
 QEMU block drivers reference
 ============================
 
-.. |qemu_system| replace:: qemu-system-x86_64
-
-..
-   We put the 'Synopsis' and 'See also' sections into the manpage, but not
-   the HTML. This makes the HTML docs read better and means the ToC in
-   the index has a more useful set of entries. Ideally, the section
-   headings 'Disk image file formats' would be top-level headings for
-   the HTML, but sub-headings of the conventional manpage 'Description'
-   header for the manpage. Unfortunately, due to deficiencies in
-   the Sphinx 'only' directive, this isn't possible: they must be headers
-   at the same level as 'Synopsis' and 'See also', otherwise Sphinx's
-   identification of which header underline style is which gets confused.
-
-.. only:: man
-
-  Synopsis
-  --------
-
-  QEMU block driver reference manual
-
-Disk image file formats
------------------------
-
-QEMU supports many image file formats that can be used with VMs as well as with
-any of the tools (like ``qemu-img``). This includes the preferred formats
-raw and qcow2 as well as formats that are supported for compatibility with
-older QEMU versions or other hypervisors.
-
-Depending on the image format, different options can be passed to
-``qemu-img create`` and ``qemu-img convert`` using the ``-o`` option.
-This section describes each format and the options that are supported for it.
-
-.. program:: image-formats
-.. option:: raw
-
-  Raw disk image format. This format has the advantage of
-  being simple and easily exportable to all other emulators. If your
-  file system supports *holes* (for example in ext2 or ext3 on
-  Linux or NTFS on Windows), then only the written sectors will reserve
-  space. Use ``qemu-img info`` to know the real size used by the
-  image or ``ls -ls`` on Unix/Linux.
-
-  Supported options:
-
-  .. program:: raw
-  .. option:: preallocation
-
-    Preallocation mode (allowed values: ``off``, ``falloc``,
-    ``full``). ``falloc`` mode preallocates space for image by
-    calling ``posix_fallocate()``. ``full`` mode preallocates space
-    for image by writing data to underlying storage. This data may or
-    may not be zero, depending on the storage location.
-
-.. program:: image-formats
-.. option:: qcow2
-
-  QEMU image format, the most versatile format. Use it to have smaller
-  images (useful if your filesystem does not supports holes, for example
-  on Windows), zlib based compression and support of multiple VM
-  snapshots.
-
-  Supported options:
-
-  .. program:: qcow2
-  .. option:: compat
-
-    Determines the qcow2 version to use. ``compat=0.10`` uses the
-    traditional image format that can be read by any QEMU since 0.10.
-    ``compat=1.1`` enables image format extensions that only QEMU 1.1 and
-    newer understand (this is the default). Amongst others, this includes
-    zero clusters, which allow efficient copy-on-read for sparse images.
-
-  .. option:: backing_file
-
-    File name of a base image (see ``create`` subcommand)
-
-  .. option:: backing_fmt
-
-    Image format of the base image
-
-  .. option:: encryption
-
-    This option is deprecated and equivalent to ``encrypt.format=aes``
-
-  .. option:: encrypt.format
-
-    If this is set to ``luks``, it requests that the qcow2 payload (not
-    qcow2 header) be encrypted using the LUKS format. The passphrase to
-    use to unlock the LUKS key slot is given by the ``encrypt.key-secret``
-    parameter. LUKS encryption parameters can be tuned with the other
-    ``encrypt.*`` parameters.
-
-    If this is set to ``aes``, the image is encrypted with 128-bit AES-CBC.
-    The encryption key is given by the ``encrypt.key-secret`` parameter.
-    This encryption format is considered to be flawed by modern cryptography
-    standards, suffering from a number of design problems:
-
-    - The AES-CBC cipher is used with predictable initialization vectors based
-      on the sector number. This makes it vulnerable to chosen plaintext attacks
-      which can reveal the existence of encrypted data.
-    - The user passphrase is directly used as the encryption key. A poorly
-      chosen or short passphrase will compromise the security of the encryption.
-    - In the event of the passphrase being compromised there is no way to
-      change the passphrase to protect data in any qcow images. The files must
-      be cloned, using a different encryption passphrase in the new file. The
-      original file must then be securely erased using a program like shred,
-      though even this is ineffective with many modern storage technologies.
-
-    The use of this is no longer supported in system emulators. Support only
-    remains in the command line utilities, for the purposes of data liberation
-    and interoperability with old versions of QEMU. The ``luks`` format
-    should be used instead.
-
-  .. option:: encrypt.key-secret
-
-    Provides the ID of a ``secret`` object that contains the passphrase
-    (``encrypt.format=luks``) or encryption key (``encrypt.format=aes``).
-
-  .. option:: encrypt.cipher-alg
-
-    Name of the cipher algorithm and key length. Currently defaults
-    to ``aes-256``. Only used when ``encrypt.format=luks``.
-
-  .. option:: encrypt.cipher-mode
-
-    Name of the encryption mode to use. Currently defaults to ``xts``.
-    Only used when ``encrypt.format=luks``.
-
-  .. option:: encrypt.ivgen-alg
-
-    Name of the initialization vector generator algorithm. Currently defaults
-    to ``plain64``. Only used when ``encrypt.format=luks``.
-
-  .. option:: encrypt.ivgen-hash-alg
-
-    Name of the hash algorithm to use with the initialization vector generator
-    (if required). Defaults to ``sha256``. Only used when ``encrypt.format=luks``.
-
-  .. option:: encrypt.hash-alg
-
-    Name of the hash algorithm to use for PBKDF algorithm
-    Defaults to ``sha256``. Only used when ``encrypt.format=luks``.
-
-  .. option:: encrypt.iter-time
-
-    Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
-    Defaults to ``2000``. Only used when ``encrypt.format=luks``.
-
-  .. option:: cluster_size
-
-    Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
-    sizes can improve the image file size whereas larger cluster sizes generally
-    provide better performance.
-
-  .. option:: preallocation
-
-    Preallocation mode (allowed values: ``off``, ``metadata``, ``falloc``,
-    ``full``). An image with preallocated metadata is initially larger but can
-    improve performance when the image needs to grow. ``falloc`` and ``full``
-    preallocations are like the same options of ``raw`` format, but sets up
-    metadata also.
-
-  .. option:: lazy_refcounts
-
-    If this option is set to ``on``, reference count updates are postponed with
-    the goal of avoiding metadata I/O and improving performance. This is
-    particularly interesting with :option:`cache=writethrough` which doesn't batch
-    metadata updates. The tradeoff is that after a host crash, the reference count
-    tables must be rebuilt, i.e. on the next open an (automatic) ``qemu-img
-    check -r all`` is required, which may take some time.
-
-    This option can only be enabled if ``compat=1.1`` is specified.
-
-  .. option:: nocow
-
-    If this option is set to ``on``, it will turn off COW of the file. It's only
-    valid on btrfs, no effect on other file systems.
-
-    Btrfs has low performance when hosting a VM image file, even more
-    when the guest on the VM also using btrfs as file system. Turning off
-    COW is a way to mitigate this bad performance. Generally there are two
-    ways to turn off COW on btrfs:
-
-    - Disable it by mounting with nodatacow, then all newly created files
-      will be NOCOW.
-    - For an empty file, add the NOCOW file attribute. That's what this
-      option does.
-
-    Note: this option is only valid to new or empty files. If there is
-    an existing file which is COW and has data blocks already, it couldn't
-    be changed to NOCOW by setting ``nocow=on``. One can issue ``lsattr
-    filename`` to check if the NOCOW flag is set or not (Capital 'C' is
-    NOCOW flag).
-
-.. program:: image-formats
-.. option:: qed
-
-   Old QEMU image format with support for backing files and compact image files
-   (when your filesystem or transport medium does not support holes).
-
-   When converting QED images to qcow2, you might want to consider using the
-   ``lazy_refcounts=on`` option to get a more QED-like behaviour.
-
-   Supported options:
-
-   .. program:: qed
-   .. option:: backing_file
-
-      File name of a base image (see ``create`` subcommand).
-
-   .. option:: backing_fmt
-
-     Image file format of backing file (optional).  Useful if the format cannot be
-     autodetected because it has no header, like some vhd/vpc files.
-
-   .. option:: cluster_size
-
-     Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
-     cluster sizes can improve the image file size whereas larger cluster sizes
-     generally provide better performance.
-
-   .. option:: table_size
-
-     Changes the number of clusters per L1/L2 table (must be
-     power-of-2 between 1 and 16).  There is normally no need to
-     change this value but this option can between used for
-     performance benchmarking.
-
-.. program:: image-formats
-.. option:: qcow
-
-  Old QEMU image format with support for backing files, compact image files,
-  encryption and compression.
-
-  Supported options:
-
-   .. program:: qcow
-   .. option:: backing_file
-
-     File name of a base image (see ``create`` subcommand)
-
-   .. option:: encryption
-
-     This option is deprecated and equivalent to ``encrypt.format=aes``
-
-   .. option:: encrypt.format
-
-     If this is set to ``aes``, the image is encrypted with 128-bit AES-CBC.
-     The encryption key is given by the ``encrypt.key-secret`` parameter.
-     This encryption format is considered to be flawed by modern cryptography
-     standards, suffering from a number of design problems enumerated previously
-     against the ``qcow2`` image format.
-
-     The use of this is no longer supported in system emulators. Support only
-     remains in the command line utilities, for the purposes of data liberation
-     and interoperability with old versions of QEMU.
-
-     Users requiring native encryption should use the ``qcow2`` format
-     instead with ``encrypt.format=luks``.
-
-   .. option:: encrypt.key-secret
-
-     Provides the ID of a ``secret`` object that contains the encryption
-     key (``encrypt.format=aes``).
-
-.. program:: image-formats
-.. option:: luks
-
-  LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
-
-  Supported options:
-
-  .. program:: luks
-  .. option:: key-secret
-
-    Provides the ID of a ``secret`` object that contains the passphrase.
-
-  .. option:: cipher-alg
-
-    Name of the cipher algorithm and key length. Currently defaults
-    to ``aes-256``.
-
-  .. option:: cipher-mode
-
-    Name of the encryption mode to use. Currently defaults to ``xts``.
-
-  .. option:: ivgen-alg
-
-    Name of the initialization vector generator algorithm. Currently defaults
-    to ``plain64``.
-
-  .. option:: ivgen-hash-alg
-
-    Name of the hash algorithm to use with the initialization vector generator
-    (if required). Defaults to ``sha256``.
-
-  .. option:: hash-alg
-
-    Name of the hash algorithm to use for PBKDF algorithm
-    Defaults to ``sha256``.
-
-  .. option:: iter-time
-
-    Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
-    Defaults to ``2000``.
-
-.. program:: image-formats
-.. option:: vdi
-
-  VirtualBox 1.1 compatible image format.
-
-  Supported options:
-
-  .. program:: vdi
-  .. option:: static
-
-    If this option is set to ``on``, the image is created with metadata
-    preallocation.
-
-.. program:: image-formats
-.. option:: vmdk
-
-  VMware 3 and 4 compatible image format.
-
-  Supported options:
-
-  .. program: vmdk
-  .. option:: backing_file
-
-    File name of a base image (see ``create`` subcommand).
-
-  .. option:: compat6
-
-    Create a VMDK version 6 image (instead of version 4)
-
-  .. option:: hwversion
-
-    Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
-    if hwversion is specified.
-
-  .. option:: subformat
-
-    Specifies which VMDK subformat to use. Valid options are
-    ``monolithicSparse`` (default),
-    ``monolithicFlat``,
-    ``twoGbMaxExtentSparse``,
-    ``twoGbMaxExtentFlat`` and
-    ``streamOptimized``.
-
-.. program:: image-formats
-.. option:: vpc
-
-  VirtualPC compatible image format (VHD).
-
-  Supported options:
-
-  .. program:: vpc
-  .. option:: subformat
-
-    Specifies which VHD subformat to use. Valid options are
-    ``dynamic`` (default) and ``fixed``.
-
-.. program:: image-formats
-.. option:: VHDX
-
-  Hyper-V compatible image format (VHDX).
-
-  Supported options:
-
-  .. program:: VHDX
-  .. option:: subformat
-
-    Specifies which VHDX subformat to use. Valid options are
-    ``dynamic`` (default) and ``fixed``.
-
-    .. option:: block_state_zero
-
-      Force use of payload blocks of type 'ZERO'.  Can be set to ``on`` (default)
-      or ``off``.  When set to ``off``, new blocks will be created as
-      ``PAYLOAD_BLOCK_NOT_PRESENT``, which means parsers are free to return
-      arbitrary data for those blocks.  Do not set to ``off`` when using
-      ``qemu-img convert`` with ``subformat=dynamic``.
-
-    .. option:: block_size
-
-      Block size; min 1 MB, max 256 MB.  0 means auto-calculate based on
-      image size.
-
-    .. option:: log_size
-
-      Log size; min 1 MB.
-
-Read-only formats
------------------
-
-More disk image file formats are supported in a read-only mode.
-
-.. program:: image-formats
-.. option:: bochs
-
-  Bochs images of ``growing`` type.
-
-.. program:: image-formats
-.. option:: cloop
-
-  Linux Compressed Loop image, useful only to reuse directly compressed
-  CD-ROM images present for example in the Knoppix CD-ROMs.
-
-.. program:: image-formats
-.. option:: dmg
-
-  Apple disk image.
-
-.. program:: image-formats
-.. option:: parallels
-
-  Parallels disk image format.
-
-Using host drives
------------------
-
-In addition to disk image files, QEMU can directly access host
-devices. We describe here the usage for QEMU version >= 0.8.3.
-
-Linux
-'''''
-
-On Linux, you can directly use the host device filename instead of a
-disk image filename provided you have enough privileges to access
-it. For example, use ``/dev/cdrom`` to access to the CDROM.
-
-CD
-  You can specify a CDROM device even if no CDROM is loaded. QEMU has
-  specific code to detect CDROM insertion or removal. CDROM ejection by
-  the guest OS is supported. Currently only data CDs are supported.
-
-Floppy
-  You can specify a floppy device even if no floppy is loaded. Floppy
-  removal is currently not detected accurately (if you change floppy
-  without doing floppy access while the floppy is not loaded, the guest
-  OS will think that the same floppy is loaded).
-  Use of the host's floppy device is deprecated, and support for it will
-  be removed in a future release.
-
-Hard disks
-  Hard disks can be used. Normally you must specify the whole disk
-  (``/dev/hdb`` instead of ``/dev/hdb1``) so that the guest OS can
-  see it as a partitioned disk. WARNING: unless you know what you do, it
-  is better to only make READ-ONLY accesses to the hard disk otherwise
-  you may corrupt your host data (use the ``-snapshot`` command
-  line option or modify the device permissions accordingly).
-
-Windows
-'''''''
-
-CD
-  The preferred syntax is the drive letter (e.g. ``d:``). The
-  alternate syntax ``\\.\d:`` is supported. ``/dev/cdrom`` is
-  supported as an alias to the first CDROM drive.
-
-  Currently there is no specific code to handle removable media, so it
-  is better to use the ``change`` or ``eject`` monitor commands to
-  change or eject media.
-
-Hard disks
-  Hard disks can be used with the syntax: ``\\.\PhysicalDriveN``
-  where *N* is the drive number (0 is the first hard disk).
-
-  WARNING: unless you know what you do, it is better to only make
-  READ-ONLY accesses to the hard disk otherwise you may corrupt your
-  host data (use the ``-snapshot`` command line so that the
-  modifications are written in a temporary file).
-
-Mac OS X
-''''''''
-
-``/dev/cdrom`` is an alias to the first CDROM.
-
-Currently there is no specific code to handle removable media, so it
-is better to use the ``change`` or ``eject`` monitor commands to
-change or eject media.
-
-Virtual FAT disk images
------------------------
-
-QEMU can automatically create a virtual FAT disk image from a
-directory tree. In order to use it, just type:
-
-.. parsed-literal::
-
-  |qemu_system| linux.img -hdb fat:/my_directory
-
-Then you access access to all the files in the ``/my_directory``
-directory without having to copy them in a disk image or to export
-them via SAMBA or NFS. The default access is *read-only*.
-
-Floppies can be emulated with the ``:floppy:`` option:
-
-.. parsed-literal::
-
-  |qemu_system| linux.img -fda fat:floppy:/my_directory
-
-A read/write support is available for testing (beta stage) with the
-``:rw:`` option:
-
-.. parsed-literal::
-
-  |qemu_system| linux.img -fda fat:floppy:rw:/my_directory
-
-What you should *never* do:
-
-- use non-ASCII filenames
-- use "-snapshot" together with ":rw:"
-- expect it to work when loadvm'ing
-- write to the FAT directory on the host system while accessing it with the guest system
-
-NBD access
-----------
-
-QEMU can access directly to block device exported using the Network Block Device
-protocol.
-
-.. parsed-literal::
-
-  |qemu_system| linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
-
-If the NBD server is located on the same host, you can use an unix socket instead
-of an inet socket:
-
-.. parsed-literal::
-
-  |qemu_system| linux.img -hdb nbd+unix://?socket=/tmp/my_socket
-
-In this case, the block device must be exported using qemu-nbd:
-
-.. parsed-literal::
-
-  qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
-
-The use of qemu-nbd allows sharing of a disk between several guests:
-
-.. parsed-literal::
-
-  qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
-
-and then you can use it with two guests:
-
-.. parsed-literal::
-
-  |qemu_system| linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
-  |qemu_system| linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
-
-If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
-own embedded NBD server), you must specify an export name in the URI:
-
-.. parsed-literal::
-
-  |qemu_system| -cdrom nbd://localhost/debian-500-ppc-netinst
-  |qemu_system| -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
-
-The URI syntax for NBD is supported since QEMU 1.3.  An alternative syntax is
-also available.  Here are some example of the older syntax:
-
-.. parsed-literal::
-
-  |qemu_system| linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
-  |qemu_system| linux2.img -hdb nbd:unix:/tmp/my_socket
-  |qemu_system| -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
-
-
-
-Sheepdog disk images
---------------------
-
-Sheepdog is a distributed storage system for QEMU.  It provides highly
-available block level storage volumes that can be attached to
-QEMU-based virtual machines.
-
-You can create a Sheepdog disk image with the command:
-
-.. parsed-literal::
-
-  qemu-img create sheepdog:///IMAGE SIZE
-
-where *IMAGE* is the Sheepdog image name and *SIZE* is its
-size.
-
-To import the existing *FILENAME* to Sheepdog, you can use a
-convert command.
-
-.. parsed-literal::
-
-  qemu-img convert FILENAME sheepdog:///IMAGE
-
-You can boot from the Sheepdog disk image with the command:
-
-.. parsed-literal::
-
-  |qemu_system| sheepdog:///IMAGE
-
-You can also create a snapshot of the Sheepdog image like qcow2.
-
-.. parsed-literal::
-
-  qemu-img snapshot -c TAG sheepdog:///IMAGE
-
-where *TAG* is a tag name of the newly created snapshot.
-
-To boot from the Sheepdog snapshot, specify the tag name of the
-snapshot.
-
-.. parsed-literal::
-
-  |qemu_system| sheepdog:///IMAGE#TAG
-
-You can create a cloned image from the existing snapshot.
-
-.. parsed-literal::
-
-  qemu-img create -b sheepdog:///BASE#TAG sheepdog:///IMAGE
-
-where *BASE* is an image name of the source snapshot and *TAG*
-is its tag name.
-
-You can use an unix socket instead of an inet socket:
-
-.. parsed-literal::
-
-  |qemu_system| sheepdog+unix:///IMAGE?socket=PATH
-
-If the Sheepdog daemon doesn't run on the local host, you need to
-specify one of the Sheepdog servers to connect to.
-
-.. parsed-literal::
-
-  qemu-img create sheepdog://HOSTNAME:PORT/IMAGE SIZE
-  |qemu_system| sheepdog://HOSTNAME:PORT/IMAGE
-
-iSCSI LUNs
-----------
-
-iSCSI is a popular protocol used to access SCSI devices across a computer
-network.
-
-There are two different ways iSCSI devices can be used by QEMU.
-
-The first method is to mount the iSCSI LUN on the host, and make it appear as
-any other ordinary SCSI device on the host and then to access this device as a
-/dev/sd device from QEMU. How to do this differs between host OSes.
-
-The second method involves using the iSCSI initiator that is built into
-QEMU. This provides a mechanism that works the same way regardless of which
-host OS you are running QEMU on. This section will describe this second method
-of using iSCSI together with QEMU.
-
-In QEMU, iSCSI devices are described using special iSCSI URLs. URL syntax:
-
-::
-
-  iscsi://[<username>[%<password>]@]<host>[:<port>]/<target-iqn-name>/<lun>
-
-Username and password are optional and only used if your target is set up
-using CHAP authentication for access control.
-Alternatively the username and password can also be set via environment
-variables to have these not show up in the process list:
-
-::
-
-  export LIBISCSI_CHAP_USERNAME=<username>
-  export LIBISCSI_CHAP_PASSWORD=<password>
-  iscsi://<host>/<target-iqn-name>/<lun>
-
-Various session related parameters can be set via special options, either
-in a configuration file provided via '-readconfig' or directly on the
-command line.
-
-If the initiator-name is not specified qemu will use a default name
-of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
-virtual machine. If the UUID is not specified qemu will use
-'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
-virtual machine.
-
-Setting a specific initiator name to use when logging in to the target:
-
-::
-
-  -iscsi initiator-name=iqn.qemu.test:my-initiator
-
-Controlling which type of header digest to negotiate with the target:
-
-::
-
-  -iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
-
-These can also be set via a configuration file:
-
-::
-
-  [iscsi]
-    user = "CHAP username"
-    password = "CHAP password"
-    initiator-name = "iqn.qemu.test:my-initiator"
-    # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
-    header-digest = "CRC32C"
-
-Setting the target name allows different options for different targets:
-
-::
-
-  [iscsi "iqn.target.name"]
-    user = "CHAP username"
-    password = "CHAP password"
-    initiator-name = "iqn.qemu.test:my-initiator"
-    # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
-    header-digest = "CRC32C"
-
-How to use a configuration file to set iSCSI configuration options:
-
-.. parsed-literal::
-
-  cat >iscsi.conf <<EOF
-  [iscsi]
-    user = "me"
-    password = "my password"
-    initiator-name = "iqn.qemu.test:my-initiator"
-    header-digest = "CRC32C"
-  EOF
-
-  |qemu_system| -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \\
-    -readconfig iscsi.conf
-
-How to set up a simple iSCSI target on loopback and access it via QEMU:
-this example shows how to set up an iSCSI target with one CDROM and one DISK
-using the Linux STGT software target. This target is available on Red Hat based
-systems as the package 'scsi-target-utils'.
-
-.. parsed-literal::
-
-  tgtd --iscsi portal=127.0.0.1:3260
-  tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
-  tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \\
-      -b /IMAGES/disk.img --device-type=disk
-  tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \\
-      -b /IMAGES/cd.iso --device-type=cd
-  tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
-
-  |qemu_system| -iscsi initiator-name=iqn.qemu.test:my-initiator \\
-    -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \\
-    -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
-
-GlusterFS disk images
----------------------
-
-GlusterFS is a user space distributed file system.
-
-You can boot from the GlusterFS disk image with the command:
-
-URI:
-
-.. parsed-literal::
-
-  |qemu_system| -drive file=gluster[+TYPE]://[HOST}[:PORT]]/VOLUME/PATH
-                               [?socket=...][,file.debug=9][,file.logfile=...]
-
-JSON:
-
-.. parsed-literal::
-
-  |qemu_system| 'json:{"driver":"qcow2",
-                           "file":{"driver":"gluster",
-                                    "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
-                                    "server":[{"type":"tcp","host":"...","port":"..."},
-                                              {"type":"unix","socket":"..."}]}}'
-
-*gluster* is the protocol.
-
-*TYPE* specifies the transport type used to connect to gluster
-management daemon (glusterd). Valid transport types are
-tcp and unix. In the URI form, if a transport type isn't specified,
-then tcp type is assumed.
-
-*HOST* specifies the server where the volume file specification for
-the given volume resides. This can be either a hostname or an ipv4 address.
-If transport type is unix, then *HOST* field should not be specified.
-Instead *socket* field needs to be populated with the path to unix domain
-socket.
-
-*PORT* is the port number on which glusterd is listening. This is optional
-and if not specified, it defaults to port 24007. If the transport type is unix,
-then *PORT* should not be specified.
-
-*VOLUME* is the name of the gluster volume which contains the disk image.
-
-*PATH* is the path to the actual disk image that resides on gluster volume.
-
-*debug* is the logging level of the gluster protocol driver. Debug levels
-are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
-The default level is 4. The current logging levels defined in the gluster source
-are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
-6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
-
-*logfile* is a commandline option to mention log file path which helps in
-logging to the specified file and also help in persisting the gfapi logs. The
-default is stderr.
-
-You can create a GlusterFS disk image with the command:
-
-.. parsed-literal::
-
-  qemu-img create gluster://HOST/VOLUME/PATH SIZE
-
-Examples
-
-.. parsed-literal::
-
-  |qemu_system| -drive file=gluster://1.2.3.4/testvol/a.img
-  |qemu_system| -drive file=gluster+tcp://1.2.3.4/testvol/a.img
-  |qemu_system| -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
-  |qemu_system| -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
-  |qemu_system| -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
-  |qemu_system| -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
-  |qemu_system| -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
-  |qemu_system| -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
-  |qemu_system| -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
-  |qemu_system| 'json:{"driver":"qcow2",
-                           "file":{"driver":"gluster",
-                                    "volume":"testvol","path":"a.img",
-                                    "debug":9,"logfile":"/var/log/qemu-gluster.log",
-                                    "server":[{"type":"tcp","host":"1.2.3.4","port":24007},
-                                              {"type":"unix","socket":"/var/run/glusterd.socket"}]}}'
-  |qemu_system| -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
-                                       file.debug=9,file.logfile=/var/log/qemu-gluster.log,
-                                       file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
-                                       file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
-
-Secure Shell (ssh) disk images
-------------------------------
-
-You can access disk images located on a remote ssh server
-by using the ssh protocol:
-
-.. parsed-literal::
-
-  |qemu_system| -drive file=ssh://[USER@]SERVER[:PORT]/PATH[?host_key_check=HOST_KEY_CHECK]
-
-Alternative syntax using properties:
-
-.. parsed-literal::
-
-  |qemu_system| -drive file.driver=ssh[,file.user=USER],file.host=SERVER[,file.port=PORT],file.path=PATH[,file.host_key_check=HOST_KEY_CHECK]
-
-*ssh* is the protocol.
-
-*USER* is the remote user.  If not specified, then the local
-username is tried.
-
-*SERVER* specifies the remote ssh server.  Any ssh server can be
-used, but it must implement the sftp-server protocol.  Most Unix/Linux
-systems should work without requiring any extra configuration.
-
-*PORT* is the port number on which sshd is listening.  By default
-the standard ssh port (22) is used.
-
-*PATH* is the path to the disk image.
-
-The optional *HOST_KEY_CHECK* parameter controls how the remote
-host's key is checked.  The default is ``yes`` which means to use
-the local ``.ssh/known_hosts`` file.  Setting this to ``no``
-turns off known-hosts checking.  Or you can check that the host key
-matches a specific fingerprint:
-``host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8``
-(``sha1:`` can also be used as a prefix, but note that OpenSSH
-tools only use MD5 to print fingerprints).
-
-Currently authentication must be done using ssh-agent.  Other
-authentication methods may be supported in future.
-
-Note: Many ssh servers do not support an ``fsync``-style operation.
-The ssh driver cannot guarantee that disk flush requests are
-obeyed, and this causes a risk of disk corruption if the remote
-server or network goes down during writes.  The driver will
-print a warning when ``fsync`` is not supported:
-
-::
-
-  warning: ssh server ssh.example.com:22 does not support fsync
-
-With sufficiently new versions of libssh and OpenSSH, ``fsync`` is
-supported.
-
-NVMe disk images
-----------------
-
-NVM Express (NVMe) storage controllers can be accessed directly by a userspace
-driver in QEMU.  This bypasses the host kernel file system and block layers
-while retaining QEMU block layer functionalities, such as block jobs, I/O
-throttling, image formats, etc.  Disk I/O performance is typically higher than
-with ``-drive file=/dev/sda`` using either thread pool or linux-aio.
-
-The controller will be exclusively used by the QEMU process once started. To be
-able to share storage between multiple VMs and other applications on the host,
-please use the file based protocols.
-
-Before starting QEMU, bind the host NVMe controller to the host vfio-pci
-driver.  For example:
-
-.. parsed-literal::
-
-  # modprobe vfio-pci
-  # lspci -n -s 0000:06:0d.0
-  06:0d.0 0401: 1102:0002 (rev 08)
-  # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
-  # echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
-
-  # |qemu_system| -drive file=nvme://HOST:BUS:SLOT.FUNC/NAMESPACE
-
-Alternative syntax using properties:
-
-.. parsed-literal::
-
-  |qemu_system| -drive file.driver=nvme,file.device=HOST:BUS:SLOT.FUNC,file.namespace=NAMESPACE
-
-*HOST*:*BUS*:*SLOT*.\ *FUNC* is the NVMe controller's PCI device
-address on the host.
-
-*NAMESPACE* is the NVMe namespace number, starting from 1.
-
-Disk image file locking
------------------------
-
-By default, QEMU tries to protect image files from unexpected concurrent
-access, as long as it's supported by the block protocol driver and host
-operating system. If multiple QEMU processes (including QEMU emulators and
-utilities) try to open the same image with conflicting accessing modes, all but
-the first one will get an error.
-
-This feature is currently supported by the file protocol on Linux with the Open
-File Descriptor (OFD) locking API, and can be configured to fall back to POSIX
-locking if the POSIX host doesn't support Linux OFD locking.
-
-To explicitly enable image locking, specify "locking=on" in the file protocol
-driver options. If OFD locking is not possible, a warning will be printed and
-the POSIX locking API will be used. In this case there is a risk that the lock
-will get silently lost when doing hot plugging and block jobs, due to the
-shortcomings of the POSIX locking API.
-
-QEMU transparently handles lock handover during shared storage migration.  For
-shared virtual disk images between multiple VMs, the "share-rw" device option
-should be used.
-
-By default, the guest has exclusive write access to its disk image. If the
-guest can safely share the disk image with other writers the
-``-device ...,share-rw=on`` parameter can be used.  This is only safe if
-the guest is running software, such as a cluster file system, that
-coordinates disk accesses to avoid corruption.
-
-Note that share-rw=on only declares the guest's ability to share the disk.
-Some QEMU features, such as image file formats, require exclusive write access
-to the disk image and this is unaffected by the share-rw=on option.
-
-Alternatively, locking can be fully disabled by "locking=off" block device
-option. In the command line, the option is usually in the form of
-"file.locking=off" as the protocol driver is normally placed as a "file" child
-under a format driver. For example:
-
-::
+Synopsis
+--------
 
-  -blockdev driver=qcow2,file.filename=/path/to/image,file.locking=off,file.driver=file
+QEMU block driver reference manual
 
-To check if image locking is active, check the output of the "lslocks" command
-on host and see if there are locks held by the QEMU process on the image file.
-More than one byte could be locked by the QEMU instance, each byte of which
-reflects a particular permission that is acquired or protected by the running
-block driver.
+Description
+-----------
 
-.. only:: man
+.. include:: qemu-block-drivers.rst.inc
 
-  See also
-  --------
+See also
+--------
 
-  The HTML documentation of QEMU for more precise information and Linux
-  user mode emulator invocation.
+The HTML documentation of QEMU for more precise information and Linux
+user mode emulator invocation.
diff --git a/docs/system/qemu-block-drivers.rst.inc b/docs/system/qemu-block-drivers.rst.inc
new file mode 100644 (file)
index 0000000..b052a6d
--- /dev/null
@@ -0,0 +1,954 @@
+Disk image file formats
+~~~~~~~~~~~~~~~~~~~~~~~
+
+QEMU supports many image file formats that can be used with VMs as well as with
+any of the tools (like ``qemu-img``). This includes the preferred formats
+raw and qcow2 as well as formats that are supported for compatibility with
+older QEMU versions or other hypervisors.
+
+Depending on the image format, different options can be passed to
+``qemu-img create`` and ``qemu-img convert`` using the ``-o`` option.
+This section describes each format and the options that are supported for it.
+
+.. program:: image-formats
+.. option:: raw
+
+  Raw disk image format. This format has the advantage of
+  being simple and easily exportable to all other emulators. If your
+  file system supports *holes* (for example in ext2 or ext3 on
+  Linux or NTFS on Windows), then only the written sectors will reserve
+  space. Use ``qemu-img info`` to know the real size used by the
+  image or ``ls -ls`` on Unix/Linux.
+
+  Supported options:
+
+  .. program:: raw
+  .. option:: preallocation
+
+    Preallocation mode (allowed values: ``off``, ``falloc``,
+    ``full``). ``falloc`` mode preallocates space for image by
+    calling ``posix_fallocate()``. ``full`` mode preallocates space
+    for image by writing data to underlying storage. This data may or
+    may not be zero, depending on the storage location.
+
+.. program:: image-formats
+.. option:: qcow2
+
+  QEMU image format, the most versatile format. Use it to have smaller
+  images (useful if your filesystem does not supports holes, for example
+  on Windows), zlib based compression and support of multiple VM
+  snapshots.
+
+  Supported options:
+
+  .. program:: qcow2
+  .. option:: compat
+
+    Determines the qcow2 version to use. ``compat=0.10`` uses the
+    traditional image format that can be read by any QEMU since 0.10.
+    ``compat=1.1`` enables image format extensions that only QEMU 1.1 and
+    newer understand (this is the default). Amongst others, this includes
+    zero clusters, which allow efficient copy-on-read for sparse images.
+
+  .. option:: backing_file
+
+    File name of a base image (see ``create`` subcommand)
+
+  .. option:: backing_fmt
+
+    Image format of the base image
+
+  .. option:: encryption
+
+    This option is deprecated and equivalent to ``encrypt.format=aes``
+
+  .. option:: encrypt.format
+
+    If this is set to ``luks``, it requests that the qcow2 payload (not
+    qcow2 header) be encrypted using the LUKS format. The passphrase to
+    use to unlock the LUKS key slot is given by the ``encrypt.key-secret``
+    parameter. LUKS encryption parameters can be tuned with the other
+    ``encrypt.*`` parameters.
+
+    If this is set to ``aes``, the image is encrypted with 128-bit AES-CBC.
+    The encryption key is given by the ``encrypt.key-secret`` parameter.
+    This encryption format is considered to be flawed by modern cryptography
+    standards, suffering from a number of design problems:
+
+    - The AES-CBC cipher is used with predictable initialization vectors based
+      on the sector number. This makes it vulnerable to chosen plaintext attacks
+      which can reveal the existence of encrypted data.
+    - The user passphrase is directly used as the encryption key. A poorly
+      chosen or short passphrase will compromise the security of the encryption.
+    - In the event of the passphrase being compromised there is no way to
+      change the passphrase to protect data in any qcow images. The files must
+      be cloned, using a different encryption passphrase in the new file. The
+      original file must then be securely erased using a program like shred,
+      though even this is ineffective with many modern storage technologies.
+
+    The use of this is no longer supported in system emulators. Support only
+    remains in the command line utilities, for the purposes of data liberation
+    and interoperability with old versions of QEMU. The ``luks`` format
+    should be used instead.
+
+  .. option:: encrypt.key-secret
+
+    Provides the ID of a ``secret`` object that contains the passphrase
+    (``encrypt.format=luks``) or encryption key (``encrypt.format=aes``).
+
+  .. option:: encrypt.cipher-alg
+
+    Name of the cipher algorithm and key length. Currently defaults
+    to ``aes-256``. Only used when ``encrypt.format=luks``.
+
+  .. option:: encrypt.cipher-mode
+
+    Name of the encryption mode to use. Currently defaults to ``xts``.
+    Only used when ``encrypt.format=luks``.
+
+  .. option:: encrypt.ivgen-alg
+
+    Name of the initialization vector generator algorithm. Currently defaults
+    to ``plain64``. Only used when ``encrypt.format=luks``.
+
+  .. option:: encrypt.ivgen-hash-alg
+
+    Name of the hash algorithm to use with the initialization vector generator
+    (if required). Defaults to ``sha256``. Only used when ``encrypt.format=luks``.
+
+  .. option:: encrypt.hash-alg
+
+    Name of the hash algorithm to use for PBKDF algorithm
+    Defaults to ``sha256``. Only used when ``encrypt.format=luks``.
+
+  .. option:: encrypt.iter-time
+
+    Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
+    Defaults to ``2000``. Only used when ``encrypt.format=luks``.
+
+  .. option:: cluster_size
+
+    Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
+    sizes can improve the image file size whereas larger cluster sizes generally
+    provide better performance.
+
+  .. option:: preallocation
+
+    Preallocation mode (allowed values: ``off``, ``metadata``, ``falloc``,
+    ``full``). An image with preallocated metadata is initially larger but can
+    improve performance when the image needs to grow. ``falloc`` and ``full``
+    preallocations are like the same options of ``raw`` format, but sets up
+    metadata also.
+
+  .. option:: lazy_refcounts
+
+    If this option is set to ``on``, reference count updates are postponed with
+    the goal of avoiding metadata I/O and improving performance. This is
+    particularly interesting with :option:`cache=writethrough` which doesn't batch
+    metadata updates. The tradeoff is that after a host crash, the reference count
+    tables must be rebuilt, i.e. on the next open an (automatic) ``qemu-img
+    check -r all`` is required, which may take some time.
+
+    This option can only be enabled if ``compat=1.1`` is specified.
+
+  .. option:: nocow
+
+    If this option is set to ``on``, it will turn off COW of the file. It's only
+    valid on btrfs, no effect on other file systems.
+
+    Btrfs has low performance when hosting a VM image file, even more
+    when the guest on the VM also using btrfs as file system. Turning off
+    COW is a way to mitigate this bad performance. Generally there are two
+    ways to turn off COW on btrfs:
+
+    - Disable it by mounting with nodatacow, then all newly created files
+      will be NOCOW.
+    - For an empty file, add the NOCOW file attribute. That's what this
+      option does.
+
+    Note: this option is only valid to new or empty files. If there is
+    an existing file which is COW and has data blocks already, it couldn't
+    be changed to NOCOW by setting ``nocow=on``. One can issue ``lsattr
+    filename`` to check if the NOCOW flag is set or not (Capital 'C' is
+    NOCOW flag).
+
+.. program:: image-formats
+.. option:: qed
+
+   Old QEMU image format with support for backing files and compact image files
+   (when your filesystem or transport medium does not support holes).
+
+   When converting QED images to qcow2, you might want to consider using the
+   ``lazy_refcounts=on`` option to get a more QED-like behaviour.
+
+   Supported options:
+
+   .. program:: qed
+   .. option:: backing_file
+
+      File name of a base image (see ``create`` subcommand).
+
+   .. option:: backing_fmt
+
+     Image file format of backing file (optional).  Useful if the format cannot be
+     autodetected because it has no header, like some vhd/vpc files.
+
+   .. option:: cluster_size
+
+     Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
+     cluster sizes can improve the image file size whereas larger cluster sizes
+     generally provide better performance.
+
+   .. option:: table_size
+
+     Changes the number of clusters per L1/L2 table (must be
+     power-of-2 between 1 and 16).  There is normally no need to
+     change this value but this option can between used for
+     performance benchmarking.
+
+.. program:: image-formats
+.. option:: qcow
+
+  Old QEMU image format with support for backing files, compact image files,
+  encryption and compression.
+
+  Supported options:
+
+   .. program:: qcow
+   .. option:: backing_file
+
+     File name of a base image (see ``create`` subcommand)
+
+   .. option:: encryption
+
+     This option is deprecated and equivalent to ``encrypt.format=aes``
+
+   .. option:: encrypt.format
+
+     If this is set to ``aes``, the image is encrypted with 128-bit AES-CBC.
+     The encryption key is given by the ``encrypt.key-secret`` parameter.
+     This encryption format is considered to be flawed by modern cryptography
+     standards, suffering from a number of design problems enumerated previously
+     against the ``qcow2`` image format.
+
+     The use of this is no longer supported in system emulators. Support only
+     remains in the command line utilities, for the purposes of data liberation
+     and interoperability with old versions of QEMU.
+
+     Users requiring native encryption should use the ``qcow2`` format
+     instead with ``encrypt.format=luks``.
+
+   .. option:: encrypt.key-secret
+
+     Provides the ID of a ``secret`` object that contains the encryption
+     key (``encrypt.format=aes``).
+
+.. program:: image-formats
+.. option:: luks
+
+  LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
+
+  Supported options:
+
+  .. program:: luks
+  .. option:: key-secret
+
+    Provides the ID of a ``secret`` object that contains the passphrase.
+
+  .. option:: cipher-alg
+
+    Name of the cipher algorithm and key length. Currently defaults
+    to ``aes-256``.
+
+  .. option:: cipher-mode
+
+    Name of the encryption mode to use. Currently defaults to ``xts``.
+
+  .. option:: ivgen-alg
+
+    Name of the initialization vector generator algorithm. Currently defaults
+    to ``plain64``.
+
+  .. option:: ivgen-hash-alg
+
+    Name of the hash algorithm to use with the initialization vector generator
+    (if required). Defaults to ``sha256``.
+
+  .. option:: hash-alg
+
+    Name of the hash algorithm to use for PBKDF algorithm
+    Defaults to ``sha256``.
+
+  .. option:: iter-time
+
+    Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
+    Defaults to ``2000``.
+
+.. program:: image-formats
+.. option:: vdi
+
+  VirtualBox 1.1 compatible image format.
+
+  Supported options:
+
+  .. program:: vdi
+  .. option:: static
+
+    If this option is set to ``on``, the image is created with metadata
+    preallocation.
+
+.. program:: image-formats
+.. option:: vmdk
+
+  VMware 3 and 4 compatible image format.
+
+  Supported options:
+
+  .. program: vmdk
+  .. option:: backing_file
+
+    File name of a base image (see ``create`` subcommand).
+
+  .. option:: compat6
+
+    Create a VMDK version 6 image (instead of version 4)
+
+  .. option:: hwversion
+
+    Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
+    if hwversion is specified.
+
+  .. option:: subformat
+
+    Specifies which VMDK subformat to use. Valid options are
+    ``monolithicSparse`` (default),
+    ``monolithicFlat``,
+    ``twoGbMaxExtentSparse``,
+    ``twoGbMaxExtentFlat`` and
+    ``streamOptimized``.
+
+.. program:: image-formats
+.. option:: vpc
+
+  VirtualPC compatible image format (VHD).
+
+  Supported options:
+
+  .. program:: vpc
+  .. option:: subformat
+
+    Specifies which VHD subformat to use. Valid options are
+    ``dynamic`` (default) and ``fixed``.
+
+.. program:: image-formats
+.. option:: VHDX
+
+  Hyper-V compatible image format (VHDX).
+
+  Supported options:
+
+  .. program:: VHDX
+  .. option:: subformat
+
+    Specifies which VHDX subformat to use. Valid options are
+    ``dynamic`` (default) and ``fixed``.
+
+    .. option:: block_state_zero
+
+      Force use of payload blocks of type 'ZERO'.  Can be set to ``on`` (default)
+      or ``off``.  When set to ``off``, new blocks will be created as
+      ``PAYLOAD_BLOCK_NOT_PRESENT``, which means parsers are free to return
+      arbitrary data for those blocks.  Do not set to ``off`` when using
+      ``qemu-img convert`` with ``subformat=dynamic``.
+
+    .. option:: block_size
+
+      Block size; min 1 MB, max 256 MB.  0 means auto-calculate based on
+      image size.
+
+    .. option:: log_size
+
+      Log size; min 1 MB.
+
+Read-only formats
+~~~~~~~~~~~~~~~~~
+
+More disk image file formats are supported in a read-only mode.
+
+.. program:: image-formats
+.. option:: bochs
+
+  Bochs images of ``growing`` type.
+
+.. program:: image-formats
+.. option:: cloop
+
+  Linux Compressed Loop image, useful only to reuse directly compressed
+  CD-ROM images present for example in the Knoppix CD-ROMs.
+
+.. program:: image-formats
+.. option:: dmg
+
+  Apple disk image.
+
+.. program:: image-formats
+.. option:: parallels
+
+  Parallels disk image format.
+
+Using host drives
+~~~~~~~~~~~~~~~~~
+
+In addition to disk image files, QEMU can directly access host
+devices. We describe here the usage for QEMU version >= 0.8.3.
+
+Linux
+^^^^^
+
+On Linux, you can directly use the host device filename instead of a
+disk image filename provided you have enough privileges to access
+it. For example, use ``/dev/cdrom`` to access to the CDROM.
+
+CD
+  You can specify a CDROM device even if no CDROM is loaded. QEMU has
+  specific code to detect CDROM insertion or removal. CDROM ejection by
+  the guest OS is supported. Currently only data CDs are supported.
+
+Floppy
+  You can specify a floppy device even if no floppy is loaded. Floppy
+  removal is currently not detected accurately (if you change floppy
+  without doing floppy access while the floppy is not loaded, the guest
+  OS will think that the same floppy is loaded).
+  Use of the host's floppy device is deprecated, and support for it will
+  be removed in a future release.
+
+Hard disks
+  Hard disks can be used. Normally you must specify the whole disk
+  (``/dev/hdb`` instead of ``/dev/hdb1``) so that the guest OS can
+  see it as a partitioned disk. WARNING: unless you know what you do, it
+  is better to only make READ-ONLY accesses to the hard disk otherwise
+  you may corrupt your host data (use the ``-snapshot`` command
+  line option or modify the device permissions accordingly).
+
+Windows
+^^^^^^^
+
+CD
+  The preferred syntax is the drive letter (e.g. ``d:``). The
+  alternate syntax ``\\.\d:`` is supported. ``/dev/cdrom`` is
+  supported as an alias to the first CDROM drive.
+
+  Currently there is no specific code to handle removable media, so it
+  is better to use the ``change`` or ``eject`` monitor commands to
+  change or eject media.
+
+Hard disks
+  Hard disks can be used with the syntax: ``\\.\PhysicalDriveN``
+  where *N* is the drive number (0 is the first hard disk).
+
+  WARNING: unless you know what you do, it is better to only make
+  READ-ONLY accesses to the hard disk otherwise you may corrupt your
+  host data (use the ``-snapshot`` command line so that the
+  modifications are written in a temporary file).
+
+Mac OS X
+^^^^^^^^
+
+``/dev/cdrom`` is an alias to the first CDROM.
+
+Currently there is no specific code to handle removable media, so it
+is better to use the ``change`` or ``eject`` monitor commands to
+change or eject media.
+
+Virtual FAT disk images
+~~~~~~~~~~~~~~~~~~~~~~~
+
+QEMU can automatically create a virtual FAT disk image from a
+directory tree. In order to use it, just type:
+
+.. parsed-literal::
+
+  |qemu_system| linux.img -hdb fat:/my_directory
+
+Then you access access to all the files in the ``/my_directory``
+directory without having to copy them in a disk image or to export
+them via SAMBA or NFS. The default access is *read-only*.
+
+Floppies can be emulated with the ``:floppy:`` option:
+
+.. parsed-literal::
+
+  |qemu_system| linux.img -fda fat:floppy:/my_directory
+
+A read/write support is available for testing (beta stage) with the
+``:rw:`` option:
+
+.. parsed-literal::
+
+  |qemu_system| linux.img -fda fat:floppy:rw:/my_directory
+
+What you should *never* do:
+
+- use non-ASCII filenames
+- use "-snapshot" together with ":rw:"
+- expect it to work when loadvm'ing
+- write to the FAT directory on the host system while accessing it with the guest system
+
+NBD access
+~~~~~~~~~~
+
+QEMU can access directly to block device exported using the Network Block Device
+protocol.
+
+.. parsed-literal::
+
+  |qemu_system| linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
+
+If the NBD server is located on the same host, you can use an unix socket instead
+of an inet socket:
+
+.. parsed-literal::
+
+  |qemu_system| linux.img -hdb nbd+unix://?socket=/tmp/my_socket
+
+In this case, the block device must be exported using qemu-nbd:
+
+.. parsed-literal::
+
+  qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
+
+The use of qemu-nbd allows sharing of a disk between several guests:
+
+.. parsed-literal::
+
+  qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
+
+and then you can use it with two guests:
+
+.. parsed-literal::
+
+  |qemu_system| linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
+  |qemu_system| linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
+
+If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
+own embedded NBD server), you must specify an export name in the URI:
+
+.. parsed-literal::
+
+  |qemu_system| -cdrom nbd://localhost/debian-500-ppc-netinst
+  |qemu_system| -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
+
+The URI syntax for NBD is supported since QEMU 1.3.  An alternative syntax is
+also available.  Here are some example of the older syntax:
+
+.. parsed-literal::
+
+  |qemu_system| linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
+  |qemu_system| linux2.img -hdb nbd:unix:/tmp/my_socket
+  |qemu_system| -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
+
+
+
+Sheepdog disk images
+~~~~~~~~~~~~~~~~~~~~
+
+Sheepdog is a distributed storage system for QEMU.  It provides highly
+available block level storage volumes that can be attached to
+QEMU-based virtual machines.
+
+You can create a Sheepdog disk image with the command:
+
+.. parsed-literal::
+
+  qemu-img create sheepdog:///IMAGE SIZE
+
+where *IMAGE* is the Sheepdog image name and *SIZE* is its
+size.
+
+To import the existing *FILENAME* to Sheepdog, you can use a
+convert command.
+
+.. parsed-literal::
+
+  qemu-img convert FILENAME sheepdog:///IMAGE
+
+You can boot from the Sheepdog disk image with the command:
+
+.. parsed-literal::
+
+  |qemu_system| sheepdog:///IMAGE
+
+You can also create a snapshot of the Sheepdog image like qcow2.
+
+.. parsed-literal::
+
+  qemu-img snapshot -c TAG sheepdog:///IMAGE
+
+where *TAG* is a tag name of the newly created snapshot.
+
+To boot from the Sheepdog snapshot, specify the tag name of the
+snapshot.
+
+.. parsed-literal::
+
+  |qemu_system| sheepdog:///IMAGE#TAG
+
+You can create a cloned image from the existing snapshot.
+
+.. parsed-literal::
+
+  qemu-img create -b sheepdog:///BASE#TAG sheepdog:///IMAGE
+
+where *BASE* is an image name of the source snapshot and *TAG*
+is its tag name.
+
+You can use an unix socket instead of an inet socket:
+
+.. parsed-literal::
+
+  |qemu_system| sheepdog+unix:///IMAGE?socket=PATH
+
+If the Sheepdog daemon doesn't run on the local host, you need to
+specify one of the Sheepdog servers to connect to.
+
+.. parsed-literal::
+
+  qemu-img create sheepdog://HOSTNAME:PORT/IMAGE SIZE
+  |qemu_system| sheepdog://HOSTNAME:PORT/IMAGE
+
+iSCSI LUNs
+~~~~~~~~~~
+
+iSCSI is a popular protocol used to access SCSI devices across a computer
+network.
+
+There are two different ways iSCSI devices can be used by QEMU.
+
+The first method is to mount the iSCSI LUN on the host, and make it appear as
+any other ordinary SCSI device on the host and then to access this device as a
+/dev/sd device from QEMU. How to do this differs between host OSes.
+
+The second method involves using the iSCSI initiator that is built into
+QEMU. This provides a mechanism that works the same way regardless of which
+host OS you are running QEMU on. This section will describe this second method
+of using iSCSI together with QEMU.
+
+In QEMU, iSCSI devices are described using special iSCSI URLs. URL syntax:
+
+::
+
+  iscsi://[<username>[%<password>]@]<host>[:<port>]/<target-iqn-name>/<lun>
+
+Username and password are optional and only used if your target is set up
+using CHAP authentication for access control.
+Alternatively the username and password can also be set via environment
+variables to have these not show up in the process list:
+
+::
+
+  export LIBISCSI_CHAP_USERNAME=<username>
+  export LIBISCSI_CHAP_PASSWORD=<password>
+  iscsi://<host>/<target-iqn-name>/<lun>
+
+Various session related parameters can be set via special options, either
+in a configuration file provided via '-readconfig' or directly on the
+command line.
+
+If the initiator-name is not specified qemu will use a default name
+of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
+virtual machine. If the UUID is not specified qemu will use
+'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
+virtual machine.
+
+Setting a specific initiator name to use when logging in to the target:
+
+::
+
+  -iscsi initiator-name=iqn.qemu.test:my-initiator
+
+Controlling which type of header digest to negotiate with the target:
+
+::
+
+  -iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
+
+These can also be set via a configuration file:
+
+::
+
+  [iscsi]
+    user = "CHAP username"
+    password = "CHAP password"
+    initiator-name = "iqn.qemu.test:my-initiator"
+    # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
+    header-digest = "CRC32C"
+
+Setting the target name allows different options for different targets:
+
+::
+
+  [iscsi "iqn.target.name"]
+    user = "CHAP username"
+    password = "CHAP password"
+    initiator-name = "iqn.qemu.test:my-initiator"
+    # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
+    header-digest = "CRC32C"
+
+How to use a configuration file to set iSCSI configuration options:
+
+.. parsed-literal::
+
+  cat >iscsi.conf <<EOF
+  [iscsi]
+    user = "me"
+    password = "my password"
+    initiator-name = "iqn.qemu.test:my-initiator"
+    header-digest = "CRC32C"
+  EOF
+
+  |qemu_system| -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \\
+    -readconfig iscsi.conf
+
+How to set up a simple iSCSI target on loopback and access it via QEMU:
+this example shows how to set up an iSCSI target with one CDROM and one DISK
+using the Linux STGT software target. This target is available on Red Hat based
+systems as the package 'scsi-target-utils'.
+
+.. parsed-literal::
+
+  tgtd --iscsi portal=127.0.0.1:3260
+  tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
+  tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \\
+      -b /IMAGES/disk.img --device-type=disk
+  tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \\
+      -b /IMAGES/cd.iso --device-type=cd
+  tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
+
+  |qemu_system| -iscsi initiator-name=iqn.qemu.test:my-initiator \\
+    -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \\
+    -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
+
+GlusterFS disk images
+~~~~~~~~~~~~~~~~~~~~~
+
+GlusterFS is a user space distributed file system.
+
+You can boot from the GlusterFS disk image with the command:
+
+URI:
+
+.. parsed-literal::
+
+  |qemu_system| -drive file=gluster[+TYPE]://[HOST}[:PORT]]/VOLUME/PATH
+                               [?socket=...][,file.debug=9][,file.logfile=...]
+
+JSON:
+
+.. parsed-literal::
+
+  |qemu_system| 'json:{"driver":"qcow2",
+                           "file":{"driver":"gluster",
+                                    "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
+                                    "server":[{"type":"tcp","host":"...","port":"..."},
+                                              {"type":"unix","socket":"..."}]}}'
+
+*gluster* is the protocol.
+
+*TYPE* specifies the transport type used to connect to gluster
+management daemon (glusterd). Valid transport types are
+tcp and unix. In the URI form, if a transport type isn't specified,
+then tcp type is assumed.
+
+*HOST* specifies the server where the volume file specification for
+the given volume resides. This can be either a hostname or an ipv4 address.
+If transport type is unix, then *HOST* field should not be specified.
+Instead *socket* field needs to be populated with the path to unix domain
+socket.
+
+*PORT* is the port number on which glusterd is listening. This is optional
+and if not specified, it defaults to port 24007. If the transport type is unix,
+then *PORT* should not be specified.
+
+*VOLUME* is the name of the gluster volume which contains the disk image.
+
+*PATH* is the path to the actual disk image that resides on gluster volume.
+
+*debug* is the logging level of the gluster protocol driver. Debug levels
+are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
+The default level is 4. The current logging levels defined in the gluster source
+are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
+6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
+
+*logfile* is a commandline option to mention log file path which helps in
+logging to the specified file and also help in persisting the gfapi logs. The
+default is stderr.
+
+You can create a GlusterFS disk image with the command:
+
+.. parsed-literal::
+
+  qemu-img create gluster://HOST/VOLUME/PATH SIZE
+
+Examples
+
+.. parsed-literal::
+
+  |qemu_system| -drive file=gluster://1.2.3.4/testvol/a.img
+  |qemu_system| -drive file=gluster+tcp://1.2.3.4/testvol/a.img
+  |qemu_system| -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
+  |qemu_system| -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
+  |qemu_system| -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
+  |qemu_system| -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
+  |qemu_system| -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
+  |qemu_system| -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
+  |qemu_system| -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
+  |qemu_system| 'json:{"driver":"qcow2",
+                           "file":{"driver":"gluster",
+                                    "volume":"testvol","path":"a.img",
+                                    "debug":9,"logfile":"/var/log/qemu-gluster.log",
+                                    "server":[{"type":"tcp","host":"1.2.3.4","port":24007},
+                                              {"type":"unix","socket":"/var/run/glusterd.socket"}]}}'
+  |qemu_system| -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
+                                       file.debug=9,file.logfile=/var/log/qemu-gluster.log,
+                                       file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
+                                       file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
+
+Secure Shell (ssh) disk images
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can access disk images located on a remote ssh server
+by using the ssh protocol:
+
+.. parsed-literal::
+
+  |qemu_system| -drive file=ssh://[USER@]SERVER[:PORT]/PATH[?host_key_check=HOST_KEY_CHECK]
+
+Alternative syntax using properties:
+
+.. parsed-literal::
+
+  |qemu_system| -drive file.driver=ssh[,file.user=USER],file.host=SERVER[,file.port=PORT],file.path=PATH[,file.host_key_check=HOST_KEY_CHECK]
+
+*ssh* is the protocol.
+
+*USER* is the remote user.  If not specified, then the local
+username is tried.
+
+*SERVER* specifies the remote ssh server.  Any ssh server can be
+used, but it must implement the sftp-server protocol.  Most Unix/Linux
+systems should work without requiring any extra configuration.
+
+*PORT* is the port number on which sshd is listening.  By default
+the standard ssh port (22) is used.
+
+*PATH* is the path to the disk image.
+
+The optional *HOST_KEY_CHECK* parameter controls how the remote
+host's key is checked.  The default is ``yes`` which means to use
+the local ``.ssh/known_hosts`` file.  Setting this to ``no``
+turns off known-hosts checking.  Or you can check that the host key
+matches a specific fingerprint:
+``host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8``
+(``sha1:`` can also be used as a prefix, but note that OpenSSH
+tools only use MD5 to print fingerprints).
+
+Currently authentication must be done using ssh-agent.  Other
+authentication methods may be supported in future.
+
+Note: Many ssh servers do not support an ``fsync``-style operation.
+The ssh driver cannot guarantee that disk flush requests are
+obeyed, and this causes a risk of disk corruption if the remote
+server or network goes down during writes.  The driver will
+print a warning when ``fsync`` is not supported:
+
+::
+
+  warning: ssh server ssh.example.com:22 does not support fsync
+
+With sufficiently new versions of libssh and OpenSSH, ``fsync`` is
+supported.
+
+NVMe disk images
+~~~~~~~~~~~~~~~~
+
+NVM Express (NVMe) storage controllers can be accessed directly by a userspace
+driver in QEMU.  This bypasses the host kernel file system and block layers
+while retaining QEMU block layer functionalities, such as block jobs, I/O
+throttling, image formats, etc.  Disk I/O performance is typically higher than
+with ``-drive file=/dev/sda`` using either thread pool or linux-aio.
+
+The controller will be exclusively used by the QEMU process once started. To be
+able to share storage between multiple VMs and other applications on the host,
+please use the file based protocols.
+
+Before starting QEMU, bind the host NVMe controller to the host vfio-pci
+driver.  For example:
+
+.. parsed-literal::
+
+  # modprobe vfio-pci
+  # lspci -n -s 0000:06:0d.0
+  06:0d.0 0401: 1102:0002 (rev 08)
+  # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
+  # echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
+
+  # |qemu_system| -drive file=nvme://HOST:BUS:SLOT.FUNC/NAMESPACE
+
+Alternative syntax using properties:
+
+.. parsed-literal::
+
+  |qemu_system| -drive file.driver=nvme,file.device=HOST:BUS:SLOT.FUNC,file.namespace=NAMESPACE
+
+*HOST*:*BUS*:*SLOT*.\ *FUNC* is the NVMe controller's PCI device
+address on the host.
+
+*NAMESPACE* is the NVMe namespace number, starting from 1.
+
+Disk image file locking
+~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, QEMU tries to protect image files from unexpected concurrent
+access, as long as it's supported by the block protocol driver and host
+operating system. If multiple QEMU processes (including QEMU emulators and
+utilities) try to open the same image with conflicting accessing modes, all but
+the first one will get an error.
+
+This feature is currently supported by the file protocol on Linux with the Open
+File Descriptor (OFD) locking API, and can be configured to fall back to POSIX
+locking if the POSIX host doesn't support Linux OFD locking.
+
+To explicitly enable image locking, specify "locking=on" in the file protocol
+driver options. If OFD locking is not possible, a warning will be printed and
+the POSIX locking API will be used. In this case there is a risk that the lock
+will get silently lost when doing hot plugging and block jobs, due to the
+shortcomings of the POSIX locking API.
+
+QEMU transparently handles lock handover during shared storage migration.  For
+shared virtual disk images between multiple VMs, the "share-rw" device option
+should be used.
+
+By default, the guest has exclusive write access to its disk image. If the
+guest can safely share the disk image with other writers the
+``-device ...,share-rw=on`` parameter can be used.  This is only safe if
+the guest is running software, such as a cluster file system, that
+coordinates disk accesses to avoid corruption.
+
+Note that share-rw=on only declares the guest's ability to share the disk.
+Some QEMU features, such as image file formats, require exclusive write access
+to the disk image and this is unaffected by the share-rw=on option.
+
+Alternatively, locking can be fully disabled by "locking=off" block device
+option. In the command line, the option is usually in the form of
+"file.locking=off" as the protocol driver is normally placed as a "file" child
+under a format driver. For example:
+
+::
+
+  -blockdev driver=qcow2,file.filename=/path/to/image,file.locking=off,file.driver=file
+
+To check if image locking is active, check the output of the "lslocks" command
+on host and see if there are locks held by the QEMU process on the image file.
+More than one byte could be locked by the QEMU instance, each byte of which
+reflects a particular permission that is acquired or protected by the running
+block driver.
diff --git a/docs/system/qemu-cpu-models.rst b/docs/system/qemu-cpu-models.rst
new file mode 100644 (file)
index 0000000..53d7538
--- /dev/null
@@ -0,0 +1,20 @@
+:orphan:
+
+QEMU / KVM CPU model configuration
+==================================
+
+Synopsis
+''''''''
+
+QEMU CPU Modelling Infrastructure manual
+
+Description
+'''''''''''
+
+.. include:: cpu-models-x86.rst.inc
+.. include:: cpu-models-mips.rst.inc
+
+See also
+''''''''
+
+The HTML documentation of QEMU for more precise information and Linux user mode emulator invocation.
diff --git a/docs/system/qemu-manpage.rst b/docs/system/qemu-manpage.rst
new file mode 100644 (file)
index 0000000..e9a25d0
--- /dev/null
@@ -0,0 +1,45 @@
+:orphan:
+
+..
+   This file is the skeleton for the qemu.1 manpage. It mostly
+   should simply include the .rst.inc files corresponding to the
+   parts of the documentation that go in the manpage as well as the
+   HTML manual.
+
+Title
+=====
+
+Synopsis
+--------
+
+.. parsed-literal::
+
+   |qemu_system| [options] [disk_image]
+
+Description
+-----------
+
+.. include:: target-i386-desc.rst.inc
+
+Options
+-------
+
+disk_image is a raw hard disk image for IDE hard disk 0. Some targets do
+not need a disk image.
+
+.. hxtool-doc:: qemu-options.hx
+
+.. include:: keys.rst.inc
+
+.. include:: mux-chardev.rst.inc
+
+Notes
+-----
+
+.. include:: device-url-syntax.rst.inc
+
+See also
+--------
+
+The HTML documentation of QEMU for more precise information and Linux
+user mode emulator invocation.
diff --git a/docs/system/quickstart.rst b/docs/system/quickstart.rst
new file mode 100644 (file)
index 0000000..3a3acab
--- /dev/null
@@ -0,0 +1,13 @@
+.. _pcsys_005fquickstart:
+
+Quick Start
+-----------
+
+Download and uncompress a PC hard disk image with Linux installed (e.g.
+``linux.img``) and type:
+
+.. parsed-literal::
+
+   |qemu_system| linux.img
+
+Linux should boot and give you a prompt.
diff --git a/docs/system/security.rst b/docs/system/security.rst
new file mode 100644 (file)
index 0000000..f2092c8
--- /dev/null
@@ -0,0 +1,173 @@
+Security
+========
+
+Overview
+--------
+
+This chapter explains the security requirements that QEMU is designed to meet
+and principles for securely deploying QEMU.
+
+Security Requirements
+---------------------
+
+QEMU supports many different use cases, some of which have stricter security
+requirements than others.  The community has agreed on the overall security
+requirements that users may depend on.  These requirements define what is
+considered supported from a security perspective.
+
+Virtualization Use Case
+'''''''''''''''''''''''
+
+The virtualization use case covers cloud and virtual private server (VPS)
+hosting, as well as traditional data center and desktop virtualization.  These
+use cases rely on hardware virtualization extensions to execute guest code
+safely on the physical CPU at close-to-native speed.
+
+The following entities are untrusted, meaning that they may be buggy or
+malicious:
+
+- Guest
+- User-facing interfaces (e.g. VNC, SPICE, WebSocket)
+- Network protocols (e.g. NBD, live migration)
+- User-supplied files (e.g. disk images, kernels, device trees)
+- Passthrough devices (e.g. PCI, USB)
+
+Bugs affecting these entities are evaluated on whether they can cause damage in
+real-world use cases and treated as security bugs if this is the case.
+
+Non-virtualization Use Case
+'''''''''''''''''''''''''''
+
+The non-virtualization use case covers emulation using the Tiny Code Generator
+(TCG).  In principle the TCG and device emulation code used in conjunction with
+the non-virtualization use case should meet the same security requirements as
+the virtualization use case.  However, for historical reasons much of the
+non-virtualization use case code was not written with these security
+requirements in mind.
+
+Bugs affecting the non-virtualization use case are not considered security
+bugs at this time.  Users with non-virtualization use cases must not rely on
+QEMU to provide guest isolation or any security guarantees.
+
+Architecture
+------------
+
+This section describes the design principles that ensure the security
+requirements are met.
+
+Guest Isolation
+'''''''''''''''
+
+Guest isolation is the confinement of guest code to the virtual machine.  When
+guest code gains control of execution on the host this is called escaping the
+virtual machine.  Isolation also includes resource limits such as throttling of
+CPU, memory, disk, or network.  Guests must be unable to exceed their resource
+limits.
+
+QEMU presents an attack surface to the guest in the form of emulated devices.
+The guest must not be able to gain control of QEMU.  Bugs in emulated devices
+could allow malicious guests to gain code execution in QEMU.  At this point the
+guest has escaped the virtual machine and is able to act in the context of the
+QEMU process on the host.
+
+Guests often interact with other guests and share resources with them.  A
+malicious guest must not gain control of other guests or access their data.
+Disk image files and network traffic must be protected from other guests unless
+explicitly shared between them by the user.
+
+Principle of Least Privilege
+''''''''''''''''''''''''''''
+
+The principle of least privilege states that each component only has access to
+the privileges necessary for its function.  In the case of QEMU this means that
+each process only has access to resources belonging to the guest.
+
+The QEMU process should not have access to any resources that are inaccessible
+to the guest.  This way the guest does not gain anything by escaping into the
+QEMU process since it already has access to those same resources from within
+the guest.
+
+Following the principle of least privilege immediately fulfills guest isolation
+requirements.  For example, guest A only has access to its own disk image file
+``a.img`` and not guest B's disk image file ``b.img``.
+
+In reality certain resources are inaccessible to the guest but must be
+available to QEMU to perform its function.  For example, host system calls are
+necessary for QEMU but are not exposed to guests.  A guest that escapes into
+the QEMU process can then begin invoking host system calls.
+
+New features must be designed to follow the principle of least privilege.
+Should this not be possible for technical reasons, the security risk must be
+clearly documented so users are aware of the trade-off of enabling the feature.
+
+Isolation mechanisms
+''''''''''''''''''''
+
+Several isolation mechanisms are available to realize this architecture of
+guest isolation and the principle of least privilege.  With the exception of
+Linux seccomp, these mechanisms are all deployed by management tools that
+launch QEMU, such as libvirt.  They are also platform-specific so they are only
+described briefly for Linux here.
+
+The fundamental isolation mechanism is that QEMU processes must run as
+unprivileged users.  Sometimes it seems more convenient to launch QEMU as
+root to give it access to host devices (e.g. ``/dev/net/tun``) but this poses a
+huge security risk.  File descriptor passing can be used to give an otherwise
+unprivileged QEMU process access to host devices without running QEMU as root.
+It is also possible to launch QEMU as a non-root user and configure UNIX groups
+for access to ``/dev/kvm``, ``/dev/net/tun``, and other device nodes.
+Some Linux distros already ship with UNIX groups for these devices by default.
+
+- SELinux and AppArmor make it possible to confine processes beyond the
+  traditional UNIX process and file permissions model.  They restrict the QEMU
+  process from accessing processes and files on the host system that are not
+  needed by QEMU.
+
+- Resource limits and cgroup controllers provide throughput and utilization
+  limits on key resources such as CPU time, memory, and I/O bandwidth.
+
+- Linux namespaces can be used to make process, file system, and other system
+  resources unavailable to QEMU.  A namespaced QEMU process is restricted to only
+  those resources that were granted to it.
+
+- Linux seccomp is available via the QEMU ``--sandbox`` option.  It disables
+  system calls that are not needed by QEMU, thereby reducing the host kernel
+  attack surface.
+
+Sensitive configurations
+------------------------
+
+There are aspects of QEMU that can have security implications which users &
+management applications must be aware of.
+
+Monitor console (QMP and HMP)
+'''''''''''''''''''''''''''''
+
+The monitor console (whether used with QMP or HMP) provides an interface
+to dynamically control many aspects of QEMU's runtime operation. Many of the
+commands exposed will instruct QEMU to access content on the host file system
+and/or trigger spawning of external processes.
+
+For example, the ``migrate`` command allows for the spawning of arbitrary
+processes for the purpose of tunnelling the migration data stream. The
+``blockdev-add`` command instructs QEMU to open arbitrary files, exposing
+their content to the guest as a virtual disk.
+
+Unless QEMU is otherwise confined using technologies such as SELinux, AppArmor,
+or Linux namespaces, the monitor console should be considered to have privileges
+equivalent to those of the user account QEMU is running under.
+
+It is further important to consider the security of the character device backend
+over which the monitor console is exposed. It needs to have protection against
+malicious third parties which might try to make unauthorized connections, or
+perform man-in-the-middle attacks. Many of the character device backends do not
+satisfy this requirement and so must not be used for the monitor console.
+
+The general recommendation is that the monitor console should be exposed over
+a UNIX domain socket backend to the local host only. Use of the TCP based
+character device backend is inappropriate unless configured to use both TLS
+encryption and authorization control policy on client connections.
+
+In summary, the monitor console is considered a privileged control interface to
+QEMU and as such should only be made accessible to a trusted management
+application or user.
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
new file mode 100644 (file)
index 0000000..1425bd5
--- /dev/null
@@ -0,0 +1,86 @@
+.. _ARM-System-emulator:
+
+Arm System emulator
+-------------------
+
+QEMU can emulate both 32-bit and 64-bit Arm CPUs. Use the
+``qemu-system-aarch64`` executable to simulate a 64-bit Arm machine.
+You can use either ``qemu-system-arm`` or ``qemu-system-aarch64``
+to simulate a 32-bit Arm machine: in general, command lines that
+work for ``qemu-system-arm`` will behave the same when used with
+``qemu-system-aarch64``.
+
+QEMU has generally good support for Arm guests. It has support for
+nearly fifty different machines. The reason we support so many is that
+Arm hardware is much more widely varying than x86 hardware. Arm CPUs
+are generally built into "system-on-chip" (SoC) designs created by
+many different companies with different devices, and these SoCs are
+then built into machines which can vary still further even if they use
+the same SoC. Even with fifty boards QEMU does not cover more than a
+small fraction of the Arm hardware ecosystem.
+
+The situation for 64-bit Arm is fairly similar, except that we don't
+implement so many different machines.
+
+As well as the more common "A-profile" CPUs (which have MMUs and will
+run Linux) QEMU also supports "M-profile" CPUs such as the Cortex-M0,
+Cortex-M4 and Cortex-M33 (which are microcontrollers used in very
+embedded boards). For most boards the CPU type is fixed (matching what
+the hardware has), so typically you don't need to specify the CPU type
+by hand, except for special cases like the ``virt`` board.
+
+Choosing a board model
+======================
+
+For QEMU's Arm system emulation, you must specify which board
+model you want to use with the ``-M`` or ``--machine`` option;
+there is no default.
+
+Because Arm systems differ so much and in fundamental ways, typically
+operating system or firmware images intended to run on one machine
+will not run at all on any other. This is often surprising for new
+users who are used to the x86 world where every system looks like a
+standard PC. (Once the kernel has booted, most userspace software
+cares much less about the detail of the hardware.)
+
+If you already have a system image or a kernel that works on hardware
+and you want to boot with QEMU, check whether QEMU lists that machine
+in its ``-machine help`` output. If it is listed, then you can probably
+use that board model. If it is not listed, then unfortunately your image
+will almost certainly not boot on QEMU. (You might be able to
+extract the filesystem and use that with a different kernel which
+boots on a system that QEMU does emulate.)
+
+If you don't care about reproducing the idiosyncrasies of a particular
+bit of hardware, such as small amount of RAM, no PCI or other hard
+disk, etc., and just want to run Linux, the best option is to use the
+``virt`` board. This is a platform which doesn't correspond to any
+real hardware and is designed for use in virtual machines. You'll
+need to compile Linux with a suitable configuration for running on
+the ``virt`` board. ``virt`` supports PCI, virtio, recent CPUs and
+large amounts of RAM. It also supports 64-bit CPUs.
+
+Board-specific documentation
+============================
+
+Unfortunately many of the Arm boards QEMU supports are currently
+undocumented; you can get a complete list by running
+``qemu-system-aarch64 --machine help``.
+
+.. toctree::
+
+   arm/integratorcp
+   arm/versatile
+   arm/realview
+   arm/xscale
+   arm/palm
+   arm/nseries
+   arm/stellaris
+   arm/musicpal
+   arm/sx1
+
+Arm CPU features
+================
+
+.. toctree::
+   arm/cpu-features
diff --git a/docs/system/target-i386-desc.rst.inc b/docs/system/target-i386-desc.rst.inc
new file mode 100644 (file)
index 0000000..47a169e
--- /dev/null
@@ -0,0 +1,62 @@
+The QEMU PC System emulator simulates the following peripherals:
+
+-  i440FX host PCI bridge and PIIX3 PCI to ISA bridge
+
+-  Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA
+   extensions (hardware level, including all non standard modes).
+
+-  PS/2 mouse and keyboard
+
+-  2 PCI IDE interfaces with hard disk and CD-ROM support
+
+-  Floppy disk
+
+-  PCI and ISA network adapters
+
+-  Serial ports
+
+-  IPMI BMC, either and internal or external one
+
+-  Creative SoundBlaster 16 sound card
+
+-  ENSONIQ AudioPCI ES1370 sound card
+
+-  Intel 82801AA AC97 Audio compatible sound card
+
+-  Intel HD Audio Controller and HDA codec
+
+-  Adlib (OPL2) - Yamaha YM3812 compatible chip
+
+-  Gravis Ultrasound GF1 sound card
+
+-  CS4231A compatible sound card
+
+-  PCI UHCI, OHCI, EHCI or XHCI USB controller and a virtual USB-1.1
+   hub.
+
+SMP is supported with up to 255 CPUs.
+
+QEMU uses the PC BIOS from the Seabios project and the Plex86/Bochs LGPL
+VGA BIOS.
+
+QEMU uses YM3812 emulation by Tatsuyuki Satoh.
+
+QEMU uses GUS emulation (GUSEMU32 http://www.deinmeister.de/gusemu/) by
+Tibor \"TS\" Schütz.
+
+Note that, by default, GUS shares IRQ(7) with parallel ports and so QEMU
+must be told to not have parallel ports to have working GUS.
+
+.. parsed-literal::
+
+   |qemu_system_x86| dos.img -soundhw gus -parallel none
+
+Alternatively:
+
+.. parsed-literal::
+
+   |qemu_system_x86| dos.img -device gus,irq=5
+
+Or some other unclaimed IRQ.
+
+CS4231A is the chip used in Windows Sound System and GUSMAX products
diff --git a/docs/system/target-i386.rst b/docs/system/target-i386.rst
new file mode 100644 (file)
index 0000000..51be03d
--- /dev/null
@@ -0,0 +1,23 @@
+.. _QEMU-PC-System-emulator:
+
+x86 (PC) System emulator
+------------------------
+
+.. _pcsys_005fdevices:
+
+Peripherals
+~~~~~~~~~~~
+
+.. include:: target-i386-desc.rst.inc
+
+.. include:: cpu-models-x86.rst.inc
+
+.. _pcsys_005freq:
+
+OS requirements
+~~~~~~~~~~~~~~~
+
+On x86_64 hosts, the default set of CPU features enabled by the KVM
+accelerator require the host to be running Linux v4.5 or newer. Red Hat
+Enterprise Linux 7 is also supported, since the required
+functionality was backported.
diff --git a/docs/system/target-m68k.rst b/docs/system/target-m68k.rst
new file mode 100644 (file)
index 0000000..d28d3b9
--- /dev/null
@@ -0,0 +1,21 @@
+.. _ColdFire-System-emulator:
+
+ColdFire System emulator
+------------------------
+
+Use the executable ``qemu-system-m68k`` to simulate a ColdFire machine.
+The emulator is able to boot a uClinux kernel.
+
+The M5208EVB emulation includes the following devices:
+
+-  MCF5208 ColdFire V2 Microprocessor (ISA A+ with EMAC).
+
+-  Three Two on-chip UARTs.
+
+-  Fast Ethernet Controller (FEC)
+
+The AN5206 emulation includes the following devices:
+
+-  MCF5206 ColdFire V2 Microprocessor.
+
+-  Two on-chip UARTs.
diff --git a/docs/system/target-mips.rst b/docs/system/target-mips.rst
new file mode 100644 (file)
index 0000000..2736fd0
--- /dev/null
@@ -0,0 +1,120 @@
+.. _MIPS-System-emulator:
+
+MIPS System emulator
+--------------------
+
+Four executables cover simulation of 32 and 64-bit MIPS systems in both
+endian options, ``qemu-system-mips``, ``qemu-system-mipsel``
+``qemu-system-mips64`` and ``qemu-system-mips64el``. Five different
+machine types are emulated:
+
+-  A generic ISA PC-like machine \"mips\"
+
+-  The MIPS Malta prototype board \"malta\"
+
+-  An ACER Pica \"pica61\". This machine needs the 64-bit emulator.
+
+-  MIPS emulator pseudo board \"mipssim\"
+
+-  A MIPS Magnum R4000 machine \"magnum\". This machine needs the
+   64-bit emulator.
+
+The generic emulation is supported by Debian 'Etch' and is able to
+install Debian into a virtual disk image. The following devices are
+emulated:
+
+-  A range of MIPS CPUs, default is the 24Kf
+
+-  PC style serial port
+
+-  PC style IDE disk
+
+-  NE2000 network card
+
+The Malta emulation supports the following devices:
+
+-  Core board with MIPS 24Kf CPU and Galileo system controller
+
+-  PIIX4 PCI/USB/SMbus controller
+
+-  The Multi-I/O chip's serial device
+
+-  PCI network cards (PCnet32 and others)
+
+-  Malta FPGA serial device
+
+-  Cirrus (default) or any other PCI VGA graphics card
+
+The Boston board emulation supports the following devices:
+
+-  Xilinx FPGA, which includes a PCIe root port and an UART
+
+-  Intel EG20T PCH connects the I/O peripherals, but only the SATA bus
+   is emulated
+
+The ACER Pica emulation supports:
+
+-  MIPS R4000 CPU
+
+-  PC-style IRQ and DMA controllers
+
+-  PC Keyboard
+
+-  IDE controller
+
+The MIPS Magnum R4000 emulation supports:
+
+-  MIPS R4000 CPU
+
+-  PC-style IRQ controller
+
+-  PC Keyboard
+
+-  SCSI controller
+
+-  G364 framebuffer
+
+The Fulong 2E emulation supports:
+
+-  Loongson 2E CPU
+
+-  Bonito64 system controller as North Bridge
+
+-  VT82C686 chipset as South Bridge
+
+-  RTL8139D as a network card chipset
+
+The mipssim pseudo board emulation provides an environment similar to
+what the proprietary MIPS emulator uses for running Linux. It supports:
+
+-  A range of MIPS CPUs, default is the 24Kf
+
+-  PC style serial port
+
+-  MIPSnet network emulation
+
+.. include:: cpu-models-mips.rst.inc
+
+.. _nanoMIPS-System-emulator:
+
+nanoMIPS System emulator
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Executable ``qemu-system-mipsel`` also covers simulation of 32-bit
+nanoMIPS system in little endian mode:
+
+-  nanoMIPS I7200 CPU
+
+Example of ``qemu-system-mipsel`` usage for nanoMIPS is shown below:
+
+Download ``<disk_image_file>`` from
+https://mipsdistros.mips.com/LinuxDistro/nanomips/buildroot/index.html.
+
+Download ``<kernel_image_file>`` from
+https://mipsdistros.mips.com/LinuxDistro/nanomips/kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/index.html.
+
+Start system emulation of Malta board with nanoMIPS I7200 CPU::
+
+   qemu-system-mipsel -cpu I7200 -kernel <kernel_image_file> \
+       -M malta -serial stdio -m <memory_size> -hda <disk_image_file> \
+       -append "mem=256m@0x0 rw console=ttyS0 vga=cirrus vesa=0x111 root=/dev/sda"
diff --git a/docs/system/target-ppc.rst b/docs/system/target-ppc.rst
new file mode 100644 (file)
index 0000000..a2f04c5
--- /dev/null
@@ -0,0 +1,47 @@
+.. _PowerPC-System-emulator:
+
+PowerPC System emulator
+-----------------------
+
+Use the executable ``qemu-system-ppc`` to simulate a complete 40P (PREP)
+or PowerMac PowerPC system.
+
+QEMU emulates the following PowerMac peripherals:
+
+-  UniNorth or Grackle PCI Bridge
+
+-  PCI VGA compatible card with VESA Bochs Extensions
+
+-  2 PMAC IDE interfaces with hard disk and CD-ROM support
+
+-  NE2000 PCI adapters
+
+-  Non Volatile RAM
+
+-  VIA-CUDA with ADB keyboard and mouse.
+
+QEMU emulates the following 40P (PREP) peripherals:
+
+-  PCI Bridge
+
+-  PCI VGA compatible card with VESA Bochs Extensions
+
+-  2 IDE interfaces with hard disk and CD-ROM support
+
+-  Floppy disk
+
+-  PCnet network adapters
+
+-  Serial port
+
+-  PREP Non Volatile RAM
+
+-  PC compatible keyboard and mouse.
+
+Since version 0.9.1, QEMU uses OpenBIOS https://www.openbios.org/ for
+the g3beige and mac99 PowerMac and the 40p machines. OpenBIOS is a free
+(GPL v2) portable firmware implementation. The goal is to implement a
+100% IEEE 1275-1994 (referred to as Open Firmware) compliant firmware.
+
+More information is available at
+http://perso.magic.fr/l_indien/qemu-ppc/.
diff --git a/docs/system/target-sparc.rst b/docs/system/target-sparc.rst
new file mode 100644 (file)
index 0000000..b55f8d0
--- /dev/null
@@ -0,0 +1,62 @@
+.. _Sparc32-System-emulator:
+
+Sparc32 System emulator
+-----------------------
+
+Use the executable ``qemu-system-sparc`` to simulate the following Sun4m
+architecture machines:
+
+-  SPARCstation 4
+
+-  SPARCstation 5
+
+-  SPARCstation 10
+
+-  SPARCstation 20
+
+-  SPARCserver 600MP
+
+-  SPARCstation LX
+
+-  SPARCstation Voyager
+
+-  SPARCclassic
+
+-  SPARCbook
+
+The emulation is somewhat complete. SMP up to 16 CPUs is supported, but
+Linux limits the number of usable CPUs to 4.
+
+QEMU emulates the following sun4m peripherals:
+
+-  IOMMU
+
+-  TCX or cgthree Frame buffer
+
+-  Lance (Am7990) Ethernet
+
+-  Non Volatile RAM M48T02/M48T08
+
+-  Slave I/O: timers, interrupt controllers, Zilog serial ports,
+   keyboard and power/reset logic
+
+-  ESP SCSI controller with hard disk and CD-ROM support
+
+-  Floppy drive (not on SS-600MP)
+
+-  CS4231 sound device (only on SS-5, not working yet)
+
+The number of peripherals is fixed in the architecture. Maximum memory
+size depends on the machine type, for SS-5 it is 256MB and for others
+2047MB.
+
+Since version 0.8.2, QEMU uses OpenBIOS https://www.openbios.org/.
+OpenBIOS is a free (GPL v2) portable firmware implementation. The goal
+is to implement a 100% IEEE 1275-1994 (referred to as Open Firmware)
+compliant firmware.
+
+A sample Linux 2.6 series kernel and ram disk image are available on the
+QEMU web site. There are still issues with NetBSD and OpenBSD, but most
+kernel versions work. Please note that currently older Solaris kernels
+don't work probably due to interface issues between OpenBIOS and
+Solaris.
diff --git a/docs/system/target-sparc64.rst b/docs/system/target-sparc64.rst
new file mode 100644 (file)
index 0000000..97e334b
--- /dev/null
@@ -0,0 +1,37 @@
+.. _Sparc64-System-emulator:
+
+Sparc64 System emulator
+-----------------------
+
+Use the executable ``qemu-system-sparc64`` to simulate a Sun4u
+(UltraSPARC PC-like machine), Sun4v (T1 PC-like machine), or generic
+Niagara (T1) machine. The Sun4u emulator is mostly complete, being able
+to run Linux, NetBSD and OpenBSD in headless (-nographic) mode. The
+Sun4v emulator is still a work in progress.
+
+The Niagara T1 emulator makes use of firmware and OS binaries supplied
+in the S10image/ directory of the OpenSPARC T1 project
+http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
+and is able to boot the disk.s10hw2 Solaris image.
+
+::
+
+   qemu-system-sparc64 -M niagara -L /path-to/S10image/ \
+                       -nographic -m 256 \
+                       -drive if=pflash,readonly=on,file=/S10image/disk.s10hw2
+
+QEMU emulates the following peripherals:
+
+-  UltraSparc IIi APB PCI Bridge
+
+-  PCI VGA compatible card with VESA Bochs Extensions
+
+-  PS/2 mouse and keyboard
+
+-  Non Volatile RAM M48T59
+
+-  PC-compatible serial ports
+
+-  2 PCI IDE interfaces with hard disk and CD-ROM support
+
+-  Floppy disk
diff --git a/docs/system/target-xtensa.rst b/docs/system/target-xtensa.rst
new file mode 100644 (file)
index 0000000..8d703ad
--- /dev/null
@@ -0,0 +1,27 @@
+.. _Xtensa-System-emulator:
+
+Xtensa System emulator
+----------------------
+
+Two executables cover simulation of both Xtensa endian options,
+``qemu-system-xtensa`` and ``qemu-system-xtensaeb``. Two different
+machine types are emulated:
+
+-  Xtensa emulator pseudo board \"sim\"
+
+-  Avnet LX60/LX110/LX200 board
+
+The sim pseudo board emulation provides an environment similar to one
+provided by the proprietary Tensilica ISS. It supports:
+
+-  A range of Xtensa CPUs, default is the DC232B
+
+-  Console and filesystem access via semihosting calls
+
+The Avnet LX60/LX110/LX200 emulation supports:
+
+-  A range of Xtensa CPUs, default is the DC232B
+
+-  16550 UART
+
+-  OpenCores 10/100 Mbps Ethernet MAC
diff --git a/docs/system/targets.rst b/docs/system/targets.rst
new file mode 100644 (file)
index 0000000..eba3111
--- /dev/null
@@ -0,0 +1,19 @@
+QEMU System Emulator Targets
+============================
+
+QEMU is a generic emulator and it emulates many machines. Most of the
+options are similar for all machines. Specific information about the
+various targets are mentioned in the following sections.
+
+Contents:
+
+.. toctree::
+
+   target-i386
+   target-ppc
+   target-sparc
+   target-sparc64
+   target-mips
+   target-arm
+   target-m68k
+   target-xtensa
diff --git a/docs/system/tls.rst b/docs/system/tls.rst
new file mode 100644 (file)
index 0000000..dc2b942
--- /dev/null
@@ -0,0 +1,328 @@
+.. _network_005ftls:
+
+TLS setup for network services
+------------------------------
+
+Almost all network services in QEMU have the ability to use TLS for
+session data encryption, along with x509 certificates for simple client
+authentication. What follows is a description of how to generate
+certificates suitable for usage with QEMU, and applies to the VNC
+server, character devices with the TCP backend, NBD server and client,
+and migration server and client.
+
+At a high level, QEMU requires certificates and private keys to be
+provided in PEM format. Aside from the core fields, the certificates
+should include various extension data sets, including v3 basic
+constraints data, key purpose, key usage and subject alt name.
+
+The GnuTLS package includes a command called ``certtool`` which can be
+used to easily generate certificates and keys in the required format
+with expected data present. Alternatively a certificate management
+service may be used.
+
+At a minimum it is necessary to setup a certificate authority, and issue
+certificates to each server. If using x509 certificates for
+authentication, then each client will also need to be issued a
+certificate.
+
+Assuming that the QEMU network services will only ever be exposed to
+clients on a private intranet, there is no need to use a commercial
+certificate authority to create certificates. A self-signed CA is
+sufficient, and in fact likely to be more secure since it removes the
+ability of malicious 3rd parties to trick the CA into mis-issuing certs
+for impersonating your services. The only likely exception where a
+commercial CA might be desirable is if enabling the VNC websockets
+server and exposing it directly to remote browser clients. In such a
+case it might be useful to use a commercial CA to avoid needing to
+install custom CA certs in the web browsers.
+
+The recommendation is for the server to keep its certificates in either
+``/etc/pki/qemu`` or for unprivileged users in ``$HOME/.pki/qemu``.
+
+.. _tls_005fgenerate_005fca:
+
+Setup the Certificate Authority
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This step only needs to be performed once per organization /
+organizational unit. First the CA needs a private key. This key must be
+kept VERY secret and secure. If this key is compromised the entire trust
+chain of the certificates issued with it is lost.
+
+::
+
+   # certtool --generate-privkey > ca-key.pem
+
+To generate a self-signed certificate requires one core piece of
+information, the name of the organization. A template file ``ca.info``
+should be populated with the desired data to avoid having to deal with
+interactive prompts from certtool::
+
+   # cat > ca.info <<EOF
+   cn = Name of your organization
+   ca
+   cert_signing_key
+   EOF
+   # certtool --generate-self-signed \
+              --load-privkey ca-key.pem
+              --template ca.info \
+              --outfile ca-cert.pem
+
+The ``ca`` keyword in the template sets the v3 basic constraints
+extension to indicate this certificate is for a CA, while
+``cert_signing_key`` sets the key usage extension to indicate this will
+be used for signing other keys. The generated ``ca-cert.pem`` file
+should be copied to all servers and clients wishing to utilize TLS
+support in the VNC server. The ``ca-key.pem`` must not be
+disclosed/copied anywhere except the host responsible for issuing
+certificates.
+
+.. _tls_005fgenerate_005fserver:
+
+Issuing server certificates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each server (or host) needs to be issued with a key and certificate.
+When connecting the certificate is sent to the client which validates it
+against the CA certificate. The core pieces of information for a server
+certificate are the hostnames and/or IP addresses that will be used by
+clients when connecting. The hostname / IP address that the client
+specifies when connecting will be validated against the hostname(s) and
+IP address(es) recorded in the server certificate, and if no match is
+found the client will close the connection.
+
+Thus it is recommended that the server certificate include both the
+fully qualified and unqualified hostnames. If the server will have
+permanently assigned IP address(es), and clients are likely to use them
+when connecting, they may also be included in the certificate. Both IPv4
+and IPv6 addresses are supported. Historically certificates only
+included 1 hostname in the ``CN`` field, however, usage of this field
+for validation is now deprecated. Instead modern TLS clients will
+validate against the Subject Alt Name extension data, which allows for
+multiple entries. In the future usage of the ``CN`` field may be
+discontinued entirely, so providing SAN extension data is strongly
+recommended.
+
+On the host holding the CA, create template files containing the
+information for each server, and use it to issue server certificates.
+
+::
+
+   # cat > server-hostNNN.info <<EOF
+   organization = Name  of your organization
+   cn = hostNNN.foo.example.com
+   dns_name = hostNNN
+   dns_name = hostNNN.foo.example.com
+   ip_address = 10.0.1.87
+   ip_address = 192.8.0.92
+   ip_address = 2620:0:cafe::87
+   ip_address = 2001:24::92
+   tls_www_server
+   encryption_key
+   signing_key
+   EOF
+   # certtool --generate-privkey > server-hostNNN-key.pem
+   # certtool --generate-certificate \
+              --load-ca-certificate ca-cert.pem \
+              --load-ca-privkey ca-key.pem \
+              --load-privkey server-hostNNN-key.pem \
+              --template server-hostNNN.info \
+              --outfile server-hostNNN-cert.pem
+
+The ``dns_name`` and ``ip_address`` fields in the template are setting
+the subject alt name extension data. The ``tls_www_server`` keyword is
+the key purpose extension to indicate this certificate is intended for
+usage in a web server. Although QEMU network services are not in fact
+HTTP servers (except for VNC websockets), setting this key purpose is
+still recommended. The ``encryption_key`` and ``signing_key`` keyword is
+the key usage extension to indicate this certificate is intended for
+usage in the data session.
+
+The ``server-hostNNN-key.pem`` and ``server-hostNNN-cert.pem`` files
+should now be securely copied to the server for which they were
+generated, and renamed to ``server-key.pem`` and ``server-cert.pem``
+when added to the ``/etc/pki/qemu`` directory on the target host. The
+``server-key.pem`` file is security sensitive and should be kept
+protected with file mode 0600 to prevent disclosure.
+
+.. _tls_005fgenerate_005fclient:
+
+Issuing client certificates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The QEMU x509 TLS credential setup defaults to enabling client
+verification using certificates, providing a simple authentication
+mechanism. If this default is used, each client also needs to be issued
+a certificate. The client certificate contains enough metadata to
+uniquely identify the client with the scope of the certificate
+authority. The client certificate would typically include fields for
+organization, state, city, building, etc.
+
+Once again on the host holding the CA, create template files containing
+the information for each client, and use it to issue client
+certificates.
+
+::
+
+   # cat > client-hostNNN.info <<EOF
+   country = GB
+   state = London
+   locality = City Of London
+   organization = Name of your organization
+   cn = hostNNN.foo.example.com
+   tls_www_client
+   encryption_key
+   signing_key
+   EOF
+   # certtool --generate-privkey > client-hostNNN-key.pem
+   # certtool --generate-certificate \
+              --load-ca-certificate ca-cert.pem \
+              --load-ca-privkey ca-key.pem \
+              --load-privkey client-hostNNN-key.pem \
+              --template client-hostNNN.info \
+              --outfile client-hostNNN-cert.pem
+
+The subject alt name extension data is not required for clients, so the
+the ``dns_name`` and ``ip_address`` fields are not included. The
+``tls_www_client`` keyword is the key purpose extension to indicate this
+certificate is intended for usage in a web client. Although QEMU network
+clients are not in fact HTTP clients, setting this key purpose is still
+recommended. The ``encryption_key`` and ``signing_key`` keyword is the
+key usage extension to indicate this certificate is intended for usage
+in the data session.
+
+The ``client-hostNNN-key.pem`` and ``client-hostNNN-cert.pem`` files
+should now be securely copied to the client for which they were
+generated, and renamed to ``client-key.pem`` and ``client-cert.pem``
+when added to the ``/etc/pki/qemu`` directory on the target host. The
+``client-key.pem`` file is security sensitive and should be kept
+protected with file mode 0600 to prevent disclosure.
+
+If a single host is going to be using TLS in both a client and server
+role, it is possible to create a single certificate to cover both roles.
+This would be quite common for the migration and NBD services, where a
+QEMU process will be started by accepting a TLS protected incoming
+migration, and later itself be migrated out to another host. To generate
+a single certificate, simply include the template data from both the
+client and server instructions in one.
+
+::
+
+   # cat > both-hostNNN.info <<EOF
+   country = GB
+   state = London
+   locality = City Of London
+   organization = Name of your organization
+   cn = hostNNN.foo.example.com
+   dns_name = hostNNN
+   dns_name = hostNNN.foo.example.com
+   ip_address = 10.0.1.87
+   ip_address = 192.8.0.92
+   ip_address = 2620:0:cafe::87
+   ip_address = 2001:24::92
+   tls_www_server
+   tls_www_client
+   encryption_key
+   signing_key
+   EOF
+   # certtool --generate-privkey > both-hostNNN-key.pem
+   # certtool --generate-certificate \
+              --load-ca-certificate ca-cert.pem \
+              --load-ca-privkey ca-key.pem \
+              --load-privkey both-hostNNN-key.pem \
+              --template both-hostNNN.info \
+              --outfile both-hostNNN-cert.pem
+
+When copying the PEM files to the target host, save them twice, once as
+``server-cert.pem`` and ``server-key.pem``, and again as
+``client-cert.pem`` and ``client-key.pem``.
+
+.. _tls_005fcreds_005fsetup:
+
+TLS x509 credential configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+QEMU has a standard mechanism for loading x509 credentials that will be
+used for network services and clients. It requires specifying the
+``tls-creds-x509`` class name to the ``--object`` command line argument
+for the system emulators. Each set of credentials loaded should be given
+a unique string identifier via the ``id`` parameter. A single set of TLS
+credentials can be used for multiple network backends, so VNC,
+migration, NBD, character devices can all share the same credentials.
+Note, however, that credentials for use in a client endpoint must be
+loaded separately from those used in a server endpoint.
+
+When specifying the object, the ``dir`` parameters specifies which
+directory contains the credential files. This directory is expected to
+contain files with the names mentioned previously, ``ca-cert.pem``,
+``server-key.pem``, ``server-cert.pem``, ``client-key.pem`` and
+``client-cert.pem`` as appropriate. It is also possible to include a set
+of pre-generated Diffie-Hellman (DH) parameters in a file
+``dh-params.pem``, which can be created using the
+``certtool --generate-dh-params`` command. If omitted, QEMU will
+dynamically generate DH parameters when loading the credentials.
+
+The ``endpoint`` parameter indicates whether the credentials will be
+used for a network client or server, and determines which PEM files are
+loaded.
+
+The ``verify`` parameter determines whether x509 certificate validation
+should be performed. This defaults to enabled, meaning clients will
+always validate the server hostname against the certificate subject alt
+name fields and/or CN field. It also means that servers will request
+that clients provide a certificate and validate them. Verification
+should never be turned off for client endpoints, however, it may be
+turned off for server endpoints if an alternative mechanism is used to
+authenticate clients. For example, the VNC server can use SASL to
+authenticate clients instead.
+
+To load server credentials with client certificate validation enabled
+
+.. parsed-literal::
+
+   |qemu_system| -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server
+
+while to load client credentials use
+
+.. parsed-literal::
+
+   |qemu_system| -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=client
+
+Network services which support TLS will all have a ``tls-creds``
+parameter which expects the ID of the TLS credentials object. For
+example with VNC:
+
+.. parsed-literal::
+
+   |qemu_system| -vnc 0.0.0.0:0,tls-creds=tls0
+
+.. _tls_005fpsk:
+
+TLS Pre-Shared Keys (PSK)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Instead of using certificates, you may also use TLS Pre-Shared Keys
+(TLS-PSK). This can be simpler to set up than certificates but is less
+scalable.
+
+Use the GnuTLS ``psktool`` program to generate a ``keys.psk`` file
+containing one or more usernames and random keys::
+
+   mkdir -m 0700 /tmp/keys
+   psktool -u rich -p /tmp/keys/keys.psk
+
+TLS-enabled servers such as qemu-nbd can use this directory like so::
+
+   qemu-nbd \
+     -t -x / \
+     --object tls-creds-psk,id=tls0,endpoint=server,dir=/tmp/keys \
+     --tls-creds tls0 \
+     image.qcow2
+
+When connecting from a qemu-based client you must specify the directory
+containing ``keys.psk`` and an optional username (defaults to "qemu")::
+
+   qemu-img info \
+     --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=rich,endpoint=client \
+     --image-opts \
+     file.driver=nbd,file.host=localhost,file.port=10809,file.tls-creds=tls0,file.export=/
diff --git a/docs/system/usb.rst b/docs/system/usb.rst
new file mode 100644 (file)
index 0000000..ddfa828
--- /dev/null
@@ -0,0 +1,137 @@
+.. _pcsys_005fusb:
+
+USB emulation
+-------------
+
+QEMU can emulate a PCI UHCI, OHCI, EHCI or XHCI USB controller. You can
+plug virtual USB devices or real host USB devices (only works with
+certain host operating systems). QEMU will automatically create and
+connect virtual USB hubs as necessary to connect multiple USB devices.
+
+.. _usb_005fdevices:
+
+Connecting USB devices
+~~~~~~~~~~~~~~~~~~~~~~
+
+USB devices can be connected with the ``-device usb-...`` command line
+option or the ``device_add`` monitor command. Available devices are:
+
+``usb-mouse``
+   Virtual Mouse. This will override the PS/2 mouse emulation when
+   activated.
+
+``usb-tablet``
+   Pointer device that uses absolute coordinates (like a touchscreen).
+   This means QEMU is able to report the mouse position without having
+   to grab the mouse. Also overrides the PS/2 mouse emulation when
+   activated.
+
+``usb-storage,drive=drive_id``
+   Mass storage device backed by drive_id (see
+   :ref:`disk_005fimages`)
+
+``usb-uas``
+   USB attached SCSI device, see
+   `usb-storage.txt <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt>`__
+   for details
+
+``usb-bot``
+   Bulk-only transport storage device, see
+   `usb-storage.txt <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt>`__
+   for details here, too
+
+``usb-mtp,rootdir=dir``
+   Media transfer protocol device, using dir as root of the file tree
+   that is presented to the guest.
+
+``usb-host,hostbus=bus,hostaddr=addr``
+   Pass through the host device identified by bus and addr
+
+``usb-host,vendorid=vendor,productid=product``
+   Pass through the host device identified by vendor and product ID
+
+``usb-wacom-tablet``
+   Virtual Wacom PenPartner tablet. This device is similar to the
+   ``tablet`` above but it can be used with the tslib library because in
+   addition to touch coordinates it reports touch pressure.
+
+``usb-kbd``
+   Standard USB keyboard. Will override the PS/2 keyboard (if present).
+
+``usb-serial,chardev=id``
+   Serial converter. This emulates an FTDI FT232BM chip connected to
+   host character device id.
+
+``usb-braille,chardev=id``
+   Braille device. This will use BrlAPI to display the braille output on
+   a real or fake device referenced by id.
+
+``usb-net[,netdev=id]``
+   Network adapter that supports CDC ethernet and RNDIS protocols. id
+   specifies a netdev defined with ``-netdev …,id=id``. For instance,
+   user-mode networking can be used with
+
+   .. parsed-literal::
+
+      |qemu_system| [...] -netdev user,id=net0 -device usb-net,netdev=net0
+
+``usb-ccid``
+   Smartcard reader device
+
+``usb-audio``
+   USB audio device
+
+.. _host_005fusb_005fdevices:
+
+Using host USB devices on a Linux host
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+WARNING: this is an experimental feature. QEMU will slow down when using
+it. USB devices requiring real time streaming (i.e. USB Video Cameras)
+are not supported yet.
+
+1. If you use an early Linux 2.4 kernel, verify that no Linux driver is
+   actually using the USB device. A simple way to do that is simply to
+   disable the corresponding kernel module by renaming it from
+   ``mydriver.o`` to ``mydriver.o.disabled``.
+
+2. Verify that ``/proc/bus/usb`` is working (most Linux distributions
+   should enable it by default). You should see something like that:
+
+   ::
+
+      ls /proc/bus/usb
+      001  devices  drivers
+
+3. Since only root can access to the USB devices directly, you can
+   either launch QEMU as root or change the permissions of the USB
+   devices you want to use. For testing, the following suffices:
+
+   ::
+
+      chown -R myuid /proc/bus/usb
+
+4. Launch QEMU and do in the monitor:
+
+   ::
+
+      info usbhost
+        Device 1.2, speed 480 Mb/s
+          Class 00: USB device 1234:5678, USB DISK
+
+   You should see the list of the devices you can use (Never try to use
+   hubs, it won't work).
+
+5. Add the device in QEMU by using:
+
+   ::
+
+      device_add usb-host,vendorid=0x1234,productid=0x5678
+
+   Normally the guest OS should report that a new USB device is plugged.
+   You can use the option ``-device usb-host,...`` to do the same.
+
+6. Now you can try to use the host USB device in QEMU.
+
+When relaunching QEMU, you may have to unplug and plug again the USB
+device to make it work again (this is a bug).
diff --git a/docs/system/vnc-security.rst b/docs/system/vnc-security.rst
new file mode 100644 (file)
index 0000000..b237b07
--- /dev/null
@@ -0,0 +1,202 @@
+.. _vnc_005fsecurity:
+
+VNC security
+------------
+
+The VNC server capability provides access to the graphical console of
+the guest VM across the network. This has a number of security
+considerations depending on the deployment scenarios.
+
+.. _vnc_005fsec_005fnone:
+
+Without passwords
+~~~~~~~~~~~~~~~~~
+
+The simplest VNC server setup does not include any form of
+authentication. For this setup it is recommended to restrict it to
+listen on a UNIX domain socket only. For example
+
+.. parsed-literal::
+
+   |qemu_system| [...OPTIONS...] -vnc unix:/home/joebloggs/.qemu-myvm-vnc
+
+This ensures that only users on local box with read/write access to that
+path can access the VNC server. To securely access the VNC server from a
+remote machine, a combination of netcat+ssh can be used to provide a
+secure tunnel.
+
+.. _vnc_005fsec_005fpassword:
+
+With passwords
+~~~~~~~~~~~~~~
+
+The VNC protocol has limited support for password based authentication.
+Since the protocol limits passwords to 8 characters it should not be
+considered to provide high security. The password can be fairly easily
+brute-forced by a client making repeat connections. For this reason, a
+VNC server using password authentication should be restricted to only
+listen on the loopback interface or UNIX domain sockets. Password
+authentication is not supported when operating in FIPS 140-2 compliance
+mode as it requires the use of the DES cipher. Password authentication
+is requested with the ``password`` option, and then once QEMU is running
+the password is set with the monitor. Until the monitor is used to set
+the password all clients will be rejected.
+
+.. parsed-literal::
+
+   |qemu_system| [...OPTIONS...] -vnc :1,password -monitor stdio
+   (qemu) change vnc password
+   Password: ********
+   (qemu)
+
+.. _vnc_005fsec_005fcertificate:
+
+With x509 certificates
+~~~~~~~~~~~~~~~~~~~~~~
+
+The QEMU VNC server also implements the VeNCrypt extension allowing use
+of TLS for encryption of the session, and x509 certificates for
+authentication. The use of x509 certificates is strongly recommended,
+because TLS on its own is susceptible to man-in-the-middle attacks.
+Basic x509 certificate support provides a secure session, but no
+authentication. This allows any client to connect, and provides an
+encrypted session.
+
+.. parsed-literal::
+
+   |qemu_system| [...OPTIONS...] \
+     -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=no \
+     -vnc :1,tls-creds=tls0 -monitor stdio
+
+In the above example ``/etc/pki/qemu`` should contain at least three
+files, ``ca-cert.pem``, ``server-cert.pem`` and ``server-key.pem``.
+Unprivileged users will want to use a private directory, for example
+``$HOME/.pki/qemu``. NB the ``server-key.pem`` file should be protected
+with file mode 0600 to only be readable by the user owning it.
+
+.. _vnc_005fsec_005fcertificate_005fverify:
+
+With x509 certificates and client verification
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Certificates can also provide a means to authenticate the client
+connecting. The server will request that the client provide a
+certificate, which it will then validate against the CA certificate.
+This is a good choice if deploying in an environment with a private
+internal certificate authority. It uses the same syntax as previously,
+but with ``verify-peer`` set to ``yes`` instead.
+
+.. parsed-literal::
+
+   |qemu_system| [...OPTIONS...] \
+     -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
+     -vnc :1,tls-creds=tls0 -monitor stdio
+
+.. _vnc_005fsec_005fcertificate_005fpw:
+
+With x509 certificates, client verification and passwords
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Finally, the previous method can be combined with VNC password
+authentication to provide two layers of authentication for clients.
+
+.. parsed-literal::
+
+   |qemu_system| [...OPTIONS...] \
+     -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
+     -vnc :1,tls-creds=tls0,password -monitor stdio
+   (qemu) change vnc password
+   Password: ********
+   (qemu)
+
+.. _vnc_005fsec_005fsasl:
+
+With SASL authentication
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The SASL authentication method is a VNC extension, that provides an
+easily extendable, pluggable authentication method. This allows for
+integration with a wide range of authentication mechanisms, such as PAM,
+GSSAPI/Kerberos, LDAP, SQL databases, one-time keys and more. The
+strength of the authentication depends on the exact mechanism
+configured. If the chosen mechanism also provides a SSF layer, then it
+will encrypt the datastream as well.
+
+Refer to the later docs on how to choose the exact SASL mechanism used
+for authentication, but assuming use of one supporting SSF, then QEMU
+can be launched with:
+
+.. parsed-literal::
+
+   |qemu_system| [...OPTIONS...] -vnc :1,sasl -monitor stdio
+
+.. _vnc_005fsec_005fcertificate_005fsasl:
+
+With x509 certificates and SASL authentication
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the desired SASL authentication mechanism does not supported SSF
+layers, then it is strongly advised to run it in combination with TLS
+and x509 certificates. This provides securely encrypted data stream,
+avoiding risk of compromising of the security credentials. This can be
+enabled, by combining the 'sasl' option with the aforementioned TLS +
+x509 options:
+
+.. parsed-literal::
+
+   |qemu_system| [...OPTIONS...] \
+     -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
+     -vnc :1,tls-creds=tls0,sasl -monitor stdio
+
+.. _vnc_005fsetup_005fsasl:
+
+Configuring SASL mechanisms
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following documentation assumes use of the Cyrus SASL implementation
+on a Linux host, but the principles should apply to any other SASL
+implementation or host. When SASL is enabled, the mechanism
+configuration will be loaded from system default SASL service config
+/etc/sasl2/qemu.conf. If running QEMU as an unprivileged user, an
+environment variable SASL_CONF_PATH can be used to make it search
+alternate locations for the service config file.
+
+If the TLS option is enabled for VNC, then it will provide session
+encryption, otherwise the SASL mechanism will have to provide
+encryption. In the latter case the list of possible plugins that can be
+used is drastically reduced. In fact only the GSSAPI SASL mechanism
+provides an acceptable level of security by modern standards. Previous
+versions of QEMU referred to the DIGEST-MD5 mechanism, however, it has
+multiple serious flaws described in detail in RFC 6331 and thus should
+never be used any more. The SCRAM-SHA-1 mechanism provides a simple
+username/password auth facility similar to DIGEST-MD5, but does not
+support session encryption, so can only be used in combination with TLS.
+
+When not using TLS the recommended configuration is
+
+::
+
+   mech_list: gssapi
+   keytab: /etc/qemu/krb5.tab
+
+This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol,
+with the server principal stored in /etc/qemu/krb5.tab. For this to work
+the administrator of your KDC must generate a Kerberos principal for the
+server, with a name of 'qemu/somehost.example.com@EXAMPLE.COM' replacing
+'somehost.example.com' with the fully qualified host name of the machine
+running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm.
+
+When using TLS, if username+password authentication is desired, then a
+reasonable configuration is
+
+::
+
+   mech_list: scram-sha-1
+   sasldb_path: /etc/qemu/passwd.db
+
+The ``saslpasswd2`` program can be used to populate the ``passwd.db``
+file with accounts.
+
+Other SASL configurations will be left as an exercise for the reader.
+Note that all mechanisms, except GSSAPI, should be combined with use of
+TLS to ensure a secure data channel.
diff --git a/docs/user/conf.py b/docs/user/conf.py
new file mode 100644 (file)
index 0000000..4b09aed
--- /dev/null
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+#
+# QEMU documentation build configuration file for the 'user' manual.
+#
+# This includes the top level conf file and then makes any necessary tweaks.
+import sys
+import os
+
+qemu_docdir = os.path.abspath("..")
+parent_config = os.path.join(qemu_docdir, "conf.py")
+exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
+
+# This slightly misuses the 'description', but is the best way to get
+# the manual title to appear in the sidebar.
+html_theme_options['description'] = u'User Mode Emulation User''s Guide'
diff --git a/docs/user/index.rst b/docs/user/index.rst
new file mode 100644 (file)
index 0000000..e030dad
--- /dev/null
@@ -0,0 +1,16 @@
+.. This is the top level page for the 'user' manual.
+
+
+QEMU User Mode Emulation User's Guide
+=====================================
+
+This manual is the overall guide for users using QEMU
+for user-mode emulation.  In this mode, QEMU can launch
+processes compiled for one CPU on another CPU.
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   main
diff --git a/docs/user/main.rst b/docs/user/main.rst
new file mode 100644 (file)
index 0000000..bd99b0f
--- /dev/null
@@ -0,0 +1,295 @@
+QEMU User space emulator
+========================
+
+Supported Operating Systems
+---------------------------
+
+The following OS are supported in user space emulation:
+
+-  Linux (referred as qemu-linux-user)
+
+-  BSD (referred as qemu-bsd-user)
+
+Features
+--------
+
+QEMU user space emulation has the following notable features:
+
+**System call translation:**
+   QEMU includes a generic system call translator. This means that the
+   parameters of the system calls can be converted to fix endianness and
+   32/64-bit mismatches between hosts and targets. IOCTLs can be
+   converted too.
+
+**POSIX signal handling:**
+   QEMU can redirect to the running program all signals coming from the
+   host (such as ``SIGALRM``), as well as synthesize signals from
+   virtual CPU exceptions (for example ``SIGFPE`` when the program
+   executes a division by zero).
+
+   QEMU relies on the host kernel to emulate most signal system calls,
+   for example to emulate the signal mask. On Linux, QEMU supports both
+   normal and real-time signals.
+
+**Threading:**
+   On Linux, QEMU can emulate the ``clone`` syscall and create a real
+   host thread (with a separate virtual CPU) for each emulated thread.
+   Note that not all targets currently emulate atomic operations
+   correctly. x86 and Arm use a global lock in order to preserve their
+   semantics.
+
+QEMU was conceived so that ultimately it can emulate itself. Although it
+is not very useful, it is an important test to show the power of the
+emulator.
+
+Linux User space emulator
+-------------------------
+
+Quick Start
+~~~~~~~~~~~
+
+In order to launch a Linux process, QEMU needs the process executable
+itself and all the target (x86) dynamic libraries used by it.
+
+-  On x86, you can just try to launch any process by using the native
+   libraries::
+
+      qemu-i386 -L / /bin/ls
+
+   ``-L /`` tells that the x86 dynamic linker must be searched with a
+   ``/`` prefix.
+
+-  Since QEMU is also a linux process, you can launch QEMU with QEMU
+   (NOTE: you can only do that if you compiled QEMU from the sources)::
+
+      qemu-i386 -L / qemu-i386 -L / /bin/ls
+
+-  On non x86 CPUs, you need first to download at least an x86 glibc
+   (``qemu-runtime-i386-XXX-.tar.gz`` on the QEMU web page). Ensure that
+   ``LD_LIBRARY_PATH`` is not set::
+
+      unset LD_LIBRARY_PATH
+
+   Then you can launch the precompiled ``ls`` x86 executable::
+
+      qemu-i386 tests/i386/ls
+
+   You can look at ``scripts/qemu-binfmt-conf.sh`` so that QEMU is
+   automatically launched by the Linux kernel when you try to launch x86
+   executables. It requires the ``binfmt_misc`` module in the Linux
+   kernel.
+
+-  The x86 version of QEMU is also included. You can try weird things
+   such as::
+
+      qemu-i386 /usr/local/qemu-i386/bin/qemu-i386 \
+                /usr/local/qemu-i386/bin/ls-i386
+
+Wine launch
+~~~~~~~~~~~
+
+-  Ensure that you have a working QEMU with the x86 glibc distribution
+   (see previous section). In order to verify it, you must be able to
+   do::
+
+      qemu-i386 /usr/local/qemu-i386/bin/ls-i386
+
+-  Download the binary x86 Wine install (``qemu-XXX-i386-wine.tar.gz``
+   on the QEMU web page).
+
+-  Configure Wine on your account. Look at the provided script
+   ``/usr/local/qemu-i386/bin/wine-conf.sh``. Your previous
+   ``${HOME}/.wine`` directory is saved to ``${HOME}/.wine.org``.
+
+-  Then you can try the example ``putty.exe``::
+
+      qemu-i386 /usr/local/qemu-i386/wine/bin/wine \
+                /usr/local/qemu-i386/wine/c/Program\ Files/putty.exe
+
+Command line options
+~~~~~~~~~~~~~~~~~~~~
+
+::
+
+   qemu-i386 [-h] [-d] [-L path] [-s size] [-cpu model] [-g port] [-B offset] [-R size] program [arguments...]
+
+``-h``
+   Print the help
+
+``-L path``
+   Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
+
+``-s size``
+   Set the x86 stack size in bytes (default=524288)
+
+``-cpu model``
+   Select CPU model (-cpu help for list and additional feature
+   selection)
+
+``-E var=value``
+   Set environment var to value.
+
+``-U var``
+   Remove var from the environment.
+
+``-B offset``
+   Offset guest address by the specified number of bytes. This is useful
+   when the address region required by guest applications is reserved on
+   the host. This option is currently only supported on some hosts.
+
+``-R size``
+   Pre-allocate a guest virtual address space of the given size (in
+   bytes). \"G\", \"M\", and \"k\" suffixes may be used when specifying
+   the size.
+
+Debug options:
+
+``-d item1,...``
+   Activate logging of the specified items (use '-d help' for a list of
+   log items)
+
+``-p pagesize``
+   Act as if the host page size was 'pagesize' bytes
+
+``-g port``
+   Wait gdb connection to port
+
+``-singlestep``
+   Run the emulation in single step mode.
+
+Environment variables:
+
+QEMU_STRACE
+   Print system calls and arguments similar to the 'strace' program
+   (NOTE: the actual 'strace' program will not work because the user
+   space emulator hasn't implemented ptrace). At the moment this is
+   incomplete. All system calls that don't have a specific argument
+   format are printed with information for six arguments. Many
+   flag-style arguments don't have decoders and will show up as numbers.
+
+Other binaries
+~~~~~~~~~~~~~~
+
+user mode (Alpha)
+``qemu-alpha`` TODO.
+
+user mode (Arm)
+``qemu-armeb`` TODO.
+
+user mode (Arm)
+``qemu-arm`` is also capable of running Arm \"Angel\" semihosted ELF
+binaries (as implemented by the arm-elf and arm-eabi Newlib/GDB
+configurations), and arm-uclinux bFLT format binaries.
+
+user mode (ColdFire)
+user mode (M68K)
+``qemu-m68k`` is capable of running semihosted binaries using the BDM
+(m5xxx-ram-hosted.ld) or m68k-sim (sim.ld) syscall interfaces, and
+coldfire uClinux bFLT format binaries.
+
+The binary format is detected automatically.
+
+user mode (Cris)
+``qemu-cris`` TODO.
+
+user mode (i386)
+``qemu-i386`` TODO. ``qemu-x86_64`` TODO.
+
+user mode (Microblaze)
+``qemu-microblaze`` TODO.
+
+user mode (MIPS)
+``qemu-mips`` executes 32-bit big endian MIPS binaries (MIPS O32 ABI).
+
+``qemu-mipsel`` executes 32-bit little endian MIPS binaries (MIPS O32
+ABI).
+
+``qemu-mips64`` executes 64-bit big endian MIPS binaries (MIPS N64 ABI).
+
+``qemu-mips64el`` executes 64-bit little endian MIPS binaries (MIPS N64
+ABI).
+
+``qemu-mipsn32`` executes 32-bit big endian MIPS binaries (MIPS N32
+ABI).
+
+``qemu-mipsn32el`` executes 32-bit little endian MIPS binaries (MIPS N32
+ABI).
+
+user mode (NiosII)
+``qemu-nios2`` TODO.
+
+user mode (PowerPC)
+``qemu-ppc64abi32`` TODO. ``qemu-ppc64`` TODO. ``qemu-ppc`` TODO.
+
+user mode (SH4)
+``qemu-sh4eb`` TODO. ``qemu-sh4`` TODO.
+
+user mode (SPARC)
+``qemu-sparc`` can execute Sparc32 binaries (Sparc32 CPU, 32 bit ABI).
+
+``qemu-sparc32plus`` can execute Sparc32 and SPARC32PLUS binaries
+(Sparc64 CPU, 32 bit ABI).
+
+``qemu-sparc64`` can execute some Sparc64 (Sparc64 CPU, 64 bit ABI) and
+SPARC32PLUS binaries (Sparc64 CPU, 32 bit ABI).
+
+BSD User space emulator
+-----------------------
+
+BSD Status
+~~~~~~~~~~
+
+-  target Sparc64 on Sparc64: Some trivial programs work.
+
+Quick Start
+~~~~~~~~~~~
+
+In order to launch a BSD process, QEMU needs the process executable
+itself and all the target dynamic libraries used by it.
+
+-  On Sparc64, you can just try to launch any process by using the
+   native libraries::
+
+      qemu-sparc64 /bin/ls
+
+Command line options
+~~~~~~~~~~~~~~~~~~~~
+
+::
+
+   qemu-sparc64 [-h] [-d] [-L path] [-s size] [-bsd type] program [arguments...]
+
+``-h``
+   Print the help
+
+``-L path``
+   Set the library root path (default=/)
+
+``-s size``
+   Set the stack size in bytes (default=524288)
+
+``-ignore-environment``
+   Start with an empty environment. Without this option, the initial
+   environment is a copy of the caller's environment.
+
+``-E var=value``
+   Set environment var to value.
+
+``-U var``
+   Remove var from the environment.
+
+``-bsd type``
+   Set the type of the emulated BSD Operating system. Valid values are
+   FreeBSD, NetBSD and OpenBSD (default).
+
+Debug options:
+
+``-d item1,...``
+   Activate logging of the specified items (use '-d help' for a list of
+   log items)
+
+``-p pagesize``
+   Act as if the host page size was 'pagesize' bytes
+
+``-singlestep``
+   Run the emulation in single step mode.
index aa1ab2590d425248967647400992fc62e78fbe41..de061a8a0eaaa496ce70ec859a0d36f66793fcbc 100644 (file)
@@ -43,7 +43,7 @@
 #define BTRFS_SUPER_MAGIC 0x9123683E
 #endif
 
-static struct option helper_opts[] = {
+static const struct option helper_opts[] = {
     {"fd", required_argument, NULL, 'f'},
     {"path", required_argument, NULL, 'p'},
     {"nodaemon", no_argument, NULL, 'n'},
index ce304ff4822ea99194d5c35ba39d30ad211b224e..22a2d630cdca049b6835e99a05b8763c6a0d250f 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -3367,7 +3367,7 @@ int gdbserver_start(const char *device)
         /* Initialize a monitor terminal for gdb */
         mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
                                    NULL, NULL, &error_abort);
-        monitor_init_hmp(mon_chr, false);
+        monitor_init_hmp(mon_chr, false, &error_abort);
     } else {
         qemu_chr_fe_deinit(&s->chr, true);
         mon_chr = s->mon_chr;
index 257ee7d7a3f9249ca14e5d35016ea90fd296b355..ca5198438deccd2b9e9e8350fe913435c0ba34e0 100644 (file)
@@ -1,17 +1,21 @@
-HXCOMM Use DEFHEADING() to define headings in both help text and texi
-HXCOMM Text between STEXI and ETEXI are copied to texi version and
-HXCOMM discarded from C version
+HXCOMM Use DEFHEADING() to define headings in both help text and rST.
+HXCOMM Text between SRST and ERST is copied to the rST version and
+HXCOMM discarded from C version.
 HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
 HXCOMM monitor info commands
-HXCOMM HXCOMM can be used for comments, discarded from both texi and C
+HXCOMM HXCOMM can be used for comments, discarded from both rST and C.
+HXCOMM
+HXCOMM In this file, generally SRST fragments should have two extra
+HXCOMM spaces of indent, so that the documentation list item for "info foo"
+HXCOMM appears inside the documentation list item for the top level
+HXCOMM "info" documentation entry. The exception is the first SRST
+HXCOMM fragment that defines that top level entry.
 
-STEXI
-@table @option
-@item info @var{subcommand}
-@findex info
-Show various information about the system state.
-@table @option
-ETEXI
+SRST
+``info`` *subcommand*
+  Show various information about the system state.
+
+ERST
 
     {
         .name       = "version",
@@ -22,11 +26,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info version
-@findex info version
-Show the version of QEMU.
-ETEXI
+SRST
+  ``info version``
+    Show the version of QEMU.
+ERST
 
     {
         .name       = "network",
@@ -36,11 +39,10 @@ ETEXI
         .cmd        = hmp_info_network,
     },
 
-STEXI
-@item info network
-@findex info network
-Show the network state.
-ETEXI
+SRST
+  ``info network``
+    Show the network state.
+ERST
 
     {
         .name       = "chardev",
@@ -51,11 +53,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info chardev
-@findex info chardev
-Show the character devices.
-ETEXI
+SRST
+  ``info chardev``
+    Show the character devices.
+ERST
 
     {
         .name       = "block",
@@ -66,11 +67,10 @@ ETEXI
         .cmd        = hmp_info_block,
     },
 
-STEXI
-@item info block
-@findex info block
-Show info of one block device or all block devices.
-ETEXI
+SRST
+  ``info block``
+    Show info of one block device or all block devices.
+ERST
 
     {
         .name       = "blockstats",
@@ -80,11 +80,10 @@ ETEXI
         .cmd        = hmp_info_blockstats,
     },
 
-STEXI
-@item info blockstats
-@findex info blockstats
-Show block device statistics.
-ETEXI
+SRST
+  ``info blockstats``
+    Show block device statistics.
+ERST
 
     {
         .name       = "block-jobs",
@@ -94,11 +93,10 @@ ETEXI
         .cmd        = hmp_info_block_jobs,
     },
 
-STEXI
-@item info block-jobs
-@findex info block-jobs
-Show progress of ongoing block device operations.
-ETEXI
+SRST
+  ``info block-jobs``
+    Show progress of ongoing block device operations.
+ERST
 
     {
         .name       = "registers",
@@ -108,11 +106,10 @@ ETEXI
         .cmd        = hmp_info_registers,
     },
 
-STEXI
-@item info registers
-@findex info registers
-Show the cpu registers.
-ETEXI
+SRST
+  ``info registers``
+    Show the cpu registers.
+ERST
 
 #if defined(TARGET_I386)
     {
@@ -125,11 +122,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info lapic
-@findex info lapic
-Show local APIC state
-ETEXI
+SRST
+  ``info lapic``
+    Show local APIC state
+ERST
 
 #if defined(TARGET_I386)
     {
@@ -141,11 +137,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info ioapic
-@findex info ioapic
-Show io APIC state
-ETEXI
+SRST
+  ``info ioapic``
+    Show io APIC state
+ERST
 
     {
         .name       = "cpus",
@@ -155,11 +150,10 @@ ETEXI
         .cmd        = hmp_info_cpus,
     },
 
-STEXI
-@item info cpus
-@findex info cpus
-Show infos for each CPU.
-ETEXI
+SRST
+  ``info cpus``
+    Show infos for each CPU.
+ERST
 
     {
         .name       = "history",
@@ -170,11 +164,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info history
-@findex info history
-Show the command line history.
-ETEXI
+SRST
+  ``info history``
+    Show the command line history.
+ERST
 
     {
         .name       = "irq",
@@ -184,11 +177,10 @@ ETEXI
         .cmd        = hmp_info_irq,
     },
 
-STEXI
-@item info irq
-@findex info irq
-Show the interrupts statistics (if available).
-ETEXI
+SRST
+  ``info irq``
+    Show the interrupts statistics (if available).
+ERST
 
     {
         .name       = "pic",
@@ -198,11 +190,10 @@ ETEXI
         .cmd        = hmp_info_pic,
     },
 
-STEXI
-@item info pic
-@findex info pic
-Show PIC state.
-ETEXI
+SRST
+  ``info pic``
+    Show PIC state.
+ERST
 
     {
         .name       = "rdma",
@@ -212,11 +203,10 @@ ETEXI
         .cmd        = hmp_info_rdma,
     },
 
-STEXI
-@item info rdma
-@findex info rdma
-Show RDMA state.
-ETEXI
+SRST
+  ``info rdma``
+    Show RDMA state.
+ERST
 
     {
         .name       = "pci",
@@ -226,11 +216,10 @@ ETEXI
         .cmd        = hmp_info_pci,
     },
 
-STEXI
-@item info pci
-@findex info pci
-Show PCI information.
-ETEXI
+SRST
+  ``info pci``
+    Show PCI information.
+ERST
 
 #if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \
     defined(TARGET_PPC) || defined(TARGET_XTENSA) || defined(TARGET_M68K)
@@ -243,11 +232,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info tlb
-@findex info tlb
-Show virtual to physical memory mappings.
-ETEXI
+SRST
+  ``info tlb``
+    Show virtual to physical memory mappings.
+ERST
 
 #if defined(TARGET_I386) || defined(TARGET_RISCV)
     {
@@ -259,11 +247,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info mem
-@findex info mem
-Show the active virtual memory mappings.
-ETEXI
+SRST
+  ``info mem``
+    Show the active virtual memory mappings.
+ERST
 
     {
         .name       = "mtree",
@@ -275,11 +262,10 @@ ETEXI
         .cmd        = hmp_info_mtree,
     },
 
-STEXI
-@item info mtree
-@findex info mtree
-Show memory tree.
-ETEXI
+SRST
+  ``info mtree``
+    Show memory tree.
+ERST
 
 #if defined(CONFIG_TCG)
     {
@@ -291,11 +277,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info jit
-@findex info jit
-Show dynamic compiler info.
-ETEXI
+SRST
+  ``info jit``
+    Show dynamic compiler info.
+ERST
 
 #if defined(CONFIG_TCG)
     {
@@ -307,11 +292,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info opcount
-@findex info opcount
-Show dynamic compiler opcode counters
-ETEXI
+SRST
+  ``info opcount``
+    Show dynamic compiler opcode counters
+ERST
 
     {
         .name       = "sync-profile",
@@ -324,16 +308,20 @@ ETEXI
         .cmd        = hmp_info_sync_profile,
     },
 
-STEXI
-@item info sync-profile [-m|-n] [@var{max}]
-@findex info sync-profile
-Show synchronization profiling info, up to @var{max} entries (default: 10),
-sorted by total wait time.
-        -m: sort by mean wait time
-        -n: do not coalesce objects with the same call site
-When different objects that share the same call site are coalesced, the "Object"
-field shows---enclosed in brackets---the number of objects being coalesced.
-ETEXI
+SRST
+  ``info sync-profile [-m|-n]`` [*max*]
+    Show synchronization profiling info, up to *max* entries (default: 10),
+    sorted by total wait time.
+
+    ``-m``
+      sort by mean wait time
+    ``-n``
+      do not coalesce objects with the same call site
+
+    When different objects that share the same call site are coalesced,
+    the "Object" field shows---enclosed in brackets---the number of objects
+    being coalesced.
+ERST
 
     {
         .name       = "kvm",
@@ -343,11 +331,10 @@ ETEXI
         .cmd        = hmp_info_kvm,
     },
 
-STEXI
-@item info kvm
-@findex info kvm
-Show KVM information.
-ETEXI
+SRST
+  ``info kvm``
+    Show KVM information.
+ERST
 
     {
         .name       = "numa",
@@ -357,11 +344,10 @@ ETEXI
         .cmd        = hmp_info_numa,
     },
 
-STEXI
-@item info numa
-@findex info numa
-Show NUMA information.
-ETEXI
+SRST
+  ``info numa``
+    Show NUMA information.
+ERST
 
     {
         .name       = "usb",
@@ -371,11 +357,10 @@ ETEXI
         .cmd        = hmp_info_usb,
     },
 
-STEXI
-@item info usb
-@findex info usb
-Show guest USB devices.
-ETEXI
+SRST
+  ``info usb``
+    Show guest USB devices.
+ERST
 
     {
         .name       = "usbhost",
@@ -385,11 +370,10 @@ ETEXI
         .cmd        = hmp_info_usbhost,
     },
 
-STEXI
-@item info usbhost
-@findex info usbhost
-Show host USB devices.
-ETEXI
+SRST
+  ``info usbhost``
+    Show host USB devices.
+ERST
 
     {
         .name       = "profile",
@@ -399,11 +383,10 @@ ETEXI
         .cmd        = hmp_info_profile,
     },
 
-STEXI
-@item info profile
-@findex info profile
-Show profiling information.
-ETEXI
+SRST
+  ``info profile``
+    Show profiling information.
+ERST
 
     {
         .name       = "capture",
@@ -413,11 +396,10 @@ ETEXI
         .cmd        = hmp_info_capture,
     },
 
-STEXI
-@item info capture
-@findex info capture
-Show capture information.
-ETEXI
+SRST
+  ``info capture``
+    Show capture information.
+ERST
 
     {
         .name       = "snapshots",
@@ -427,11 +409,10 @@ ETEXI
         .cmd        = hmp_info_snapshots,
     },
 
-STEXI
-@item info snapshots
-@findex info snapshots
-Show the currently saved VM snapshots.
-ETEXI
+SRST
+  ``info snapshots``
+    Show the currently saved VM snapshots.
+ERST
 
     {
         .name       = "status",
@@ -442,11 +423,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info status
-@findex info status
-Show the current VM status (running|paused).
-ETEXI
+SRST
+  ``info status``
+    Show the current VM status (running|paused).
+ERST
 
     {
         .name       = "mice",
@@ -456,11 +436,10 @@ ETEXI
         .cmd        = hmp_info_mice,
     },
 
-STEXI
-@item info mice
-@findex info mice
-Show which guest mouse is receiving events.
-ETEXI
+SRST
+  ``info mice``
+    Show which guest mouse is receiving events.
+ERST
 
 #if defined(CONFIG_VNC)
     {
@@ -472,11 +451,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info vnc
-@findex info vnc
-Show the vnc server status.
-ETEXI
+SRST
+  ``info vnc``
+    Show the vnc server status.
+ERST
 
 #if defined(CONFIG_SPICE)
     {
@@ -488,11 +466,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info spice
-@findex info spice
-Show the spice server status.
-ETEXI
+SRST
+  ``info spice``
+    Show the spice server status.
+ERST
 
     {
         .name       = "name",
@@ -503,11 +480,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info name
-@findex info name
-Show the current VM name.
-ETEXI
+SRST
+  ``info name``
+    Show the current VM name.
+ERST
 
     {
         .name       = "uuid",
@@ -518,11 +494,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info uuid
-@findex info uuid
-Show the current VM UUID.
-ETEXI
+SRST
+  ``info uuid``
+    Show the current VM UUID.
+ERST
 
     {
         .name       = "cpustats",
@@ -532,11 +507,10 @@ ETEXI
         .cmd        = hmp_info_cpustats,
     },
 
-STEXI
-@item info cpustats
-@findex info cpustats
-Show CPU statistics.
-ETEXI
+SRST
+  ``info cpustats``
+    Show CPU statistics.
+ERST
 
 #if defined(CONFIG_SLIRP)
     {
@@ -548,11 +522,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info usernet
-@findex info usernet
-Show user network stack connection states.
-ETEXI
+SRST
+  ``info usernet``
+    Show user network stack connection states.
+ERST
 
     {
         .name       = "migrate",
@@ -562,11 +535,10 @@ ETEXI
         .cmd        = hmp_info_migrate,
     },
 
-STEXI
-@item info migrate
-@findex info migrate
-Show migration status.
-ETEXI
+SRST
+  ``info migrate``
+    Show migration status.
+ERST
 
     {
         .name       = "migrate_capabilities",
@@ -576,11 +548,10 @@ ETEXI
         .cmd        = hmp_info_migrate_capabilities,
     },
 
-STEXI
-@item info migrate_capabilities
-@findex info migrate_capabilities
-Show current migration capabilities.
-ETEXI
+SRST
+  ``info migrate_capabilities``
+    Show current migration capabilities.
+ERST
 
     {
         .name       = "migrate_parameters",
@@ -590,11 +561,10 @@ ETEXI
         .cmd        = hmp_info_migrate_parameters,
     },
 
-STEXI
-@item info migrate_parameters
-@findex info migrate_parameters
-Show current migration parameters.
-ETEXI
+SRST
+  ``info migrate_parameters``
+    Show current migration parameters.
+ERST
 
     {
         .name       = "migrate_cache_size",
@@ -604,11 +574,10 @@ ETEXI
         .cmd        = hmp_info_migrate_cache_size,
     },
 
-STEXI
-@item info migrate_cache_size
-@findex info migrate_cache_size
-Show current migration xbzrle cache size.
-ETEXI
+SRST
+  ``info migrate_cache_size``
+    Show current migration xbzrle cache size.
+ERST
 
     {
         .name       = "balloon",
@@ -618,11 +587,10 @@ ETEXI
         .cmd        = hmp_info_balloon,
     },
 
-STEXI
-@item info balloon
-@findex info balloon
-Show balloon information.
-ETEXI
+SRST
+  ``info balloon``
+    Show balloon information.
+ERST
 
     {
         .name       = "qtree",
@@ -632,11 +600,10 @@ ETEXI
         .cmd        = hmp_info_qtree,
     },
 
-STEXI
-@item info qtree
-@findex info qtree
-Show device tree.
-ETEXI
+SRST
+  ``info qtree``
+    Show device tree.
+ERST
 
     {
         .name       = "qdm",
@@ -646,11 +613,10 @@ ETEXI
         .cmd        = hmp_info_qdm,
     },
 
-STEXI
-@item info qdm
-@findex info qdm
-Show qdev device model list.
-ETEXI
+SRST
+  ``info qdm``
+    Show qdev device model list.
+ERST
 
     {
         .name       = "qom-tree",
@@ -661,11 +627,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info qom-tree
-@findex info qom-tree
-Show QOM composition tree.
-ETEXI
+SRST
+  ``info qom-tree``
+    Show QOM composition tree.
+ERST
 
     {
         .name       = "roms",
@@ -675,11 +640,10 @@ ETEXI
         .cmd        = hmp_info_roms,
     },
 
-STEXI
-@item info roms
-@findex info roms
-Show roms.
-ETEXI
+SRST
+  ``info roms``
+    Show roms.
+ERST
 
     {
         .name       = "trace-events",
@@ -691,11 +655,10 @@ ETEXI
         .command_completion = info_trace_events_completion,
     },
 
-STEXI
-@item info trace-events
-@findex info trace-events
-Show available trace-events & their state.
-ETEXI
+SRST
+  ``info trace-events``
+    Show available trace-events & their state.
+ERST
 
     {
         .name       = "tpm",
@@ -705,11 +668,10 @@ ETEXI
         .cmd        = hmp_info_tpm,
     },
 
-STEXI
-@item info tpm
-@findex info tpm
-Show the TPM device.
-ETEXI
+SRST
+  ``info tpm``
+    Show the TPM device.
+ERST
 
     {
         .name       = "memdev",
@@ -720,11 +682,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info memdev
-@findex info memdev
-Show memory backends
-ETEXI
+SRST
+  ``info memdev``
+    Show memory backends
+ERST
 
     {
         .name       = "memory-devices",
@@ -734,11 +695,10 @@ ETEXI
         .cmd        = hmp_info_memory_devices,
     },
 
-STEXI
-@item info memory-devices
-@findex info memory-devices
-Show memory devices.
-ETEXI
+SRST
+  ``info memory-devices``
+    Show memory devices.
+ERST
 
     {
         .name       = "iothreads",
@@ -749,11 +709,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info iothreads
-@findex info iothreads
-Show iothread's identifiers.
-ETEXI
+SRST
+  ``info iothreads``
+    Show iothread's identifiers.
+ERST
 
     {
         .name       = "rocker",
@@ -763,11 +722,10 @@ ETEXI
         .cmd        = hmp_rocker,
     },
 
-STEXI
-@item info rocker @var{name}
-@findex info rocker
-Show rocker switch.
-ETEXI
+SRST
+  ``info rocker`` *name*
+    Show rocker switch.
+ERST
 
     {
         .name       = "rocker-ports",
@@ -777,11 +735,10 @@ ETEXI
         .cmd        = hmp_rocker_ports,
     },
 
-STEXI
-@item info rocker-ports @var{name}-ports
-@findex info rocker-ports
-Show rocker ports.
-ETEXI
+SRST
+  ``info rocker-ports`` *name*-ports
+    Show rocker ports.
+ERST
 
     {
         .name       = "rocker-of-dpa-flows",
@@ -791,11 +748,10 @@ ETEXI
         .cmd        = hmp_rocker_of_dpa_flows,
     },
 
-STEXI
-@item info rocker-of-dpa-flows @var{name} [@var{tbl_id}]
-@findex info rocker-of-dpa-flows
-Show rocker OF-DPA flow tables.
-ETEXI
+SRST
+  ``info rocker-of-dpa-flows`` *name* [*tbl_id*]
+    Show rocker OF-DPA flow tables.
+ERST
 
     {
         .name       = "rocker-of-dpa-groups",
@@ -805,11 +761,10 @@ ETEXI
         .cmd        = hmp_rocker_of_dpa_groups,
     },
 
-STEXI
-@item info rocker-of-dpa-groups @var{name} [@var{type}]
-@findex info rocker-of-dpa-groups
-Show rocker OF-DPA groups.
-ETEXI
+SRST
+  ``info rocker-of-dpa-groups`` *name* [*type*]
+    Show rocker OF-DPA groups.
+ERST
 
 #if defined(TARGET_S390X)
     {
@@ -821,11 +776,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info skeys @var{address}
-@findex info skeys
-Display the value of a storage key (s390 only)
-ETEXI
+SRST
+  ``info skeys`` *address*
+    Display the value of a storage key (s390 only)
+ERST
 
 #if defined(TARGET_S390X)
     {
@@ -837,11 +791,11 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info cmma @var{address}
-@findex info cmma
-Display the values of the CMMA storage attributes for a range of pages (s390 only)
-ETEXI
+SRST
+  ``info cmma`` *address*
+    Display the values of the CMMA storage attributes for a range of
+    pages (s390 only)
+ERST
 
     {
         .name       = "dump",
@@ -851,11 +805,10 @@ ETEXI
         .cmd        = hmp_info_dump,
     },
 
-STEXI
-@item info dump
-@findex info dump
-Display the latest dump status.
-ETEXI
+SRST
+  ``info dump``
+    Display the latest dump status.
+ERST
 
     {
         .name       = "ramblock",
@@ -865,11 +818,10 @@ ETEXI
         .cmd        = hmp_info_ramblock,
     },
 
-STEXI
-@item info ramblock
-@findex info ramblock
-Dump all the ramblocks of the system.
-ETEXI
+SRST
+  ``info ramblock``
+    Dump all the ramblocks of the system.
+ERST
 
     {
         .name       = "hotpluggable-cpus",
@@ -880,11 +832,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item info hotpluggable-cpus
-@findex info hotpluggable-cpus
-Show information about hotpluggable CPUs
-ETEXI
+SRST
+  ``info hotpluggable-cpus``
+    Show information about hotpluggable CPUs
+ERST
 
     {
         .name       = "vm-generation-id",
@@ -894,11 +845,10 @@ ETEXI
         .cmd = hmp_info_vm_generation_id,
     },
 
-STEXI
-@item info vm-generation-id
-@findex info vm-generation-id
-Show Virtual Machine Generation ID
-ETEXI
+SRST
+  ``info vm-generation-id``
+    Show Virtual Machine Generation ID
+ERST
 
     {
         .name       = "memory_size_summary",
@@ -909,12 +859,11 @@ ETEXI
         .cmd        = hmp_info_memory_size_summary,
     },
 
-STEXI
-@item info memory_size_summary
-@findex info memory_size_summary
-Display the amount of initially allocated and present hotpluggable (if
-enabled) memory in bytes.
-ETEXI
+SRST
+  ``info memory_size_summary``
+    Display the amount of initially allocated and present hotpluggable (if
+    enabled) memory in bytes.
+ERST
 
 #if defined(TARGET_I386)
     {
@@ -926,16 +875,9 @@ ETEXI
     },
 #endif
 
-STEXI
-@item info sev
-@findex info sev
-Show SEV information.
-ETEXI
+SRST
+  ``info sev``
+    Show SEV information.
+ERST
 
-STEXI
-@end table
-ETEXI
 
-STEXI
-@end table
-ETEXI
index dc23185de439050982ada379d5e92a45b2c396da..7f0f3974ad908fb8e2bb965b3c85146330ab73f5 100644 (file)
@@ -1,13 +1,10 @@
-HXCOMM Use DEFHEADING() to define headings in both help text and texi
-HXCOMM Text between STEXI and ETEXI are copied to texi version and
-HXCOMM discarded from C version
+HXCOMM Use DEFHEADING() to define headings in both help text and rST.
+HXCOMM Text between SRST and ERST is copied to the rST version and
+HXCOMM discarded from C version.
 HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
 HXCOMM monitor commands
-HXCOMM HXCOMM can be used for comments, discarded from both texi and C
+HXCOMM HXCOMM can be used for comments, discarded from both rST and C.
 
-STEXI
-@table @option
-ETEXI
 
     {
         .name       = "help|?",
@@ -18,11 +15,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item help or ? [@var{cmd}]
-@findex help
-Show the help for all commands or just for command @var{cmd}.
-ETEXI
+SRST
+``help`` or ``?`` [*cmd*]
+  Show the help for all commands or just for command *cmd*.
+ERST
 
     {
         .name       = "commit",
@@ -32,16 +28,16 @@ ETEXI
         .cmd        = hmp_commit,
     },
 
-STEXI
-@item commit
-@findex commit
-Commit changes to the disk images (if -snapshot is used) or backing files.
-If the backing file is smaller than the snapshot, then the backing file will be
-resized to be the same size as the snapshot.  If the snapshot is smaller than
-the backing file, the backing file will not be truncated.  If you want the
-backing file to match the size of the smaller snapshot, you can safely truncate
-it yourself once the commit operation successfully completes.
-ETEXI
+SRST
+``commit``
+  Commit changes to the disk images (if -snapshot is used) or backing files.
+  If the backing file is smaller than the snapshot, then the backing file
+  will be resized to be the same size as the snapshot.  If the snapshot is
+  smaller than the backing file, the backing file will not be truncated.
+  If you want the backing file to match the size of the smaller snapshot,
+  you can safely truncate it yourself once the commit operation successfully
+  completes.
+ERST
 
     {
         .name       = "q|quit",
@@ -51,11 +47,10 @@ ETEXI
         .cmd        = hmp_quit,
     },
 
-STEXI
-@item q or quit
-@findex quit
-Quit the emulator.
-ETEXI
+SRST
+``q`` or ``quit``
+  Quit the emulator.
+ERST
 
     {
         .name       = "exit_preconfig",
@@ -66,15 +61,14 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item exit_preconfig
-@findex exit_preconfig
-This command makes QEMU exit the preconfig state and proceed with
-VM initialization using configuration data provided on the command line
-and via the QMP monitor during the preconfig state. The command is only
-available during the preconfig state (i.e. when the --preconfig command
-line option was in use).
-ETEXI
+SRST
+``exit_preconfig``
+  This command makes QEMU exit the preconfig state and proceed with
+  VM initialization using configuration data provided on the command line
+  and via the QMP monitor during the preconfig state. The command is only
+  available during the preconfig state (i.e. when the --preconfig command
+  line option was in use).
+ERST
 
     {
         .name       = "block_resize",
@@ -84,14 +78,13 @@ ETEXI
         .cmd        = hmp_block_resize,
     },
 
-STEXI
-@item block_resize
-@findex block_resize
-Resize a block image while a guest is running.  Usually requires guest
-action to see the updated size.  Resize to a lower size is supported,
-but should be used with extreme caution.  Note that this command only
-resizes image files, it can not resize block devices like LVM volumes.
-ETEXI
+SRST
+``block_resize``
+  Resize a block image while a guest is running.  Usually requires guest
+  action to see the updated size.  Resize to a lower size is supported,
+  but should be used with extreme caution.  Note that this command only
+  resizes image files, it can not resize block devices like LVM volumes.
+ERST
 
     {
         .name       = "block_stream",
@@ -101,11 +94,10 @@ ETEXI
         .cmd        = hmp_block_stream,
     },
 
-STEXI
-@item block_stream
-@findex block_stream
-Copy data from a backing file into a block device.
-ETEXI
+SRST
+``block_stream``
+  Copy data from a backing file into a block device.
+ERST
 
     {
         .name       = "block_job_set_speed",
@@ -115,11 +107,10 @@ ETEXI
         .cmd        = hmp_block_job_set_speed,
     },
 
-STEXI
-@item block_job_set_speed
-@findex block_job_set_speed
-Set maximum speed for a background block operation.
-ETEXI
+SRST
+``block_job_set_speed``
+  Set maximum speed for a background block operation.
+ERST
 
     {
         .name       = "block_job_cancel",
@@ -131,11 +122,10 @@ ETEXI
         .cmd        = hmp_block_job_cancel,
     },
 
-STEXI
-@item block_job_cancel
-@findex block_job_cancel
-Stop an active background block operation (streaming, mirroring).
-ETEXI
+SRST
+``block_job_cancel``
+  Stop an active background block operation (streaming, mirroring).
+ERST
 
     {
         .name       = "block_job_complete",
@@ -145,12 +135,11 @@ ETEXI
         .cmd        = hmp_block_job_complete,
     },
 
-STEXI
-@item block_job_complete
-@findex block_job_complete
-Manually trigger completion of an active background block operation.
-For mirroring, this will switch the device to the destination path.
-ETEXI
+SRST
+``block_job_complete``
+  Manually trigger completion of an active background block operation.
+  For mirroring, this will switch the device to the destination path.
+ERST
 
     {
         .name       = "block_job_pause",
@@ -160,11 +149,10 @@ ETEXI
         .cmd        = hmp_block_job_pause,
     },
 
-STEXI
-@item block_job_pause
-@findex block_job_pause
-Pause an active block streaming operation.
-ETEXI
+SRST
+``block_job_pause``
+  Pause an active block streaming operation.
+ERST
 
     {
         .name       = "block_job_resume",
@@ -174,11 +162,10 @@ ETEXI
         .cmd        = hmp_block_job_resume,
     },
 
-STEXI
-@item block_job_resume
-@findex block_job_resume
-Resume a paused block streaming operation.
-ETEXI
+SRST
+``block_job_resume``
+  Resume a paused block streaming operation.
+ERST
 
     {
         .name       = "eject",
@@ -188,11 +175,10 @@ ETEXI
         .cmd        = hmp_eject,
     },
 
-STEXI
-@item eject [-f] @var{device}
-@findex eject
-Eject a removable medium (use -f to force it).
-ETEXI
+SRST
+``eject [-f]`` *device*
+  Eject a removable medium (use -f to force it).
+ERST
 
     {
         .name       = "drive_del",
@@ -202,16 +188,15 @@ ETEXI
         .cmd        = hmp_drive_del,
     },
 
-STEXI
-@item drive_del @var{device}
-@findex drive_del
-Remove host block device.  The result is that guest generated IO is no longer
-submitted against the host device underlying the disk.  Once a drive has
-been deleted, the QEMU Block layer returns -EIO which results in IO
-errors in the guest for applications that are reading/writing to the device.
-These errors are always reported to the guest, regardless of the drive's error
-actions (drive options rerror, werror).
-ETEXI
+SRST
+``drive_del`` *device*
+  Remove host block device.  The result is that guest generated IO is no longer
+  submitted against the host device underlying the disk.  Once a drive has
+  been deleted, the QEMU Block layer returns -EIO which results in IO
+  errors in the guest for applications that are reading/writing to the device.
+  These errors are always reported to the guest, regardless of the drive's error
+  actions (drive options rerror, werror).
+ERST
 
     {
         .name       = "change",
@@ -221,56 +206,45 @@ ETEXI
         .cmd        = hmp_change,
     },
 
-STEXI
-@item change @var{device} @var{setting}
-@findex change
-Change the configuration of a device.
+SRST
+``change`` *device* *setting*
+  Change the configuration of a device.
 
-@table @option
-@item change @var{diskdevice} @var{filename} [@var{format} [@var{read-only-mode}]]
-Change the medium for a removable disk device to point to @var{filename}. eg
+  ``change`` *diskdevice* *filename* [*format* [*read-only-mode*]]
+    Change the medium for a removable disk device to point to *filename*. eg::
 
-@example
-(qemu) change ide1-cd0 /path/to/some.iso
-@end example
+      (qemu) change ide1-cd0 /path/to/some.iso
 
-@var{format} is optional.
+    *format* is optional.
 
-@var{read-only-mode} may be used to change the read-only status of the device.
-It accepts the following values:
+    *read-only-mode* may be used to change the read-only status of the device.
+    It accepts the following values:
 
-@table @var
-@item retain
-Retains the current status; this is the default.
+    retain
+      Retains the current status; this is the default.
 
-@item read-only
-Makes the device read-only.
+    read-only
+      Makes the device read-only.
 
-@item read-write
-Makes the device writable.
-@end table
+    read-write
+      Makes the device writable.
 
-@item change vnc @var{display},@var{options}
-Change the configuration of the VNC server. The valid syntax for @var{display}
-and @var{options} are described at @ref{sec_invocation}. eg
+  ``change vnc`` *display*,\ *options*
+    Change the configuration of the VNC server. The valid syntax for *display*
+    and *options* are described at :ref:`sec_005finvocation`. eg::
 
-@example
-(qemu) change vnc localhost:1
-@end example
+      (qemu) change vnc localhost:1
 
-@item change vnc password [@var{password}]
+  ``change vnc password`` [*password*]
 
-Change the password associated with the VNC server. If the new password is not
-supplied, the monitor will prompt for it to be entered. VNC passwords are only
-significant up to 8 letters. eg
+    Change the password associated with the VNC server. If the new password
+    is not supplied, the monitor will prompt for it to be entered. VNC
+    passwords are only significant up to 8 letters. eg::
 
-@example
-(qemu) change vnc password
-Password: ********
-@end example
+      (qemu) change vnc password
+      Password: ********
 
-@end table
-ETEXI
+ERST
 
     {
         .name       = "screendump",
@@ -281,11 +255,10 @@ ETEXI
         .cmd        = hmp_screendump,
     },
 
-STEXI
-@item screendump @var{filename}
-@findex screendump
-Save screen into PPM image @var{filename}.
-ETEXI
+SRST
+``screendump`` *filename*
+  Save screen into PPM image *filename*.
+ERST
 
     {
         .name       = "logfile",
@@ -295,11 +268,10 @@ ETEXI
         .cmd        = hmp_logfile,
     },
 
-STEXI
-@item logfile @var{filename}
-@findex logfile
-Output logs to @var{filename}.
-ETEXI
+SRST
+``logfile`` *filename*
+  Output logs to *filename*.
+ERST
 
     {
         .name       = "trace-event",
@@ -311,11 +283,10 @@ ETEXI
         .command_completion = trace_event_completion,
     },
 
-STEXI
-@item trace-event
-@findex trace-event
-changes status of a trace event
-ETEXI
+SRST
+``trace-event``
+  changes status of a trace event
+ERST
 
 #if defined(CONFIG_TRACE_SIMPLE)
     {
@@ -326,11 +297,11 @@ ETEXI
         .cmd        = hmp_trace_file,
     },
 
-STEXI
-@item trace-file on|off|flush
-@findex trace-file
-Open, close, or flush the trace file.  If no argument is given, the status of the trace file is displayed.
-ETEXI
+SRST
+``trace-file on|off|flush``
+  Open, close, or flush the trace file.  If no argument is given, the
+  status of the trace file is displayed.
+ERST
 #endif
 
     {
@@ -341,11 +312,10 @@ ETEXI
         .cmd        = hmp_log,
     },
 
-STEXI
-@item log @var{item1}[,...]
-@findex log
-Activate logging of the specified items.
-ETEXI
+SRST
+``log`` *item1*\ [,...]
+  Activate logging of the specified items.
+ERST
 
     {
         .name       = "savevm",
@@ -355,17 +325,16 @@ ETEXI
         .cmd        = hmp_savevm,
     },
 
-STEXI
-@item savevm @var{tag}
-@findex savevm
-Create a snapshot of the whole virtual machine. If @var{tag} is
-provided, it is used as human readable identifier. If there is already
-a snapshot with the same tag, it is replaced. More info at
-@ref{vm_snapshots}.
+SRST
+``savevm`` *tag*
+  Create a snapshot of the whole virtual machine. If *tag* is
+  provided, it is used as human readable identifier. If there is already
+  a snapshot with the same tag, it is replaced. More info at
+  :ref:`vm_005fsnapshots`.
 
-Since 4.0, savevm stopped allowing the snapshot id to be set, accepting
-only @var{tag} as parameter.
-ETEXI
+  Since 4.0, savevm stopped allowing the snapshot id to be set, accepting
+  only *tag* as parameter.
+ERST
 
     {
         .name       = "loadvm",
@@ -376,14 +345,13 @@ ETEXI
         .command_completion = loadvm_completion,
     },
 
-STEXI
-@item loadvm @var{tag}
-@findex loadvm
-Set the whole virtual machine to the snapshot identified by the tag
-@var{tag}.
+SRST
+``loadvm`` *tag*
+  Set the whole virtual machine to the snapshot identified by the tag
+  *tag*.
 
-Since 4.0, loadvm stopped accepting snapshot id as parameter.
-ETEXI
+  Since 4.0, loadvm stopped accepting snapshot id as parameter.
+ERST
 
     {
         .name       = "delvm",
@@ -394,14 +362,13 @@ ETEXI
         .command_completion = delvm_completion,
     },
 
-STEXI
-@item delvm @var{tag}
-@findex delvm
-Delete the snapshot identified by @var{tag}.
+SRST
+``delvm`` *tag*
+  Delete the snapshot identified by *tag*.
 
-Since 4.0, delvm stopped deleting snapshots by snapshot id, accepting
-only @var{tag} as parameter.
-ETEXI
+  Since 4.0, delvm stopped deleting snapshots by snapshot id, accepting
+  only *tag* as parameter.
+ERST
 
     {
         .name       = "singlestep",
@@ -411,12 +378,11 @@ ETEXI
         .cmd        = hmp_singlestep,
     },
 
-STEXI
-@item singlestep [off]
-@findex singlestep
-Run the emulation in single step mode.
-If called with option off, the emulation returns to normal mode.
-ETEXI
+SRST
+``singlestep [off]``
+  Run the emulation in single step mode.
+  If called with option off, the emulation returns to normal mode.
+ERST
 
     {
         .name       = "stop",
@@ -426,11 +392,10 @@ ETEXI
         .cmd        = hmp_stop,
     },
 
-STEXI
-@item stop
-@findex stop
-Stop emulation.
-ETEXI
+SRST
+``stop``
+  Stop emulation.
+ERST
 
     {
         .name       = "c|cont",
@@ -440,11 +405,10 @@ ETEXI
         .cmd        = hmp_cont,
     },
 
-STEXI
-@item c or cont
-@findex cont
-Resume emulation.
-ETEXI
+SRST
+``c`` or ``cont``
+  Resume emulation.
+ERST
 
     {
         .name       = "system_wakeup",
@@ -454,11 +418,10 @@ ETEXI
         .cmd        = hmp_system_wakeup,
     },
 
-STEXI
-@item system_wakeup
-@findex system_wakeup
-Wakeup guest from suspend.
-ETEXI
+SRST
+``system_wakeup``
+  Wakeup guest from suspend.
+ERST
 
     {
         .name       = "gdbserver",
@@ -468,11 +431,10 @@ ETEXI
         .cmd        = hmp_gdbserver,
     },
 
-STEXI
-@item gdbserver [@var{port}]
-@findex gdbserver
-Start gdbserver session (default @var{port}=1234)
-ETEXI
+SRST
+``gdbserver`` [*port*]
+  Start gdbserver session (default *port*\=1234)
+ERST
 
     {
         .name       = "x",
@@ -482,11 +444,10 @@ ETEXI
         .cmd        = hmp_memory_dump,
     },
 
-STEXI
-@item x/fmt @var{addr}
-@findex x
-Virtual memory dump starting at @var{addr}.
-ETEXI
+SRST
+``x/``\ *fmt* *addr*
+  Virtual memory dump starting at *addr*.
+ERST
 
     {
         .name       = "xp",
@@ -496,64 +457,54 @@ ETEXI
         .cmd        = hmp_physical_memory_dump,
     },
 
-STEXI
-@item xp /@var{fmt} @var{addr}
-@findex xp
-Physical memory dump starting at @var{addr}.
-
-@var{fmt} is a format which tells the command how to format the
-data. Its syntax is: @option{/@{count@}@{format@}@{size@}}
-
-@table @var
-@item count
-is the number of items to be dumped.
-
-@item format
-can be x (hex), d (signed decimal), u (unsigned decimal), o (octal),
-c (char) or i (asm instruction).
-
-@item size
-can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86,
-@code{h} or @code{w} can be specified with the @code{i} format to
-respectively select 16 or 32 bit code instruction size.
-
-@end table
-
-Examples:
-@itemize
-@item
-Dump 10 instructions at the current instruction pointer:
-@example
-(qemu) x/10i $eip
-0x90107063:  ret
-0x90107064:  sti
-0x90107065:  lea    0x0(%esi,1),%esi
-0x90107069:  lea    0x0(%edi,1),%edi
-0x90107070:  ret
-0x90107071:  jmp    0x90107080
-0x90107073:  nop
-0x90107074:  nop
-0x90107075:  nop
-0x90107076:  nop
-@end example
-
-@item
-Dump 80 16 bit values at the start of the video memory.
-@smallexample
-(qemu) xp/80hx 0xb8000
-0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
-0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
-0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72
-0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73
-0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20
-0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720
-0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
-@end smallexample
-@end itemize
-ETEXI
+SRST
+``xp /``\ *fmt* *addr*
+  Physical memory dump starting at *addr*.
+
+  *fmt* is a format which tells the command how to format the
+  data. Its syntax is: ``/{count}{format}{size}``
+
+  *count*
+    is the number of items to be dumped.
+  *format*
+    can be x (hex), d (signed decimal), u (unsigned decimal), o (octal),
+    c (char) or i (asm instruction).
+  *size*
+    can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86,
+    ``h`` or ``w`` can be specified with the ``i`` format to
+    respectively select 16 or 32 bit code instruction size.
+
+  Examples:
+
+  Dump 10 instructions at the current instruction pointer::
+
+    (qemu) x/10i $eip
+    0x90107063:  ret
+    0x90107064:  sti
+    0x90107065:  lea    0x0(%esi,1),%esi
+    0x90107069:  lea    0x0(%edi,1),%edi
+    0x90107070:  ret
+    0x90107071:  jmp    0x90107080
+    0x90107073:  nop
+    0x90107074:  nop
+    0x90107075:  nop
+    0x90107076:  nop
+
+  Dump 80 16 bit values at the start of the video memory::
+
+    (qemu) xp/80hx 0xb8000
+    0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
+    0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
+    0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72
+    0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73
+    0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20
+    0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720
+    0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+    0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+    0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+    0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+
+ERST
 
     {
         .name       = "gpa2hva",
@@ -563,12 +514,11 @@ ETEXI
         .cmd        = hmp_gpa2hva,
     },
 
-STEXI
-@item gpa2hva @var{addr}
-@findex gpa2hva
-Print the host virtual address at which the guest's physical address @var{addr}
-is mapped.
-ETEXI
+SRST
+``gpa2hva`` *addr*
+  Print the host virtual address at which the guest's physical address *addr*
+  is mapped.
+ERST
 
 #ifdef CONFIG_LINUX
     {
@@ -580,12 +530,11 @@ ETEXI
     },
 #endif
 
-STEXI
-@item gpa2hpa @var{addr}
-@findex gpa2hpa
-Print the host physical address at which the guest's physical address @var{addr}
-is mapped.
-ETEXI
+SRST
+``gpa2hpa`` *addr*
+  Print the host physical address at which the guest's physical address *addr*
+  is mapped.
+ERST
 
     {
         .name       = "gva2gpa",
@@ -595,12 +544,11 @@ ETEXI
         .cmd        = hmp_gva2gpa,
     },
 
-STEXI
-@item gva2gpa @var{addr}
-@findex gva2gpa
-Print the guest physical address at which the guest's virtual address @var{addr}
-is mapped based on the mapping for the current CPU.
-ETEXI
+SRST
+``gva2gpa`` *addr*
+  Print the guest physical address at which the guest's virtual address *addr*
+  is mapped based on the mapping for the current CPU.
+ERST
 
     {
         .name       = "p|print",
@@ -610,12 +558,11 @@ ETEXI
         .cmd        = do_print,
     },
 
-STEXI
-@item p or print/@var{fmt} @var{expr}
-@findex print
-Print expression value. Only the @var{format} part of @var{fmt} is
-used.
-ETEXI
+SRST
+``p`` or ``print/``\ *fmt* *expr*
+  Print expression value. Only the *format* part of *fmt* is
+  used.
+ERST
 
     {
         .name       = "i",
@@ -625,11 +572,10 @@ ETEXI
         .cmd        = hmp_ioport_read,
     },
 
-STEXI
-@item i/@var{fmt} @var{addr} [.@var{index}]
-@findex i
-Read I/O port.
-ETEXI
+SRST
+``i/``\ *fmt* *addr* [.\ *index*\ ]
+  Read I/O port.
+ERST
 
     {
         .name       = "o",
@@ -639,11 +585,10 @@ ETEXI
         .cmd        = hmp_ioport_write,
     },
 
-STEXI
-@item o/@var{fmt} @var{addr} @var{val}
-@findex o
-Write to I/O port.
-ETEXI
+SRST
+``o/``\ *fmt* *addr* *val*
+  Write to I/O port.
+ERST
 
     {
         .name       = "sendkey",
@@ -654,19 +599,17 @@ ETEXI
         .command_completion = sendkey_completion,
     },
 
-STEXI
-@item sendkey @var{keys}
-@findex sendkey
-Send @var{keys} to the guest. @var{keys} could be the name of the
-key or the raw value in hexadecimal format. Use @code{-} to press
-several keys simultaneously. Example:
-@example
-sendkey ctrl-alt-f1
-@end example
+SRST
+``sendkey`` *keys*
+  Send *keys* to the guest. *keys* could be the name of the
+  key or the raw value in hexadecimal format. Use ``-`` to press
+  several keys simultaneously. Example::
 
-This command is useful to send keys that your graphical user interface
-intercepts at low level, such as @code{ctrl-alt-f1} in X Window.
-ETEXI
+    sendkey ctrl-alt-f1
+
+  This command is useful to send keys that your graphical user interface
+  intercepts at low level, such as ``ctrl-alt-f1`` in X Window.
+ERST
     {
         .name       = "sync-profile",
         .args_type  = "op:s?",
@@ -676,12 +619,11 @@ ETEXI
         .cmd        = hmp_sync_profile,
     },
 
-STEXI
-@item sync-profile [on|off|reset]
-@findex sync-profile
-Enable, disable or reset synchronization profiling. With no arguments, prints
-whether profiling is on or off.
-ETEXI
+SRST
+``sync-profile [on|off|reset]``
+  Enable, disable or reset synchronization profiling. With no arguments, prints
+  whether profiling is on or off.
+ERST
 
     {
         .name       = "system_reset",
@@ -691,11 +633,10 @@ ETEXI
         .cmd        = hmp_system_reset,
     },
 
-STEXI
-@item system_reset
-@findex system_reset
-Reset the system.
-ETEXI
+SRST
+``system_reset``
+  Reset the system.
+ERST
 
     {
         .name       = "system_powerdown",
@@ -705,11 +646,10 @@ ETEXI
         .cmd        = hmp_system_powerdown,
     },
 
-STEXI
-@item system_powerdown
-@findex system_powerdown
-Power down the system (if supported).
-ETEXI
+SRST
+``system_powerdown``
+  Power down the system (if supported).
+ERST
 
     {
         .name       = "sum",
@@ -719,11 +659,10 @@ ETEXI
         .cmd        = hmp_sum,
     },
 
-STEXI
-@item sum @var{addr} @var{size}
-@findex sum
-Compute the checksum of a memory region.
-ETEXI
+SRST
+``sum`` *addr* *size*
+  Compute the checksum of a memory region.
+ERST
 
     {
         .name       = "device_add",
@@ -734,11 +673,10 @@ ETEXI
         .command_completion = device_add_completion,
     },
 
-STEXI
-@item device_add @var{config}
-@findex device_add
-Add device.
-ETEXI
+SRST
+``device_add`` *config*
+  Add device.
+ERST
 
     {
         .name       = "device_del",
@@ -749,12 +687,11 @@ ETEXI
         .command_completion = device_del_completion,
     },
 
-STEXI
-@item device_del @var{id}
-@findex device_del
-Remove device @var{id}. @var{id} may be a short ID
-or a QOM object path.
-ETEXI
+SRST
+``device_del`` *id*
+  Remove device *id*. *id* may be a short ID
+  or a QOM object path.
+ERST
 
     {
         .name       = "cpu",
@@ -764,11 +701,10 @@ ETEXI
         .cmd        = hmp_cpu,
     },
 
-STEXI
-@item cpu @var{index}
-@findex cpu
-Set the default CPU.
-ETEXI
+SRST
+``cpu`` *index*
+  Set the default CPU.
+ERST
 
     {
         .name       = "mouse_move",
@@ -778,12 +714,11 @@ ETEXI
         .cmd        = hmp_mouse_move,
     },
 
-STEXI
-@item mouse_move @var{dx} @var{dy} [@var{dz}]
-@findex mouse_move
-Move the active mouse to the specified coordinates @var{dx} @var{dy}
-with optional scroll axis @var{dz}.
-ETEXI
+SRST
+``mouse_move`` *dx* *dy* [*dz*]
+  Move the active mouse to the specified coordinates *dx* *dy*
+  with optional scroll axis *dz*.
+ERST
 
     {
         .name       = "mouse_button",
@@ -793,11 +728,10 @@ ETEXI
         .cmd        = hmp_mouse_button,
     },
 
-STEXI
-@item mouse_button @var{val}
-@findex mouse_button
-Change the active mouse button state @var{val} (1=L, 2=M, 4=R).
-ETEXI
+SRST
+``mouse_button`` *val*
+  Change the active mouse button state *val* (1=L, 2=M, 4=R).
+ERST
 
     {
         .name       = "mouse_set",
@@ -807,15 +741,14 @@ ETEXI
         .cmd        = hmp_mouse_set,
     },
 
-STEXI
-@item mouse_set @var{index}
-@findex mouse_set
-Set which mouse device receives events at given @var{index}, index
-can be obtained with
-@example
-info mice
-@end example
-ETEXI
+SRST
+``mouse_set`` *index*
+  Set which mouse device receives events at given *index*, index
+  can be obtained with::
+
+    info mice
+
+ERST
 
     {
         .name       = "wavcapture",
@@ -824,20 +757,18 @@ ETEXI
         .help       = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)",
         .cmd        = hmp_wavcapture,
     },
-STEXI
-@item wavcapture @var{filename} @var{audiodev} [@var{frequency} [@var{bits} [@var{channels}]]]
-@findex wavcapture
-Capture audio into @var{filename} from @var{audiodev}, using sample rate
-@var{frequency} bits per sample @var{bits} and number of channels
-@var{channels}.
+SRST
+``wavcapture`` *filename* *audiodev* [*frequency* [*bits* [*channels*]]]
+  Capture audio into *filename* from *audiodev*, using sample rate
+  *frequency* bits per sample *bits* and number of channels
+  *channels*.
 
-Defaults:
-@itemize @minus
-@item Sample rate = 44100 Hz - CD quality
-@item Bits = 16
-@item Number of channels = 2 - Stereo
-@end itemize
-ETEXI
+  Defaults:
+
+  - Sample rate = 44100 Hz - CD quality
+  - Bits = 16
+  - Number of channels = 2 - Stereo
+ERST
 
     {
         .name       = "stopcapture",
@@ -846,14 +777,13 @@ ETEXI
         .help       = "stop capture",
         .cmd        = hmp_stopcapture,
     },
-STEXI
-@item stopcapture @var{index}
-@findex stopcapture
-Stop capture with a given @var{index}, index can be obtained with
-@example
-info capture
-@end example
-ETEXI
+SRST
+``stopcapture`` *index*
+  Stop capture with a given *index*, index can be obtained with::
+
+    info capture
+
+ERST
 
     {
         .name       = "memsave",
@@ -863,11 +793,10 @@ ETEXI
         .cmd        = hmp_memsave,
     },
 
-STEXI
-@item memsave @var{addr} @var{size} @var{file}
-@findex memsave
-save to disk virtual memory dump starting at @var{addr} of size @var{size}.
-ETEXI
+SRST
+``memsave`` *addr* *size* *file*
+  save to disk virtual memory dump starting at *addr* of size *size*.
+ERST
 
     {
         .name       = "pmemsave",
@@ -877,11 +806,10 @@ ETEXI
         .cmd        = hmp_pmemsave,
     },
 
-STEXI
-@item pmemsave @var{addr} @var{size} @var{file}
-@findex pmemsave
-save to disk physical memory dump starting at @var{addr} of size @var{size}.
-ETEXI
+SRST
+``pmemsave`` *addr* *size* *file*
+  save to disk physical memory dump starting at *addr* of size *size*.
+ERST
 
     {
         .name       = "boot_set",
@@ -891,15 +819,14 @@ ETEXI
         .cmd        = hmp_boot_set,
     },
 
-STEXI
-@item boot_set @var{bootdevicelist}
-@findex boot_set
-Define new values for the boot device list. Those values will override
-the values specified on the command line through the @code{-boot} option.
+SRST
+``boot_set`` *bootdevicelist*
+  Define new values for the boot device list. Those values will override
+  the values specified on the command line through the ``-boot`` option.
 
-The values that can be specified here depend on the machine type, but are
-the same that can be specified in the @code{-boot} command line option.
-ETEXI
+  The values that can be specified here depend on the machine type, but are
+  the same that can be specified in the ``-boot`` command line option.
+ERST
 
     {
         .name       = "nmi",
@@ -908,12 +835,10 @@ ETEXI
         .help       = "inject an NMI",
         .cmd        = hmp_nmi,
     },
-STEXI
-@item nmi @var{cpu}
-@findex nmi
-Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
-
-ETEXI
+SRST
+``nmi`` *cpu*
+  Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
+ERST
 
     {
         .name       = "ringbuf_write",
@@ -924,13 +849,11 @@ ETEXI
         .command_completion = ringbuf_write_completion,
     },
 
-STEXI
-@item ringbuf_write @var{device} @var{data}
-@findex ringbuf_write
-Write @var{data} to ring buffer character device @var{device}.
-@var{data} must be a UTF-8 string.
-
-ETEXI
+SRST
+``ringbuf_write`` *device* *data*
+  Write *data* to ring buffer character device *device*.
+  *data* must be a UTF-8 string.
+ERST
 
     {
         .name       = "ringbuf_read",
@@ -941,18 +864,16 @@ ETEXI
         .command_completion = ringbuf_write_completion,
     },
 
-STEXI
-@item ringbuf_read @var{device}
-@findex ringbuf_read
-Read and print up to @var{size} bytes from ring buffer character
-device @var{device}.
-Certain non-printable characters are printed \uXXXX, where XXXX is the
-character code in hexadecimal.  Character \ is printed \\.
-Bug: can screw up when the buffer contains invalid UTF-8 sequences,
-NUL characters, after the ring buffer lost data, and when reading
-stops because the size limit is reached.
-
-ETEXI
+SRST
+``ringbuf_read`` *device*
+  Read and print up to *size* bytes from ring buffer character
+  device *device*.
+  Certain non-printable characters are printed ``\uXXXX``, where ``XXXX`` is the
+  character code in hexadecimal.  Character ``\`` is printed ``\\``.
+  Bug: can screw up when the buffer contains invalid UTF-8 sequences,
+  NUL characters, after the ring buffer lost data, and when reading
+  stops because the size limit is reached.
+ERST
 
     {
         .name       = "announce_self",
@@ -962,16 +883,15 @@ ETEXI
         .cmd        = hmp_announce_self,
     },
 
-STEXI
-@item announce_self
-@findex announce_self
-Trigger a round of GARP/RARP broadcasts; this is useful for explicitly updating the
-network infrastructure after a reconfiguration or some forms of migration.
-The timings of the round are set by the migration announce parameters.
-An optional comma separated @var{interfaces} list restricts the announce to the
-named set of interfaces. An optional @var{id} can be used to start a separate announce
-timer and to change the parameters of it later.
-ETEXI
+SRST
+``announce_self``
+  Trigger a round of GARP/RARP broadcasts; this is useful for explicitly
+  updating the network infrastructure after a reconfiguration or some forms
+  of migration. The timings of the round are set by the migration announce
+  parameters. An optional comma separated *interfaces* list restricts the
+  announce to the named set of interfaces. An optional *id* can be used to
+  start a separate announce timer and to change the parameters of it later.
+ERST
 
     {
         .name       = "migrate",
@@ -987,13 +907,15 @@ ETEXI
     },
 
 
-STEXI
-@item migrate [-d] [-b] [-i] @var{uri}
-@findex migrate
-Migrate to @var{uri} (using -d to not wait for completion).
-       -b for migration with full copy of disk
-       -i for migration with incremental copy of disk (base image is shared)
-ETEXI
+SRST
+``migrate [-d] [-b] [-i]`` *uri*
+  Migrate to *uri* (using -d to not wait for completion).
+
+  ``-b``
+    for migration with full copy of disk
+  ``-i``
+    for migration with incremental copy of disk (base image is shared)
+ERST
 
     {
         .name       = "migrate_cancel",
@@ -1003,11 +925,10 @@ ETEXI
         .cmd        = hmp_migrate_cancel,
     },
 
-STEXI
-@item migrate_cancel
-@findex migrate_cancel
-Cancel the current VM migration.
-ETEXI
+SRST
+``migrate_cancel``
+  Cancel the current VM migration.
+ERST
 
     {
         .name       = "migrate_continue",
@@ -1016,11 +937,10 @@ ETEXI
         .help       = "Continue migration from the given paused state",
         .cmd        = hmp_migrate_continue,
     },
-STEXI
-@item migrate_continue @var{state}
-@findex migrate_continue
-Continue migration from the paused state @var{state}
-ETEXI
+SRST
+``migrate_continue`` *state*
+  Continue migration from the paused state *state*
+ERST
 
     {
         .name       = "migrate_incoming",
@@ -1030,12 +950,11 @@ ETEXI
         .cmd        = hmp_migrate_incoming,
     },
 
-STEXI
-@item migrate_incoming @var{uri}
-@findex migrate_incoming
-Continue an incoming migration using the @var{uri} (that has the same syntax
-as the -incoming option).
-ETEXI
+SRST
+``migrate_incoming`` *uri*
+  Continue an incoming migration using the *uri* (that has the same syntax
+  as the ``-incoming`` option).
+ERST
 
     {
         .name       = "migrate_recover",
@@ -1045,11 +964,10 @@ ETEXI
         .cmd        = hmp_migrate_recover,
     },
 
-STEXI
-@item migrate_recover @var{uri}
-@findex migrate_recover
-Continue a paused incoming postcopy migration using the @var{uri}.
-ETEXI
+SRST
+``migrate_recover`` *uri*
+  Continue a paused incoming postcopy migration using the *uri*.
+ERST
 
     {
         .name       = "migrate_pause",
@@ -1059,11 +977,10 @@ ETEXI
         .cmd        = hmp_migrate_pause,
     },
 
-STEXI
-@item migrate_pause
-@findex migrate_pause
-Pause an ongoing migration.  Currently it only supports postcopy.
-ETEXI
+SRST
+``migrate_pause``
+  Pause an ongoing migration.  Currently it only supports postcopy.
+ERST
 
     {
         .name       = "migrate_set_cache_size",
@@ -1078,11 +995,10 @@ ETEXI
         .cmd        = hmp_migrate_set_cache_size,
     },
 
-STEXI
-@item migrate_set_cache_size @var{value}
-@findex migrate_set_cache_size
-Set cache size to @var{value} (in bytes) for xbzrle migrations.
-ETEXI
+SRST
+``migrate_set_cache_size`` *value*
+  Set cache size to *value* (in bytes) for xbzrle migrations.
+ERST
 
     {
         .name       = "migrate_set_speed",
@@ -1093,11 +1009,10 @@ ETEXI
         .cmd        = hmp_migrate_set_speed,
     },
 
-STEXI
-@item migrate_set_speed @var{value}
-@findex migrate_set_speed
-Set maximum speed to @var{value} (in bytes) for migrations.
-ETEXI
+SRST
+``migrate_set_speed`` *value*
+  Set maximum speed to *value* (in bytes) for migrations.
+ERST
 
     {
         .name       = "migrate_set_downtime",
@@ -1107,11 +1022,10 @@ ETEXI
         .cmd        = hmp_migrate_set_downtime,
     },
 
-STEXI
-@item migrate_set_downtime @var{second}
-@findex migrate_set_downtime
-Set maximum tolerated downtime (in seconds) for migration.
-ETEXI
+SRST
+``migrate_set_downtime`` *second*
+  Set maximum tolerated downtime (in seconds) for migration.
+ERST
 
     {
         .name       = "migrate_set_capability",
@@ -1122,11 +1036,10 @@ ETEXI
         .command_completion = migrate_set_capability_completion,
     },
 
-STEXI
-@item migrate_set_capability @var{capability} @var{state}
-@findex migrate_set_capability
-Enable/Disable the usage of a capability @var{capability} for migration.
-ETEXI
+SRST
+``migrate_set_capability`` *capability* *state*
+  Enable/Disable the usage of a capability *capability* for migration.
+ERST
 
     {
         .name       = "migrate_set_parameter",
@@ -1137,11 +1050,10 @@ ETEXI
         .command_completion = migrate_set_parameter_completion,
     },
 
-STEXI
-@item migrate_set_parameter @var{parameter} @var{value}
-@findex migrate_set_parameter
-Set the parameter @var{parameter} for migration.
-ETEXI
+SRST
+``migrate_set_parameter`` *parameter* *value*
+  Set the parameter *parameter* for migration.
+ERST
 
     {
         .name       = "migrate_start_postcopy",
@@ -1154,12 +1066,11 @@ ETEXI
         .cmd        = hmp_migrate_start_postcopy,
     },
 
-STEXI
-@item migrate_start_postcopy
-@findex migrate_start_postcopy
-Switch in-progress migration to postcopy mode. Ignored after the end of
-migration (or once already in postcopy).
-ETEXI
+SRST
+``migrate_start_postcopy``
+  Switch in-progress migration to postcopy mode. Ignored after the end of
+  migration (or once already in postcopy).
+ERST
 
     {
         .name       = "x_colo_lost_heartbeat",
@@ -1170,11 +1081,10 @@ ETEXI
         .cmd = hmp_x_colo_lost_heartbeat,
     },
 
-STEXI
-@item x_colo_lost_heartbeat
-@findex x_colo_lost_heartbeat
-Tell COLO that heartbeat is lost, a failover or takeover is needed.
-ETEXI
+SRST
+``x_colo_lost_heartbeat``
+  Tell COLO that heartbeat is lost, a failover or takeover is needed.
+ERST
 
     {
         .name       = "client_migrate_info",
@@ -1184,13 +1094,12 @@ ETEXI
         .cmd        = hmp_client_migrate_info,
     },
 
-STEXI
-@item client_migrate_info @var{protocol} @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
-@findex client_migrate_info
-Set migration information for remote display.  This makes the server
-ask the client to automatically reconnect using the new parameters
-once migration finished successfully.  Only implemented for SPICE.
-ETEXI
+SRST
+``client_migrate_info`` *protocol* *hostname* *port* *tls-port* *cert-subject*
+  Set migration information for remote display.  This makes the server
+  ask the client to automatically reconnect using the new parameters
+  once migration finished successfully.  Only implemented for SPICE.
+ERST
 
     {
         .name       = "dump-guest-memory",
@@ -1209,24 +1118,34 @@ ETEXI
         .cmd        = hmp_dump_guest_memory,
     },
 
-STEXI
-@item dump-guest-memory [-p] @var{filename} @var{begin} @var{length}
-@item dump-guest-memory [-z|-l|-s|-w] @var{filename}
-@findex dump-guest-memory
-Dump guest memory to @var{protocol}. The file can be processed with crash or
-gdb. Without -z|-l|-s|-w, the dump format is ELF.
-        -p: do paging to get guest's memory mapping.
-        -z: dump in kdump-compressed format, with zlib compression.
-        -l: dump in kdump-compressed format, with lzo compression.
-        -s: dump in kdump-compressed format, with snappy compression.
-        -w: dump in Windows crashdump format (can be used instead of ELF-dump converting),
-            for Windows x64 guests with vmcoreinfo driver only
-  filename: dump file name.
-     begin: the starting physical address. It's optional, and should be
-            specified together with length.
-    length: the memory size, in bytes. It's optional, and should be specified
-            together with begin.
-ETEXI
+SRST
+``dump-guest-memory [-p]`` *filename* *begin* *length*
+  \ 
+``dump-guest-memory [-z|-l|-s|-w]`` *filename*
+  Dump guest memory to *protocol*. The file can be processed with crash or
+  gdb. Without ``-z|-l|-s|-w``, the dump format is ELF.
+
+  ``-p``
+    do paging to get guest's memory mapping.
+  ``-z``
+    dump in kdump-compressed format, with zlib compression.
+  ``-l``
+    dump in kdump-compressed format, with lzo compression.
+  ``-s``
+    dump in kdump-compressed format, with snappy compression.
+  ``-w``
+    dump in Windows crashdump format (can be used instead of ELF-dump converting),
+    for Windows x64 guests with vmcoreinfo driver only
+  *filename*
+    dump file name.
+  *begin*
+    the starting physical address. It's optional, and should be
+    specified together with *length*.
+  *length*
+    the memory size, in bytes. It's optional, and should be specified
+    together with *begin*.
+
+ERST
 
 #if defined(TARGET_S390X)
     {
@@ -1238,11 +1157,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item dump-skeys @var{filename}
-@findex dump-skeys
-Save guest storage keys to a file.
-ETEXI
+SRST
+``dump-skeys`` *filename*
+  Save guest storage keys to a file.
+ERST
 
 #if defined(TARGET_S390X)
     {
@@ -1254,11 +1172,10 @@ ETEXI
     },
 #endif
 
-STEXI
-@item migration_mode @var{mode}
-@findex migration_mode
-Enables or disables migration mode.
-ETEXI
+SRST
+``migration_mode`` *mode*
+  Enables or disables migration mode.
+ERST
 
     {
         .name       = "snapshot_blkdev",
@@ -1275,11 +1192,10 @@ ETEXI
         .cmd        = hmp_snapshot_blkdev,
     },
 
-STEXI
-@item snapshot_blkdev
-@findex snapshot_blkdev
-Snapshot device, using snapshot file as target if provided
-ETEXI
+SRST
+``snapshot_blkdev``
+  Snapshot device, using snapshot file as target if provided
+ERST
 
     {
         .name       = "snapshot_blkdev_internal",
@@ -1291,11 +1207,10 @@ ETEXI
         .cmd        = hmp_snapshot_blkdev_internal,
     },
 
-STEXI
-@item snapshot_blkdev_internal
-@findex snapshot_blkdev_internal
-Take an internal snapshot on device if it support
-ETEXI
+SRST
+``snapshot_blkdev_internal``
+  Take an internal snapshot on device if it support
+ERST
 
     {
         .name       = "snapshot_delete_blkdev_internal",
@@ -1309,11 +1224,10 @@ ETEXI
         .cmd        = hmp_snapshot_delete_blkdev_internal,
     },
 
-STEXI
-@item snapshot_delete_blkdev_internal
-@findex snapshot_delete_blkdev_internal
-Delete an internal snapshot on device if it support
-ETEXI
+SRST
+``snapshot_delete_blkdev_internal``
+  Delete an internal snapshot on device if it support
+ERST
 
     {
         .name       = "drive_mirror",
@@ -1329,12 +1243,11 @@ ETEXI
                       "so that the result does not need a backing file.\n\t\t\t",
         .cmd        = hmp_drive_mirror,
     },
-STEXI
-@item drive_mirror
-@findex drive_mirror
-Start mirroring a block device's writes to a new destination,
-using the specified target.
-ETEXI
+SRST
+``drive_mirror``
+  Start mirroring a block device's writes to a new destination,
+  using the specified target.
+ERST
 
     {
         .name       = "drive_backup",
@@ -1352,11 +1265,10 @@ ETEXI
                       "(if the target format supports it).\n\t\t\t",
         .cmd        = hmp_drive_backup,
     },
-STEXI
-@item drive_backup
-@findex drive_backup
-Start a point-in-time copy of a block device to a specificed target.
-ETEXI
+SRST
+``drive_backup``
+  Start a point-in-time copy of a block device to a specificed target.
+ERST
 
     {
         .name       = "drive_add",
@@ -1370,11 +1282,10 @@ ETEXI
         .cmd        = hmp_drive_add,
     },
 
-STEXI
-@item drive_add
-@findex drive_add
-Add drive to PCI storage controller.
-ETEXI
+SRST
+``drive_add``
+  Add drive to PCI storage controller.
+ERST
 
     {
         .name       = "pcie_aer_inject_error",
@@ -1394,11 +1305,10 @@ ETEXI
         .cmd        = hmp_pcie_aer_inject_error,
     },
 
-STEXI
-@item pcie_aer_inject_error
-@findex pcie_aer_inject_error
-Inject PCIe AER error
-ETEXI
+SRST
+``pcie_aer_inject_error``
+  Inject PCIe AER error
+ERST
 
     {
         .name       = "netdev_add",
@@ -1409,11 +1319,10 @@ ETEXI
         .command_completion = netdev_add_completion,
     },
 
-STEXI
-@item netdev_add
-@findex netdev_add
-Add host network device.
-ETEXI
+SRST
+``netdev_add``
+  Add host network device.
+ERST
 
     {
         .name       = "netdev_del",
@@ -1424,11 +1333,10 @@ ETEXI
         .command_completion = netdev_del_completion,
     },
 
-STEXI
-@item netdev_del
-@findex netdev_del
-Remove host network device.
-ETEXI
+SRST
+``netdev_del``
+  Remove host network device.
+ERST
 
     {
         .name       = "object_add",
@@ -1439,11 +1347,10 @@ ETEXI
         .command_completion = object_add_completion,
     },
 
-STEXI
-@item object_add
-@findex object_add
-Create QOM object.
-ETEXI
+SRST
+``object_add``
+  Create QOM object.
+ERST
 
     {
         .name       = "object_del",
@@ -1454,42 +1361,39 @@ ETEXI
         .command_completion = object_del_completion,
     },
 
-STEXI
-@item object_del
-@findex object_del
-Destroy QOM object.
-ETEXI
+SRST
+``object_del``
+  Destroy QOM object.
+ERST
 
 #ifdef CONFIG_SLIRP
     {
         .name       = "hostfwd_add",
-        .args_type  = "arg1:s,arg2:s?,arg3:s?",
-        .params     = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
+        .args_type  = "arg1:s,arg2:s?",
+        .params     = "[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
         .help       = "redirect TCP or UDP connections from host to guest (requires -net user)",
         .cmd        = hmp_hostfwd_add,
     },
 #endif
-STEXI
-@item hostfwd_add
-@findex hostfwd_add
-Redirect TCP or UDP connections from host to guest (requires -net user).
-ETEXI
+SRST
+``hostfwd_add``
+  Redirect TCP or UDP connections from host to guest (requires -net user).
+ERST
 
 #ifdef CONFIG_SLIRP
     {
         .name       = "hostfwd_remove",
-        .args_type  = "arg1:s,arg2:s?,arg3:s?",
-        .params     = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport",
+        .args_type  = "arg1:s,arg2:s?",
+        .params     = "[netdev_id] [tcp|udp]:[hostaddr]:hostport",
         .help       = "remove host-to-guest TCP or UDP redirection",
         .cmd        = hmp_hostfwd_remove,
     },
 
 #endif
-STEXI
-@item hostfwd_remove
-@findex hostfwd_remove
-Remove host-to-guest TCP or UDP redirection.
-ETEXI
+SRST
+``hostfwd_remove``
+  Remove host-to-guest TCP or UDP redirection.
+ERST
 
     {
         .name       = "balloon",
@@ -1499,11 +1403,10 @@ ETEXI
         .cmd        = hmp_balloon,
     },
 
-STEXI
-@item balloon @var{value}
-@findex balloon
-Request VM to change its memory allocation to @var{value} (in MB).
-ETEXI
+SRST
+``balloon`` *value*
+  Request VM to change its memory allocation to *value* (in MB).
+ERST
 
     {
         .name       = "set_link",
@@ -1514,11 +1417,10 @@ ETEXI
         .command_completion = set_link_completion,
     },
 
-STEXI
-@item set_link @var{name} [on|off]
-@findex set_link
-Switch link @var{name} on (i.e. up) or off (i.e. down).
-ETEXI
+SRST
+``set_link`` *name* ``[on|off]``
+  Switch link *name* on (i.e. up) or off (i.e. down).
+ERST
 
     {
         .name       = "watchdog_action",
@@ -1529,11 +1431,10 @@ ETEXI
         .command_completion = watchdog_action_completion,
     },
 
-STEXI
-@item watchdog_action
-@findex watchdog_action
-Change watchdog action.
-ETEXI
+SRST
+``watchdog_action``
+  Change watchdog action.
+ERST
 
     {
         .name       = "acl_show",
@@ -1543,14 +1444,13 @@ ETEXI
         .cmd        = hmp_acl_show,
     },
 
-STEXI
-@item acl_show @var{aclname}
-@findex acl_show
-List all the matching rules in the access control list, and the default
-policy. There are currently two named access control lists,
-@var{vnc.x509dname} and @var{vnc.username} matching on the x509 client
-certificate distinguished name, and SASL username respectively.
-ETEXI
+SRST
+``acl_show`` *aclname*
+  List all the matching rules in the access control list, and the default
+  policy. There are currently two named access control lists,
+  *vnc.x509dname* and *vnc.username* matching on the x509 client
+  certificate distinguished name, and SASL username respectively.
+ERST
 
     {
         .name       = "acl_policy",
@@ -1560,13 +1460,12 @@ ETEXI
         .cmd        = hmp_acl_policy,
     },
 
-STEXI
-@item acl_policy @var{aclname} @code{allow|deny}
-@findex acl_policy
-Set the default access control list policy, used in the event that
-none of the explicit rules match. The default policy at startup is
-always @code{deny}.
-ETEXI
+SRST
+``acl_policy`` *aclname* ``allow|deny``
+  Set the default access control list policy, used in the event that
+  none of the explicit rules match. The default policy at startup is
+  always ``deny``.
+ERST
 
     {
         .name       = "acl_add",
@@ -1576,16 +1475,15 @@ ETEXI
         .cmd        = hmp_acl_add,
     },
 
-STEXI
-@item acl_add @var{aclname} @var{match} @code{allow|deny} [@var{index}]
-@findex acl_add
-Add a match rule to the access control list, allowing or denying access.
-The match will normally be an exact username or x509 distinguished name,
-but can optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to
-allow all users in the @code{EXAMPLE.COM} kerberos realm. The match will
-normally be appended to the end of the ACL, but can be inserted
-earlier in the list if the optional @var{index} parameter is supplied.
-ETEXI
+SRST
+``acl_add`` *aclname* *match* ``allow|deny`` [*index*]
+  Add a match rule to the access control list, allowing or denying access.
+  The match will normally be an exact username or x509 distinguished name,
+  but can optionally include wildcard globs. eg ``*@EXAMPLE.COM`` to
+  allow all users in the ``EXAMPLE.COM`` kerberos realm. The match will
+  normally be appended to the end of the ACL, but can be inserted
+  earlier in the list if the optional *index* parameter is supplied.
+ERST
 
     {
         .name       = "acl_remove",
@@ -1595,11 +1493,10 @@ ETEXI
         .cmd        = hmp_acl_remove,
     },
 
-STEXI
-@item acl_remove @var{aclname} @var{match}
-@findex acl_remove
-Remove the specified match rule from the access control list.
-ETEXI
+SRST
+``acl_remove`` *aclname* *match*
+  Remove the specified match rule from the access control list.
+ERST
 
     {
         .name       = "acl_reset",
@@ -1609,12 +1506,11 @@ ETEXI
         .cmd        = hmp_acl_reset,
     },
 
-STEXI
-@item acl_reset @var{aclname}
-@findex acl_reset
-Remove all matches from the access control list, and set the default
-policy back to @code{deny}.
-ETEXI
+SRST
+``acl_reset`` *aclname*
+  Remove all matches from the access control list, and set the default
+  policy back to ``deny``.
+ERST
 
     {
         .name       = "nbd_server_start",
@@ -1623,14 +1519,13 @@ ETEXI
         .help       = "serve block devices on the given host and port",
         .cmd        = hmp_nbd_server_start,
     },
-STEXI
-@item nbd_server_start @var{host}:@var{port}
-@findex nbd_server_start
-Start an NBD server on the given host and/or port.  If the @option{-a}
-option is included, all of the virtual machine's block devices that
-have an inserted media on them are automatically exported; in this case,
-the @option{-w} option makes the devices writable too.
-ETEXI
+SRST
+``nbd_server_start`` *host*:*port*
+  Start an NBD server on the given host and/or port.  If the ``-a``
+  option is included, all of the virtual machine's block devices that
+  have an inserted media on them are automatically exported; in this case,
+  the ``-w`` option makes the devices writable too.
+ERST
 
     {
         .name       = "nbd_server_add",
@@ -1639,14 +1534,13 @@ ETEXI
         .help       = "export a block device via NBD",
         .cmd        = hmp_nbd_server_add,
     },
-STEXI
-@item nbd_server_add @var{device} [ @var{name} ]
-@findex nbd_server_add
-Export a block device through QEMU's NBD server, which must be started
-beforehand with @command{nbd_server_start}.  The @option{-w} option makes the
-exported device writable too.  The export name is controlled by @var{name},
-defaulting to @var{device}.
-ETEXI
+SRST
+``nbd_server_add`` *device* [ *name* ]
+  Export a block device through QEMU's NBD server, which must be started
+  beforehand with ``nbd_server_start``.  The ``-w`` option makes the
+  exported device writable too.  The export name is controlled by *name*,
+  defaulting to *device*.
+ERST
 
     {
         .name       = "nbd_server_remove",
@@ -1655,15 +1549,14 @@ ETEXI
         .help       = "remove an export previously exposed via NBD",
         .cmd        = hmp_nbd_server_remove,
     },
-STEXI
-@item nbd_server_remove [-f] @var{name}
-@findex nbd_server_remove
-Stop exporting a block device through QEMU's NBD server, which was
-previously started with @command{nbd_server_add}.  The @option{-f}
-option forces the server to drop the export immediately even if
-clients are connected; otherwise the command fails unless there are no
-clients.
-ETEXI
+SRST
+``nbd_server_remove [-f]`` *name*
+  Stop exporting a block device through QEMU's NBD server, which was
+  previously started with ``nbd_server_add``.  The ``-f``
+  option forces the server to drop the export immediately even if
+  clients are connected; otherwise the command fails unless there are no
+  clients.
+ERST
 
     {
         .name       = "nbd_server_stop",
@@ -1672,11 +1565,10 @@ ETEXI
         .help       = "stop serving block devices using the NBD protocol",
         .cmd        = hmp_nbd_server_stop,
     },
-STEXI
-@item nbd_server_stop
-@findex nbd_server_stop
-Stop the QEMU embedded NBD server.
-ETEXI
+SRST
+``nbd_server_stop``
+  Stop the QEMU embedded NBD server.
+ERST
 
 
 #if defined(TARGET_I386)
@@ -1690,11 +1582,10 @@ ETEXI
     },
 
 #endif
-STEXI
-@item mce @var{cpu} @var{bank} @var{status} @var{mcgstatus} @var{addr} @var{misc}
-@findex mce (x86)
-Inject an MCE on the given CPU (x86 only).
-ETEXI
+SRST
+``mce`` *cpu* *bank* *status* *mcgstatus* *addr* *misc*
+  Inject an MCE on the given CPU (x86 only).
+ERST
 
     {
         .name       = "getfd",
@@ -1704,13 +1595,12 @@ ETEXI
         .cmd        = hmp_getfd,
     },
 
-STEXI
-@item getfd @var{fdname}
-@findex getfd
-If a file descriptor is passed alongside this command using the SCM_RIGHTS
-mechanism on unix sockets, it is stored using the name @var{fdname} for
-later use by other monitor commands.
-ETEXI
+SRST
+``getfd`` *fdname*
+  If a file descriptor is passed alongside this command using the SCM_RIGHTS
+  mechanism on unix sockets, it is stored using the name *fdname* for
+  later use by other monitor commands.
+ERST
 
     {
         .name       = "closefd",
@@ -1720,13 +1610,12 @@ ETEXI
         .cmd        = hmp_closefd,
     },
 
-STEXI
-@item closefd @var{fdname}
-@findex closefd
-Close the file descriptor previously assigned to @var{fdname} using the
-@code{getfd} command. This is only needed if the file descriptor was never
-used by another monitor command.
-ETEXI
+SRST
+``closefd`` *fdname*
+  Close the file descriptor previously assigned to *fdname* using the
+  ``getfd`` command. This is only needed if the file descriptor was never
+  used by another monitor command.
+ERST
 
     {
         .name       = "block_passwd",
@@ -1736,13 +1625,12 @@ ETEXI
         .cmd        = hmp_block_passwd,
     },
 
-STEXI
-@item block_passwd @var{device} @var{password}
-@findex block_passwd
-Set the encrypted device @var{device} password to @var{password}
+SRST
+``block_passwd`` *device* *password*
+  Set the encrypted device *device* password to *password*
 
-This command is now obsolete and will always return an error since 2.10
-ETEXI
+  This command is now obsolete and will always return an error since 2.10
+ERST
 
     {
         .name       = "block_set_io_throttle",
@@ -1752,12 +1640,12 @@ ETEXI
         .cmd        = hmp_block_set_io_throttle,
     },
 
-STEXI
-@item block_set_io_throttle @var{device} @var{bps} @var{bps_rd} @var{bps_wr} @var{iops} @var{iops_rd} @var{iops_wr}
-@findex block_set_io_throttle
-Change I/O throttle limits for a block drive to @var{bps} @var{bps_rd} @var{bps_wr} @var{iops} @var{iops_rd} @var{iops_wr}.
-@var{device} can be a block device name, a qdev ID or a QOM path.
-ETEXI
+SRST
+``block_set_io_throttle`` *device* *bps* *bps_rd* *bps_wr* *iops* *iops_rd* *iops_wr*
+  Change I/O throttle limits for a block drive to
+  *bps* *bps_rd* *bps_wr* *iops* *iops_rd* *iops_wr*.
+  *device* can be a block device name, a qdev ID or a QOM path.
+ERST
 
     {
         .name       = "set_password",
@@ -1767,16 +1655,15 @@ ETEXI
         .cmd        = hmp_set_password,
     },
 
-STEXI
-@item set_password [ vnc | spice ] password [ action-if-connected ]
-@findex set_password
-Change spice/vnc password.  Use zero to make the password stay valid
-forever.  @var{action-if-connected} specifies what should happen in
-case a connection is established: @var{fail} makes the password change
-fail.  @var{disconnect} changes the password and disconnects the
-client.  @var{keep} changes the password and keeps the connection up.
-@var{keep} is the default.
-ETEXI
+SRST
+``set_password [ vnc | spice ] password [ action-if-connected ]``
+  Change spice/vnc password.  Use zero to make the password stay valid
+  forever.  *action-if-connected* specifies what should happen in
+  case a connection is established: *fail* makes the password change
+  fail.  *disconnect* changes the password and disconnects the
+  client.  *keep* changes the password and keeps the connection up.
+  *keep* is the default.
+ERST
 
     {
         .name       = "expire_password",
@@ -1786,28 +1673,22 @@ ETEXI
         .cmd        = hmp_expire_password,
     },
 
-STEXI
-@item expire_password [ vnc | spice ] expire-time
-@findex expire_password
-Specify when a password for spice/vnc becomes
-invalid. @var{expire-time} accepts:
-
-@table @var
-@item now
-Invalidate password instantly.
-
-@item never
-Password stays valid forever.
+SRST
+``expire_password [ vnc | spice ]`` *expire-time*
+  Specify when a password for spice/vnc becomes
+  invalid. *expire-time* accepts:
 
-@item +nsec
-Password stays valid for @var{nsec} seconds starting now.
+  ``now``
+    Invalidate password instantly.
+  ``never``
+    Password stays valid forever.
+  ``+``\ *nsec*
+    Password stays valid for *nsec* seconds starting now.
+  *nsec*
+    Password is invalidated at the given time.  *nsec* are the seconds
+    passed since 1970, i.e. unix epoch.
 
-@item nsec
-Password is invalidated at the given time.  @var{nsec} are the seconds
-passed since 1970, i.e. unix epoch.
-
-@end table
-ETEXI
+ERST
 
     {
         .name       = "chardev-add",
@@ -1818,12 +1699,10 @@ ETEXI
         .command_completion = chardev_add_completion,
     },
 
-STEXI
-@item chardev-add args
-@findex chardev-add
-chardev-add accepts the same parameters as the -chardev command line switch.
-
-ETEXI
+SRST
+``chardev-add`` *args*
+  chardev-add accepts the same parameters as the -chardev command line switch.
+ERST
 
     {
         .name       = "chardev-change",
@@ -1833,13 +1712,11 @@ ETEXI
         .cmd        = hmp_chardev_change,
     },
 
-STEXI
-@item chardev-change args
-@findex chardev-change
-chardev-change accepts existing chardev @var{id} and then the same arguments
-as the -chardev command line switch (except for "id").
-
-ETEXI
+SRST
+``chardev-change`` *args*
+  chardev-change accepts existing chardev *id* and then the same arguments
+  as the -chardev command line switch (except for "id").
+ERST
 
     {
         .name       = "chardev-remove",
@@ -1850,12 +1727,10 @@ ETEXI
         .command_completion = chardev_remove_completion,
     },
 
-STEXI
-@item chardev-remove id
-@findex chardev-remove
-Removes the chardev @var{id}.
-
-ETEXI
+SRST
+``chardev-remove`` *id*
+  Removes the chardev *id*.
+ERST
 
     {
         .name       = "chardev-send-break",
@@ -1866,12 +1741,10 @@ ETEXI
         .command_completion = chardev_remove_completion,
     },
 
-STEXI
-@item chardev-send-break id
-@findex chardev-send-break
-Send a break on the chardev @var{id}.
-
-ETEXI
+SRST
+``chardev-send-break`` *id*
+  Send a break on the chardev *id*.
+ERST
 
     {
         .name       = "qemu-io",
@@ -1883,12 +1756,10 @@ ETEXI
         .cmd        = hmp_qemu_io,
     },
 
-STEXI
-@item qemu-io @var{device} @var{command}
-@findex qemu-io
-Executes a qemu-io command on the given block device.
-
-ETEXI
+SRST
+``qemu-io`` *device* *command*
+  Executes a qemu-io command on the given block device.
+ERST
 
     {
         .name       = "cpu-add",
@@ -1898,13 +1769,12 @@ ETEXI
         .cmd        = hmp_cpu_add,
     },
 
-STEXI
-@item cpu-add @var{id}
-@findex cpu-add
-Add CPU with id @var{id}.  This command is deprecated, please
-+use @code{device_add} instead. For details, refer to
-'docs/cpu-hotplug.rst'.
-ETEXI
+SRST
+``cpu-add`` *id*
+  Add CPU with id *id*.  This command is deprecated, please
+  +use ``device_add`` instead. For details, refer to
+  'docs/cpu-hotplug.rst'.
+ERST
 
     {
         .name       = "qom-list",
@@ -1915,10 +1785,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item qom-list [@var{path}]
-Print QOM properties of object at location @var{path}
-ETEXI
+SRST
+``qom-list`` [*path*]
+  Print QOM properties of object at location *path*
+ERST
 
     {
         .name       = "qom-set",
@@ -1929,10 +1799,10 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@item qom-set @var{path} @var{property} @var{value}
-Set QOM property @var{property} of object at location @var{path} to value @var{value}
-ETEXI
+SRST
+``qom-set`` *path* *property* *value*
+  Set QOM property *property* of object at location *path* to value *value*
+ERST
 
     {
         .name       = "info",
@@ -1944,6 +1814,3 @@ ETEXI
         .flags      = "p",
     },
 
-STEXI
-@end table
-ETEXI
index 8136e1342d785488cb092d7756ee8621a51a336a..6f598a0f111c5d01798bb84322db22ef8558dcb9 100644 (file)
@@ -1139,10 +1139,10 @@ static int proxy_parse_opts(QemuOpts *opts, FsDriverEntry *fs, Error **errp)
     }
     if (socket) {
         fs->path = g_strdup(socket);
-        fs->export_flags = V9FS_PROXY_SOCK_NAME;
+        fs->export_flags |= V9FS_PROXY_SOCK_NAME;
     } else {
         fs->path = g_strdup(sock_fd);
-        fs->export_flags = V9FS_PROXY_SOCK_FD;
+        fs->export_flags |= V9FS_PROXY_SOCK_FD;
     }
     return 0;
 }
index 9c3bcc84de56d8a48ddcd65a692baaa26f6c30e2..3e687d227a65ddc207230b05985956ce172cfb84 100644 (file)
@@ -14,6 +14,7 @@
 #include "qapi/error.h"
 #include "hw/core/cpu.h"
 #include "hw/i386/pc.h"
+#include "hw/pci/pci.h"
 #include "qemu/error-report.h"
 
 #define CPU_EJECT_METHOD "CPEJ"
index 2034dd749edc2316a9bee06f5b7eebde1632c958..4e74284b65b7d9e9a1b22d6ff10654c37b24609c 100644 (file)
@@ -27,7 +27,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
-#include "hw/i386/pc.h"
 #include "hw/pci/pci.h"
 #include "migration/vmstate.h"
 #include "qemu/timer.h"
@@ -40,6 +39,7 @@
 
 #include "hw/i386/ich9.h"
 #include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
 
 //#define DEBUG
 
index 6d621c31e7515bbdab45085c9735db158f4fb62d..b84dbba2c3e89c89e27b0a7073532cd584642f17 100644 (file)
@@ -38,6 +38,7 @@
 #include "hw/acpi/cpu.h"
 #include "hw/hotplug.h"
 #include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/xen/xen.h"
index bc0a286226f17da6ed5e57f43eb7126192791c17..e2c02e2bbe1d470f7e202e65ab513d6c75eb7e93 100644 (file)
@@ -6,7 +6,6 @@
 #include "target/alpha/cpu-qom.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
-#include "hw/ide.h"
 #include "hw/boards.h"
 #include "hw/intc/i8259.h"
 
index d28f57199fa13cd6eb58a3ad7a92f6554c8b3a82..e5350a287f73dd496371b9b8c97a5413c60a0989 100644 (file)
@@ -21,6 +21,7 @@
 #include "hw/dma/i8257.h"
 #include "net/net.h"
 #include "qemu/cutils.h"
+#include "net/net.h"
 
 #define MAX_IDE_BUS 2
 
index 61635f52c42d04b9585f93c17bf3fa6b445142d5..bc54fd61f94ce3f163cf00b4604958733a6baec1 100644 (file)
@@ -5,6 +5,7 @@ config ARM_VIRT
     imply VFIO_AMD_XGBE
     imply VFIO_PLATFORM
     imply VFIO_XGMAC
+    imply TPM_TIS_SYSBUS
     select A15MPCORE
     select ACPI
     select ARM_SMMUV3
index 089f9a30c12148ce5dbfda47a580b0fe69aaf992..871b1beef4c809f493a63f7a321f69b397aa81cd 100644 (file)
@@ -19,6 +19,7 @@
 #include "exec/address-spaces.h"
 #include "qapi/error.h"
 #include "cpu.h"
+#include "sysemu/sysemu.h"
 #include "hw/sysbus.h"
 #include "hw/boards.h"
 #include "hw/arm/allwinner-a10.h"
@@ -30,9 +31,30 @@ static struct arm_boot_info cubieboard_binfo = {
 
 static void cubieboard_init(MachineState *machine)
 {
-    AwA10State *a10 = AW_A10(object_new(TYPE_AW_A10));
+    AwA10State *a10;
     Error *err = NULL;
 
+    /* BIOS is not supported by this board */
+    if (bios_name) {
+        error_report("BIOS not supported for this machine");
+        exit(1);
+    }
+
+    /* This board has fixed size RAM (512MiB or 1GiB) */
+    if (machine->ram_size != 512 * MiB &&
+        machine->ram_size != 1 * GiB) {
+        error_report("This machine can only be used with 512MiB or 1GiB RAM");
+        exit(1);
+    }
+
+    /* Only allow Cortex-A8 for this board */
+    if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a8")) != 0) {
+        error_report("This board can only be used with cortex-a8 CPU");
+        exit(1);
+    }
+
+    a10 = AW_A10(object_new(TYPE_AW_A10));
+
     object_property_set_int(OBJECT(&a10->emac), 1, "phy-addr", &err);
     if (err != NULL) {
         error_reportf_err(err, "Couldn't set phy address: ");
@@ -68,8 +90,9 @@ static void cubieboard_init(MachineState *machine)
 
 static void cubieboard_machine_init(MachineClass *mc)
 {
-    mc->desc = "cubietech cubieboard (Cortex-A9)";
-    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
+    mc->desc = "cubietech cubieboard (Cortex-A8)";
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8");
+    mc->default_ram_size = 1 * GiB;
     mc->init = cubieboard_init;
     mc->block_default_type = IF_IDE;
     mc->units_per_default_bus = 1;
index f26a0e8010f58a11e736c7b83fd93c706d78fb9e..3a4bc332c42d646ff79efd564f6319cb892ccc61 100644 (file)
@@ -51,7 +51,6 @@ static void connex_init(MachineState *machine)
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    int be;
     MemoryRegion *address_space_mem = get_system_memory();
 
     uint32_t connex_rom = 0x01000000;
@@ -66,14 +65,9 @@ static void connex_init(MachineState *machine)
         exit(1);
     }
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
-#else
-    be = 0;
-#endif
     if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom,
                                dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
-                               sector_len, 2, 0, 0, 0, 0, be)) {
+                               sector_len, 2, 0, 0, 0, 0, 0)) {
         error_report("Error registering flash memory");
         exit(1);
     }
@@ -87,7 +81,6 @@ static void verdex_init(MachineState *machine)
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    int be;
     MemoryRegion *address_space_mem = get_system_memory();
 
     uint32_t verdex_rom = 0x02000000;
@@ -102,14 +95,9 @@ static void verdex_init(MachineState *machine)
         exit(1);
     }
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
-#else
-    be = 0;
-#endif
     if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom,
                                dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
-                               sector_len, 2, 0, 0, 0, 0, be)) {
+                               sector_len, 2, 0, 0, 0, 0, 0)) {
         error_report("Error registering flash memory");
         exit(1);
     }
index 6e64dfab5068f72778756b44bfc1634e671b7d4e..10420170866363d56b9f66c3213ad6d2432161f4 100644 (file)
@@ -119,7 +119,6 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
     DeviceState *mst_irq;
     DriveInfo *dinfo;
     int i;
-    int be;
     MemoryRegion *rom = g_new(MemoryRegion, 1);
 
     /* Setup CPU & memory */
@@ -130,11 +129,6 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
     memory_region_set_readonly(rom, true);
     memory_region_add_subregion(address_space_mem, 0, rom);
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
-#else
-    be = 0;
-#endif
     /* There are two 32MiB flash devices on the board */
     for (i = 0; i < 2; i ++) {
         dinfo = drive_get(IF_PFLASH, 0, i);
@@ -142,7 +136,7 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
                                    i ? "mainstone.flash1" : "mainstone.flash0",
                                    MAINSTONE_FLASH,
                                    dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
-                                   sector_len, 4, 0, 0, 0, 0, be)) {
+                                   sector_len, 4, 0, 0, 0, 0, 0)) {
             error_report("Error registering flash memory");
             exit(1);
         }
index db8b03cb833a12a2aa7cc36e86562559970904ae..b2d0cfdac8ad9d244a7819d1c67b7f840698ab21 100644 (file)
@@ -1645,22 +1645,12 @@ static void musicpal_init(MachineState *machine)
          * 0xFF800000 (if there is 8 MB flash). So remap flash access if the
          * image is smaller than 32 MB.
          */
-#ifdef TARGET_WORDS_BIGENDIAN
-        pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
-                              "musicpal.flash", flash_size,
-                              blk, 0x10000,
-                              MP_FLASH_SIZE_MAX / flash_size,
-                              2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA, 1);
-#else
         pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
                               "musicpal.flash", flash_size,
                               blk, 0x10000,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
                               0x5555, 0x2AAA, 0);
-#endif
-
     }
     sysbus_create_simple(TYPE_MV88W8618_FLASHCFG, MP_FLASHCFG_BASE, NULL);
 
index 2bebab4171bc5bdee9b46654c6e66357d1683283..de5ff447dcf4b51c213d85a549ad9d39099da6b9 100644 (file)
@@ -114,7 +114,6 @@ static void sx1_init(MachineState *machine, const int version)
     DriveInfo *dinfo;
     int fl_idx;
     uint32_t flash_size = flash0_size;
-    int be;
 
     if (machine->ram_size != mc->default_ram_size) {
         char *sz = size_to_str(mc->default_ram_size);
@@ -154,17 +153,11 @@ static void sx1_init(MachineState *machine, const int version)
                                 OMAP_CS2_BASE, &cs[3]);
 
     fl_idx = 0;
-#ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
-#else
-    be = 0;
-#endif
-
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
         if (!pflash_cfi01_register(OMAP_CS0_BASE,
                                    "omap_sx1.flash0-1", flash_size,
                                    blk_by_legacy_dinfo(dinfo),
-                                   sector_size, 4, 0, 0, 0, 0, be)) {
+                                   sector_size, 4, 0, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
@@ -187,7 +180,7 @@ static void sx1_init(MachineState *machine, const int version)
         if (!pflash_cfi01_register(OMAP_CS1_BASE,
                                    "omap_sx1.flash1-1", flash1_size,
                                    blk_by_legacy_dinfo(dinfo),
-                                   sector_size, 4, 0, 0, 0, 0, be)) {
+                                   sector_size, 4, 0, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
index b33f8f1351f8b09bffda885cf36fe0379795d56a..56a36202d7191da5c95bf0aae92439a8af43061d 100644 (file)
@@ -1134,18 +1134,22 @@ static void pxa2xx_rtc_init(Object *obj)
     s->last_rtcpicr = 0;
     s->last_hz = s->last_sw = s->last_pi = qemu_clock_get_ms(rtc_clock);
 
+    sysbus_init_irq(dev, &s->rtc_irq);
+
+    memory_region_init_io(&s->iomem, obj, &pxa2xx_rtc_ops, s,
+                          "pxa2xx-rtc", 0x10000);
+    sysbus_init_mmio(dev, &s->iomem);
+}
+
+static void pxa2xx_rtc_realize(DeviceState *dev, Error **errp)
+{
+    PXA2xxRTCState *s = PXA2XX_RTC(dev);
     s->rtc_hz    = timer_new_ms(rtc_clock, pxa2xx_rtc_hz_tick,    s);
     s->rtc_rdal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
     s->rtc_rdal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
     s->rtc_swal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
     s->rtc_swal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
     s->rtc_pi    = timer_new_ms(rtc_clock, pxa2xx_rtc_pi_tick,    s);
-
-    sysbus_init_irq(dev, &s->rtc_irq);
-
-    memory_region_init_io(&s->iomem, obj, &pxa2xx_rtc_ops, s,
-                          "pxa2xx-rtc", 0x10000);
-    sysbus_init_mmio(dev, &s->iomem);
 }
 
 static int pxa2xx_rtc_pre_save(void *opaque)
@@ -1203,6 +1207,7 @@ static void pxa2xx_rtc_sysbus_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "PXA2xx RTC Controller";
     dc->vmsd = &vmstate_pxa2xx_rtc_regs;
+    dc->realize = pxa2xx_rtc_realize;
 }
 
 static const TypeInfo pxa2xx_rtc_sysbus_info = {
index 0f2573f0045bd666bc02734df3ce28f57be07f43..e13a5f4a7cb3ef298549300dd1daf3ebc901f8d5 100644 (file)
@@ -290,19 +290,21 @@ inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
 SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
 {
     SMMUPciBus *smmu_pci_bus = s->smmu_pcibus_by_bus_num[bus_num];
+    GHashTableIter iter;
 
-    if (!smmu_pci_bus) {
-        GHashTableIter iter;
+    if (smmu_pci_bus) {
+        return smmu_pci_bus;
+    }
 
-        g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr);
-        while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) {
-            if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
-                s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
-                return smmu_pci_bus;
-            }
+    g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr);
+    while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) {
+        if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
+            s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
+            return smmu_pci_bus;
         }
     }
-    return smmu_pci_bus;
+
+    return NULL;
 }
 
 static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
index e0010881038e987f2d392bb5a1103cc0064b03ba..cbfa6934cfd6021bfdf0477f80f27e638b2e717b 100644 (file)
@@ -524,11 +524,16 @@ static void spitz_keyboard_init(Object *obj)
 
     spitz_keyboard_pre_map(s);
 
-    s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
     qdev_init_gpio_in(dev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
     qdev_init_gpio_out(dev, s->sense, SPITZ_KEY_SENSE_NUM);
 }
 
+static void spitz_keyboard_realize(DeviceState *dev, Error **errp)
+{
+    SpitzKeyboardState *s = SPITZ_KEYBOARD(dev);
+    s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
+}
+
 /* LCD backlight controller */
 
 #define LCDTG_RESCTL   0x00
@@ -1115,6 +1120,7 @@ static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd = &vmstate_spitz_kbd;
+    dc->realize = spitz_keyboard_realize;
 }
 
 static const TypeInfo spitz_keyboard_info = {
index cd8a99aaf2e411cfcba98f15d20a54c4b45f4856..3010d765bb7d393fba78cda3d1b2cf61c49eeb3d 100644 (file)
@@ -399,9 +399,6 @@ static void strongarm_rtc_init(Object *obj)
     s->last_rcnr = (uint32_t) mktimegm(&tm);
     s->last_hz = qemu_clock_get_ms(rtc_clock);
 
-    s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
-    s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
-
     sysbus_init_irq(dev, &s->rtc_irq);
     sysbus_init_irq(dev, &s->rtc_hz_irq);
 
@@ -410,6 +407,13 @@ static void strongarm_rtc_init(Object *obj)
     sysbus_init_mmio(dev, &s->iomem);
 }
 
+static void strongarm_rtc_realize(DeviceState *dev, Error **errp)
+{
+    StrongARMRTCState *s = STRONGARM_RTC(dev);
+    s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
+    s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
+}
+
 static int strongarm_rtc_pre_save(void *opaque)
 {
     StrongARMRTCState *s = opaque;
@@ -451,6 +455,7 @@ static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "StrongARM RTC Controller";
     dc->vmsd = &vmstate_strongarm_rtc_regs;
+    dc->realize = strongarm_rtc_realize;
 }
 
 static const TypeInfo strongarm_rtc_sysbus_info = {
@@ -1240,15 +1245,16 @@ static void strongarm_uart_init(Object *obj)
                           "uart", 0x10000);
     sysbus_init_mmio(dev, &s->iomem);
     sysbus_init_irq(dev, &s->irq);
-
-    s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
-    s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
 }
 
 static void strongarm_uart_realize(DeviceState *dev, Error **errp)
 {
     StrongARMUARTState *s = STRONGARM_UART(dev);
 
+    s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                       strongarm_uart_rx_to,
+                                       s);
+    s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
     qemu_chr_fe_set_handlers(&s->chr,
                              strongarm_uart_can_receive,
                              strongarm_uart_receive,
index 022fc97ecd88ac568fe43a83697204f4ce4706ee..6b6906f4cfc36198b6ef6f2c3ddc6370d0237658 100644 (file)
@@ -30,6 +30,7 @@
 #include "hw/arm/sysbus-fdt.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
+#include "sysemu/tpm.h"
 #include "hw/platform-bus.h"
 #include "hw/vfio/vfio-platform.h"
 #include "hw/vfio/vfio-calxeda-xgmac.h"
@@ -436,6 +437,37 @@ static bool vfio_platform_match(SysBusDevice *sbdev,
 
 #endif /* CONFIG_LINUX */
 
+/*
+ * add_tpm_tis_fdt_node: Create a DT node for TPM TIS
+ *
+ * See kernel documentation:
+ * Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
+ * Optional interrupt for command completion is not exposed
+ */
+static int add_tpm_tis_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+    PlatformBusFDTData *data = opaque;
+    PlatformBusDevice *pbus = data->pbus;
+    void *fdt = data->fdt;
+    const char *parent_node = data->pbus_node_name;
+    char *nodename;
+    uint32_t reg_attr[2];
+    uint64_t mmio_base;
+
+    mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+    nodename = g_strdup_printf("%s/tpm_tis@%" PRIx64, parent_node, mmio_base);
+    qemu_fdt_add_subnode(fdt, nodename);
+
+    qemu_fdt_setprop_string(fdt, nodename, "compatible", "tcg,tpm-tis-mmio");
+
+    reg_attr[0] = cpu_to_be32(mmio_base);
+    reg_attr[1] = cpu_to_be32(0x5000);
+    qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 2 * sizeof(uint32_t));
+
+    g_free(nodename);
+    return 0;
+}
+
 static int no_fdt_node(SysBusDevice *sbdev, void *opaque)
 {
     return 0;
@@ -456,6 +488,7 @@ static const BindingEntry bindings[] = {
     TYPE_BINDING(TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node),
     VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
 #endif
+    TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node),
     TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
     TYPE_BINDING("", NULL), /* last element */
 };
index 856808599d2165c3f059e7efa374417b7bf5f177..32d865a48861a4ec2203b0f9b8465dfa81ce577f 100644 (file)
@@ -48,6 +48,7 @@
 #include "sysemu/numa.h"
 #include "sysemu/runstate.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/tpm.h"
 #include "sysemu/kvm.h"
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
@@ -2083,6 +2084,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
+    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
     mc->block_default_type = IF_VIRTIO;
     mc->no_cdrom = 1;
     mc->pci_allow_0_address = true;
@@ -2196,6 +2198,11 @@ type_init(machvirt_machine_init);
 
 static void virt_machine_5_0_options(MachineClass *mc)
 {
+    static GlobalProperty compat[] = {
+        { TYPE_TPM_TIS_SYSBUS, "ppi", "false" },
+    };
+
+    compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
 }
 DEFINE_VIRT_MACHINE_AS_LATEST(5, 0)
 
index e7f4ca8bf950ddefeb07765f3d9d175d252ebc1c..878a27514001b859769590d3971433f265e6d8b3 100644 (file)
@@ -229,6 +229,33 @@ static void fdt_add_gem_nodes(VersalVirt *s)
     }
 }
 
+static void fdt_add_zdma_nodes(VersalVirt *s)
+{
+    const char clocknames[] = "clk_main\0clk_apb";
+    const char compat[] = "xlnx,zynqmp-dma-1.0";
+    int i;
+
+    for (i = XLNX_VERSAL_NR_ADMAS - 1; i >= 0; i--) {
+        uint64_t addr = MM_ADMA_CH0 + MM_ADMA_CH0_SIZE * i;
+        char *name = g_strdup_printf("/dma@%" PRIx64, addr);
+
+        qemu_fdt_add_subnode(s->fdt, name);
+
+        qemu_fdt_setprop_cell(s->fdt, name, "xlnx,bus-width", 64);
+        qemu_fdt_setprop_cells(s->fdt, name, "clocks",
+                               s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
+        qemu_fdt_setprop(s->fdt, name, "clock-names",
+                         clocknames, sizeof(clocknames));
+        qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
+                               GIC_FDT_IRQ_TYPE_SPI, VERSAL_ADMA_IRQ_0 + i,
+                               GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+        qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
+                                     2, addr, 2, 0x1000);
+        qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
+        g_free(name);
+    }
+}
+
 static void fdt_nop_memory_nodes(void *fdt, Error **errp)
 {
     Error *err = NULL;
@@ -427,6 +454,7 @@ static void versal_virt_init(MachineState *machine)
     fdt_add_uart_nodes(s);
     fdt_add_gic_nodes(s);
     fdt_add_timer_nodes(s);
+    fdt_add_zdma_nodes(s);
     fdt_add_cpu_nodes(s, psci_conduit);
     fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
     fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
index 403fc7b8814b27a413c57913c8fc30a954dbb7a7..cb0122a3a68b7bde9fd94e9a9ace966acdcca047 100644 (file)
@@ -194,6 +194,29 @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
     }
 }
 
+static void versal_create_admas(Versal *s, qemu_irq *pic)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
+        char *name = g_strdup_printf("adma%d", i);
+        DeviceState *dev;
+        MemoryRegion *mr;
+
+        dev = qdev_create(NULL, "xlnx.zdma");
+        s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
+        object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
+        qdev_init_nofail(dev);
+
+        mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
+        memory_region_add_subregion(&s->mr_ps,
+                                    MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
+
+        sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
+        g_free(name);
+    }
+}
+
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/aperture on the Versal address map.
  */
@@ -275,6 +298,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
     versal_create_apu_gic(s, pic);
     versal_create_uarts(s, pic);
     versal_create_gems(s, pic);
+    versal_create_admas(s, pic);
     versal_map_ddr(s);
     versal_unimp(s);
 
index 4bb237f22d2914fbbb96e30cd20394a72f1a6a37..a0f4095990450c1808848d420848ac7fd355cd85 100644 (file)
@@ -300,7 +300,6 @@ static void z2_init(MachineState *machine)
     uint32_t sector_len = 0x10000;
     PXA2xxState *mpu;
     DriveInfo *dinfo;
-    int be;
     void *z2_lcd;
     I2CBus *bus;
     DeviceState *wm;
@@ -308,15 +307,10 @@ static void z2_init(MachineState *machine)
     /* Setup CPU & memory */
     mpu = pxa270_init(address_space_mem, z2_binfo.ram_size, machine->cpu_type);
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
-#else
-    be = 0;
-#endif
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
                                dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
-                               sector_len, 4, 0, 0, 0, 0, be)) {
+                               sector_len, 4, 0, 0, 0, 0, 0)) {
         error_report("Error registering flash memory");
         exit(1);
     }
index 9f50a89b4a888962092e2f4daf8754eeff08e6a8..173a7521f2a72377d982eaec39ac1410930541dc 100644 (file)
@@ -1066,7 +1066,7 @@ static void OPLResetChip(FM_OPL *OPL)
        }
 }
 
-/* ----------  Create one of vietual YM3812 ----------       */
+/* ----------  Create one of virtual YM3812 ----------       */
 /* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
 FM_OPL *OPLCreate(int clock, int rate)
 {
@@ -1115,7 +1115,7 @@ FM_OPL *OPLCreate(int clock, int rate)
        return OPL;
 }
 
-/* ----------  Destroy one of vietual YM3812 ----------       */
+/* ----------  Destroy one of virtual YM3812 ----------       */
 void OPLDestroy(FM_OPL *OPL)
 {
 #ifdef OPL_OUTPUT_LOG
index 686bbc3f0dec32c38b47a6813f4e01a0620c2f02..38854645131f92234b1c351ca561f20530009e21 100644 (file)
@@ -18,6 +18,7 @@
 #include "qapi/visitor.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
+#include "qom/object_interfaces.h"
 #include "hw/xen/xen_common.h"
 #include "hw/block/xen_blkif.h"
 #include "hw/qdev-properties.h"
@@ -858,10 +859,18 @@ static XenBlockIOThread *xen_block_iothread_create(const char *id,
 {
     XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
     Error *local_err = NULL;
+    QDict *opts;
+    QObject *ret_data;
 
     iothread->id = g_strdup(id);
 
-    qmp_object_add(TYPE_IOTHREAD, id, false, NULL, &local_err);
+    opts = qdict_new();
+    qdict_put_str(opts, "qom-type", TYPE_IOTHREAD);
+    qdict_put_str(opts, "id", id);
+    qmp_object_add(opts, &ret_data, &local_err);
+    qobject_unref(opts);
+    qobject_unref(ret_data);
+
     if (local_err) {
         error_propagate(errp, local_err);
 
index 3937d1eb1a5f4831e9865aaf858f69d33e8ad56f..85f062def72b5cf6769f29b91f09cf3c00a6c39d 100644 (file)
@@ -557,7 +557,7 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
 
 qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
 {
-    char *propname = g_strdup_printf("%s[%d]",
+    g_autofree char *propname = g_strdup_printf("%s[%d]",
                                      name ? name : "unnamed-gpio-out", n);
 
     qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
index ec6776680e41fabbb36a59f6cf0cfaa657bbd854..1c0266ce9f2d74f0abc958b6b836a25998c24f34 100644 (file)
@@ -1311,7 +1311,6 @@ static void exynos4210_fimd_update(void *opaque)
                 }
                 host_fb_addr += inc_size;
                 fb_line_addr += inc_size;
-                is_dirty = false;
             }
             g_free(snap);
             blend = true;
index 05f5f8467123fe178f4291660e9fb8252436c33c..464e93161a2130464f6154ee8e1d8b36f0936ce4 100644 (file)
@@ -593,7 +593,6 @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
         n = 256;
         break;
     default:
-        format = 0;
         return;
     }
 
index 1c1b142293a64324cd5a16b15967390ba3614593..2d9c0a0d5e19620072cc1584238c9b4a7205275d 100644 (file)
@@ -372,7 +372,7 @@ static uint64_t zdma_update_descr_addr(XlnxZDMA *s, bool type,
 static void zdma_write_dst(XlnxZDMA *s, uint8_t *buf, uint32_t len)
 {
     uint32_t dst_size, dlen;
-    bool dst_intr, dst_type;
+    bool dst_intr;
     unsigned int ptype = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, POINT_TYPE);
     unsigned int rw_mode = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, MODE);
     unsigned int burst_type = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_DATA_ATTR,
@@ -386,17 +386,17 @@ static void zdma_write_dst(XlnxZDMA *s, uint8_t *buf, uint32_t len)
     while (len) {
         dst_size = FIELD_EX32(s->dsc_dst.words[2], ZDMA_CH_DST_DSCR_WORD2,
                               SIZE);
-        dst_type = FIELD_EX32(s->dsc_dst.words[3], ZDMA_CH_DST_DSCR_WORD3,
-                              TYPE);
         if (dst_size == 0 && ptype == PT_MEM) {
             uint64_t next;
+            bool dst_type = FIELD_EX32(s->dsc_dst.words[3],
+                                       ZDMA_CH_DST_DSCR_WORD3,
+                                       TYPE);
+
             next = zdma_update_descr_addr(s, dst_type,
                                           R_ZDMA_CH_DST_CUR_DSCR_LSB);
             zdma_load_descriptor(s, next, &s->dsc_dst);
             dst_size = FIELD_EX32(s->dsc_dst.words[2], ZDMA_CH_DST_DSCR_WORD2,
                                   SIZE);
-            dst_type = FIELD_EX32(s->dsc_dst.words[3], ZDMA_CH_DST_DSCR_WORD3,
-                                  TYPE);
         }
 
         /* Match what hardware does by ignoring the dst_size and only using
index bf18767e2494cfde02a5f4f5996cfa6fa864150c..9175f4b790f5c4354d18431818281373cae4bcdb 100644 (file)
@@ -22,6 +22,7 @@
 #include "qapi/error.h"
 #include "net/net.h"
 #include "qemu/log.h"
+#include "net/net.h"
 
 #define MAX_IDE_BUS 2
 
index fd50fb851af4b33a7dd26dc5128b93023b1a9345..48f1ff419174c9b5c736fed5de7d09fb5a4d29a7 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/range.h"
 #include "hw/i2c/pm_smbus.h"
 #include "hw/pci/pci.h"
 #include "migration/vmstate.h"
index cdc851598c7751caa46ddf3f1aff0eccd58e134b..c93f32f6579dbbf3d94eb9b03aa783d3d066d011 100644 (file)
@@ -20,7 +20,7 @@ config PC
     imply SGA
     imply TEST_DEVICES
     imply TPM_CRB
-    imply TPM_TIS
+    imply TPM_TIS_ISA
     imply VGA_PCI
     imply VIRTIO_VGA
     select FDC
index 9c4e46fa7466328fdb9d627ac23fb8ff9fe382c4..9a19c14e661bea0a70daa823a912a96ac8394c3a 100644 (file)
@@ -47,6 +47,7 @@
 #include "hw/rtc/mc146818rtc_regs.h"
 #include "migration/vmstate.h"
 #include "hw/mem/memory-device.h"
+#include "hw/mem/nvdimm.h"
 #include "sysemu/numa.h"
 #include "sysemu/reset.h"
 
@@ -2026,7 +2027,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         }
     }
 
-    if (TPM_IS_TIS(tpm_find())) {
+    if (TPM_IS_TIS_ISA(tpm_find())) {
         aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,
                    TPM_TIS_ADDR_SIZE, AML_READ_WRITE));
     }
@@ -2197,7 +2198,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
             /* Scan all PCI buses. Generate tables to support hotplug. */
             build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
 
-            if (TPM_IS_TIS(tpm)) {
+            if (TPM_IS_TIS_ISA(tpm)) {
                 if (misc->tpm_version == TPM_VERSION_2_0) {
                     dev = aml_device("TPM");
                     aml_append(dev, aml_name_decl("_HID",
@@ -2304,7 +2305,7 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog)
         (char *)&tpm2_ptr->log_area_start_address - table_data->data;
 
     tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
-    if (TPM_IS_TIS(tpm_find())) {
+    if (TPM_IS_TIS_ISA(tpm_find())) {
         tpm2_ptr->control_area_address = cpu_to_le64(0);
         tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
     } else if (TPM_IS_CRB(tpm_find())) {
index 6258c58ac9b472fa92477ffd8a4f470e9c464222..204b6841ec0d6bb42e9462074a5121ebbd11fee5 100644 (file)
@@ -987,24 +987,26 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level)
 static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState *s, uint8_t bus_num)
 {
     VTDBus *vtd_bus = s->vtd_as_by_bus_num[bus_num];
-    if (!vtd_bus) {
-        /*
-         * Iterate over the registered buses to find the one which
-         * currently hold this bus number, and update the bus_num
-         * lookup table:
-         */
-        GHashTableIter iter;
+    GHashTableIter iter;
 
-        g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
-        while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
-            if (pci_bus_num(vtd_bus->bus) == bus_num) {
-                s->vtd_as_by_bus_num[bus_num] = vtd_bus;
-                return vtd_bus;
-            }
+    if (vtd_bus) {
+        return vtd_bus;
+    }
+
+    /*
+     * Iterate over the registered buses to find the one which
+     * currently holds this bus number and update the bus_num
+     * lookup table.
+     */
+    g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
+    while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
+        if (pci_bus_num(vtd_bus->bus) == bus_num) {
+            s->vtd_as_by_bus_num[bus_num] = vtd_bus;
+            return vtd_bus;
         }
-        vtd_bus = NULL;
     }
-    return vtd_bus;
+
+    return NULL;
 }
 
 /* Given the @iova, get relevant @slptep. @slpte_level will be the last level
index 6ab4acb0c62e22b82178ff113ed4fe1e667f2520..362eb2a180ff9620d4db49416283dd8c804b2a91 100644 (file)
@@ -76,6 +76,7 @@
 #include "hw/boards.h"
 #include "acpi-build.h"
 #include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
 #include "qapi/error.h"
 #include "qapi/qapi-visit-common.h"
 #include "qapi/visitor.h"
index 9088db8fb601a47aca61b6acf8fbce2247967bef..e2d98243bc64797062a6e9da7581fb7ef55fd80a 100644 (file)
@@ -60,6 +60,7 @@
 #include "migration/global_state.h"
 #include "migration/misc.h"
 #include "sysemu/numa.h"
+#include "hw/mem/nvdimm.h"
 
 #define MAX_IDE_BUS 2
 
index 84cf925cf43a00decfc76cd1fae75473df2f14c9..d37c425e2236faf42b05495ab74e6414473760f7 100644 (file)
@@ -53,6 +53,7 @@
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "sysemu/numa.h"
+#include "hw/mem/nvdimm.h"
 
 /* ICH9 AHCI has 6 ports */
 #define MAX_SATA_PORTS     6
index f85b484eac631387eaa4cf609f47e437c415ac03..cb79616cede82c4dcf29cbb9bbe77decf26113da 100644 (file)
@@ -37,7 +37,6 @@
 #include "migration/vmstate.h"
 #include "hw/irq.h"
 #include "hw/isa/apm.h"
-#include "hw/i386/ioapic.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bridge.h"
 #include "hw/i386/ich9.h"
index 8a3504d9628e006e4195bfa1e50524a3391cb84f..81fc13ee9fa72b67e6332d7599b6664bdd889dc2 100644 (file)
@@ -525,8 +525,8 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
                                  * (4 + 3 * s->regs[SONIC_TFC]),
                                MEMTXATTRS_UNSPECIFIED, s->data,
                                size);
-            s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0) & ~0x1;
-            if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
+            s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0);
+            if (s->regs[SONIC_CTDA] & SONIC_DESC_EOL) {
                 /* EOL detected */
                 break;
             }
index 0b833d5a152e979214d7c39d1d3f119eec2c3539..9233248c9af0fc799b3581f58f490c80468c7e7d 100644 (file)
@@ -1150,7 +1150,8 @@ set_ims(E1000State *s, int index, uint32_t val)
 }
 
 #define getreg(x)    [x] = mac_readreg
-static uint32_t (*macreg_readops[])(E1000State *, int) = {
+typedef uint32_t (*readops)(E1000State *, int);
+static const readops macreg_readops[] = {
     getreg(PBA),      getreg(RCTL),     getreg(TDH),      getreg(TXDCTL),
     getreg(WUFC),     getreg(TDT),      getreg(CTRL),     getreg(LEDCTL),
     getreg(MANC),     getreg(MDIC),     getreg(SWSM),     getreg(STATUS),
@@ -1205,7 +1206,8 @@ static uint32_t (*macreg_readops[])(E1000State *, int) = {
 enum { NREADOPS = ARRAY_SIZE(macreg_readops) };
 
 #define putreg(x)    [x] = mac_writereg
-static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
+typedef void (*writeops)(E1000State *, int, uint32_t);
+static const writeops macreg_writeops[] = {
     putreg(PBA),      putreg(EERD),     putreg(SWSM),     putreg(WUFC),
     putreg(TDBAL),    putreg(TDBAH),    putreg(TXDCTL),   putreg(RDBAH),
     putreg(RDBAL),    putreg(LEDCTL),   putreg(VET),      putreg(FCRUC),
index 94ea34dca56dffd248a33f5ac5bee6110a020fbc..df957e0c1a09fd83b7f4fe051fece4338aaf55e1 100644 (file)
@@ -2855,7 +2855,8 @@ e1000e_set_gcr(E1000ECore *core, int index, uint32_t val)
 }
 
 #define e1000e_getreg(x)    [x] = e1000e_mac_readreg
-static uint32_t (*e1000e_macreg_readops[])(E1000ECore *, int) = {
+typedef uint32_t (*readops)(E1000ECore *, int);
+static const readops e1000e_macreg_readops[] = {
     e1000e_getreg(PBA),
     e1000e_getreg(WUFC),
     e1000e_getreg(MANC),
@@ -3061,7 +3062,8 @@ static uint32_t (*e1000e_macreg_readops[])(E1000ECore *, int) = {
 enum { E1000E_NREADOPS = ARRAY_SIZE(e1000e_macreg_readops) };
 
 #define e1000e_putreg(x)    [x] = e1000e_mac_writereg
-static void (*e1000e_macreg_writeops[])(E1000ECore *, int, uint32_t) = {
+typedef void (*writeops)(E1000ECore *, int, uint32_t);
+static const writeops e1000e_macreg_writeops[] = {
     e1000e_putreg(PBA),
     e1000e_putreg(SWSM),
     e1000e_putreg(WUFC),
index 0ba4e4dea45fb680329380e2b606899d56126330..f1cfe9d14aaf7927a1faf9e0c4c3cc9cefc2c54f 100644 (file)
@@ -94,7 +94,7 @@ static void rp_realize(PCIDevice *d, Error **errp)
 
     pcie_cap_arifwd_init(d);
     pcie_cap_deverr_init(d);
-    pcie_cap_slot_init(d, s->slot);
+    pcie_cap_slot_init(d, s);
     pcie_cap_root_init(d);
 
     pcie_chassis_create(s->chassis);
index 153a4acad27405c64554bd8a84197453a16d53d4..04aae72cd614d4d8eb9c8a3f023ec71323f09086 100644 (file)
@@ -94,7 +94,7 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
     }
     pcie_cap_flr_init(d);
     pcie_cap_deverr_init(d);
-    pcie_cap_slot_init(d, s->slot);
+    pcie_cap_slot_init(d, s);
     pcie_cap_arifwd_init(d);
 
     pcie_chassis_create(s->chassis);
index 11050a0f8bb91573be77ba4a50456740cb0b7ba3..d980c9704906cd5dd705abb7e1ed225a417c03d5 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/range.h"
 #include "hw/i386/pc.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
index a9b9ccc87657018bf1f9cc57e0bc2abc298cd758..993f467668dc471da2fe5088742a93a47a3abdfc 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "hw/i386/pc.h"
 #include "hw/pci-host/q35.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
index 08718188bb7c71659837a2ea602caa117a643582..0eb3a2a5d231205d424acff6008c836f242e6ca2 100644 (file)
@@ -495,7 +495,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
 
 /* pci express slot for pci express root/downstream port
    PCI express capability slot registers */
-void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
+void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
 {
     uint32_t pos = dev->exp.exp_cap;
 
@@ -505,13 +505,16 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
     pci_long_test_and_clear_mask(dev->config + pos + PCI_EXP_SLTCAP,
                                  ~PCI_EXP_SLTCAP_PSN);
     pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
-                               (slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
+                               (s->slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
                                PCI_EXP_SLTCAP_EIP |
-                               PCI_EXP_SLTCAP_HPS |
-                               PCI_EXP_SLTCAP_HPC |
                                PCI_EXP_SLTCAP_PIP |
                                PCI_EXP_SLTCAP_AIP |
                                PCI_EXP_SLTCAP_ABP);
+    if (s->hotplug) {
+        pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
+                                   PCI_EXP_SLTCAP_HPS |
+                                   PCI_EXP_SLTCAP_HPC);
+    }
 
     if (dev->cap_present & QEMU_PCIE_SLTCAP_PCP) {
         pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
index f8263cb306182a57620b24916fc467acaac87d1f..eb563ad4354f0da779ab04700c47e43c8843d1d3 100644 (file)
@@ -147,6 +147,7 @@ static const TypeInfo pcie_port_type_info = {
 static Property pcie_slot_props[] = {
     DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
     DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
+    DEFINE_PROP_BOOL("hotplug", PCIESlot, hotplug, true),
     DEFINE_PROP_END_OF_LIST()
 };
 
index 63bd13d2caa44609dadb24e26fa41ca9c4781f23..d0011be89eefbcb9e71a12181184ec51b24c763e 100644 (file)
@@ -27,7 +27,6 @@
 #include "migration/qemu-file-types.h"
 #include "migration/vmstate.h"
 #include "sysemu/sysemu.h"
-#include "ui/console.h"
 #include "qemu/bcd.h"
 #include "qemu/module.h"
 
index 9c1ecd423c236ed0d4e1d684674fc759617364c5..b81942e1e6f9002ee27e372aa6c473fc514726c2 100644 (file)
@@ -538,6 +538,30 @@ static bool is_virtio_scsi_device(IplParameterBlock *iplb)
     return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
 }
 
+static void update_machine_ipl_properties(IplParameterBlock *iplb)
+{
+    Object *machine = qdev_get_machine();
+    Error *err = NULL;
+
+    /* Sync loadparm */
+    if (iplb->flags & DIAG308_FLAGS_LP_VALID) {
+        uint8_t *ebcdic_loadparm = iplb->loadparm;
+        char ascii_loadparm[8];
+        int i;
+
+        for (i = 0; i < 8 && ebcdic_loadparm[i]; i++) {
+            ascii_loadparm[i] = ebcdic2ascii[(uint8_t) ebcdic_loadparm[i]];
+        }
+        ascii_loadparm[i] = 0;
+        object_property_set_str(machine, ascii_loadparm, "loadparm", &err);
+    } else {
+        object_property_set_str(machine, "", "loadparm", &err);
+    }
+    if (err) {
+        warn_report_err(err);
+    }
+}
+
 void s390_ipl_update_diag308(IplParameterBlock *iplb)
 {
     S390IPLState *ipl = get_ipl_device();
@@ -545,6 +569,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb)
     ipl->iplb = *iplb;
     ipl->iplb_valid = true;
     ipl->netboot = is_virtio_net_device(iplb);
+    update_machine_ipl_properties(iplb);
 }
 
 IplParameterBlock *s390_ipl_get_iplb(void)
index d4813105db33253fd1eba53cd7e364f9956c0bc3..3e44abe1c651d8a01f4708c2801c62d04701cefc 100644 (file)
@@ -173,16 +173,16 @@ static inline bool iplb_valid_len(IplParameterBlock *iplb)
     return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock);
 }
 
-static inline bool iplb_valid_ccw(IplParameterBlock *iplb)
+static inline bool iplb_valid(IplParameterBlock *iplb)
 {
-    return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN &&
-           iplb->pbt == S390_IPL_TYPE_CCW;
-}
-
-static inline bool iplb_valid_fcp(IplParameterBlock *iplb)
-{
-    return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN &&
-           iplb->pbt == S390_IPL_TYPE_FCP;
+    switch (iplb->pbt) {
+    case S390_IPL_TYPE_FCP:
+        return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN;
+    case S390_IPL_TYPE_CCW:
+        return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN;
+    default:
+        return false;
+    }
 }
 
 #endif
index 10d0794d60f196f177563aae00bed2181f5c1bb1..1c0cb63a6fe05fc643ad68d2137be284e2bb4948 100644 (file)
@@ -1915,7 +1915,6 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
         r->iov.iov_base = blk_blockalign(s->qdev.conf.blk, r->buflen);
     }
 
-    buflen = req->cmd.xfer;
     outbuf = r->iov.iov_base;
     memset(outbuf, 0, r->buflen);
     switch (req->cmd.buf[0]) {
index 5e3128c1e3739bb88c52f809252d81e688704b9d..b0ba6b2bbaee8602cfc42368c00fc88acc9844cd 100644 (file)
@@ -412,16 +412,21 @@ static void cadence_timer_init(uint32_t freq, CadenceTimerState *s)
 static void cadence_ttc_init(Object *obj)
 {
     CadenceTTCState *s = CADENCE_TTC(obj);
+
+    memory_region_init_io(&s->iomem, obj, &cadence_ttc_ops, s,
+                          "timer", 0x1000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static void cadence_ttc_realize(DeviceState *dev, Error **errp)
+{
+    CadenceTTCState *s = CADENCE_TTC(dev);
     int i;
 
     for (i = 0; i < 3; ++i) {
         cadence_timer_init(133000000, &s->timer[i]);
-        sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->timer[i].irq);
+        sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->timer[i].irq);
     }
-
-    memory_region_init_io(&s->iomem, obj, &cadence_ttc_ops, s,
-                          "timer", 0x1000);
-    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
 }
 
 static int cadence_timer_pre_save(void *opaque)
@@ -479,6 +484,7 @@ static void cadence_ttc_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd = &vmstate_cadence_ttc;
+    dc->realize = cadence_ttc_realize;
 }
 
 static const TypeInfo cadence_ttc_info = {
index 8dbcbdca16a6a2d46ff3ef9306474d3a674f7f1e..380acfa7c8a5a277a63ecb2be43599cd66eb9951 100644 (file)
@@ -27,7 +27,6 @@
 #include "qemu/osdep.h"
 #include "hw/i386/pc.h"
 #include "hw/irq.h"
-#include "ui/console.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
@@ -37,6 +36,7 @@
 #include "hw/rtc/mc146818rtc_regs.h"
 #include "migration/vmstate.h"
 #include "hw/timer/i8254.h"
+#include "exec/address-spaces.h"
 
 //#define HPET_DEBUG
 #ifdef HPET_DEBUG
index 9e67d990e8513e7183a7411a233cb1ccd96a9799..4794e7fe28ae052073d220b3e046f7d95bef019e 100644 (file)
@@ -2,9 +2,19 @@ config TPMDEV
     bool
     depends on TPM
 
-config TPM_TIS
+config TPM_TIS_ISA
     bool
     depends on TPM && ISA_BUS
+    select TPM_TIS
+
+config TPM_TIS_SYSBUS
+    bool
+    depends on TPM
+    select TPM_TIS
+
+config TPM_TIS
+    bool
+    depends on TPM
     select TPMDEV
 
 config TPM_CRB
index 85eb99ae05923d1fec2a57ddcee2dfe12dfc163b..f1ec4beb95cfb4ec7149e66c172a2371beb5b198 100644 (file)
@@ -1,6 +1,8 @@
 common-obj-$(CONFIG_TPM) += tpm_util.o
 obj-$(call lor,$(CONFIG_TPM_TIS),$(CONFIG_TPM_CRB)) += tpm_ppi.o
-common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o
+common-obj-$(CONFIG_TPM_TIS_ISA) += tpm_tis_isa.o
+common-obj-$(CONFIG_TPM_TIS_SYSBUS) += tpm_tis_sysbus.o
+common-obj-$(CONFIG_TPM_TIS) += tpm_tis_common.o
 common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
 common-obj-$(CONFIG_TPM_EMULATOR) += tpm_emulator.o
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
deleted file mode 100644 (file)
index 31facb8..0000000
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * tpm_tis.c - QEMU's TPM TIS interface emulator
- *
- * Copyright (C) 2006,2010-2013 IBM Corporation
- *
- * Authors:
- *  Stefan Berger <stefanb@us.ibm.com>
- *  David Safford <safford@us.ibm.com>
- *
- * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- * Implementation of the TIS interface according to specs found at
- * http://www.trustedcomputinggroup.org. This implementation currently
- * supports version 1.3, 21 March 2013
- * In the developers menu choose the PC Client section then find the TIS
- * specification.
- *
- * TPM TIS for TPM 2 implementation following TCG PC Client Platform
- * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/isa/isa.h"
-#include "qapi/error.h"
-#include "qemu/module.h"
-
-#include "hw/acpi/tpm.h"
-#include "hw/pci/pci_ids.h"
-#include "hw/qdev-properties.h"
-#include "migration/vmstate.h"
-#include "sysemu/tpm_backend.h"
-#include "tpm_int.h"
-#include "tpm_util.h"
-#include "tpm_ppi.h"
-#include "trace.h"
-
-#define TPM_TIS_NUM_LOCALITIES      5     /* per spec */
-#define TPM_TIS_LOCALITY_SHIFT      12
-#define TPM_TIS_NO_LOCALITY         0xff
-
-#define TPM_TIS_IS_VALID_LOCTY(x)   ((x) < TPM_TIS_NUM_LOCALITIES)
-
-#define TPM_TIS_BUFFER_MAX          4096
-
-typedef enum {
-    TPM_TIS_STATE_IDLE = 0,
-    TPM_TIS_STATE_READY,
-    TPM_TIS_STATE_COMPLETION,
-    TPM_TIS_STATE_EXECUTION,
-    TPM_TIS_STATE_RECEPTION,
-} TPMTISState;
-
-/* locality data  -- all fields are persisted */
-typedef struct TPMLocality {
-    TPMTISState state;
-    uint8_t access;
-    uint32_t sts;
-    uint32_t iface_id;
-    uint32_t inte;
-    uint32_t ints;
-} TPMLocality;
-
-typedef struct TPMState {
-    ISADevice busdev;
-    MemoryRegion mmio;
-
-    unsigned char buffer[TPM_TIS_BUFFER_MAX];
-    uint16_t rw_offset;
-
-    uint8_t active_locty;
-    uint8_t aborting_locty;
-    uint8_t next_locty;
-
-    TPMLocality loc[TPM_TIS_NUM_LOCALITIES];
-
-    qemu_irq irq;
-    uint32_t irq_num;
-
-    TPMBackendCmd cmd;
-
-    TPMBackend *be_driver;
-    TPMVersion be_tpm_version;
-
-    size_t be_buffer_size;
-
-    bool ppi_enabled;
-    TPMPPI ppi;
-} TPMState;
-
-#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS)
-
-#define DEBUG_TIS 0
-
-/* local prototypes */
-
-static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
-                                  unsigned size);
-
-/* utility functions */
-
-static uint8_t tpm_tis_locality_from_addr(hwaddr addr)
-{
-    return (uint8_t)((addr >> TPM_TIS_LOCALITY_SHIFT) & 0x7);
-}
-
-
-/*
- * Set the given flags in the STS register by clearing the register but
- * preserving the SELFTEST_DONE and TPM_FAMILY_MASK flags and then setting
- * the new flags.
- *
- * The SELFTEST_DONE flag is acquired from the backend that determines it by
- * peeking into TPM commands.
- *
- * A VM suspend/resume will preserve the flag by storing it into the VM
- * device state, but the backend will not remember it when QEMU is started
- * again. Therefore, we cache the flag here. Once set, it will not be unset
- * except by a reset.
- */
-static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags)
-{
-    l->sts &= TPM_TIS_STS_SELFTEST_DONE | TPM_TIS_STS_TPM_FAMILY_MASK;
-    l->sts |= flags;
-}
-
-/*
- * Send a request to the TPM.
- */
-static void tpm_tis_tpm_send(TPMState *s, uint8_t locty)
-{
-    if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
-        tpm_util_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
-    }
-
-    /*
-     * rw_offset serves as length indicator for length of data;
-     * it's reset when the response comes back
-     */
-    s->loc[locty].state = TPM_TIS_STATE_EXECUTION;
-
-    s->cmd = (TPMBackendCmd) {
-        .locty = locty,
-        .in = s->buffer,
-        .in_len = s->rw_offset,
-        .out = s->buffer,
-        .out_len = s->be_buffer_size,
-    };
-
-    tpm_backend_deliver_request(s->be_driver, &s->cmd);
-}
-
-/* raise an interrupt if allowed */
-static void tpm_tis_raise_irq(TPMState *s, uint8_t locty, uint32_t irqmask)
-{
-    if (!TPM_TIS_IS_VALID_LOCTY(locty)) {
-        return;
-    }
-
-    if ((s->loc[locty].inte & TPM_TIS_INT_ENABLED) &&
-        (s->loc[locty].inte & irqmask)) {
-        trace_tpm_tis_raise_irq(irqmask);
-        qemu_irq_raise(s->irq);
-        s->loc[locty].ints |= irqmask;
-    }
-}
-
-static uint32_t tpm_tis_check_request_use_except(TPMState *s, uint8_t locty)
-{
-    uint8_t l;
-
-    for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
-        if (l == locty) {
-            continue;
-        }
-        if ((s->loc[l].access & TPM_TIS_ACCESS_REQUEST_USE)) {
-            return 1;
-        }
-    }
-
-    return 0;
-}
-
-static void tpm_tis_new_active_locality(TPMState *s, uint8_t new_active_locty)
-{
-    bool change = (s->active_locty != new_active_locty);
-    bool is_seize;
-    uint8_t mask;
-
-    if (change && TPM_TIS_IS_VALID_LOCTY(s->active_locty)) {
-        is_seize = TPM_TIS_IS_VALID_LOCTY(new_active_locty) &&
-                   s->loc[new_active_locty].access & TPM_TIS_ACCESS_SEIZE;
-
-        if (is_seize) {
-            mask = ~(TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-        } else {
-            mask = ~(TPM_TIS_ACCESS_ACTIVE_LOCALITY|
-                     TPM_TIS_ACCESS_REQUEST_USE);
-        }
-        /* reset flags on the old active locality */
-        s->loc[s->active_locty].access &= mask;
-
-        if (is_seize) {
-            s->loc[s->active_locty].access |= TPM_TIS_ACCESS_BEEN_SEIZED;
-        }
-    }
-
-    s->active_locty = new_active_locty;
-
-    trace_tpm_tis_new_active_locality(s->active_locty);
-
-    if (TPM_TIS_IS_VALID_LOCTY(new_active_locty)) {
-        /* set flags on the new active locality */
-        s->loc[new_active_locty].access |= TPM_TIS_ACCESS_ACTIVE_LOCALITY;
-        s->loc[new_active_locty].access &= ~(TPM_TIS_ACCESS_REQUEST_USE |
-                                               TPM_TIS_ACCESS_SEIZE);
-    }
-
-    if (change) {
-        tpm_tis_raise_irq(s, s->active_locty, TPM_TIS_INT_LOCALITY_CHANGED);
-    }
-}
-
-/* abort -- this function switches the locality */
-static void tpm_tis_abort(TPMState *s)
-{
-    s->rw_offset = 0;
-
-    trace_tpm_tis_abort(s->next_locty);
-
-    /*
-     * Need to react differently depending on who's aborting now and
-     * which locality will become active afterwards.
-     */
-    if (s->aborting_locty == s->next_locty) {
-        s->loc[s->aborting_locty].state = TPM_TIS_STATE_READY;
-        tpm_tis_sts_set(&s->loc[s->aborting_locty],
-                        TPM_TIS_STS_COMMAND_READY);
-        tpm_tis_raise_irq(s, s->aborting_locty, TPM_TIS_INT_COMMAND_READY);
-    }
-
-    /* locality after abort is another one than the current one */
-    tpm_tis_new_active_locality(s, s->next_locty);
-
-    s->next_locty = TPM_TIS_NO_LOCALITY;
-    /* nobody's aborting a command anymore */
-    s->aborting_locty = TPM_TIS_NO_LOCALITY;
-}
-
-/* prepare aborting current command */
-static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty)
-{
-    uint8_t busy_locty;
-
-    assert(TPM_TIS_IS_VALID_LOCTY(newlocty));
-
-    s->aborting_locty = locty; /* may also be TPM_TIS_NO_LOCALITY */
-    s->next_locty = newlocty;  /* locality after successful abort */
-
-    /*
-     * only abort a command using an interrupt if currently executing
-     * a command AND if there's a valid connection to the vTPM.
-     */
-    for (busy_locty = 0; busy_locty < TPM_TIS_NUM_LOCALITIES; busy_locty++) {
-        if (s->loc[busy_locty].state == TPM_TIS_STATE_EXECUTION) {
-            /*
-             * request the backend to cancel. Some backends may not
-             * support it
-             */
-            tpm_backend_cancel_cmd(s->be_driver);
-            return;
-        }
-    }
-
-    tpm_tis_abort(s);
-}
-
-/*
- * Callback from the TPM to indicate that the response was received.
- */
-static void tpm_tis_request_completed(TPMIf *ti, int ret)
-{
-    TPMState *s = TPM(ti);
-    uint8_t locty = s->cmd.locty;
-    uint8_t l;
-
-    assert(TPM_TIS_IS_VALID_LOCTY(locty));
-
-    if (s->cmd.selftest_done) {
-        for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
-            s->loc[l].sts |= TPM_TIS_STS_SELFTEST_DONE;
-        }
-    }
-
-    /* FIXME: report error if ret != 0 */
-    tpm_tis_sts_set(&s->loc[locty],
-                    TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
-    s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
-    s->rw_offset = 0;
-
-    if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
-        tpm_util_show_buffer(s->buffer, s->be_buffer_size, "From TPM");
-    }
-
-    if (TPM_TIS_IS_VALID_LOCTY(s->next_locty)) {
-        tpm_tis_abort(s);
-    }
-
-    tpm_tis_raise_irq(s, locty,
-                      TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID);
-}
-
-/*
- * Read a byte of response data
- */
-static uint32_t tpm_tis_data_read(TPMState *s, uint8_t locty)
-{
-    uint32_t ret = TPM_TIS_NO_DATA_BYTE;
-    uint16_t len;
-
-    if ((s->loc[locty].sts & TPM_TIS_STS_DATA_AVAILABLE)) {
-        len = MIN(tpm_cmd_get_size(&s->buffer),
-                  s->be_buffer_size);
-
-        ret = s->buffer[s->rw_offset++];
-        if (s->rw_offset >= len) {
-            /* got last byte */
-            tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID);
-            tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID);
-        }
-        trace_tpm_tis_data_read(ret, s->rw_offset - 1);
-    }
-
-    return ret;
-}
-
-#ifdef DEBUG_TIS
-static void tpm_tis_dump_state(void *opaque, hwaddr addr)
-{
-    static const unsigned regs[] = {
-        TPM_TIS_REG_ACCESS,
-        TPM_TIS_REG_INT_ENABLE,
-        TPM_TIS_REG_INT_VECTOR,
-        TPM_TIS_REG_INT_STATUS,
-        TPM_TIS_REG_INTF_CAPABILITY,
-        TPM_TIS_REG_STS,
-        TPM_TIS_REG_DID_VID,
-        TPM_TIS_REG_RID,
-        0xfff};
-    int idx;
-    uint8_t locty = tpm_tis_locality_from_addr(addr);
-    hwaddr base = addr & ~0xfff;
-    TPMState *s = opaque;
-
-    printf("tpm_tis: active locality      : %d\n"
-           "tpm_tis: state of locality %d : %d\n"
-           "tpm_tis: register dump:\n",
-           s->active_locty,
-           locty, s->loc[locty].state);
-
-    for (idx = 0; regs[idx] != 0xfff; idx++) {
-        printf("tpm_tis: 0x%04x : 0x%08x\n", regs[idx],
-               (int)tpm_tis_mmio_read(opaque, base + regs[idx], 4));
-    }
-
-    printf("tpm_tis: r/w offset    : %d\n"
-           "tpm_tis: result buffer : ",
-           s->rw_offset);
-    for (idx = 0;
-         idx < MIN(tpm_cmd_get_size(&s->buffer), s->be_buffer_size);
-         idx++) {
-        printf("%c%02x%s",
-               s->rw_offset == idx ? '>' : ' ',
-               s->buffer[idx],
-               ((idx & 0xf) == 0xf) ? "\ntpm_tis:                 " : "");
-    }
-    printf("\n");
-}
-#endif
-
-/*
- * Read a register of the TIS interface
- * See specs pages 33-63 for description of the registers
- */
-static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
-                                  unsigned size)
-{
-    TPMState *s = opaque;
-    uint16_t offset = addr & 0xffc;
-    uint8_t shift = (addr & 0x3) * 8;
-    uint32_t val = 0xffffffff;
-    uint8_t locty = tpm_tis_locality_from_addr(addr);
-    uint32_t avail;
-    uint8_t v;
-
-    if (tpm_backend_had_startup_error(s->be_driver)) {
-        return 0;
-    }
-
-    switch (offset) {
-    case TPM_TIS_REG_ACCESS:
-        /* never show the SEIZE flag even though we use it internally */
-        val = s->loc[locty].access & ~TPM_TIS_ACCESS_SEIZE;
-        /* the pending flag is always calculated */
-        if (tpm_tis_check_request_use_except(s, locty)) {
-            val |= TPM_TIS_ACCESS_PENDING_REQUEST;
-        }
-        val |= !tpm_backend_get_tpm_established_flag(s->be_driver);
-        break;
-    case TPM_TIS_REG_INT_ENABLE:
-        val = s->loc[locty].inte;
-        break;
-    case TPM_TIS_REG_INT_VECTOR:
-        val = s->irq_num;
-        break;
-    case TPM_TIS_REG_INT_STATUS:
-        val = s->loc[locty].ints;
-        break;
-    case TPM_TIS_REG_INTF_CAPABILITY:
-        switch (s->be_tpm_version) {
-        case TPM_VERSION_UNSPEC:
-            val = 0;
-            break;
-        case TPM_VERSION_1_2:
-            val = TPM_TIS_CAPABILITIES_SUPPORTED1_3;
-            break;
-        case TPM_VERSION_2_0:
-            val = TPM_TIS_CAPABILITIES_SUPPORTED2_0;
-            break;
-        }
-        break;
-    case TPM_TIS_REG_STS:
-        if (s->active_locty == locty) {
-            if ((s->loc[locty].sts & TPM_TIS_STS_DATA_AVAILABLE)) {
-                val = TPM_TIS_BURST_COUNT(
-                       MIN(tpm_cmd_get_size(&s->buffer),
-                           s->be_buffer_size)
-                       - s->rw_offset) | s->loc[locty].sts;
-            } else {
-                avail = s->be_buffer_size - s->rw_offset;
-                /*
-                 * byte-sized reads should not return 0x00 for 0x100
-                 * available bytes.
-                 */
-                if (size == 1 && avail > 0xff) {
-                    avail = 0xff;
-                }
-                val = TPM_TIS_BURST_COUNT(avail) | s->loc[locty].sts;
-            }
-        }
-        break;
-    case TPM_TIS_REG_DATA_FIFO:
-    case TPM_TIS_REG_DATA_XFIFO ... TPM_TIS_REG_DATA_XFIFO_END:
-        if (s->active_locty == locty) {
-            if (size > 4 - (addr & 0x3)) {
-                /* prevent access beyond FIFO */
-                size = 4 - (addr & 0x3);
-            }
-            val = 0;
-            shift = 0;
-            while (size > 0) {
-                switch (s->loc[locty].state) {
-                case TPM_TIS_STATE_COMPLETION:
-                    v = tpm_tis_data_read(s, locty);
-                    break;
-                default:
-                    v = TPM_TIS_NO_DATA_BYTE;
-                    break;
-                }
-                val |= (v << shift);
-                shift += 8;
-                size--;
-            }
-            shift = 0; /* no more adjustments */
-        }
-        break;
-    case TPM_TIS_REG_INTERFACE_ID:
-        val = s->loc[locty].iface_id;
-        break;
-    case TPM_TIS_REG_DID_VID:
-        val = (TPM_TIS_TPM_DID << 16) | TPM_TIS_TPM_VID;
-        break;
-    case TPM_TIS_REG_RID:
-        val = TPM_TIS_TPM_RID;
-        break;
-#ifdef DEBUG_TIS
-    case TPM_TIS_REG_DEBUG:
-        tpm_tis_dump_state(opaque, addr);
-        break;
-#endif
-    }
-
-    if (shift) {
-        val >>= shift;
-    }
-
-    trace_tpm_tis_mmio_read(size, addr, val);
-
-    return val;
-}
-
-/*
- * Write a value to a register of the TIS interface
- * See specs pages 33-63 for description of the registers
- */
-static void tpm_tis_mmio_write(void *opaque, hwaddr addr,
-                               uint64_t val, unsigned size)
-{
-    TPMState *s = opaque;
-    uint16_t off = addr & 0xffc;
-    uint8_t shift = (addr & 0x3) * 8;
-    uint8_t locty = tpm_tis_locality_from_addr(addr);
-    uint8_t active_locty, l;
-    int c, set_new_locty = 1;
-    uint16_t len;
-    uint32_t mask = (size == 1) ? 0xff : ((size == 2) ? 0xffff : ~0);
-
-    trace_tpm_tis_mmio_write(size, addr, val);
-
-    if (locty == 4) {
-        trace_tpm_tis_mmio_write_locty4();
-        return;
-    }
-
-    if (tpm_backend_had_startup_error(s->be_driver)) {
-        return;
-    }
-
-    val &= mask;
-
-    if (shift) {
-        val <<= shift;
-        mask <<= shift;
-    }
-
-    mask ^= 0xffffffff;
-
-    switch (off) {
-    case TPM_TIS_REG_ACCESS:
-
-        if ((val & TPM_TIS_ACCESS_SEIZE)) {
-            val &= ~(TPM_TIS_ACCESS_REQUEST_USE |
-                     TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-        }
-
-        active_locty = s->active_locty;
-
-        if ((val & TPM_TIS_ACCESS_ACTIVE_LOCALITY)) {
-            /* give up locality if currently owned */
-            if (s->active_locty == locty) {
-                trace_tpm_tis_mmio_write_release_locty(locty);
-
-                uint8_t newlocty = TPM_TIS_NO_LOCALITY;
-                /* anybody wants the locality ? */
-                for (c = TPM_TIS_NUM_LOCALITIES - 1; c >= 0; c--) {
-                    if ((s->loc[c].access & TPM_TIS_ACCESS_REQUEST_USE)) {
-                        trace_tpm_tis_mmio_write_locty_req_use(c);
-                        newlocty = c;
-                        break;
-                    }
-                }
-                trace_tpm_tis_mmio_write_next_locty(newlocty);
-
-                if (TPM_TIS_IS_VALID_LOCTY(newlocty)) {
-                    set_new_locty = 0;
-                    tpm_tis_prep_abort(s, locty, newlocty);
-                } else {
-                    active_locty = TPM_TIS_NO_LOCALITY;
-                }
-            } else {
-                /* not currently the owner; clear a pending request */
-                s->loc[locty].access &= ~TPM_TIS_ACCESS_REQUEST_USE;
-            }
-        }
-
-        if ((val & TPM_TIS_ACCESS_BEEN_SEIZED)) {
-            s->loc[locty].access &= ~TPM_TIS_ACCESS_BEEN_SEIZED;
-        }
-
-        if ((val & TPM_TIS_ACCESS_SEIZE)) {
-            /*
-             * allow seize if a locality is active and the requesting
-             * locality is higher than the one that's active
-             * OR
-             * allow seize for requesting locality if no locality is
-             * active
-             */
-            while ((TPM_TIS_IS_VALID_LOCTY(s->active_locty) &&
-                    locty > s->active_locty) ||
-                    !TPM_TIS_IS_VALID_LOCTY(s->active_locty)) {
-                bool higher_seize = FALSE;
-
-                /* already a pending SEIZE ? */
-                if ((s->loc[locty].access & TPM_TIS_ACCESS_SEIZE)) {
-                    break;
-                }
-
-                /* check for ongoing seize by a higher locality */
-                for (l = locty + 1; l < TPM_TIS_NUM_LOCALITIES; l++) {
-                    if ((s->loc[l].access & TPM_TIS_ACCESS_SEIZE)) {
-                        higher_seize = TRUE;
-                        break;
-                    }
-                }
-
-                if (higher_seize) {
-                    break;
-                }
-
-                /* cancel any seize by a lower locality */
-                for (l = 0; l < locty; l++) {
-                    s->loc[l].access &= ~TPM_TIS_ACCESS_SEIZE;
-                }
-
-                s->loc[locty].access |= TPM_TIS_ACCESS_SEIZE;
-
-                trace_tpm_tis_mmio_write_locty_seized(locty, s->active_locty);
-                trace_tpm_tis_mmio_write_init_abort();
-
-                set_new_locty = 0;
-                tpm_tis_prep_abort(s, s->active_locty, locty);
-                break;
-            }
-        }
-
-        if ((val & TPM_TIS_ACCESS_REQUEST_USE)) {
-            if (s->active_locty != locty) {
-                if (TPM_TIS_IS_VALID_LOCTY(s->active_locty)) {
-                    s->loc[locty].access |= TPM_TIS_ACCESS_REQUEST_USE;
-                } else {
-                    /* no locality active -> make this one active now */
-                    active_locty = locty;
-                }
-            }
-        }
-
-        if (set_new_locty) {
-            tpm_tis_new_active_locality(s, active_locty);
-        }
-
-        break;
-    case TPM_TIS_REG_INT_ENABLE:
-        if (s->active_locty != locty) {
-            break;
-        }
-
-        s->loc[locty].inte &= mask;
-        s->loc[locty].inte |= (val & (TPM_TIS_INT_ENABLED |
-                                        TPM_TIS_INT_POLARITY_MASK |
-                                        TPM_TIS_INTERRUPTS_SUPPORTED));
-        break;
-    case TPM_TIS_REG_INT_VECTOR:
-        /* hard wired -- ignore */
-        break;
-    case TPM_TIS_REG_INT_STATUS:
-        if (s->active_locty != locty) {
-            break;
-        }
-
-        /* clearing of interrupt flags */
-        if (((val & TPM_TIS_INTERRUPTS_SUPPORTED)) &&
-            (s->loc[locty].ints & TPM_TIS_INTERRUPTS_SUPPORTED)) {
-            s->loc[locty].ints &= ~val;
-            if (s->loc[locty].ints == 0) {
-                qemu_irq_lower(s->irq);
-                trace_tpm_tis_mmio_write_lowering_irq();
-            }
-        }
-        s->loc[locty].ints &= ~(val & TPM_TIS_INTERRUPTS_SUPPORTED);
-        break;
-    case TPM_TIS_REG_STS:
-        if (s->active_locty != locty) {
-            break;
-        }
-
-        if (s->be_tpm_version == TPM_VERSION_2_0) {
-            /* some flags that are only supported for TPM 2 */
-            if (val & TPM_TIS_STS_COMMAND_CANCEL) {
-                if (s->loc[locty].state == TPM_TIS_STATE_EXECUTION) {
-                    /*
-                     * request the backend to cancel. Some backends may not
-                     * support it
-                     */
-                    tpm_backend_cancel_cmd(s->be_driver);
-                }
-            }
-
-            if (val & TPM_TIS_STS_RESET_ESTABLISHMENT_BIT) {
-                if (locty == 3 || locty == 4) {
-                    tpm_backend_reset_tpm_established_flag(s->be_driver, locty);
-                }
-            }
-        }
-
-        val &= (TPM_TIS_STS_COMMAND_READY | TPM_TIS_STS_TPM_GO |
-                TPM_TIS_STS_RESPONSE_RETRY);
-
-        if (val == TPM_TIS_STS_COMMAND_READY) {
-            switch (s->loc[locty].state) {
-
-            case TPM_TIS_STATE_READY:
-                s->rw_offset = 0;
-            break;
-
-            case TPM_TIS_STATE_IDLE:
-                tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_COMMAND_READY);
-                s->loc[locty].state = TPM_TIS_STATE_READY;
-                tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY);
-            break;
-
-            case TPM_TIS_STATE_EXECUTION:
-            case TPM_TIS_STATE_RECEPTION:
-                /* abort currently running command */
-                trace_tpm_tis_mmio_write_init_abort();
-                tpm_tis_prep_abort(s, locty, locty);
-            break;
-
-            case TPM_TIS_STATE_COMPLETION:
-                s->rw_offset = 0;
-                /* shortcut to ready state with C/R set */
-                s->loc[locty].state = TPM_TIS_STATE_READY;
-                if (!(s->loc[locty].sts & TPM_TIS_STS_COMMAND_READY)) {
-                    tpm_tis_sts_set(&s->loc[locty],
-                                    TPM_TIS_STS_COMMAND_READY);
-                    tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY);
-                }
-                s->loc[locty].sts &= ~(TPM_TIS_STS_DATA_AVAILABLE);
-            break;
-
-            }
-        } else if (val == TPM_TIS_STS_TPM_GO) {
-            switch (s->loc[locty].state) {
-            case TPM_TIS_STATE_RECEPTION:
-                if ((s->loc[locty].sts & TPM_TIS_STS_EXPECT) == 0) {
-                    tpm_tis_tpm_send(s, locty);
-                }
-                break;
-            default:
-                /* ignore */
-                break;
-            }
-        } else if (val == TPM_TIS_STS_RESPONSE_RETRY) {
-            switch (s->loc[locty].state) {
-            case TPM_TIS_STATE_COMPLETION:
-                s->rw_offset = 0;
-                tpm_tis_sts_set(&s->loc[locty],
-                                TPM_TIS_STS_VALID|
-                                TPM_TIS_STS_DATA_AVAILABLE);
-                break;
-            default:
-                /* ignore */
-                break;
-            }
-        }
-        break;
-    case TPM_TIS_REG_DATA_FIFO:
-    case TPM_TIS_REG_DATA_XFIFO ... TPM_TIS_REG_DATA_XFIFO_END:
-        /* data fifo */
-        if (s->active_locty != locty) {
-            break;
-        }
-
-        if (s->loc[locty].state == TPM_TIS_STATE_IDLE ||
-            s->loc[locty].state == TPM_TIS_STATE_EXECUTION ||
-            s->loc[locty].state == TPM_TIS_STATE_COMPLETION) {
-            /* drop the byte */
-        } else {
-            trace_tpm_tis_mmio_write_data2send(val, size);
-            if (s->loc[locty].state == TPM_TIS_STATE_READY) {
-                s->loc[locty].state = TPM_TIS_STATE_RECEPTION;
-                tpm_tis_sts_set(&s->loc[locty],
-                                TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
-            }
-
-            val >>= shift;
-            if (size > 4 - (addr & 0x3)) {
-                /* prevent access beyond FIFO */
-                size = 4 - (addr & 0x3);
-            }
-
-            while ((s->loc[locty].sts & TPM_TIS_STS_EXPECT) && size > 0) {
-                if (s->rw_offset < s->be_buffer_size) {
-                    s->buffer[s->rw_offset++] =
-                        (uint8_t)val;
-                    val >>= 8;
-                    size--;
-                } else {
-                    tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID);
-                }
-            }
-
-            /* check for complete packet */
-            if (s->rw_offset > 5 &&
-                (s->loc[locty].sts & TPM_TIS_STS_EXPECT)) {
-                /* we have a packet length - see if we have all of it */
-                bool need_irq = !(s->loc[locty].sts & TPM_TIS_STS_VALID);
-
-                len = tpm_cmd_get_size(&s->buffer);
-                if (len > s->rw_offset) {
-                    tpm_tis_sts_set(&s->loc[locty],
-                                    TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
-                } else {
-                    /* packet complete */
-                    tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID);
-                }
-                if (need_irq) {
-                    tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID);
-                }
-            }
-        }
-        break;
-    case TPM_TIS_REG_INTERFACE_ID:
-        if (val & TPM_TIS_IFACE_ID_INT_SEL_LOCK) {
-            for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
-                s->loc[l].iface_id |= TPM_TIS_IFACE_ID_INT_SEL_LOCK;
-            }
-        }
-        break;
-    }
-}
-
-static const MemoryRegionOps tpm_tis_memory_ops = {
-    .read = tpm_tis_mmio_read,
-    .write = tpm_tis_mmio_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 4,
-    },
-};
-
-/*
- * Get the TPMVersion of the backend device being used
- */
-static enum TPMVersion tpm_tis_get_tpm_version(TPMIf *ti)
-{
-    TPMState *s = TPM(ti);
-
-    if (tpm_backend_had_startup_error(s->be_driver)) {
-        return TPM_VERSION_UNSPEC;
-    }
-
-    return tpm_backend_get_tpm_version(s->be_driver);
-}
-
-/*
- * This function is called when the machine starts, resets or due to
- * S3 resume.
- */
-static void tpm_tis_reset(DeviceState *dev)
-{
-    TPMState *s = TPM(dev);
-    int c;
-
-    s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);
-    s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->be_driver),
-                            TPM_TIS_BUFFER_MAX);
-
-    if (s->ppi_enabled) {
-        tpm_ppi_reset(&s->ppi);
-    }
-    tpm_backend_reset(s->be_driver);
-
-    s->active_locty = TPM_TIS_NO_LOCALITY;
-    s->next_locty = TPM_TIS_NO_LOCALITY;
-    s->aborting_locty = TPM_TIS_NO_LOCALITY;
-
-    for (c = 0; c < TPM_TIS_NUM_LOCALITIES; c++) {
-        s->loc[c].access = TPM_TIS_ACCESS_TPM_REG_VALID_STS;
-        switch (s->be_tpm_version) {
-        case TPM_VERSION_UNSPEC:
-            break;
-        case TPM_VERSION_1_2:
-            s->loc[c].sts = TPM_TIS_STS_TPM_FAMILY1_2;
-            s->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3;
-            break;
-        case TPM_VERSION_2_0:
-            s->loc[c].sts = TPM_TIS_STS_TPM_FAMILY2_0;
-            s->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0;
-            break;
-        }
-        s->loc[c].inte = TPM_TIS_INT_POLARITY_LOW_LEVEL;
-        s->loc[c].ints = 0;
-        s->loc[c].state = TPM_TIS_STATE_IDLE;
-
-        s->rw_offset = 0;
-    }
-
-    if (tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size) < 0) {
-        exit(1);
-    }
-}
-
-/* persistent state handling */
-
-static int tpm_tis_pre_save(void *opaque)
-{
-    TPMState *s = opaque;
-    uint8_t locty = s->active_locty;
-
-    trace_tpm_tis_pre_save(locty, s->rw_offset);
-
-    if (DEBUG_TIS) {
-        tpm_tis_dump_state(opaque, 0);
-    }
-
-    /*
-     * Synchronize with backend completion.
-     */
-    tpm_backend_finish_sync(s->be_driver);
-
-    return 0;
-}
-
-static const VMStateDescription vmstate_locty = {
-    .name = "tpm-tis/locty",
-    .version_id = 0,
-    .fields      = (VMStateField[]) {
-        VMSTATE_UINT32(state, TPMLocality),
-        VMSTATE_UINT32(inte, TPMLocality),
-        VMSTATE_UINT32(ints, TPMLocality),
-        VMSTATE_UINT8(access, TPMLocality),
-        VMSTATE_UINT32(sts, TPMLocality),
-        VMSTATE_UINT32(iface_id, TPMLocality),
-        VMSTATE_END_OF_LIST(),
-    }
-};
-
-static const VMStateDescription vmstate_tpm_tis = {
-    .name = "tpm-tis",
-    .version_id = 0,
-    .pre_save  = tpm_tis_pre_save,
-    .fields = (VMStateField[]) {
-        VMSTATE_BUFFER(buffer, TPMState),
-        VMSTATE_UINT16(rw_offset, TPMState),
-        VMSTATE_UINT8(active_locty, TPMState),
-        VMSTATE_UINT8(aborting_locty, TPMState),
-        VMSTATE_UINT8(next_locty, TPMState),
-
-        VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 0,
-                             vmstate_locty, TPMLocality),
-
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static Property tpm_tis_properties[] = {
-    DEFINE_PROP_UINT32("irq", TPMState, irq_num, TPM_TIS_IRQ),
-    DEFINE_PROP_TPMBE("tpmdev", TPMState, be_driver),
-    DEFINE_PROP_BOOL("ppi", TPMState, ppi_enabled, true),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
-{
-    TPMState *s = TPM(dev);
-
-    if (!tpm_find()) {
-        error_setg(errp, "at most one TPM device is permitted");
-        return;
-    }
-
-    if (!s->be_driver) {
-        error_setg(errp, "'tpmdev' property is required");
-        return;
-    }
-    if (s->irq_num > 15) {
-        error_setg(errp, "IRQ %d is outside valid range of 0 to 15",
-                   s->irq_num);
-        return;
-    }
-
-    isa_init_irq(&s->busdev, &s->irq, s->irq_num);
-
-    memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),
-                                TPM_TIS_ADDR_BASE, &s->mmio);
-
-    if (s->ppi_enabled) {
-        tpm_ppi_init(&s->ppi, isa_address_space(ISA_DEVICE(dev)),
-                     TPM_PPI_ADDR_BASE, OBJECT(s));
-    }
-}
-
-static void tpm_tis_initfn(Object *obj)
-{
-    TPMState *s = TPM(obj);
-
-    memory_region_init_io(&s->mmio, OBJECT(s), &tpm_tis_memory_ops,
-                          s, "tpm-tis-mmio",
-                          TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
-}
-
-static void tpm_tis_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    TPMIfClass *tc = TPM_IF_CLASS(klass);
-
-    dc->realize = tpm_tis_realizefn;
-    device_class_set_props(dc, tpm_tis_properties);
-    dc->reset = tpm_tis_reset;
-    dc->vmsd  = &vmstate_tpm_tis;
-    tc->model = TPM_MODEL_TPM_TIS;
-    tc->get_version = tpm_tis_get_tpm_version;
-    tc->request_completed = tpm_tis_request_completed;
-}
-
-static const TypeInfo tpm_tis_info = {
-    .name = TYPE_TPM_TIS,
-    .parent = TYPE_ISA_DEVICE,
-    .instance_size = sizeof(TPMState),
-    .instance_init = tpm_tis_initfn,
-    .class_init  = tpm_tis_class_init,
-    .interfaces = (InterfaceInfo[]) {
-        { TYPE_TPM_IF },
-        { }
-    }
-};
-
-static void tpm_tis_register(void)
-{
-    type_register_static(&tpm_tis_info);
-}
-
-type_init(tpm_tis_register)
diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h
new file mode 100644 (file)
index 0000000..5554989
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * tpm_tis.h - QEMU's TPM TIS common header
+ *
+ * Copyright (C) 2006,2010-2013 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger <stefanb@us.ibm.com>
+ *  David Safford <safford@us.ibm.com>
+ *
+ * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputinggroup.org. This implementation currently
+ * supports version 1.3, 21 March 2013
+ * In the developers menu choose the PC Client section then find the TIS
+ * specification.
+ *
+ * TPM TIS for TPM 2 implementation following TCG PC Client Platform
+ * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
+ */
+#ifndef TPM_TPM_TIS_H
+#define TPM_TPM_TIS_H
+
+#include "qemu/osdep.h"
+#include "sysemu/tpm_backend.h"
+#include "tpm_ppi.h"
+
+#define TPM_TIS_NUM_LOCALITIES      5     /* per spec */
+#define TPM_TIS_LOCALITY_SHIFT      12
+#define TPM_TIS_NO_LOCALITY         0xff
+
+#define TPM_TIS_IS_VALID_LOCTY(x)   ((x) < TPM_TIS_NUM_LOCALITIES)
+
+#define TPM_TIS_BUFFER_MAX          4096
+
+typedef enum {
+    TPM_TIS_STATE_IDLE = 0,
+    TPM_TIS_STATE_READY,
+    TPM_TIS_STATE_COMPLETION,
+    TPM_TIS_STATE_EXECUTION,
+    TPM_TIS_STATE_RECEPTION,
+} TPMTISState;
+
+/* locality data  -- all fields are persisted */
+typedef struct TPMLocality {
+    TPMTISState state;
+    uint8_t access;
+    uint32_t sts;
+    uint32_t iface_id;
+    uint32_t inte;
+    uint32_t ints;
+} TPMLocality;
+
+typedef struct TPMState {
+    MemoryRegion mmio;
+
+    unsigned char buffer[TPM_TIS_BUFFER_MAX];
+    uint16_t rw_offset;
+
+    uint8_t active_locty;
+    uint8_t aborting_locty;
+    uint8_t next_locty;
+
+    TPMLocality loc[TPM_TIS_NUM_LOCALITIES];
+
+    qemu_irq irq;
+    uint32_t irq_num;
+
+    TPMBackendCmd cmd;
+
+    TPMBackend *be_driver;
+    TPMVersion be_tpm_version;
+
+    size_t be_buffer_size;
+
+    bool ppi_enabled;
+    TPMPPI ppi;
+} TPMState;
+
+extern const VMStateDescription vmstate_locty;
+extern const MemoryRegionOps tpm_tis_memory_ops;
+
+int tpm_tis_pre_save(TPMState *s);
+void tpm_tis_reset(TPMState *s);
+enum TPMVersion tpm_tis_get_tpm_version(TPMState *s);
+void tpm_tis_request_completed(TPMState *s, int ret);
+
+#endif /* TPM_TPM_TIS_H */
diff --git a/hw/tpm/tpm_tis_common.c b/hw/tpm/tpm_tis_common.c
new file mode 100644 (file)
index 0000000..9ce64d4
--- /dev/null
@@ -0,0 +1,872 @@
+/*
+ * tpm_tis_common.c - QEMU's TPM TIS interface emulator
+ * device agnostic functions
+ *
+ * Copyright (C) 2006,2010-2013 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger <stefanb@us.ibm.com>
+ *  David Safford <safford@us.ibm.com>
+ *
+ * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputinggroup.org. This implementation currently
+ * supports version 1.3, 21 March 2013
+ * In the developers menu choose the PC Client section then find the TIS
+ * specification.
+ *
+ * TPM TIS for TPM 2 implementation following TCG PC Client Platform
+ * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
+ */
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/isa/isa.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+
+#include "hw/acpi/tpm.h"
+#include "hw/pci/pci_ids.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "sysemu/tpm_backend.h"
+#include "tpm_int.h"
+#include "tpm_util.h"
+#include "tpm_ppi.h"
+#include "trace.h"
+
+#include "tpm_tis.h"
+
+#define DEBUG_TIS 0
+
+/* local prototypes */
+
+static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
+                                  unsigned size);
+
+/* utility functions */
+
+static uint8_t tpm_tis_locality_from_addr(hwaddr addr)
+{
+    return (uint8_t)((addr >> TPM_TIS_LOCALITY_SHIFT) & 0x7);
+}
+
+
+/*
+ * Set the given flags in the STS register by clearing the register but
+ * preserving the SELFTEST_DONE and TPM_FAMILY_MASK flags and then setting
+ * the new flags.
+ *
+ * The SELFTEST_DONE flag is acquired from the backend that determines it by
+ * peeking into TPM commands.
+ *
+ * A VM suspend/resume will preserve the flag by storing it into the VM
+ * device state, but the backend will not remember it when QEMU is started
+ * again. Therefore, we cache the flag here. Once set, it will not be unset
+ * except by a reset.
+ */
+static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags)
+{
+    l->sts &= TPM_TIS_STS_SELFTEST_DONE | TPM_TIS_STS_TPM_FAMILY_MASK;
+    l->sts |= flags;
+}
+
+/*
+ * Send a request to the TPM.
+ */
+static void tpm_tis_tpm_send(TPMState *s, uint8_t locty)
+{
+    if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
+        tpm_util_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
+    }
+
+    /*
+     * rw_offset serves as length indicator for length of data;
+     * it's reset when the response comes back
+     */
+    s->loc[locty].state = TPM_TIS_STATE_EXECUTION;
+
+    s->cmd = (TPMBackendCmd) {
+        .locty = locty,
+        .in = s->buffer,
+        .in_len = s->rw_offset,
+        .out = s->buffer,
+        .out_len = s->be_buffer_size,
+    };
+
+    tpm_backend_deliver_request(s->be_driver, &s->cmd);
+}
+
+/* raise an interrupt if allowed */
+static void tpm_tis_raise_irq(TPMState *s, uint8_t locty, uint32_t irqmask)
+{
+    if (!TPM_TIS_IS_VALID_LOCTY(locty)) {
+        return;
+    }
+
+    if ((s->loc[locty].inte & TPM_TIS_INT_ENABLED) &&
+        (s->loc[locty].inte & irqmask)) {
+        trace_tpm_tis_raise_irq(irqmask);
+        qemu_irq_raise(s->irq);
+        s->loc[locty].ints |= irqmask;
+    }
+}
+
+static uint32_t tpm_tis_check_request_use_except(TPMState *s, uint8_t locty)
+{
+    uint8_t l;
+
+    for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
+        if (l == locty) {
+            continue;
+        }
+        if ((s->loc[l].access & TPM_TIS_ACCESS_REQUEST_USE)) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+static void tpm_tis_new_active_locality(TPMState *s, uint8_t new_active_locty)
+{
+    bool change = (s->active_locty != new_active_locty);
+    bool is_seize;
+    uint8_t mask;
+
+    if (change && TPM_TIS_IS_VALID_LOCTY(s->active_locty)) {
+        is_seize = TPM_TIS_IS_VALID_LOCTY(new_active_locty) &&
+                   s->loc[new_active_locty].access & TPM_TIS_ACCESS_SEIZE;
+
+        if (is_seize) {
+            mask = ~(TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+        } else {
+            mask = ~(TPM_TIS_ACCESS_ACTIVE_LOCALITY|
+                     TPM_TIS_ACCESS_REQUEST_USE);
+        }
+        /* reset flags on the old active locality */
+        s->loc[s->active_locty].access &= mask;
+
+        if (is_seize) {
+            s->loc[s->active_locty].access |= TPM_TIS_ACCESS_BEEN_SEIZED;
+        }
+    }
+
+    s->active_locty = new_active_locty;
+
+    trace_tpm_tis_new_active_locality(s->active_locty);
+
+    if (TPM_TIS_IS_VALID_LOCTY(new_active_locty)) {
+        /* set flags on the new active locality */
+        s->loc[new_active_locty].access |= TPM_TIS_ACCESS_ACTIVE_LOCALITY;
+        s->loc[new_active_locty].access &= ~(TPM_TIS_ACCESS_REQUEST_USE |
+                                               TPM_TIS_ACCESS_SEIZE);
+    }
+
+    if (change) {
+        tpm_tis_raise_irq(s, s->active_locty, TPM_TIS_INT_LOCALITY_CHANGED);
+    }
+}
+
+/* abort -- this function switches the locality */
+static void tpm_tis_abort(TPMState *s)
+{
+    s->rw_offset = 0;
+
+    trace_tpm_tis_abort(s->next_locty);
+
+    /*
+     * Need to react differently depending on who's aborting now and
+     * which locality will become active afterwards.
+     */
+    if (s->aborting_locty == s->next_locty) {
+        s->loc[s->aborting_locty].state = TPM_TIS_STATE_READY;
+        tpm_tis_sts_set(&s->loc[s->aborting_locty],
+                        TPM_TIS_STS_COMMAND_READY);
+        tpm_tis_raise_irq(s, s->aborting_locty, TPM_TIS_INT_COMMAND_READY);
+    }
+
+    /* locality after abort is another one than the current one */
+    tpm_tis_new_active_locality(s, s->next_locty);
+
+    s->next_locty = TPM_TIS_NO_LOCALITY;
+    /* nobody's aborting a command anymore */
+    s->aborting_locty = TPM_TIS_NO_LOCALITY;
+}
+
+/* prepare aborting current command */
+static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty)
+{
+    uint8_t busy_locty;
+
+    assert(TPM_TIS_IS_VALID_LOCTY(newlocty));
+
+    s->aborting_locty = locty; /* may also be TPM_TIS_NO_LOCALITY */
+    s->next_locty = newlocty;  /* locality after successful abort */
+
+    /*
+     * only abort a command using an interrupt if currently executing
+     * a command AND if there's a valid connection to the vTPM.
+     */
+    for (busy_locty = 0; busy_locty < TPM_TIS_NUM_LOCALITIES; busy_locty++) {
+        if (s->loc[busy_locty].state == TPM_TIS_STATE_EXECUTION) {
+            /*
+             * request the backend to cancel. Some backends may not
+             * support it
+             */
+            tpm_backend_cancel_cmd(s->be_driver);
+            return;
+        }
+    }
+
+    tpm_tis_abort(s);
+}
+
+/*
+ * Callback from the TPM to indicate that the response was received.
+ */
+void tpm_tis_request_completed(TPMState *s, int ret)
+{
+    uint8_t locty = s->cmd.locty;
+    uint8_t l;
+
+    assert(TPM_TIS_IS_VALID_LOCTY(locty));
+
+    if (s->cmd.selftest_done) {
+        for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
+            s->loc[l].sts |= TPM_TIS_STS_SELFTEST_DONE;
+        }
+    }
+
+    /* FIXME: report error if ret != 0 */
+    tpm_tis_sts_set(&s->loc[locty],
+                    TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
+    s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
+    s->rw_offset = 0;
+
+    if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
+        tpm_util_show_buffer(s->buffer, s->be_buffer_size, "From TPM");
+    }
+
+    if (TPM_TIS_IS_VALID_LOCTY(s->next_locty)) {
+        tpm_tis_abort(s);
+    }
+
+    tpm_tis_raise_irq(s, locty,
+                      TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID);
+}
+
+/*
+ * Read a byte of response data
+ */
+static uint32_t tpm_tis_data_read(TPMState *s, uint8_t locty)
+{
+    uint32_t ret = TPM_TIS_NO_DATA_BYTE;
+    uint16_t len;
+
+    if ((s->loc[locty].sts & TPM_TIS_STS_DATA_AVAILABLE)) {
+        len = MIN(tpm_cmd_get_size(&s->buffer),
+                  s->be_buffer_size);
+
+        ret = s->buffer[s->rw_offset++];
+        if (s->rw_offset >= len) {
+            /* got last byte */
+            tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID);
+            tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID);
+        }
+        trace_tpm_tis_data_read(ret, s->rw_offset - 1);
+    }
+
+    return ret;
+}
+
+#ifdef DEBUG_TIS
+static void tpm_tis_dump_state(TPMState *s, hwaddr addr)
+{
+    static const unsigned regs[] = {
+        TPM_TIS_REG_ACCESS,
+        TPM_TIS_REG_INT_ENABLE,
+        TPM_TIS_REG_INT_VECTOR,
+        TPM_TIS_REG_INT_STATUS,
+        TPM_TIS_REG_INTF_CAPABILITY,
+        TPM_TIS_REG_STS,
+        TPM_TIS_REG_DID_VID,
+        TPM_TIS_REG_RID,
+        0xfff};
+    int idx;
+    uint8_t locty = tpm_tis_locality_from_addr(addr);
+    hwaddr base = addr & ~0xfff;
+
+    printf("tpm_tis: active locality      : %d\n"
+           "tpm_tis: state of locality %d : %d\n"
+           "tpm_tis: register dump:\n",
+           s->active_locty,
+           locty, s->loc[locty].state);
+
+    for (idx = 0; regs[idx] != 0xfff; idx++) {
+        printf("tpm_tis: 0x%04x : 0x%08x\n", regs[idx],
+               (int)tpm_tis_mmio_read(s, base + regs[idx], 4));
+    }
+
+    printf("tpm_tis: r/w offset    : %d\n"
+           "tpm_tis: result buffer : ",
+           s->rw_offset);
+    for (idx = 0;
+         idx < MIN(tpm_cmd_get_size(&s->buffer), s->be_buffer_size);
+         idx++) {
+        printf("%c%02x%s",
+               s->rw_offset == idx ? '>' : ' ',
+               s->buffer[idx],
+               ((idx & 0xf) == 0xf) ? "\ntpm_tis:                 " : "");
+    }
+    printf("\n");
+}
+#endif
+
+/*
+ * Read a register of the TIS interface
+ * See specs pages 33-63 for description of the registers
+ */
+static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
+                                  unsigned size)
+{
+    TPMState *s = opaque;
+    uint16_t offset = addr & 0xffc;
+    uint8_t shift = (addr & 0x3) * 8;
+    uint32_t val = 0xffffffff;
+    uint8_t locty = tpm_tis_locality_from_addr(addr);
+    uint32_t avail;
+    uint8_t v;
+
+    if (tpm_backend_had_startup_error(s->be_driver)) {
+        return 0;
+    }
+
+    switch (offset) {
+    case TPM_TIS_REG_ACCESS:
+        /* never show the SEIZE flag even though we use it internally */
+        val = s->loc[locty].access & ~TPM_TIS_ACCESS_SEIZE;
+        /* the pending flag is always calculated */
+        if (tpm_tis_check_request_use_except(s, locty)) {
+            val |= TPM_TIS_ACCESS_PENDING_REQUEST;
+        }
+        val |= !tpm_backend_get_tpm_established_flag(s->be_driver);
+        break;
+    case TPM_TIS_REG_INT_ENABLE:
+        val = s->loc[locty].inte;
+        break;
+    case TPM_TIS_REG_INT_VECTOR:
+        val = s->irq_num;
+        break;
+    case TPM_TIS_REG_INT_STATUS:
+        val = s->loc[locty].ints;
+        break;
+    case TPM_TIS_REG_INTF_CAPABILITY:
+        switch (s->be_tpm_version) {
+        case TPM_VERSION_UNSPEC:
+            val = 0;
+            break;
+        case TPM_VERSION_1_2:
+            val = TPM_TIS_CAPABILITIES_SUPPORTED1_3;
+            break;
+        case TPM_VERSION_2_0:
+            val = TPM_TIS_CAPABILITIES_SUPPORTED2_0;
+            break;
+        }
+        break;
+    case TPM_TIS_REG_STS:
+        if (s->active_locty == locty) {
+            if ((s->loc[locty].sts & TPM_TIS_STS_DATA_AVAILABLE)) {
+                val = TPM_TIS_BURST_COUNT(
+                       MIN(tpm_cmd_get_size(&s->buffer),
+                           s->be_buffer_size)
+                       - s->rw_offset) | s->loc[locty].sts;
+            } else {
+                avail = s->be_buffer_size - s->rw_offset;
+                /*
+                 * byte-sized reads should not return 0x00 for 0x100
+                 * available bytes.
+                 */
+                if (size == 1 && avail > 0xff) {
+                    avail = 0xff;
+                }
+                val = TPM_TIS_BURST_COUNT(avail) | s->loc[locty].sts;
+            }
+        }
+        break;
+    case TPM_TIS_REG_DATA_FIFO:
+    case TPM_TIS_REG_DATA_XFIFO ... TPM_TIS_REG_DATA_XFIFO_END:
+        if (s->active_locty == locty) {
+            if (size > 4 - (addr & 0x3)) {
+                /* prevent access beyond FIFO */
+                size = 4 - (addr & 0x3);
+            }
+            val = 0;
+            shift = 0;
+            while (size > 0) {
+                switch (s->loc[locty].state) {
+                case TPM_TIS_STATE_COMPLETION:
+                    v = tpm_tis_data_read(s, locty);
+                    break;
+                default:
+                    v = TPM_TIS_NO_DATA_BYTE;
+                    break;
+                }
+                val |= (v << shift);
+                shift += 8;
+                size--;
+            }
+            shift = 0; /* no more adjustments */
+        }
+        break;
+    case TPM_TIS_REG_INTERFACE_ID:
+        val = s->loc[locty].iface_id;
+        break;
+    case TPM_TIS_REG_DID_VID:
+        val = (TPM_TIS_TPM_DID << 16) | TPM_TIS_TPM_VID;
+        break;
+    case TPM_TIS_REG_RID:
+        val = TPM_TIS_TPM_RID;
+        break;
+#ifdef DEBUG_TIS
+    case TPM_TIS_REG_DEBUG:
+        tpm_tis_dump_state(s, addr);
+        break;
+#endif
+    }
+
+    if (shift) {
+        val >>= shift;
+    }
+
+    trace_tpm_tis_mmio_read(size, addr, val);
+
+    return val;
+}
+
+/*
+ * Write a value to a register of the TIS interface
+ * See specs pages 33-63 for description of the registers
+ */
+static void tpm_tis_mmio_write(void *opaque, hwaddr addr,
+                               uint64_t val, unsigned size)
+{
+    TPMState *s = opaque;
+    uint16_t off = addr & 0xffc;
+    uint8_t shift = (addr & 0x3) * 8;
+    uint8_t locty = tpm_tis_locality_from_addr(addr);
+    uint8_t active_locty, l;
+    int c, set_new_locty = 1;
+    uint16_t len;
+    uint32_t mask = (size == 1) ? 0xff : ((size == 2) ? 0xffff : ~0);
+
+    trace_tpm_tis_mmio_write(size, addr, val);
+
+    if (locty == 4) {
+        trace_tpm_tis_mmio_write_locty4();
+        return;
+    }
+
+    if (tpm_backend_had_startup_error(s->be_driver)) {
+        return;
+    }
+
+    val &= mask;
+
+    if (shift) {
+        val <<= shift;
+        mask <<= shift;
+    }
+
+    mask ^= 0xffffffff;
+
+    switch (off) {
+    case TPM_TIS_REG_ACCESS:
+
+        if ((val & TPM_TIS_ACCESS_SEIZE)) {
+            val &= ~(TPM_TIS_ACCESS_REQUEST_USE |
+                     TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+        }
+
+        active_locty = s->active_locty;
+
+        if ((val & TPM_TIS_ACCESS_ACTIVE_LOCALITY)) {
+            /* give up locality if currently owned */
+            if (s->active_locty == locty) {
+                trace_tpm_tis_mmio_write_release_locty(locty);
+
+                uint8_t newlocty = TPM_TIS_NO_LOCALITY;
+                /* anybody wants the locality ? */
+                for (c = TPM_TIS_NUM_LOCALITIES - 1; c >= 0; c--) {
+                    if ((s->loc[c].access & TPM_TIS_ACCESS_REQUEST_USE)) {
+                        trace_tpm_tis_mmio_write_locty_req_use(c);
+                        newlocty = c;
+                        break;
+                    }
+                }
+                trace_tpm_tis_mmio_write_next_locty(newlocty);
+
+                if (TPM_TIS_IS_VALID_LOCTY(newlocty)) {
+                    set_new_locty = 0;
+                    tpm_tis_prep_abort(s, locty, newlocty);
+                } else {
+                    active_locty = TPM_TIS_NO_LOCALITY;
+                }
+            } else {
+                /* not currently the owner; clear a pending request */
+                s->loc[locty].access &= ~TPM_TIS_ACCESS_REQUEST_USE;
+            }
+        }
+
+        if ((val & TPM_TIS_ACCESS_BEEN_SEIZED)) {
+            s->loc[locty].access &= ~TPM_TIS_ACCESS_BEEN_SEIZED;
+        }
+
+        if ((val & TPM_TIS_ACCESS_SEIZE)) {
+            /*
+             * allow seize if a locality is active and the requesting
+             * locality is higher than the one that's active
+             * OR
+             * allow seize for requesting locality if no locality is
+             * active
+             */
+            while ((TPM_TIS_IS_VALID_LOCTY(s->active_locty) &&
+                    locty > s->active_locty) ||
+                    !TPM_TIS_IS_VALID_LOCTY(s->active_locty)) {
+                bool higher_seize = FALSE;
+
+                /* already a pending SEIZE ? */
+                if ((s->loc[locty].access & TPM_TIS_ACCESS_SEIZE)) {
+                    break;
+                }
+
+                /* check for ongoing seize by a higher locality */
+                for (l = locty + 1; l < TPM_TIS_NUM_LOCALITIES; l++) {
+                    if ((s->loc[l].access & TPM_TIS_ACCESS_SEIZE)) {
+                        higher_seize = TRUE;
+                        break;
+                    }
+                }
+
+                if (higher_seize) {
+                    break;
+                }
+
+                /* cancel any seize by a lower locality */
+                for (l = 0; l < locty; l++) {
+                    s->loc[l].access &= ~TPM_TIS_ACCESS_SEIZE;
+                }
+
+                s->loc[locty].access |= TPM_TIS_ACCESS_SEIZE;
+
+                trace_tpm_tis_mmio_write_locty_seized(locty, s->active_locty);
+                trace_tpm_tis_mmio_write_init_abort();
+
+                set_new_locty = 0;
+                tpm_tis_prep_abort(s, s->active_locty, locty);
+                break;
+            }
+        }
+
+        if ((val & TPM_TIS_ACCESS_REQUEST_USE)) {
+            if (s->active_locty != locty) {
+                if (TPM_TIS_IS_VALID_LOCTY(s->active_locty)) {
+                    s->loc[locty].access |= TPM_TIS_ACCESS_REQUEST_USE;
+                } else {
+                    /* no locality active -> make this one active now */
+                    active_locty = locty;
+                }
+            }
+        }
+
+        if (set_new_locty) {
+            tpm_tis_new_active_locality(s, active_locty);
+        }
+
+        break;
+    case TPM_TIS_REG_INT_ENABLE:
+        if (s->active_locty != locty) {
+            break;
+        }
+
+        s->loc[locty].inte &= mask;
+        s->loc[locty].inte |= (val & (TPM_TIS_INT_ENABLED |
+                                        TPM_TIS_INT_POLARITY_MASK |
+                                        TPM_TIS_INTERRUPTS_SUPPORTED));
+        break;
+    case TPM_TIS_REG_INT_VECTOR:
+        /* hard wired -- ignore */
+        break;
+    case TPM_TIS_REG_INT_STATUS:
+        if (s->active_locty != locty) {
+            break;
+        }
+
+        /* clearing of interrupt flags */
+        if (((val & TPM_TIS_INTERRUPTS_SUPPORTED)) &&
+            (s->loc[locty].ints & TPM_TIS_INTERRUPTS_SUPPORTED)) {
+            s->loc[locty].ints &= ~val;
+            if (s->loc[locty].ints == 0) {
+                qemu_irq_lower(s->irq);
+                trace_tpm_tis_mmio_write_lowering_irq();
+            }
+        }
+        s->loc[locty].ints &= ~(val & TPM_TIS_INTERRUPTS_SUPPORTED);
+        break;
+    case TPM_TIS_REG_STS:
+        if (s->active_locty != locty) {
+            break;
+        }
+
+        if (s->be_tpm_version == TPM_VERSION_2_0) {
+            /* some flags that are only supported for TPM 2 */
+            if (val & TPM_TIS_STS_COMMAND_CANCEL) {
+                if (s->loc[locty].state == TPM_TIS_STATE_EXECUTION) {
+                    /*
+                     * request the backend to cancel. Some backends may not
+                     * support it
+                     */
+                    tpm_backend_cancel_cmd(s->be_driver);
+                }
+            }
+
+            if (val & TPM_TIS_STS_RESET_ESTABLISHMENT_BIT) {
+                if (locty == 3 || locty == 4) {
+                    tpm_backend_reset_tpm_established_flag(s->be_driver, locty);
+                }
+            }
+        }
+
+        val &= (TPM_TIS_STS_COMMAND_READY | TPM_TIS_STS_TPM_GO |
+                TPM_TIS_STS_RESPONSE_RETRY);
+
+        if (val == TPM_TIS_STS_COMMAND_READY) {
+            switch (s->loc[locty].state) {
+
+            case TPM_TIS_STATE_READY:
+                s->rw_offset = 0;
+            break;
+
+            case TPM_TIS_STATE_IDLE:
+                tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_COMMAND_READY);
+                s->loc[locty].state = TPM_TIS_STATE_READY;
+                tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY);
+            break;
+
+            case TPM_TIS_STATE_EXECUTION:
+            case TPM_TIS_STATE_RECEPTION:
+                /* abort currently running command */
+                trace_tpm_tis_mmio_write_init_abort();
+                tpm_tis_prep_abort(s, locty, locty);
+            break;
+
+            case TPM_TIS_STATE_COMPLETION:
+                s->rw_offset = 0;
+                /* shortcut to ready state with C/R set */
+                s->loc[locty].state = TPM_TIS_STATE_READY;
+                if (!(s->loc[locty].sts & TPM_TIS_STS_COMMAND_READY)) {
+                    tpm_tis_sts_set(&s->loc[locty],
+                                    TPM_TIS_STS_COMMAND_READY);
+                    tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY);
+                }
+                s->loc[locty].sts &= ~(TPM_TIS_STS_DATA_AVAILABLE);
+            break;
+
+            }
+        } else if (val == TPM_TIS_STS_TPM_GO) {
+            switch (s->loc[locty].state) {
+            case TPM_TIS_STATE_RECEPTION:
+                if ((s->loc[locty].sts & TPM_TIS_STS_EXPECT) == 0) {
+                    tpm_tis_tpm_send(s, locty);
+                }
+                break;
+            default:
+                /* ignore */
+                break;
+            }
+        } else if (val == TPM_TIS_STS_RESPONSE_RETRY) {
+            switch (s->loc[locty].state) {
+            case TPM_TIS_STATE_COMPLETION:
+                s->rw_offset = 0;
+                tpm_tis_sts_set(&s->loc[locty],
+                                TPM_TIS_STS_VALID|
+                                TPM_TIS_STS_DATA_AVAILABLE);
+                break;
+            default:
+                /* ignore */
+                break;
+            }
+        }
+        break;
+    case TPM_TIS_REG_DATA_FIFO:
+    case TPM_TIS_REG_DATA_XFIFO ... TPM_TIS_REG_DATA_XFIFO_END:
+        /* data fifo */
+        if (s->active_locty != locty) {
+            break;
+        }
+
+        if (s->loc[locty].state == TPM_TIS_STATE_IDLE ||
+            s->loc[locty].state == TPM_TIS_STATE_EXECUTION ||
+            s->loc[locty].state == TPM_TIS_STATE_COMPLETION) {
+            /* drop the byte */
+        } else {
+            trace_tpm_tis_mmio_write_data2send(val, size);
+            if (s->loc[locty].state == TPM_TIS_STATE_READY) {
+                s->loc[locty].state = TPM_TIS_STATE_RECEPTION;
+                tpm_tis_sts_set(&s->loc[locty],
+                                TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
+            }
+
+            val >>= shift;
+            if (size > 4 - (addr & 0x3)) {
+                /* prevent access beyond FIFO */
+                size = 4 - (addr & 0x3);
+            }
+
+            while ((s->loc[locty].sts & TPM_TIS_STS_EXPECT) && size > 0) {
+                if (s->rw_offset < s->be_buffer_size) {
+                    s->buffer[s->rw_offset++] =
+                        (uint8_t)val;
+                    val >>= 8;
+                    size--;
+                } else {
+                    tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID);
+                }
+            }
+
+            /* check for complete packet */
+            if (s->rw_offset > 5 &&
+                (s->loc[locty].sts & TPM_TIS_STS_EXPECT)) {
+                /* we have a packet length - see if we have all of it */
+                bool need_irq = !(s->loc[locty].sts & TPM_TIS_STS_VALID);
+
+                len = tpm_cmd_get_size(&s->buffer);
+                if (len > s->rw_offset) {
+                    tpm_tis_sts_set(&s->loc[locty],
+                                    TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
+                } else {
+                    /* packet complete */
+                    tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID);
+                }
+                if (need_irq) {
+                    tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID);
+                }
+            }
+        }
+        break;
+    case TPM_TIS_REG_INTERFACE_ID:
+        if (val & TPM_TIS_IFACE_ID_INT_SEL_LOCK) {
+            for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
+                s->loc[l].iface_id |= TPM_TIS_IFACE_ID_INT_SEL_LOCK;
+            }
+        }
+        break;
+    }
+}
+
+const MemoryRegionOps tpm_tis_memory_ops = {
+    .read = tpm_tis_mmio_read,
+    .write = tpm_tis_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+/*
+ * Get the TPMVersion of the backend device being used
+ */
+enum TPMVersion tpm_tis_get_tpm_version(TPMState *s)
+{
+    if (tpm_backend_had_startup_error(s->be_driver)) {
+        return TPM_VERSION_UNSPEC;
+    }
+
+    return tpm_backend_get_tpm_version(s->be_driver);
+}
+
+/*
+ * This function is called when the machine starts, resets or due to
+ * S3 resume.
+ */
+void tpm_tis_reset(TPMState *s)
+{
+    int c;
+
+    s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);
+    s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->be_driver),
+                            TPM_TIS_BUFFER_MAX);
+
+    if (s->ppi_enabled) {
+        tpm_ppi_reset(&s->ppi);
+    }
+    tpm_backend_reset(s->be_driver);
+
+    s->active_locty = TPM_TIS_NO_LOCALITY;
+    s->next_locty = TPM_TIS_NO_LOCALITY;
+    s->aborting_locty = TPM_TIS_NO_LOCALITY;
+
+    for (c = 0; c < TPM_TIS_NUM_LOCALITIES; c++) {
+        s->loc[c].access = TPM_TIS_ACCESS_TPM_REG_VALID_STS;
+        switch (s->be_tpm_version) {
+        case TPM_VERSION_UNSPEC:
+            break;
+        case TPM_VERSION_1_2:
+            s->loc[c].sts = TPM_TIS_STS_TPM_FAMILY1_2;
+            s->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3;
+            break;
+        case TPM_VERSION_2_0:
+            s->loc[c].sts = TPM_TIS_STS_TPM_FAMILY2_0;
+            s->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0;
+            break;
+        }
+        s->loc[c].inte = TPM_TIS_INT_POLARITY_LOW_LEVEL;
+        s->loc[c].ints = 0;
+        s->loc[c].state = TPM_TIS_STATE_IDLE;
+
+        s->rw_offset = 0;
+    }
+
+    if (tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size) < 0) {
+        exit(1);
+    }
+}
+
+/* persistent state handling */
+
+int tpm_tis_pre_save(TPMState *s)
+{
+    uint8_t locty = s->active_locty;
+
+    trace_tpm_tis_pre_save(locty, s->rw_offset);
+
+    if (DEBUG_TIS) {
+        tpm_tis_dump_state(s, 0);
+    }
+
+    /*
+     * Synchronize with backend completion.
+     */
+    tpm_backend_finish_sync(s->be_driver);
+
+    return 0;
+}
+
+const VMStateDescription vmstate_locty = {
+    .name = "tpm-tis/locty",
+    .version_id = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(state, TPMLocality),
+        VMSTATE_UINT32(inte, TPMLocality),
+        VMSTATE_UINT32(ints, TPMLocality),
+        VMSTATE_UINT8(access, TPMLocality),
+        VMSTATE_UINT32(sts, TPMLocality),
+        VMSTATE_UINT32(iface_id, TPMLocality),
+        VMSTATE_END_OF_LIST(),
+    }
+};
+
diff --git a/hw/tpm/tpm_tis_isa.c b/hw/tpm/tpm_tis_isa.c
new file mode 100644 (file)
index 0000000..30ba370
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * tpm_tis_isa.c - QEMU's TPM TIS ISA Device
+ *
+ * Copyright (C) 2006,2010-2013 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger <stefanb@us.ibm.com>
+ *  David Safford <safford@us.ibm.com>
+ *
+ * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputinggroup.org. This implementation currently
+ * supports version 1.3, 21 March 2013
+ * In the developers menu choose the PC Client section then find the TIS
+ * specification.
+ *
+ * TPM TIS for TPM 2 implementation following TCG PC Client Platform
+ * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
+ */
+
+#include "qemu/osdep.h"
+#include "hw/isa/isa.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "tpm_util.h"
+#include "tpm_tis.h"
+
+typedef struct TPMStateISA {
+    /*< private >*/
+    ISADevice parent_obj;
+
+    /*< public >*/
+    TPMState state; /* not a QOM object */
+} TPMStateISA;
+
+#define TPM_TIS_ISA(obj) OBJECT_CHECK(TPMStateISA, (obj), TYPE_TPM_TIS_ISA)
+
+static int tpm_tis_pre_save_isa(void *opaque)
+{
+    TPMStateISA *isadev = opaque;
+
+    return tpm_tis_pre_save(&isadev->state);
+}
+
+static const VMStateDescription vmstate_tpm_tis_isa = {
+    .name = "tpm-tis",
+    .version_id = 0,
+    .pre_save  = tpm_tis_pre_save_isa,
+    .fields = (VMStateField[]) {
+        VMSTATE_BUFFER(state.buffer, TPMStateISA),
+        VMSTATE_UINT16(state.rw_offset, TPMStateISA),
+        VMSTATE_UINT8(state.active_locty, TPMStateISA),
+        VMSTATE_UINT8(state.aborting_locty, TPMStateISA),
+        VMSTATE_UINT8(state.next_locty, TPMStateISA),
+
+        VMSTATE_STRUCT_ARRAY(state.loc, TPMStateISA, TPM_TIS_NUM_LOCALITIES, 0,
+                             vmstate_locty, TPMLocality),
+
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void tpm_tis_isa_request_completed(TPMIf *ti, int ret)
+{
+    TPMStateISA *isadev = TPM_TIS_ISA(ti);
+    TPMState *s = &isadev->state;
+
+    tpm_tis_request_completed(s, ret);
+}
+
+static enum TPMVersion tpm_tis_isa_get_tpm_version(TPMIf *ti)
+{
+    TPMStateISA *isadev = TPM_TIS_ISA(ti);
+    TPMState *s = &isadev->state;
+
+    return tpm_tis_get_tpm_version(s);
+}
+
+static void tpm_tis_isa_reset(DeviceState *dev)
+{
+    TPMStateISA *isadev = TPM_TIS_ISA(dev);
+    TPMState *s = &isadev->state;
+
+    return tpm_tis_reset(s);
+}
+
+static Property tpm_tis_isa_properties[] = {
+    DEFINE_PROP_UINT32("irq", TPMStateISA, state.irq_num, TPM_TIS_IRQ),
+    DEFINE_PROP_TPMBE("tpmdev", TPMStateISA, state.be_driver),
+    DEFINE_PROP_BOOL("ppi", TPMStateISA, state.ppi_enabled, true),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void tpm_tis_isa_initfn(Object *obj)
+{
+    TPMStateISA *isadev = TPM_TIS_ISA(obj);
+    TPMState *s = &isadev->state;
+
+    memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops,
+                          s, "tpm-tis-mmio",
+                          TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
+}
+
+static void tpm_tis_isa_realizefn(DeviceState *dev, Error **errp)
+{
+    TPMStateISA *isadev = TPM_TIS_ISA(dev);
+    TPMState *s = &isadev->state;
+
+    if (!tpm_find()) {
+        error_setg(errp, "at most one TPM device is permitted");
+        return;
+    }
+
+    if (!s->be_driver) {
+        error_setg(errp, "'tpmdev' property is required");
+        return;
+    }
+    if (s->irq_num > 15) {
+        error_setg(errp, "IRQ %d is outside valid range of 0 to 15",
+                   s->irq_num);
+        return;
+    }
+
+    isa_init_irq(ISA_DEVICE(dev), &s->irq, s->irq_num);
+
+    memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),
+                                TPM_TIS_ADDR_BASE, &s->mmio);
+
+    if (s->ppi_enabled) {
+        tpm_ppi_init(&s->ppi, isa_address_space(ISA_DEVICE(dev)),
+                     TPM_PPI_ADDR_BASE, OBJECT(dev));
+    }
+}
+
+static void tpm_tis_isa_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    TPMIfClass *tc = TPM_IF_CLASS(klass);
+
+    device_class_set_props(dc, tpm_tis_isa_properties);
+    dc->vmsd  = &vmstate_tpm_tis_isa;
+    tc->model = TPM_MODEL_TPM_TIS;
+    dc->realize = tpm_tis_isa_realizefn;
+    dc->reset = tpm_tis_isa_reset;
+    tc->request_completed = tpm_tis_isa_request_completed;
+    tc->get_version = tpm_tis_isa_get_tpm_version;
+}
+
+static const TypeInfo tpm_tis_isa_info = {
+    .name = TYPE_TPM_TIS_ISA,
+    .parent = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(TPMStateISA),
+    .instance_init = tpm_tis_isa_initfn,
+    .class_init  = tpm_tis_isa_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_TPM_IF },
+        { }
+    }
+};
+
+static void tpm_tis_isa_register(void)
+{
+    type_register_static(&tpm_tis_isa_info);
+}
+
+type_init(tpm_tis_isa_register)
diff --git a/hw/tpm/tpm_tis_sysbus.c b/hw/tpm/tpm_tis_sysbus.c
new file mode 100644 (file)
index 0000000..18c02ae
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * tpm_tis_sysbus.c - QEMU's TPM TIS SYSBUS Device
+ *
+ * Copyright (C) 2006,2010-2013 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger <stefanb@us.ibm.com>
+ *  David Safford <safford@us.ibm.com>
+ *
+ * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputinggroup.org. This implementation currently
+ * supports version 1.3, 21 March 2013
+ * In the developers menu choose the PC Client section then find the TIS
+ * specification.
+ *
+ * TPM TIS for TPM 2 implementation following TCG PC Client Platform
+ * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "tpm_util.h"
+#include "hw/sysbus.h"
+#include "tpm_tis.h"
+
+typedef struct TPMStateSysBus {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    TPMState state; /* not a QOM object */
+} TPMStateSysBus;
+
+#define TPM_TIS_SYSBUS(obj) OBJECT_CHECK(TPMStateSysBus, (obj), TYPE_TPM_TIS_SYSBUS)
+
+static int tpm_tis_pre_save_sysbus(void *opaque)
+{
+    TPMStateSysBus *sbdev = opaque;
+
+    return tpm_tis_pre_save(&sbdev->state);
+}
+
+static const VMStateDescription vmstate_tpm_tis_sysbus = {
+    .name = "tpm-tis",
+    .version_id = 0,
+    .pre_save  = tpm_tis_pre_save_sysbus,
+    .fields = (VMStateField[]) {
+        VMSTATE_BUFFER(state.buffer, TPMStateSysBus),
+        VMSTATE_UINT16(state.rw_offset, TPMStateSysBus),
+        VMSTATE_UINT8(state.active_locty, TPMStateSysBus),
+        VMSTATE_UINT8(state.aborting_locty, TPMStateSysBus),
+        VMSTATE_UINT8(state.next_locty, TPMStateSysBus),
+
+        VMSTATE_STRUCT_ARRAY(state.loc, TPMStateSysBus, TPM_TIS_NUM_LOCALITIES,
+                             0, vmstate_locty, TPMLocality),
+
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void tpm_tis_sysbus_request_completed(TPMIf *ti, int ret)
+{
+    TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(ti);
+    TPMState *s = &sbdev->state;
+
+    tpm_tis_request_completed(s, ret);
+}
+
+static enum TPMVersion tpm_tis_sysbus_get_tpm_version(TPMIf *ti)
+{
+    TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(ti);
+    TPMState *s = &sbdev->state;
+
+    return tpm_tis_get_tpm_version(s);
+}
+
+static void tpm_tis_sysbus_reset(DeviceState *dev)
+{
+    TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(dev);
+    TPMState *s = &sbdev->state;
+
+    return tpm_tis_reset(s);
+}
+
+static Property tpm_tis_sysbus_properties[] = {
+    DEFINE_PROP_UINT32("irq", TPMStateSysBus, state.irq_num, TPM_TIS_IRQ),
+    DEFINE_PROP_TPMBE("tpmdev", TPMStateSysBus, state.be_driver),
+    DEFINE_PROP_BOOL("ppi", TPMStateSysBus, state.ppi_enabled, true),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void tpm_tis_sysbus_initfn(Object *obj)
+{
+    TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(obj);
+    TPMState *s = &sbdev->state;
+
+    memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops,
+                          s, "tpm-tis-mmio",
+                          TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
+
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+}
+
+static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp)
+{
+    TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(dev);
+    TPMState *s = &sbdev->state;
+
+    if (!tpm_find()) {
+        error_setg(errp, "at most one TPM device is permitted");
+        return;
+    }
+
+    if (!s->be_driver) {
+        error_setg(errp, "'tpmdev' property is required");
+        return;
+    }
+}
+
+static void tpm_tis_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    TPMIfClass *tc = TPM_IF_CLASS(klass);
+
+    device_class_set_props(dc, tpm_tis_sysbus_properties);
+    dc->vmsd  = &vmstate_tpm_tis_sysbus;
+    tc->model = TPM_MODEL_TPM_TIS;
+    dc->realize = tpm_tis_sysbus_realizefn;
+    dc->user_creatable = true;
+    dc->reset = tpm_tis_sysbus_reset;
+    tc->request_completed = tpm_tis_sysbus_request_completed;
+    tc->get_version = tpm_tis_sysbus_get_tpm_version;
+}
+
+static const TypeInfo tpm_tis_sysbus_info = {
+    .name = TYPE_TPM_TIS_SYSBUS,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(TPMStateSysBus),
+    .instance_init = tpm_tis_sysbus_initfn,
+    .class_init  = tpm_tis_sysbus_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_TPM_IF },
+        { }
+    }
+};
+
+static void tpm_tis_sysbus_register(void)
+{
+    type_register_static(&tpm_tis_sysbus_info);
+}
+
+type_init(tpm_tis_sysbus_register)
index 98465990ef6b3974cff167a27f392c336715baf0..daac75b7aec207f22c10037b0c058301251e964b 100644 (file)
@@ -98,6 +98,7 @@ do { printf("usb-serial: " fmt , ## __VA_ARGS__); } while (0)
 
 typedef struct {
     USBDevice dev;
+    USBEndpoint *intr;
     uint8_t recv_buf[RECV_BUF];
     uint16_t recv_ptr;
     uint16_t recv_used;
@@ -153,7 +154,7 @@ static const USBDescDevice desc_device = {
         {
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
-            .bmAttributes          = USB_CFG_ATT_ONE,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
             .bMaxPower             = 50,
             .nif = 1,
             .ifs = &desc_iface0,
@@ -459,6 +460,8 @@ static void usb_serial_read(void *opaque, const uint8_t *buf, int size)
         memcpy(s->recv_buf + start, buf, size);
     }
     s->recv_used += size;
+
+    usb_wakeup(s->intr, 0);
 }
 
 static void usb_serial_event(void *opaque, QEMUChrEvent event)
@@ -513,6 +516,7 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
     if (qemu_chr_fe_backend_open(&s->cs) && !dev->attached) {
         usb_device_attach(dev, &error_abort);
     }
+    s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
 }
 
 static USBDevice *usb_braille_init(USBBus *bus, const char *unused)
index 90da008df18c761efa99a4b1f8ee52bcba836791..5c4b57b06b6fd973541bb9e131bcfc8f88c8410b 100644 (file)
@@ -17,9 +17,7 @@
 #include "desc.h"
 #include "hw/qdev-properties.h"
 #include "hw/scsi/scsi.h"
-#include "ui/console.h"
 #include "migration/vmstate.h"
-#include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/block-backend.h"
 #include "qapi/visitor.h"
index 56ab2f457f4c139d9c38644fa1b5ae29a2b1dd5c..29d49c2d7e68f03ba9c9907055445b3b7683c115 100644 (file)
@@ -1301,7 +1301,6 @@ static void ehci_execute_complete(EHCIQueue *q)
         /* should not be triggerable */
         fprintf(stderr, "USB invalid response %d\n", p->packet.status);
         g_assert_not_reached();
-        break;
     }
 
     /* TODO check 4.12 for splits */
@@ -2105,9 +2104,7 @@ static void ehci_advance_state(EHCIState *ehci, int async)
 
         default:
             fprintf(stderr, "Bad state!\n");
-            again = -1;
             g_assert_not_reached();
-            break;
         }
 
         if (again < 0 || itd_count > 16) {
index 66da96583b70909d3f3dea72fb62ac7edf9fa04a..9f9093e19644dc99cf66e30f763deed469d32cfa 100644 (file)
@@ -325,7 +325,7 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
     } else {
         vhostfd = open("/dev/vhost-vsock", O_RDWR);
         if (vhostfd < 0) {
-            error_setg_errno(errp, -errno,
+            error_setg_errno(errp, errno,
                              "vhost-vsock: failed to open vhost device");
             return;
         }
index 0d226dae1056990c0e61347df8aa70eb3eb4e1e3..01ebe12f28e9d7e3150375dda6f55b6b8f04a42a 100644 (file)
@@ -290,7 +290,14 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
 {
     VirtIODevice *vdev = dev->vdev;
 
-    return virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+    /*
+     * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
+     * incremental memory mapping API via IOTLB API. For platform that
+     * does not have IOMMU, there's no need to enable this feature
+     * which may cause unnecessary IOTLB miss/update trnasactions.
+     */
+    return vdev->dma_as != &address_space_memory &&
+           virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
 }
 
 static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
@@ -765,6 +772,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
     if (enable_log) {
         features |= 0x1ULL << VHOST_F_LOG_ALL;
     }
+    if (!vhost_dev_has_iommu(dev)) {
+        features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
+    }
     r = dev->vhost_ops->vhost_set_features(dev, features);
     if (r < 0) {
         VHOST_OPS_DEBUG("vhost_set_features failed");
index 9dd61cee7e27d6ed1f846b83cd75ed6edfa832c5..cb1989105a8da860c48c2519828d21f0dff1396d 100644 (file)
@@ -14,6 +14,9 @@
 #ifndef QEMU_AIO_H
 #define QEMU_AIO_H
 
+#ifdef CONFIG_LINUX_IO_URING
+#include <liburing.h>
+#endif
 #include "qemu/queue.h"
 #include "qemu/event_notifier.h"
 #include "qemu/thread.h"
@@ -52,6 +55,56 @@ struct ThreadPool;
 struct LinuxAioState;
 struct LuringState;
 
+/* Is polling disabled? */
+bool aio_poll_disabled(AioContext *ctx);
+
+/* Callbacks for file descriptor monitoring implementations */
+typedef struct {
+    /*
+     * update:
+     * @ctx: the AioContext
+     * @old_node: the existing handler or NULL if this file descriptor is being
+     *            monitored for the first time
+     * @new_node: the new handler or NULL if this file descriptor is being
+     *            removed
+     *
+     * Add/remove/modify a monitored file descriptor.
+     *
+     * Called with ctx->list_lock acquired.
+     */
+    void (*update)(AioContext *ctx, AioHandler *old_node, AioHandler *new_node);
+
+    /*
+     * wait:
+     * @ctx: the AioContext
+     * @ready_list: list for handlers that become ready
+     * @timeout: maximum duration to wait, in nanoseconds
+     *
+     * Wait for file descriptors to become ready and place them on ready_list.
+     *
+     * Called with ctx->list_lock incremented but not locked.
+     *
+     * Returns: number of ready file descriptors.
+     */
+    int (*wait)(AioContext *ctx, AioHandlerList *ready_list, int64_t timeout);
+
+    /*
+     * need_wait:
+     * @ctx: the AioContext
+     *
+     * Tell aio_poll() when to stop userspace polling early because ->wait()
+     * has fds ready.
+     *
+     * File descriptor monitoring implementations that cannot poll fd readiness
+     * from userspace should use aio_poll_disabled() here.  This ensures that
+     * file descriptors are not starved by handlers that frequently make
+     * progress via userspace polling.
+     *
+     * Returns: true if ->wait() should be called, false otherwise.
+     */
+    bool (*need_wait)(AioContext *ctx);
+} FDMonOps;
+
 /*
  * Each aio_bh_poll() call carves off a slice of the BH list, so that newly
  * scheduled BHs are not processed until the next aio_bh_poll() call.  All
@@ -65,6 +118,8 @@ struct BHListSlice {
     QSIMPLEQ_ENTRY(BHListSlice) next;
 };
 
+typedef QSLIST_HEAD(, AioHandler) AioHandlerSList;
+
 struct AioContext {
     GSource source;
 
@@ -150,6 +205,10 @@ struct AioContext {
      * locking.
      */
     struct LuringState *linux_io_uring;
+
+    /* State for file descriptor monitoring using Linux io_uring */
+    struct io_uring fdmon_io_uring;
+    AioHandlerSList submit_list;
 #endif
 
     /* TimerLists for calling timers - one per clock type.  Has its own
@@ -168,13 +227,21 @@ struct AioContext {
     int64_t poll_grow;      /* polling time growth factor */
     int64_t poll_shrink;    /* polling time shrink factor */
 
+    /*
+     * List of handlers participating in userspace polling.  Protected by
+     * ctx->list_lock.  Iterated and modified mostly by the event loop thread
+     * from aio_poll() with ctx->list_lock incremented.  aio_set_fd_handler()
+     * only touches the list to delete nodes if ctx->list_lock's count is zero.
+     */
+    AioHandlerList poll_aio_handlers;
+
     /* Are we in polling mode or monitoring file descriptors? */
     bool poll_started;
 
     /* epoll(7) state used when built with CONFIG_EPOLL */
     int epollfd;
-    bool epoll_enabled;
-    bool epoll_available;
+
+    const FDMonOps *fdmon_ops;
 };
 
 /**
index 0a161724d77bddbb2e8bcfd0e91327c7404c7541..aac85e14880a430a0d37c6ac0ed570bdaaf9a327 100644 (file)
 #include "block/block.h"
 #include "qemu/co-shared-resource.h"
 
-typedef struct BlockCopyInFlightReq {
-    int64_t start_byte;
-    int64_t end_byte;
-    QLIST_ENTRY(BlockCopyInFlightReq) list;
-    CoQueue wait_queue; /* coroutines blocked on this request */
-} BlockCopyInFlightReq;
-
 typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque);
-typedef void (*ProgressResetCallbackFunc)(void *opaque);
-typedef struct BlockCopyState {
-    /*
-     * BdrvChild objects are not owned or managed by block-copy. They are
-     * provided by block-copy user and user is responsible for appropriate
-     * permissions on these children.
-     */
-    BdrvChild *source;
-    BdrvChild *target;
-    BdrvDirtyBitmap *copy_bitmap;
-    int64_t cluster_size;
-    bool use_copy_range;
-    int64_t copy_size;
-    uint64_t len;
-    QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs;
-
-    BdrvRequestFlags write_flags;
-
-    /*
-     * skip_unallocated:
-     *
-     * Used by sync=top jobs, which first scan the source node for unallocated
-     * areas and clear them in the copy_bitmap.  During this process, the bitmap
-     * is thus not fully initialized: It may still have bits set for areas that
-     * are unallocated and should actually not be copied.
-     *
-     * This is indicated by skip_unallocated.
-     *
-     * In this case, block_copy() will query the source’s allocation status,
-     * skip unallocated regions, clear them in the copy_bitmap, and invoke
-     * block_copy_reset_unallocated() every time it does.
-     */
-    bool skip_unallocated;
-
-    /* progress_bytes_callback: called when some copying progress is done. */
-    ProgressBytesCallbackFunc progress_bytes_callback;
-
-    /*
-     * progress_reset_callback: called when some bytes reset from copy_bitmap
-     * (see @skip_unallocated above). The callee is assumed to recalculate how
-     * many bytes remain based on the dirty bit count of copy_bitmap.
-     */
-    ProgressResetCallbackFunc progress_reset_callback;
-    void *progress_opaque;
-
-    SharedResource *mem;
-} BlockCopyState;
+typedef struct BlockCopyState BlockCopyState;
 
 BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
                                      int64_t cluster_size,
                                      BdrvRequestFlags write_flags,
                                      Error **errp);
 
-void block_copy_set_callbacks(
+void block_copy_set_progress_callback(
         BlockCopyState *s,
         ProgressBytesCallbackFunc progress_bytes_callback,
-        ProgressResetCallbackFunc progress_reset_callback,
         void *progress_opaque);
 
+void block_copy_set_progress_meter(BlockCopyState *s, ProgressMeter *pm);
+
 void block_copy_state_free(BlockCopyState *s);
 
 int64_t block_copy_reset_unallocated(BlockCopyState *s,
                                      int64_t offset, int64_t *count);
 
-int coroutine_fn block_copy(BlockCopyState *s, int64_t start, uint64_t bytes,
+int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
                             bool *error_is_read);
 
+BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s);
+void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip);
+
 #endif /* BLOCK_COPY_H */
diff --git a/include/block/block-hmp-cmds.h b/include/block/block-hmp-cmds.h
new file mode 100644 (file)
index 0000000..3412e10
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * HMP commands related to the block layer
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2020 Red Hat, Inc.
+ * Copyright IBM, Corp. 2011
+ *
+ * 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.
+ */
+
+#ifndef BLOCK_HMP_COMMANDS_H
+#define BLOCK_HMP_COMMANDS_H
+
+void hmp_drive_add(Monitor *mon, const QDict *qdict);
+
+void hmp_commit(Monitor *mon, const QDict *qdict);
+void hmp_drive_del(Monitor *mon, const QDict *qdict);
+
+void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
+void hmp_drive_backup(Monitor *mon, const QDict *qdict);
+
+void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
+void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
+void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
+void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
+void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
+
+void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
+void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
+void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
+
+void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
+void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
+void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
+void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
+
+void hmp_block_resize(Monitor *mon, const QDict *qdict);
+void hmp_block_stream(Monitor *mon, const QDict *qdict);
+void hmp_block_passwd(Monitor *mon, const QDict *qdict);
+void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
+void hmp_eject(Monitor *mon, const QDict *qdict);
+
+void hmp_qemu_io(Monitor *mon, const QDict *qdict);
+
+void hmp_info_block(Monitor *mon, const QDict *qdict);
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
+void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
+
+#endif
index 6f9fd5e20e3d0b1ddcdb6312e0fa9813497c553c..3f70a98b2d587e4ce6db1cf5f55f2b0a86a3f42d 100644 (file)
@@ -122,6 +122,7 @@ struct BlockDriver {
     int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
                                BlockReopenQueue *queue, Error **errp);
     void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
+    void (*bdrv_reopen_commit_post)(BDRVReopenState *reopen_state);
     void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
     void (*bdrv_join_options)(QDict *options, QDict *old_options);
 
@@ -1215,8 +1216,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
                             BlockCompletionFunc *cb, void *opaque,
                             JobTxn *txn, Error **errp);
 
-void hmp_drive_add_node(Monitor *mon, const char *optstr);
-
 BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
                                   const char *child_name,
                                   const BdrvChildRole *child_role,
@@ -1321,4 +1320,7 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, uint64_t src_offset,
 
 int refresh_total_sectors(BlockDriverState *bs, int64_t hint);
 
+void bdrv_set_monitor_owned(BlockDriverState *bs);
+BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp);
+
 #endif /* BLOCK_INT_H */
index 7f46932d80f1b4f3dcaa63c211d6f81736c1d906..20363280ae012c50947404b93187de372563b7f8 100644 (file)
@@ -353,6 +353,7 @@ void nbd_client_put(NBDClient *client);
 
 void nbd_server_start(SocketAddress *addr, const char *tls_creds,
                       const char *tls_authz, Error **errp);
+void nbd_server_start_options(NbdServerOptions *arg, Error **errp);
 
 /* nbd_read
  * Reads @size bytes from @ioc. Returns 0 on success.
index d49d2c2da964cf51eec55b35eb522826a977a62a..c77ccaf9c0a8cb2875be5a26068ab20bc3e204dc 100644 (file)
@@ -145,6 +145,26 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
                                    Error **errp);
 
 
+/**
+ * qcrypto_block_calculate_payload_offset:
+ * @create_opts: the encryption options
+ * @optprefix: name prefix for options
+ * @len: output for number of header bytes before payload
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Calculate the number of header bytes before the payload in an encrypted
+ * storage volume.  The header is an area before the payload that is reserved
+ * for encryption metadata.
+ *
+ * Returns: true on success, false on error
+ */
+bool
+qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts,
+                                       const char *optprefix,
+                                       size_t *len,
+                                       Error **errp);
+
+
 /**
  * qcrypto_block_get_info:
  * @block: the block encryption object
@@ -269,5 +289,7 @@ uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block);
 void qcrypto_block_free(QCryptoBlock *block);
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlock, qcrypto_block_free)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlockCreateOptions,
+                              qapi_free_QCryptoBlockCreateOptions)
 
 #endif /* QCRYPTO_BLOCK_H */
index d844c4ffe47df1ae542983b2e72c54a5b6e1d74a..6c0a692b2fda56d01dc15a46c02c5ffc60f6f88b 100644 (file)
@@ -22,6 +22,7 @@
 #define XLNX_VERSAL_NR_ACPUS   2
 #define XLNX_VERSAL_NR_UARTS   2
 #define XLNX_VERSAL_NR_GEMS    2
+#define XLNX_VERSAL_NR_ADMAS   8
 #define XLNX_VERSAL_NR_IRQS    192
 
 typedef struct Versal {
@@ -50,6 +51,7 @@ typedef struct Versal {
         struct {
             SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
             SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
+            SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
         } iou;
     } lpd;
 
@@ -74,6 +76,7 @@ typedef struct Versal {
 #define VERSAL_GEM0_WAKE_IRQ_0     57
 #define VERSAL_GEM1_IRQ_0          58
 #define VERSAL_GEM1_WAKE_IRQ_0     59
+#define VERSAL_ADMA_IRQ_0          60
 
 /* Architecturally reserved IRQs suitable for virtualization.  */
 #define VERSAL_RSVD_IRQ_FIRST 111
@@ -96,6 +99,9 @@ typedef struct Versal {
 #define MM_GEM1                     0xff0d0000U
 #define MM_GEM1_SIZE                0x10000
 
+#define MM_ADMA_CH0                 0xffa80000U
+#define MM_ADMA_CH0_SIZE            0x10000
+
 #define MM_OCM                      0xfffc0000U
 #define MM_OCM_SIZE                 0x40000
 
index 72e803f6e2e0eb637986e658805e2b3d70c4b7ef..a98d10b252dffe79530a39f7ca2dfc8dd51366e8 100644 (file)
@@ -5,7 +5,6 @@
 #include "hw/sysbus.h"
 #include "hw/i386/pc.h"
 #include "hw/isa/apm.h"
-#include "hw/i386/ioapic.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/pci/pci_bridge.h"
index 66b931e52628aaaec8bb0b3921d142b081fabff4..a1c4afcda5c9ba8da638613f4e1b6c0b5065acdd 100644 (file)
 #ifndef INTEL_IOMMU_H
 #define INTEL_IOMMU_H
 
-#include "sysemu/dma.h"
 #include "hw/i386/x86-iommu.h"
-#include "hw/i386/ioapic.h"
-#include "hw/pci/msi.h"
-#include "hw/sysbus.h"
 #include "qemu/iova-tree.h"
 
 #define TYPE_INTEL_IOMMU_DEVICE "intel-iommu"
index d46c87c510305bb4723691b7f40f551ea69b265c..fe06938bda47f7d95fc3634222ad78918cf04a4b 100644 (file)
@@ -23,7 +23,6 @@
 #define QEMU_IOAPIC_INTERNAL_H
 
 #include "exec/memory.h"
-#include "hw/i386/ioapic.h"
 #include "hw/sysbus.h"
 #include "qemu/notify.h"
 
index d5ac76d54e1fc687a921b003b92c740642e63054..6ab6eda046fd9816664fa1c241f4c8d412e532c9 100644 (file)
@@ -1,20 +1,15 @@
 #ifndef HW_PC_H
 #define HW_PC_H
 
-#include "exec/memory.h"
+#include "qemu/notify.h"
+#include "qapi/qapi-types-common.h"
 #include "hw/boards.h"
 #include "hw/block/fdc.h"
 #include "hw/block/flash.h"
-#include "net/net.h"
 #include "hw/i386/x86.h"
 
-#include "qemu/range.h"
-#include "qemu/bitmap.h"
-#include "qemu/module.h"
-#include "hw/pci/pci.h"
-#include "hw/mem/pc-dimm.h"
-#include "hw/mem/nvdimm.h"
 #include "hw/acpi/acpi_dev_interface.h"
+#include "hw/hotplug.h"
 
 #define HPET_INTCAP "hpet-intcap"
 
index 976fbae5996b12f22f7e2faad95d5d16c639da5d..070305f83dfd9dca2f15934ba094299b6d8c2563 100644 (file)
 #ifndef HW_Q35_H
 #define HW_Q35_H
 
-#include "hw/isa/isa.h"
-#include "hw/sysbus.h"
-#include "hw/i386/pc.h"
-#include "hw/isa/apm.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pcie_host.h"
-#include "hw/acpi/acpi.h"
-#include "hw/acpi/ich9.h"
 #include "hw/pci-host/pam.h"
-#include "hw/i386/intel_iommu.h"
 #include "qemu/units.h"
+#include "qemu/range.h"
 
 #define TYPE_Q35_HOST_DEVICE "q35-pcihost"
 #define Q35_HOST_DEVICE(obj) \
index 7064875835995d3a80a6faffc4385ff92bc6bfb9..14c58ebdb6ec1fd5dc3c8563fed9f76a58bbc434 100644 (file)
@@ -104,7 +104,7 @@ void pcie_cap_deverr_reset(PCIDevice *dev);
 void pcie_cap_lnkctl_init(PCIDevice *dev);
 void pcie_cap_lnkctl_reset(PCIDevice *dev);
 
-void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot);
+void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s);
 void pcie_cap_slot_reset(PCIDevice *dev);
 void pcie_cap_slot_get(PCIDevice *dev, uint16_t *slt_ctl, uint16_t *slt_sta);
 void pcie_cap_slot_write_config(PCIDevice *dev,
index 4b3d254b08213e593456428374a72a2c521ff34e..caae57573bf688fcbf2f7e6e033f1de8360cbf27 100644 (file)
@@ -55,6 +55,9 @@ struct PCIESlot {
 
     /* Disable ACS (really for a pcie_root_port) */
     bool        disable_acs;
+
+    /* Indicates whether hot-plug is enabled on the slot */
+    bool        hotplug;
     QLIST_ENTRY(PCIESlot) next;
 };
 
index 3d329853b2171192538e047bdde80b13411f11d2..e33ca5a911a5e5145e10ad4ea519906527c58666 100644 (file)
@@ -30,8 +30,6 @@ void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
 void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict);
 void hmp_info_cpus(Monitor *mon, const QDict *qdict);
-void hmp_info_block(Monitor *mon, const QDict *qdict);
-void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
 void hmp_info_vnc(Monitor *mon, const QDict *qdict);
 void hmp_info_spice(Monitor *mon, const QDict *qdict);
 void hmp_info_balloon(Monitor *mon, const QDict *qdict);
@@ -39,7 +37,6 @@ void hmp_info_irq(Monitor *mon, const QDict *qdict);
 void hmp_info_pic(Monitor *mon, const QDict *qdict);
 void hmp_info_rdma(Monitor *mon, const QDict *qdict);
 void hmp_info_pci(Monitor *mon, const QDict *qdict);
-void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
 void hmp_info_tpm(Monitor *mon, const QDict *qdict);
 void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
 void hmp_quit(Monitor *mon, const QDict *qdict);
@@ -58,18 +55,10 @@ void hmp_cont(Monitor *mon, const QDict *qdict);
 void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
 void hmp_nmi(Monitor *mon, const QDict *qdict);
 void hmp_set_link(Monitor *mon, const QDict *qdict);
-void hmp_block_passwd(Monitor *mon, const QDict *qdict);
 void hmp_balloon(Monitor *mon, const QDict *qdict);
-void hmp_block_resize(Monitor *mon, const QDict *qdict);
-void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
-void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
-void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
-void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
-void hmp_drive_backup(Monitor *mon, const QDict *qdict);
 void hmp_loadvm(Monitor *mon, const QDict *qdict);
 void hmp_savevm(Monitor *mon, const QDict *qdict);
 void hmp_delvm(Monitor *mon, const QDict *qdict);
-void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
 void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
@@ -85,15 +74,7 @@ void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict);
 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
 void hmp_set_password(Monitor *mon, const QDict *qdict);
 void hmp_expire_password(Monitor *mon, const QDict *qdict);
-void hmp_eject(Monitor *mon, const QDict *qdict);
 void hmp_change(Monitor *mon, const QDict *qdict);
-void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
-void hmp_block_stream(Monitor *mon, const QDict *qdict);
-void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
-void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
-void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
-void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
-void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
 void hmp_migrate(Monitor *mon, const QDict *qdict);
 void hmp_device_add(Monitor *mon, const QDict *qdict);
 void hmp_device_del(Monitor *mon, const QDict *qdict);
@@ -104,15 +85,10 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
 void hmp_closefd(Monitor *mon, const QDict *qdict);
 void hmp_sendkey(Monitor *mon, const QDict *qdict);
 void hmp_screendump(Monitor *mon, const QDict *qdict);
-void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
-void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
-void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
-void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
 void hmp_chardev_add(Monitor *mon, const QDict *qdict);
 void hmp_chardev_change(Monitor *mon, const QDict *qdict);
 void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
 void hmp_chardev_send_break(Monitor *mon, const QDict *qdict);
-void hmp_qemu_io(Monitor *mon, const QDict *qdict);
 void hmp_cpu_add(Monitor *mon, const QDict *qdict);
 void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
index b7bdd2bb2acbf00778c1ffb4b95b90d9897053c6..1018d754a6f981c2307ca93a7b92e200ee2b71b1 100644 (file)
@@ -7,6 +7,7 @@
 
 extern __thread Monitor *cur_mon;
 typedef struct MonitorHMP MonitorHMP;
+typedef struct MonitorOptions MonitorOptions;
 
 #define QMP_REQ_QUEUE_LEN_MAX 8
 
@@ -16,8 +17,9 @@ bool monitor_cur_is_qmp(void);
 
 void monitor_init_globals(void);
 void monitor_init_globals_core(void);
-void monitor_init_qmp(Chardev *chr, bool pretty);
-void monitor_init_hmp(Chardev *chr, bool use_readline);
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp);
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp);
+int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp);
 int monitor_init_opts(QemuOpts *opts, Error **errp);
 void monitor_cleanup(void);
 
index bd59cd8944de41304d8f78dce94cefddd12901c0..32aabb1c60009825ca4a921b78643fcdc7468ed9 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "qapi/qapi-types-job.h"
 #include "qemu/queue.h"
+#include "qemu/progress_meter.h"
 #include "qemu/coroutine.h"
 #include "block/aio.h"
 
@@ -117,15 +118,7 @@ typedef struct Job {
     /** True if this job should automatically dismiss itself */
     bool auto_dismiss;
 
-    /**
-     * Current progress. The unit is arbitrary as long as the ratio between
-     * progress_current and progress_total represents the estimated percentage
-     * of work already done.
-     */
-    int64_t progress_current;
-
-    /** Estimated progress_current value at the completion of the job */
-    int64_t progress_total;
+    ProgressMeter progress;
 
     /**
      * Return code from @run and/or @prepare callback(s).
diff --git a/include/qemu/progress_meter.h b/include/qemu/progress_meter.h
new file mode 100644 (file)
index 0000000..9a23ff0
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Helper functionality for some process progress tracking.
+ *
+ * Copyright (c) 2011 IBM Corp.
+ * Copyright (c) 2012, 2018 Red Hat, Inc.
+ * Copyright (c) 2020 Virtuozzo International GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef QEMU_PROGRESS_METER_H
+#define QEMU_PROGRESS_METER_H
+
+typedef struct ProgressMeter {
+    /**
+     * Current progress. The unit is arbitrary as long as the ratio between
+     * current and total represents the estimated percentage
+     * of work already done.
+     */
+    uint64_t current;
+
+    /** Estimated current value at the completion of the process */
+    uint64_t total;
+} ProgressMeter;
+
+static inline void progress_work_done(ProgressMeter *pm, uint64_t done)
+{
+    pm->current += done;
+}
+
+static inline void progress_set_remaining(ProgressMeter *pm, uint64_t remaining)
+{
+    pm->total = pm->current + remaining;
+}
+
+static inline void progress_increase_remaining(ProgressMeter *pm,
+                                               uint64_t delta)
+{
+    pm->total += delta;
+}
+
+#endif /* QEMU_PROGRESS_METER_H */
index 294db54eb147d088a0e257befac40358eb5890b8..456a5b01eeda5cf8cc91b79a1ca12145b377c9ce 100644 (file)
@@ -142,6 +142,8 @@ struct {                                                                \
                 (elm)->field.le_next->field.le_prev =                   \
                     (elm)->field.le_prev;                               \
         *(elm)->field.le_prev = (elm)->field.le_next;                   \
+        (elm)->field.le_next = NULL;                                    \
+        (elm)->field.le_prev = NULL;                                    \
 } while (/*CONSTCOND*/0)
 
 /*
@@ -225,12 +227,15 @@ struct {                                                                \
 } while (/*CONSTCOND*/0)
 
 #define QSLIST_REMOVE_HEAD(head, field) do {                             \
-        (head)->slh_first = (head)->slh_first->field.sle_next;          \
+        typeof((head)->slh_first) elm = (head)->slh_first;               \
+        (head)->slh_first = elm->field.sle_next;                         \
+        elm->field.sle_next = NULL;                                      \
 } while (/*CONSTCOND*/0)
 
 #define QSLIST_REMOVE_AFTER(slistelm, field) do {                       \
-        (slistelm)->field.sle_next =                                    \
-            QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field);         \
+        typeof(slistelm) next = (slistelm)->field.sle_next;             \
+        (slistelm)->field.sle_next = next->field.sle_next;              \
+        next->field.sle_next = NULL;                                    \
 } while (/*CONSTCOND*/0)
 
 #define QSLIST_REMOVE(head, elm, type, field) do {                      \
@@ -241,6 +246,7 @@ struct {                                                                \
         while (curelm->field.sle_next != (elm))                         \
             curelm = curelm->field.sle_next;                            \
         curelm->field.sle_next = curelm->field.sle_next->field.sle_next; \
+        (elm)->field.sle_next = NULL;                                   \
     }                                                                   \
 } while (/*CONSTCOND*/0)
 
@@ -304,8 +310,10 @@ struct {                                                                \
 } while (/*CONSTCOND*/0)
 
 #define QSIMPLEQ_REMOVE_HEAD(head, field) do {                          \
-    if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\
+    typeof((head)->sqh_first) elm = (head)->sqh_first;                  \
+    if (((head)->sqh_first = elm->field.sqe_next) == NULL)              \
         (head)->sqh_last = &(head)->sqh_first;                          \
+    elm->field.sqe_next = NULL;                                         \
 } while (/*CONSTCOND*/0)
 
 #define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do {            \
@@ -329,6 +337,7 @@ struct {                                                                \
         if ((curelm->field.sqe_next =                                   \
             curelm->field.sqe_next->field.sqe_next) == NULL)            \
                 (head)->sqh_last = &(curelm)->field.sqe_next;           \
+        (elm)->field.sqe_next = NULL;                                   \
     }                                                                   \
 } while (/*CONSTCOND*/0)
 
@@ -446,6 +455,8 @@ union {                                                                 \
             (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev; \
         (elm)->field.tqe_circ.tql_prev->tql_next = (elm)->field.tqe_next; \
         (elm)->field.tqe_circ.tql_prev = NULL;                          \
+        (elm)->field.tqe_circ.tql_next = NULL;                          \
+        (elm)->field.tqe_next = NULL;                                   \
 } while (/*CONSTCOND*/0)
 
 /* remove @left, @right and all elements in between from @head */
index 3e4e1d928b7c2bb28dd20219c40dea44791549d3..6f92f3cebbc70a1f2597a90a9f8b04ba9063ac12 100644 (file)
@@ -162,4 +162,11 @@ void user_creatable_del(const char *id, Error **errp);
  */
 void user_creatable_cleanup(void);
 
+/**
+ * qmp_object_add:
+ *
+ * QMP command handler for object-add. See the QAPI schema for documentation.
+ */
+void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp);
+
 #endif
index 62c6fe4cf12d7f019021dab56dba34f71630b835..01392dc945f13be46ea50dd1d790dc6f47a9bb1a 100644 (file)
@@ -24,6 +24,8 @@ enum {
     QEMU_ARCH_NIOS2 = (1 << 17),
     QEMU_ARCH_HPPA = (1 << 18),
     QEMU_ARCH_RISCV = (1 << 19),
+
+    QEMU_ARCH_NONE = (1 << 31),
 };
 
 extern const uint32_t arch_type;
index d34c4920dcd5fa83194a241c364e4154b6d6f57f..a86d99b3d8751b9c4eefa53dd895cfd28c1aa747 100644 (file)
@@ -57,8 +57,4 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
 DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type,
                      Error **errp);
 
-/* device-hotplug */
-
-void hmp_commit(Monitor *mon, const QDict *qdict);
-void hmp_drive_del(Monitor *mon, const QDict *qdict);
 #endif
index 479d90bcea3d5e6ef8ea272a1b7ac77f01f33aa1..ef81302e1a9f4f99107d37e79bfefc8159b1aa33 100644 (file)
@@ -63,9 +63,6 @@ extern int nb_option_roms;
 extern const char *prom_envs[MAX_PROM_ENVS];
 extern unsigned int nb_prom_envs;
 
-/* generic hotplug */
-void hmp_drive_add(Monitor *mon, const QDict *qdict);
-
 /* pcie aer error injection */
 void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict);
 
index 15979a364781f9ec337599d823da11d4c23680f7..f37851b1aabe9cfc069b3286596b97277f29e6b9 100644 (file)
@@ -43,12 +43,13 @@ typedef struct TPMIfClass {
     enum TPMVersion (*get_version)(TPMIf *obj);
 } TPMIfClass;
 
-#define TYPE_TPM_TIS                "tpm-tis"
+#define TYPE_TPM_TIS_ISA            "tpm-tis"
+#define TYPE_TPM_TIS_SYSBUS         "tpm-tis-device"
 #define TYPE_TPM_CRB                "tpm-crb"
 #define TYPE_TPM_SPAPR              "tpm-spapr"
 
-#define TPM_IS_TIS(chr)                             \
-    object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS)
+#define TPM_IS_TIS_ISA(chr)                         \
+    object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_ISA)
 #define TPM_IS_CRB(chr)                             \
     object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB)
 #define TPM_IS_SPAPR(chr)                           \
index fbfed25a00067c5035bfde3d7b89c4754527159a..fecc939ebd951aa3bb863400b71c3bd27d874c84 100644 (file)
--- a/job-qmp.c
+++ b/job-qmp.c
@@ -143,8 +143,8 @@ static JobInfo *job_query_single(Job *job, Error **errp)
         .id                 = g_strdup(job->id),
         .type               = job_type(job),
         .status             = job->status,
-        .current_progress   = job->progress_current,
-        .total_progress     = job->progress_total,
+        .current_progress   = job->progress.current,
+        .total_progress     = job->progress.total,
         .has_error          = !!job->err,
         .error              = job->err ? \
                               g_strdup(error_get_pretty(job->err)) : NULL,
diff --git a/job.c b/job.c
index 04409b40aab3545798414bda1a872b5fb8490965..134a07b92e5ef05a52bee7e21a96b8154a2e1919 100644 (file)
--- a/job.c
+++ b/job.c
@@ -369,17 +369,17 @@ void job_unref(Job *job)
 
 void job_progress_update(Job *job, uint64_t done)
 {
-    job->progress_current += done;
+    progress_work_done(&job->progress, done);
 }
 
 void job_progress_set_remaining(Job *job, uint64_t remaining)
 {
-    job->progress_total = job->progress_current + remaining;
+    progress_set_remaining(&job->progress, remaining);
 }
 
 void job_progress_increase_remaining(Job *job, uint64_t delta)
 {
-    job->progress_total += delta;
+    progress_increase_remaining(&job->progress, delta);
 }
 
 void job_event_cancelled(Job *job)
index 9244d90859a28908f5b7924f16bea37890917c08..a8533c9dd7d5613cdd9c635ccfcedc6921109fb8 100644 (file)
@@ -2,3 +2,5 @@ obj-y += misc.o
 common-obj-y += monitor.o qmp.o hmp.o
 common-obj-y += qmp-cmds.o qmp-cmds-control.o
 common-obj-y += hmp-cmds.o
+
+storage-daemon-obj-y += monitor.o qmp.o qmp-cmds-control.o
index 30313858c2ceac205b98921bddcdbd81c6ab9d20..1c69d51b973382c5f8aad3991caaa71a4ba00464 100644 (file)
@@ -47,9 +47,6 @@
 #include "qapi/string-output-visitor.h"
 #include "qom/object_interfaces.h"
 #include "ui/console.h"
-#include "block/nbd.h"
-#include "block/qapi.h"
-#include "qemu-io.h"
 #include "qemu/cutils.h"
 #include "qemu/error-report.h"
 #include "exec/ramlist.h"
@@ -472,213 +469,6 @@ void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
                    qmp_query_migrate_cache_size(NULL) >> 10);
 }
 
-static void print_block_info(Monitor *mon, BlockInfo *info,
-                             BlockDeviceInfo *inserted, bool verbose)
-{
-    ImageInfo *image_info;
-
-    assert(!info || !info->has_inserted || info->inserted == inserted);
-
-    if (info && *info->device) {
-        monitor_printf(mon, "%s", info->device);
-        if (inserted && inserted->has_node_name) {
-            monitor_printf(mon, " (%s)", inserted->node_name);
-        }
-    } else {
-        assert(info || inserted);
-        monitor_printf(mon, "%s",
-                       inserted && inserted->has_node_name ? inserted->node_name
-                       : info && info->has_qdev ? info->qdev
-                       : "<anonymous>");
-    }
-
-    if (inserted) {
-        monitor_printf(mon, ": %s (%s%s%s)\n",
-                       inserted->file,
-                       inserted->drv,
-                       inserted->ro ? ", read-only" : "",
-                       inserted->encrypted ? ", encrypted" : "");
-    } else {
-        monitor_printf(mon, ": [not inserted]\n");
-    }
-
-    if (info) {
-        if (info->has_qdev) {
-            monitor_printf(mon, "    Attached to:      %s\n", info->qdev);
-        }
-        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
-            monitor_printf(mon, "    I/O status:       %s\n",
-                           BlockDeviceIoStatus_str(info->io_status));
-        }
-
-        if (info->removable) {
-            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
-                           info->locked ? "" : "not ",
-                           info->tray_open ? "open" : "closed");
-        }
-    }
-
-
-    if (!inserted) {
-        return;
-    }
-
-    monitor_printf(mon, "    Cache mode:       %s%s%s\n",
-                   inserted->cache->writeback ? "writeback" : "writethrough",
-                   inserted->cache->direct ? ", direct" : "",
-                   inserted->cache->no_flush ? ", ignore flushes" : "");
-
-    if (inserted->has_backing_file) {
-        monitor_printf(mon,
-                       "    Backing file:     %s "
-                       "(chain depth: %" PRId64 ")\n",
-                       inserted->backing_file,
-                       inserted->backing_file_depth);
-    }
-
-    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
-        monitor_printf(mon, "    Detect zeroes:    %s\n",
-                BlockdevDetectZeroesOptions_str(inserted->detect_zeroes));
-    }
-
-    if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
-        inserted->iops || inserted->iops_rd || inserted->iops_wr)
-    {
-        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
-                        " bps_rd=%" PRId64  " bps_wr=%" PRId64
-                        " bps_max=%" PRId64
-                        " bps_rd_max=%" PRId64
-                        " bps_wr_max=%" PRId64
-                        " iops=%" PRId64 " iops_rd=%" PRId64
-                        " iops_wr=%" PRId64
-                        " iops_max=%" PRId64
-                        " iops_rd_max=%" PRId64
-                        " iops_wr_max=%" PRId64
-                        " iops_size=%" PRId64
-                        " group=%s\n",
-                        inserted->bps,
-                        inserted->bps_rd,
-                        inserted->bps_wr,
-                        inserted->bps_max,
-                        inserted->bps_rd_max,
-                        inserted->bps_wr_max,
-                        inserted->iops,
-                        inserted->iops_rd,
-                        inserted->iops_wr,
-                        inserted->iops_max,
-                        inserted->iops_rd_max,
-                        inserted->iops_wr_max,
-                        inserted->iops_size,
-                        inserted->group);
-    }
-
-    if (verbose) {
-        monitor_printf(mon, "\nImages:\n");
-        image_info = inserted->image;
-        while (1) {
-                bdrv_image_info_dump(image_info);
-            if (image_info->has_backing_image) {
-                image_info = image_info->backing_image;
-            } else {
-                break;
-            }
-        }
-    }
-}
-
-void hmp_info_block(Monitor *mon, const QDict *qdict)
-{
-    BlockInfoList *block_list, *info;
-    BlockDeviceInfoList *blockdev_list, *blockdev;
-    const char *device = qdict_get_try_str(qdict, "device");
-    bool verbose = qdict_get_try_bool(qdict, "verbose", false);
-    bool nodes = qdict_get_try_bool(qdict, "nodes", false);
-    bool printed = false;
-
-    /* Print BlockBackend information */
-    if (!nodes) {
-        block_list = qmp_query_block(NULL);
-    } else {
-        block_list = NULL;
-    }
-
-    for (info = block_list; info; info = info->next) {
-        if (device && strcmp(device, info->value->device)) {
-            continue;
-        }
-
-        if (info != block_list) {
-            monitor_printf(mon, "\n");
-        }
-
-        print_block_info(mon, info->value, info->value->has_inserted
-                                           ? info->value->inserted : NULL,
-                         verbose);
-        printed = true;
-    }
-
-    qapi_free_BlockInfoList(block_list);
-
-    if ((!device && !nodes) || printed) {
-        return;
-    }
-
-    /* Print node information */
-    blockdev_list = qmp_query_named_block_nodes(false, false, NULL);
-    for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
-        assert(blockdev->value->has_node_name);
-        if (device && strcmp(device, blockdev->value->node_name)) {
-            continue;
-        }
-
-        if (blockdev != blockdev_list) {
-            monitor_printf(mon, "\n");
-        }
-
-        print_block_info(mon, NULL, blockdev->value, verbose);
-    }
-    qapi_free_BlockDeviceInfoList(blockdev_list);
-}
-
-void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
-{
-    BlockStatsList *stats_list, *stats;
-
-    stats_list = qmp_query_blockstats(false, false, NULL);
-
-    for (stats = stats_list; stats; stats = stats->next) {
-        if (!stats->value->has_device) {
-            continue;
-        }
-
-        monitor_printf(mon, "%s:", stats->value->device);
-        monitor_printf(mon, " rd_bytes=%" PRId64
-                       " wr_bytes=%" PRId64
-                       " rd_operations=%" PRId64
-                       " wr_operations=%" PRId64
-                       " flush_operations=%" PRId64
-                       " wr_total_time_ns=%" PRId64
-                       " rd_total_time_ns=%" PRId64
-                       " flush_total_time_ns=%" PRId64
-                       " rd_merged=%" PRId64
-                       " wr_merged=%" PRId64
-                       " idle_time_ns=%" PRId64
-                       "\n",
-                       stats->value->stats->rd_bytes,
-                       stats->value->stats->wr_bytes,
-                       stats->value->stats->rd_operations,
-                       stats->value->stats->wr_operations,
-                       stats->value->stats->flush_operations,
-                       stats->value->stats->wr_total_time_ns,
-                       stats->value->stats->rd_total_time_ns,
-                       stats->value->stats->flush_total_time_ns,
-                       stats->value->stats->rd_merged,
-                       stats->value->stats->wr_merged,
-                       stats->value->stats->idle_time_ns);
-    }
-
-    qapi_free_BlockStatsList(stats_list);
-}
 
 #ifdef CONFIG_VNC
 /* Helper for hmp_info_vnc_clients, _servers */
@@ -1058,44 +848,6 @@ void hmp_info_pci(Monitor *mon, const QDict *qdict)
     qapi_free_PciInfoList(info_list);
 }
 
-void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
-{
-    BlockJobInfoList *list;
-    Error *err = NULL;
-
-    list = qmp_query_block_jobs(&err);
-    assert(!err);
-
-    if (!list) {
-        monitor_printf(mon, "No active jobs\n");
-        return;
-    }
-
-    while (list) {
-        if (strcmp(list->value->type, "stream") == 0) {
-            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRId64
-                           " bytes/s\n",
-                           list->value->device,
-                           list->value->offset,
-                           list->value->len,
-                           list->value->speed);
-        } else {
-            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRId64
-                           " bytes/s\n",
-                           list->value->type,
-                           list->value->device,
-                           list->value->offset,
-                           list->value->len,
-                           list->value->speed);
-        }
-        list = list->next;
-    }
-
-    qapi_free_BlockJobInfoList(list);
-}
-
 void hmp_info_tpm(Monitor *mon, const QDict *qdict)
 {
     TPMInfoList *info_list, *info;
@@ -1313,16 +1065,6 @@ void hmp_set_link(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_block_passwd(Monitor *mon, const QDict *qdict)
-{
-    const char *device = qdict_get_str(qdict, "device");
-    const char *password = qdict_get_str(qdict, "password");
-    Error *err = NULL;
-
-    qmp_block_passwd(true, device, false, NULL, password, &err);
-    hmp_handle_error(mon, err);
-}
-
 void hmp_balloon(Monitor *mon, const QDict *qdict)
 {
     int64_t value = qdict_get_int(qdict, "value");
@@ -1332,121 +1074,6 @@ void hmp_balloon(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_block_resize(Monitor *mon, const QDict *qdict)
-{
-    const char *device = qdict_get_str(qdict, "device");
-    int64_t size = qdict_get_int(qdict, "size");
-    Error *err = NULL;
-
-    qmp_block_resize(true, device, false, NULL, size, &err);
-    hmp_handle_error(mon, err);
-}
-
-void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
-{
-    const char *filename = qdict_get_str(qdict, "target");
-    const char *format = qdict_get_try_str(qdict, "format");
-    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
-    bool full = qdict_get_try_bool(qdict, "full", false);
-    Error *err = NULL;
-    DriveMirror mirror = {
-        .device = (char *)qdict_get_str(qdict, "device"),
-        .target = (char *)filename,
-        .has_format = !!format,
-        .format = (char *)format,
-        .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
-        .has_mode = true,
-        .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
-        .unmap = true,
-    };
-
-    if (!filename) {
-        error_setg(&err, QERR_MISSING_PARAMETER, "target");
-        hmp_handle_error(mon, err);
-        return;
-    }
-    qmp_drive_mirror(&mirror, &err);
-    hmp_handle_error(mon, err);
-}
-
-void hmp_drive_backup(Monitor *mon, const QDict *qdict)
-{
-    const char *device = qdict_get_str(qdict, "device");
-    const char *filename = qdict_get_str(qdict, "target");
-    const char *format = qdict_get_try_str(qdict, "format");
-    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
-    bool full = qdict_get_try_bool(qdict, "full", false);
-    bool compress = qdict_get_try_bool(qdict, "compress", false);
-    Error *err = NULL;
-    DriveBackup backup = {
-        .device = (char *)device,
-        .target = (char *)filename,
-        .has_format = !!format,
-        .format = (char *)format,
-        .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
-        .has_mode = true,
-        .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
-        .has_compress = !!compress,
-        .compress = compress,
-    };
-
-    if (!filename) {
-        error_setg(&err, QERR_MISSING_PARAMETER, "target");
-        hmp_handle_error(mon, err);
-        return;
-    }
-
-    qmp_drive_backup(&backup, &err);
-    hmp_handle_error(mon, err);
-}
-
-void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
-{
-    const char *device = qdict_get_str(qdict, "device");
-    const char *filename = qdict_get_try_str(qdict, "snapshot-file");
-    const char *format = qdict_get_try_str(qdict, "format");
-    bool reuse = qdict_get_try_bool(qdict, "reuse", false);
-    enum NewImageMode mode;
-    Error *err = NULL;
-
-    if (!filename) {
-        /* In the future, if 'snapshot-file' is not specified, the snapshot
-           will be taken internally. Today it's actually required. */
-        error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file");
-        hmp_handle_error(mon, err);
-        return;
-    }
-
-    mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
-    qmp_blockdev_snapshot_sync(true, device, false, NULL,
-                               filename, false, NULL,
-                               !!format, format,
-                               true, mode, &err);
-    hmp_handle_error(mon, err);
-}
-
-void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
-{
-    const char *device = qdict_get_str(qdict, "device");
-    const char *name = qdict_get_str(qdict, "name");
-    Error *err = NULL;
-
-    qmp_blockdev_snapshot_internal_sync(device, name, &err);
-    hmp_handle_error(mon, err);
-}
-
-void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
-{
-    const char *device = qdict_get_str(qdict, "device");
-    const char *name = qdict_get_str(qdict, "name");
-    const char *id = qdict_get_try_str(qdict, "id");
-    Error *err = NULL;
-
-    qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
-                                               true, name, &err);
-    hmp_handle_error(mon, err);
-}
-
 void hmp_loadvm(Monitor *mon, const QDict *qdict)
 {
     int saved_vm_running  = runstate_is_running();
@@ -1483,148 +1110,6 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
-{
-    BlockDriverState *bs, *bs1;
-    BdrvNextIterator it1;
-    QEMUSnapshotInfo *sn_tab, *sn;
-    bool no_snapshot = true;
-    int nb_sns, i;
-    int total;
-    int *global_snapshots;
-    AioContext *aio_context;
-
-    typedef struct SnapshotEntry {
-        QEMUSnapshotInfo sn;
-        QTAILQ_ENTRY(SnapshotEntry) next;
-    } SnapshotEntry;
-
-    typedef struct ImageEntry {
-        const char *imagename;
-        QTAILQ_ENTRY(ImageEntry) next;
-        QTAILQ_HEAD(, SnapshotEntry) snapshots;
-    } ImageEntry;
-
-    QTAILQ_HEAD(, ImageEntry) image_list =
-        QTAILQ_HEAD_INITIALIZER(image_list);
-
-    ImageEntry *image_entry, *next_ie;
-    SnapshotEntry *snapshot_entry;
-
-    bs = bdrv_all_find_vmstate_bs();
-    if (!bs) {
-        monitor_printf(mon, "No available block device supports snapshots\n");
-        return;
-    }
-    aio_context = bdrv_get_aio_context(bs);
-
-    aio_context_acquire(aio_context);
-    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
-    aio_context_release(aio_context);
-
-    if (nb_sns < 0) {
-        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
-        return;
-    }
-
-    for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) {
-        int bs1_nb_sns = 0;
-        ImageEntry *ie;
-        SnapshotEntry *se;
-        AioContext *ctx = bdrv_get_aio_context(bs1);
-
-        aio_context_acquire(ctx);
-        if (bdrv_can_snapshot(bs1)) {
-            sn = NULL;
-            bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
-            if (bs1_nb_sns > 0) {
-                no_snapshot = false;
-                ie = g_new0(ImageEntry, 1);
-                ie->imagename = bdrv_get_device_name(bs1);
-                QTAILQ_INIT(&ie->snapshots);
-                QTAILQ_INSERT_TAIL(&image_list, ie, next);
-                for (i = 0; i < bs1_nb_sns; i++) {
-                    se = g_new0(SnapshotEntry, 1);
-                    se->sn = sn[i];
-                    QTAILQ_INSERT_TAIL(&ie->snapshots, se, next);
-                }
-            }
-            g_free(sn);
-        }
-        aio_context_release(ctx);
-    }
-
-    if (no_snapshot) {
-        monitor_printf(mon, "There is no snapshot available.\n");
-        return;
-    }
-
-    global_snapshots = g_new0(int, nb_sns);
-    total = 0;
-    for (i = 0; i < nb_sns; i++) {
-        SnapshotEntry *next_sn;
-        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) {
-            global_snapshots[total] = i;
-            total++;
-            QTAILQ_FOREACH(image_entry, &image_list, next) {
-                QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots,
-                                    next, next_sn) {
-                    if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) {
-                        QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry,
-                                      next);
-                        g_free(snapshot_entry);
-                    }
-                }
-            }
-        }
-    }
-
-    monitor_printf(mon, "List of snapshots present on all disks:\n");
-
-    if (total > 0) {
-        bdrv_snapshot_dump(NULL);
-        monitor_printf(mon, "\n");
-        for (i = 0; i < total; i++) {
-            sn = &sn_tab[global_snapshots[i]];
-            /* The ID is not guaranteed to be the same on all images, so
-             * overwrite it.
-             */
-            pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
-            bdrv_snapshot_dump(sn);
-            monitor_printf(mon, "\n");
-        }
-    } else {
-        monitor_printf(mon, "None\n");
-    }
-
-    QTAILQ_FOREACH(image_entry, &image_list, next) {
-        if (QTAILQ_EMPTY(&image_entry->snapshots)) {
-            continue;
-        }
-        monitor_printf(mon,
-                       "\nList of partial (non-loadable) snapshots on '%s':\n",
-                       image_entry->imagename);
-        bdrv_snapshot_dump(NULL);
-        monitor_printf(mon, "\n");
-        QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
-            bdrv_snapshot_dump(&snapshot_entry->sn);
-            monitor_printf(mon, "\n");
-        }
-    }
-
-    QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) {
-        SnapshotEntry *next_sn;
-        QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next,
-                            next_sn) {
-            g_free(snapshot_entry);
-        }
-        g_free(image_entry);
-    }
-    g_free(sn_tab);
-    g_free(global_snapshots);
-
-}
-
 void hmp_announce_self(Monitor *mon, const QDict *qdict)
 {
     const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
@@ -1946,15 +1431,6 @@ void hmp_expire_password(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_eject(Monitor *mon, const QDict *qdict)
-{
-    bool force = qdict_get_try_bool(qdict, "force", false);
-    const char *device = qdict_get_str(qdict, "device");
-    Error *err = NULL;
-
-    qmp_eject(true, device, false, NULL, true, force, &err);
-    hmp_handle_error(mon, err);
-}
 
 #ifdef CONFIG_VNC
 static void hmp_change_read_arg(void *opaque, const char *password,
@@ -2012,101 +1488,6 @@ void hmp_change(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
-{
-    Error *err = NULL;
-    char *device = (char *) qdict_get_str(qdict, "device");
-    BlockIOThrottle throttle = {
-        .bps = qdict_get_int(qdict, "bps"),
-        .bps_rd = qdict_get_int(qdict, "bps_rd"),
-        .bps_wr = qdict_get_int(qdict, "bps_wr"),
-        .iops = qdict_get_int(qdict, "iops"),
-        .iops_rd = qdict_get_int(qdict, "iops_rd"),
-        .iops_wr = qdict_get_int(qdict, "iops_wr"),
-    };
-
-    /* qmp_block_set_io_throttle has separate parameters for the
-     * (deprecated) block device name and the qdev ID but the HMP
-     * version has only one, so we must decide which one to pass. */
-    if (blk_by_name(device)) {
-        throttle.has_device = true;
-        throttle.device = device;
-    } else {
-        throttle.has_id = true;
-        throttle.id = device;
-    }
-
-    qmp_block_set_io_throttle(&throttle, &err);
-    hmp_handle_error(mon, err);
-}
-
-void hmp_block_stream(Monitor *mon, const QDict *qdict)
-{
-    Error *error = NULL;
-    const char *device = qdict_get_str(qdict, "device");
-    const char *base = qdict_get_try_str(qdict, "base");
-    int64_t speed = qdict_get_try_int(qdict, "speed", 0);
-
-    qmp_block_stream(true, device, device, base != NULL, base, false, NULL,
-                     false, NULL, qdict_haskey(qdict, "speed"), speed, true,
-                     BLOCKDEV_ON_ERROR_REPORT, false, false, false, false,
-                     &error);
-
-    hmp_handle_error(mon, error);
-}
-
-void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
-{
-    Error *error = NULL;
-    const char *device = qdict_get_str(qdict, "device");
-    int64_t value = qdict_get_int(qdict, "speed");
-
-    qmp_block_job_set_speed(device, value, &error);
-
-    hmp_handle_error(mon, error);
-}
-
-void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
-{
-    Error *error = NULL;
-    const char *device = qdict_get_str(qdict, "device");
-    bool force = qdict_get_try_bool(qdict, "force", false);
-
-    qmp_block_job_cancel(device, true, force, &error);
-
-    hmp_handle_error(mon, error);
-}
-
-void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
-{
-    Error *error = NULL;
-    const char *device = qdict_get_str(qdict, "device");
-
-    qmp_block_job_pause(device, &error);
-
-    hmp_handle_error(mon, error);
-}
-
-void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
-{
-    Error *error = NULL;
-    const char *device = qdict_get_str(qdict, "device");
-
-    qmp_block_job_resume(device, &error);
-
-    hmp_handle_error(mon, error);
-}
-
-void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
-{
-    Error *error = NULL;
-    const char *device = qdict_get_str(qdict, "device");
-
-    qmp_block_job_complete(device, &error);
-
-    hmp_handle_error(mon, error);
-}
-
 typedef struct HMPMigrationStatus
 {
     QEMUTimer *timer;
@@ -2333,92 +1714,6 @@ void hmp_screendump(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
-{
-    const char *uri = qdict_get_str(qdict, "uri");
-    bool writable = qdict_get_try_bool(qdict, "writable", false);
-    bool all = qdict_get_try_bool(qdict, "all", false);
-    Error *local_err = NULL;
-    BlockInfoList *block_list, *info;
-    SocketAddress *addr;
-
-    if (writable && !all) {
-        error_setg(&local_err, "-w only valid together with -a");
-        goto exit;
-    }
-
-    /* First check if the address is valid and start the server.  */
-    addr = socket_parse(uri, &local_err);
-    if (local_err != NULL) {
-        goto exit;
-    }
-
-    nbd_server_start(addr, NULL, NULL, &local_err);
-    qapi_free_SocketAddress(addr);
-    if (local_err != NULL) {
-        goto exit;
-    }
-
-    if (!all) {
-        return;
-    }
-
-    /* Then try adding all block devices.  If one fails, close all and
-     * exit.
-     */
-    block_list = qmp_query_block(NULL);
-
-    for (info = block_list; info; info = info->next) {
-        if (!info->value->has_inserted) {
-            continue;
-        }
-
-        qmp_nbd_server_add(info->value->device, false, NULL, false, NULL,
-                           true, writable, false, NULL, &local_err);
-
-        if (local_err != NULL) {
-            qmp_nbd_server_stop(NULL);
-            break;
-        }
-    }
-
-    qapi_free_BlockInfoList(block_list);
-
-exit:
-    hmp_handle_error(mon, local_err);
-}
-
-void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
-{
-    const char *device = qdict_get_str(qdict, "device");
-    const char *name = qdict_get_try_str(qdict, "name");
-    bool writable = qdict_get_try_bool(qdict, "writable", false);
-    Error *local_err = NULL;
-
-    qmp_nbd_server_add(device, !!name, name, false, NULL, true, writable,
-                       false, NULL, &local_err);
-    hmp_handle_error(mon, local_err);
-}
-
-void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
-{
-    const char *name = qdict_get_str(qdict, "name");
-    bool force = qdict_get_try_bool(qdict, "force", false);
-    Error *err = NULL;
-
-    /* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */
-    qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, &err);
-    hmp_handle_error(mon, err);
-}
-
-void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
-{
-    Error *err = NULL;
-
-    qmp_nbd_server_stop(&err);
-    hmp_handle_error(mon, err);
-}
-
 void hmp_chardev_add(Monitor *mon, const QDict *qdict)
 {
     const char *args = qdict_get_str(qdict, "args");
@@ -2485,70 +1780,6 @@ void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, local_err);
 }
 
-void hmp_qemu_io(Monitor *mon, const QDict *qdict)
-{
-    BlockBackend *blk;
-    BlockBackend *local_blk = NULL;
-    bool qdev = qdict_get_try_bool(qdict, "qdev", false);
-    const char* device = qdict_get_str(qdict, "device");
-    const char* command = qdict_get_str(qdict, "command");
-    Error *err = NULL;
-    int ret;
-
-    if (qdev) {
-        blk = blk_by_qdev_id(device, &err);
-        if (!blk) {
-            goto fail;
-        }
-    } else {
-        blk = blk_by_name(device);
-        if (!blk) {
-            BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
-            if (bs) {
-                blk = local_blk = blk_new(bdrv_get_aio_context(bs),
-                                          0, BLK_PERM_ALL);
-                ret = blk_insert_bs(blk, bs, &err);
-                if (ret < 0) {
-                    goto fail;
-                }
-            } else {
-                goto fail;
-            }
-        }
-    }
-
-    /*
-     * Notably absent: Proper permission management. This is sad, but it seems
-     * almost impossible to achieve without changing the semantics and thereby
-     * limiting the use cases of the qemu-io HMP command.
-     *
-     * In an ideal world we would unconditionally create a new BlockBackend for
-     * qemuio_command(), but we have commands like 'reopen' and want them to
-     * take effect on the exact BlockBackend whose name the user passed instead
-     * of just on a temporary copy of it.
-     *
-     * Another problem is that deleting the temporary BlockBackend involves
-     * draining all requests on it first, but some qemu-iotests cases want to
-     * issue multiple aio_read/write requests and expect them to complete in
-     * the background while the monitor has already returned.
-     *
-     * This is also what prevents us from saving the original permissions and
-     * restoring them later: We can't revoke permissions until all requests
-     * have completed, and we don't know when that is nor can we really let
-     * anything else run before we have revoken them to avoid race conditions.
-     *
-     * What happens now is that command() in qemu-io-cmds.c can extend the
-     * permissions if necessary for the qemu-io command. And they simply stay
-     * extended, possibly resulting in a read-only guest device keeping write
-     * permissions. Ugly, but it appears to be the lesser evil.
-     */
-    qemuio_command(blk, command);
-
-fail:
-    blk_unref(local_blk);
-    hmp_handle_error(mon, err);
-}
-
 void hmp_object_del(Monitor *mon, const QDict *qdict)
 {
     const char *id = qdict_get_str(qdict, "id");
@@ -2829,7 +2060,6 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
     const char *name = qdict_get_str(qdict, "name");
     uint8_t type = qdict_get_try_int(qdict, "type", 9);
     Error *err = NULL;
-    bool set = false;
 
     list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err);
     if (err != NULL) {
@@ -2841,6 +2071,7 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
 
     for (g = list; g; g = g->next) {
         RockerOfDpaGroup *group = g->value;
+        bool set = false;
 
         monitor_printf(mon, "0x%08x", group->id);
 
@@ -2885,14 +2116,11 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
 
         if (group->has_set_eth_dst) {
             if (!set) {
-                set = true;
                 monitor_printf(mon, " set");
             }
             monitor_printf(mon, " dst %s", group->set_eth_dst);
         }
 
-        set = false;
-
         if (group->has_ttl_check && group->ttl_check) {
             monitor_printf(mon, " check TTL");
         }
index 944fa9651ede7ad4c0c25c816324e7d3c859596f..d598dd02bb0bd7d2bafee0e2617da6b874d0d30e 100644 (file)
@@ -1399,12 +1399,16 @@ static void monitor_readline_flush(void *opaque)
     monitor_flush(&mon->common);
 }
 
-void monitor_init_hmp(Chardev *chr, bool use_readline)
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp)
 {
     MonitorHMP *mon = g_new0(MonitorHMP, 1);
 
+    if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
+        g_free(mon);
+        return;
+    }
+
     monitor_data_init(&mon->common, false, false, false);
-    qemu_chr_fe_init(&mon->common.chr, chr, &error_abort);
 
     mon->use_readline = use_readline;
     if (mon->use_readline) {
index 6c412931023d7c595f1701e8076b829e9bd455d0..c3bc34c099dd95f60b8d9d3f6a3186f6763cf7c5 100644 (file)
@@ -66,6 +66,7 @@
 #include "qemu/option.h"
 #include "qemu/thread.h"
 #include "block/qapi.h"
+#include "block/block-hmp-cmds.h"
 #include "qapi/qapi-commands-char.h"
 #include "qapi/qapi-commands-control.h"
 #include "qapi/qapi-commands-migration.h"
@@ -248,6 +249,8 @@ static void monitor_init_qmp_commands(void)
                          QCO_NO_OPTIONS);
     qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
                          QCO_NO_OPTIONS);
+    qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
+                         QCO_NO_OPTIONS);
 
     QTAILQ_INIT(&qmp_cap_negotiation_commands);
     qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
index c1a6c4460fbb4b66e695f3adca92f60a02d05136..125494410ad64e2f9792e3be7b16d356c4fdda10 100644 (file)
@@ -25,7 +25,9 @@
 #include "qemu/osdep.h"
 #include "monitor-internal.h"
 #include "qapi/error.h"
+#include "qapi/opts-visitor.h"
 #include "qapi/qapi-emit-events.h"
+#include "qapi/qapi-visit-control.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
 #include "qemu/error-report.h"
@@ -609,50 +611,68 @@ void monitor_init_globals_core(void)
                                    NULL);
 }
 
-int monitor_init_opts(QemuOpts *opts, Error **errp)
+int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp)
 {
     Chardev *chr;
-    bool qmp;
-    bool pretty = false;
-    const char *chardev;
-    const char *mode;
-
-    mode = qemu_opt_get(opts, "mode");
-    if (mode == NULL) {
-        mode = "readline";
-    }
-    if (strcmp(mode, "readline") == 0) {
-        qmp = false;
-    } else if (strcmp(mode, "control") == 0) {
-        qmp = true;
-    } else {
-        error_setg(errp, "unknown monitor mode \"%s\"", mode);
+    Error *local_err = NULL;
+
+    chr = qemu_chr_find(opts->chardev);
+    if (chr == NULL) {
+        error_setg(errp, "chardev \"%s\" not found", opts->chardev);
         return -1;
     }
 
-    if (!qmp && qemu_opt_get(opts, "pretty")) {
-        warn_report("'pretty' is deprecated for HMP monitors, it has no effect "
-                    "and will be removed in future versions");
-    }
-    if (qemu_opt_get_bool(opts, "pretty", 0)) {
-        pretty = true;
+    if (!opts->has_mode) {
+        opts->mode = allow_hmp ? MONITOR_MODE_READLINE : MONITOR_MODE_CONTROL;
     }
 
-    chardev = qemu_opt_get(opts, "chardev");
-    if (!chardev) {
-        error_report("chardev is required");
-        exit(1);
+    switch (opts->mode) {
+    case MONITOR_MODE_CONTROL:
+        monitor_init_qmp(chr, opts->pretty, &local_err);
+        break;
+    case MONITOR_MODE_READLINE:
+        if (!allow_hmp) {
+            error_setg(errp, "Only QMP is supported");
+            return -1;
+        }
+        if (opts->pretty) {
+            warn_report("'pretty' is deprecated for HMP monitors, it has no "
+                        "effect and will be removed in future versions");
+        }
+        monitor_init_hmp(chr, true, &local_err);
+        break;
+    default:
+        g_assert_not_reached();
     }
-    chr = qemu_chr_find(chardev);
-    if (chr == NULL) {
-        error_setg(errp, "chardev \"%s\" not found", chardev);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
         return -1;
     }
+    return 0;
+}
+
+int monitor_init_opts(QemuOpts *opts, Error **errp)
+{
+    Visitor *v;
+    MonitorOptions *options;
+    Error *local_err = NULL;
+
+    v = opts_visitor_new(opts);
+    visit_type_MonitorOptions(v, NULL, &options, &local_err);
+    visit_free(v);
+
+    if (local_err) {
+        goto out;
+    }
 
-    if (qmp) {
-        monitor_init_qmp(chr, pretty);
-    } else {
-        monitor_init_hmp(chr, true);
+    monitor_init(options, true, &local_err);
+    qapi_free_MonitorOptions(options);
+
+out:
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return -1;
     }
     return 0;
 }
index da7083087ef48e1a9235e9154ed31f7f5dc200d5..864cbfa32e6bcfaae37057c1f36a542abe4f860f 100644 (file)
@@ -30,7 +30,7 @@
 #include "sysemu/blockdev.h"
 #include "sysemu/block-backend.h"
 #include "qapi/error.h"
-#include "qapi/qapi-commands-block-core.h"
+#include "qapi/qapi-commands-block.h"
 #include "qapi/qapi-commands-control.h"
 #include "qapi/qapi-commands-machine.h"
 #include "qapi/qapi-commands-misc.h"
index 8379c8f96e0682aa73348ec4c28ceb5d81855b94..f89e7daf278e43ba9d326bd212ddd8dc995c872b 100644 (file)
@@ -395,10 +395,16 @@ static void monitor_qmp_setup_handlers_bh(void *opaque)
     monitor_list_append(&mon->common);
 }
 
-void monitor_init_qmp(Chardev *chr, bool pretty)
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
 {
     MonitorQMP *mon = g_new0(MonitorQMP, 1);
 
+    if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
+        g_free(mon);
+        return;
+    }
+    qemu_chr_fe_set_echo(&mon->common.chr, true);
+
     /* Note: we run QMP monitor in I/O thread when @chr supports that */
     monitor_data_init(&mon->common, true, false,
                       qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT));
@@ -408,9 +414,6 @@ void monitor_init_qmp(Chardev *chr, bool pretty)
     qemu_mutex_init(&mon->qmp_queue_lock);
     mon->qmp_requests = g_queue_new();
 
-    qemu_chr_fe_init(&mon->common.chr, chr, &error_abort);
-    qemu_chr_fe_set_echo(&mon->common.chr, true);
-
     json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL);
     if (mon->common.use_io_thread) {
         /*
index 5795a678edb43a3c527b9032c3d1cdea085dcff7..88cfb876f37ccfbfaa08ff131491444d81035edd 100644 (file)
--- a/net/hub.c
+++ b/net/hub.c
@@ -193,29 +193,6 @@ NetClientState *net_hub_add_port(int hub_id, const char *name,
     return &port->nc;
 }
 
-/**
- * Find a specific client on a hub
- */
-NetClientState *net_hub_find_client_by_name(int hub_id, const char *name)
-{
-    NetHub *hub;
-    NetHubPort *port;
-    NetClientState *peer;
-
-    QLIST_FOREACH(hub, &hubs, next) {
-        if (hub->id == hub_id) {
-            QLIST_FOREACH(port, &hub->ports, next) {
-                peer = port->nc.peer;
-
-                if (peer && strcmp(peer->name, name) == 0) {
-                    return peer;
-                }
-            }
-        }
-    }
-    return NULL;
-}
-
 /**
  * Find a available port on a hub; otherwise create one new port
  */
index 66d3322facf2a8c7c03805b364cb8daad8e3e935..ce45f7b399d30038e492319009ee4c512a7528db 100644 (file)
--- a/net/hub.h
+++ b/net/hub.h
 #ifndef NET_HUB_H
 #define NET_HUB_H
 
-
 NetClientState *net_hub_add_port(int hub_id, const char *name,
                                  NetClientState *hubpeer);
-NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
 void net_hub_info(Monitor *mon);
 void net_hub_check_clients(void);
 bool net_hub_flush(NetClientState *nc);
index c4334ee876c7b72dec9f29fe949658110c8d2406..77042e6df7460d81fc7b68b5286ba28feda67786 100644 (file)
@@ -610,25 +610,13 @@ error:
     return -1;
 }
 
-static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id,
-                                const char *name)
+static SlirpState *slirp_lookup(Monitor *mon, const char *id)
 {
-    if (name) {
-        NetClientState *nc;
-        if (hub_id) {
-            nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name);
-            if (!nc) {
-                monitor_printf(mon, "unrecognized (hub-id, stackname) pair\n");
-                return NULL;
-            }
-            warn_report("Using 'hub-id' is deprecated, specify the netdev id "
-                        "directly instead");
-        } else {
-            nc = qemu_find_netdev(name);
-            if (!nc) {
-                monitor_printf(mon, "unrecognized netdev id '%s'\n", name);
-                return NULL;
-            }
+    if (id) {
+        NetClientState *nc = qemu_find_netdev(id);
+        if (!nc) {
+            monitor_printf(mon, "unrecognized netdev id '%s'\n", id);
+            return NULL;
         }
         if (strcmp(nc->model, "user")) {
             monitor_printf(mon, "invalid device specified\n");
@@ -655,16 +643,12 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
     int err;
     const char *arg1 = qdict_get_str(qdict, "arg1");
     const char *arg2 = qdict_get_try_str(qdict, "arg2");
-    const char *arg3 = qdict_get_try_str(qdict, "arg3");
 
-    if (arg3) {
-        s = slirp_lookup(mon, arg1, arg2);
-        src_str = arg3;
-    } else if (arg2) {
-        s = slirp_lookup(mon, NULL, arg1);
+    if (arg2) {
+        s = slirp_lookup(mon, arg1);
         src_str = arg2;
     } else {
-        s = slirp_lookup(mon, NULL, NULL);
+        s = slirp_lookup(mon, NULL);
         src_str = arg1;
     }
     if (!s) {
@@ -784,16 +768,12 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
     SlirpState *s;
     const char *arg1 = qdict_get_str(qdict, "arg1");
     const char *arg2 = qdict_get_try_str(qdict, "arg2");
-    const char *arg3 = qdict_get_try_str(qdict, "arg3");
 
-    if (arg3) {
-        s = slirp_lookup(mon, arg1, arg2);
-        redir_str = arg3;
-    } else if (arg2) {
-        s = slirp_lookup(mon, NULL, arg1);
+    if (arg2) {
+        s = slirp_lookup(mon, arg1);
         redir_str = arg2;
     } else {
-        s = slirp_lookup(mon, NULL, NULL);
+        s = slirp_lookup(mon, NULL);
         redir_str = arg1;
     }
     if (s) {
index 91cdee4436ad828fe6cb664cfac270a21f2bde70..b9da9d8ecb10faa484a9a524a202f1f69cb59ad6 100644 (file)
Binary files a/pc-bios/s390-ccw.img and b/pc-bios/s390-ccw.img differ
index da13c43cc0477e284bd8d5ea15452e14ab00214c..4eba2510b045ff06157ca550285605768a3b372a 100644 (file)
@@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
 {
     /* store the subsystem information _after_ the bootmap was loaded */
     write_subsystem_identification();
+    write_iplb_location();
 
     /* prevent unknown IPL types in the guest */
     if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
index a21b38628075b450477af9565fd6eb5b170cab4a..4e65b411e1d890ba7f8536d7b99f1962782eca15 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "libc.h"
+#include "helper.h"
 #include "s390-arch.h"
 #include "s390-ccw.h"
 #include "cio.h"
@@ -22,7 +23,7 @@ QemuIplParameters qipl;
 IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
 static bool have_iplb;
 static uint16_t cutype;
-LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
+LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
 
 #define LOADPARM_PROMPT "PROMPT  "
 #define LOADPARM_EMPTY  "        "
@@ -42,6 +43,11 @@ void write_subsystem_identification(void)
     *zeroes = 0;
 }
 
+void write_iplb_location(void)
+{
+    lowcore->ptr_iplb = ptr2u32(&iplb);
+}
+
 void panic(const char *string)
 {
     sclp_print(string);
index f2dcc01e27257696d110b12164c97ac6c99ccc23..309ffa30d992207770d51ffc7d9a2dc46dd2aa7e 100644 (file)
@@ -40,6 +40,7 @@
 #define DEFAULT_TFTP_RETRIES 20
 
 extern char _start[];
+void write_iplb_location(void) {}
 
 #define KERNEL_ADDR             ((void *)0L)
 #define KERNEL_MAX_SIZE         ((long)_start)
index 504fc7c2f09878cb6b37e307bb209b28439de0b5..5f36361c0223d43439a249e84040ea9b5accea8c 100644 (file)
@@ -36,7 +36,13 @@ typedef struct LowCore {
     /* prefix area: defined by architecture */
     PSWLegacy       ipl_psw;                  /* 0x000 */
     uint32_t        ccw1[2];                  /* 0x008 */
-    uint32_t        ccw2[2];                  /* 0x010 */
+    union {
+        uint32_t        ccw2[2];                  /* 0x010 */
+        struct {
+            uint32_t reserved10;
+            uint32_t ptr_iplb;
+        };
+    };
     uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
     uint32_t        ext_params;               /* 0x080 */
     uint16_t        cpu_addr;                 /* 0x084 */
@@ -85,7 +91,7 @@ typedef struct LowCore {
     PSW             io_new_psw;               /* 0x1f0 */
 } __attribute__((packed, aligned(8192))) LowCore;
 
-extern LowCore const *lowcore;
+extern LowCore *lowcore;
 
 static inline void set_prefix(uint32_t address)
 {
index 11bce7d73c85581e561d5802059be788f1229a7a..21f27e79906ea297c4480eeaee2ea939c792ccfd 100644 (file)
@@ -57,6 +57,7 @@ void consume_io_int(void);
 /* main.c */
 void panic(const char *string);
 void write_subsystem_identification(void);
+void write_iplb_location(void);
 extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
 unsigned int get_loadparm_index(void);
 
index 20fcc37c2ce219b14a2026527fc970cd9877834d..4673ab7490df4ab4dd79bde5c24ffe912d591760 100644 (file)
@@ -7,7 +7,7 @@ util-obj-y += qapi-util.o
 
 QAPI_COMMON_MODULES = audio authz block-core block char common control crypto
 QAPI_COMMON_MODULES += dump error introspect job machine migration misc
-QAPI_COMMON_MODULES += net qdev qom rdma rocker run-state sockets tpm
+QAPI_COMMON_MODULES += net pragma qdev qom rdma rocker run-state sockets tpm
 QAPI_COMMON_MODULES += trace transaction ui
 QAPI_TARGET_MODULES = machine-target misc-target
 QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES)
@@ -31,3 +31,8 @@ obj-y += qapi-events.o
 obj-y += $(QAPI_TARGET_MODULES:%=qapi-commands-%.o)
 obj-y += qapi-commands.o
 obj-y += qapi-init-commands.o
+
+QAPI_MODULES_STORAGE_DAEMON = block-core char common control crypto
+QAPI_MODULES_STORAGE_DAEMON += introspect job qom sockets pragma transaction
+
+storage-daemon-obj-y += $(QAPI_MODULES_STORAGE_DAEMON:%=qapi-commands-%.o)
index 85e27bb61f4db8ff79652375d99991c26a83049b..9758fc48d230049b4cfc8d94f2d5d718570a3c38 100644 (file)
 { 'struct': 'BlockLatencyHistogramInfo',
   'data': {'boundaries': ['uint64'], 'bins': ['uint64'] } }
 
-##
-# @block-latency-histogram-set:
-#
-# Manage read, write and flush latency histograms for the device.
-#
-# If only @id parameter is specified, remove all present latency histograms
-# for the device. Otherwise, add/reset some of (or all) latency histograms.
-#
-# @id: The name or QOM path of the guest device.
-#
-# @boundaries: list of interval boundary values (see description in
-#              BlockLatencyHistogramInfo definition). If specified, all
-#              latency histograms are removed, and empty ones created for all
-#              io types with intervals corresponding to @boundaries (except for
-#              io types, for which specific boundaries are set through the
-#              following parameters).
-#
-# @boundaries-read: list of interval boundary values for read latency
-#                   histogram. If specified, old read latency histogram is
-#                   removed, and empty one created with intervals
-#                   corresponding to @boundaries-read. The parameter has higher
-#                   priority then @boundaries.
-#
-# @boundaries-write: list of interval boundary values for write latency
-#                    histogram.
-#
-# @boundaries-flush: list of interval boundary values for flush latency
-#                    histogram.
-#
-# Returns: error if device is not found or any boundary arrays are invalid.
-#
-# Since: 4.0
-#
-# Example: set new histograms for all io types with intervals
-# [0, 10), [10, 50), [50, 100), [100, +inf):
-#
-# -> { "execute": "block-latency-histogram-set",
-#      "arguments": { "id": "drive0",
-#                     "boundaries": [10, 50, 100] } }
-# <- { "return": {} }
-#
-# Example: set new histogram only for write, other histograms will remain
-# not changed (or not created):
-#
-# -> { "execute": "block-latency-histogram-set",
-#      "arguments": { "id": "drive0",
-#                     "boundaries-write": [10, 50, 100] } }
-# <- { "return": {} }
-#
-# Example: set new histograms with the following intervals:
-#   read, flush: [0, 10), [10, 50), [50, 100), [100, +inf)
-#   write: [0, 1000), [1000, 5000), [5000, +inf)
-#
-# -> { "execute": "block-latency-histogram-set",
-#      "arguments": { "id": "drive0",
-#                     "boundaries": [10, 50, 100],
-#                     "boundaries-write": [1000, 5000] } }
-# <- { "return": {} }
-#
-# Example: remove all latency histograms:
-#
-# -> { "execute": "block-latency-histogram-set",
-#      "arguments": { "id": "drive0" } }
-# <- { "return": {} }
-##
-{ 'command': 'block-latency-histogram-set',
-  'data': {'id': 'str',
-           '*boundaries': ['uint64'],
-           '*boundaries-read': ['uint64'],
-           '*boundaries-write': ['uint64'],
-           '*boundaries-flush': ['uint64'] } }
-
 ##
 # @BlockInfo:
 #
             '*copy-mode': 'MirrorCopyMode',
             '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
 
-##
-# @block_set_io_throttle:
-#
-# Change I/O throttle limits for a block drive.
-#
-# Since QEMU 2.4, each device with I/O limits is member of a throttle
-# group.
-#
-# If two or more devices are members of the same group, the limits
-# will apply to the combined I/O of the whole group in a round-robin
-# fashion. Therefore, setting new I/O limits to a device will affect
-# the whole group.
-#
-# The name of the group can be specified using the 'group' parameter.
-# If the parameter is unset, it is assumed to be the current group of
-# that device. If it's not in any group yet, the name of the device
-# will be used as the name for its group.
-#
-# The 'group' parameter can also be used to move a device to a
-# different group. In this case the limits specified in the parameters
-# will be applied to the new group only.
-#
-# I/O limits can be disabled by setting all of them to 0. In this case
-# the device will be removed from its group and the rest of its
-# members will not be affected. The 'group' parameter is ignored.
-#
-# Returns: - Nothing on success
-#          - If @device is not a valid block device, DeviceNotFound
-#
-# Since: 1.1
-#
-# Example:
-#
-# -> { "execute": "block_set_io_throttle",
-#      "arguments": { "id": "virtio-blk-pci0/virtio-backend",
-#                     "bps": 0,
-#                     "bps_rd": 0,
-#                     "bps_wr": 0,
-#                     "iops": 512,
-#                     "iops_rd": 0,
-#                     "iops_wr": 0,
-#                     "bps_max": 0,
-#                     "bps_rd_max": 0,
-#                     "bps_wr_max": 0,
-#                     "iops_max": 0,
-#                     "iops_rd_max": 0,
-#                     "iops_wr_max": 0,
-#                     "bps_max_length": 0,
-#                     "iops_size": 0 } }
-# <- { "return": {} }
-#
-# -> { "execute": "block_set_io_throttle",
-#      "arguments": { "id": "ide0-1-0",
-#                     "bps": 1000000,
-#                     "bps_rd": 0,
-#                     "bps_wr": 0,
-#                     "iops": 0,
-#                     "iops_rd": 0,
-#                     "iops_wr": 0,
-#                     "bps_max": 8000000,
-#                     "bps_rd_max": 0,
-#                     "bps_wr_max": 0,
-#                     "iops_max": 0,
-#                     "iops_rd_max": 0,
-#                     "iops_wr_max": 0,
-#                     "bps_max_length": 60,
-#                     "iops_size": 0 } }
-# <- { "return": {} }
-##
-{ 'command': 'block_set_io_throttle', 'boxed': true,
-  'data': 'BlockIOThrottle' }
-
 ##
 # @BlockIOThrottle:
 #
 #
 # @pool: Ceph pool name.
 #
+# @namespace: Rados namespace name in the Ceph pool. (Since 5.0)
+#
 # @image: Image name in the Ceph pool.
 #
 # @conf: path to Ceph configuration file.  Values
 ##
 { 'struct': 'BlockdevOptionsRbd',
   'data': { 'pool': 'str',
+            '*namespace': 'str',
             'image': 'str',
             '*conf': 'str',
             '*snapshot': 'str',
   'data': { 'job-id': 'str',
             'options': 'BlockdevCreateOptions' } }
 
-##
-# @blockdev-open-tray:
-#
-# Opens a block device's tray. If there is a block driver state tree inserted as
-# a medium, it will become inaccessible to the guest (but it will remain
-# associated to the block device, so closing the tray will make it accessible
-# again).
-#
-# If the tray was already open before, this will be a no-op.
-#
-# Once the tray opens, a DEVICE_TRAY_MOVED event is emitted. There are cases in
-# which no such event will be generated, these include:
-#
-# - if the guest has locked the tray, @force is false and the guest does not
-#   respond to the eject request
-# - if the BlockBackend denoted by @device does not have a guest device attached
-#   to it
-# - if the guest device does not have an actual tray
-#
-# @device: Block device name (deprecated, use @id instead)
-#
-# @id: The name or QOM path of the guest device (since: 2.8)
-#
-# @force: if false (the default), an eject request will be sent to
-#         the guest if it has locked the tray (and the tray will not be opened
-#         immediately); if true, the tray will be opened regardless of whether
-#         it is locked
-#
-# Since: 2.5
-#
-# Example:
-#
-# -> { "execute": "blockdev-open-tray",
-#      "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "timestamp": { "seconds": 1418751016,
-#                     "microseconds": 716996 },
-#      "event": "DEVICE_TRAY_MOVED",
-#      "data": { "device": "ide1-cd0",
-#                "id": "ide0-1-0",
-#                "tray-open": true } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-open-tray',
-  'data': { '*device': 'str',
-            '*id': 'str',
-            '*force': 'bool' } }
-
-##
-# @blockdev-close-tray:
-#
-# Closes a block device's tray. If there is a block driver state tree associated
-# with the block device (which is currently ejected), that tree will be loaded
-# as the medium.
-#
-# If the tray was already closed before, this will be a no-op.
-#
-# @device: Block device name (deprecated, use @id instead)
-#
-# @id: The name or QOM path of the guest device (since: 2.8)
-#
-# Since: 2.5
-#
-# Example:
-#
-# -> { "execute": "blockdev-close-tray",
-#      "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "timestamp": { "seconds": 1418751345,
-#                     "microseconds": 272147 },
-#      "event": "DEVICE_TRAY_MOVED",
-#      "data": { "device": "ide1-cd0",
-#                "id": "ide0-1-0",
-#                "tray-open": false } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-close-tray',
-  'data': { '*device': 'str',
-            '*id': 'str' } }
-
-##
-# @blockdev-remove-medium:
-#
-# Removes a medium (a block driver state tree) from a block device. That block
-# device's tray must currently be open (unless there is no attached guest
-# device).
-#
-# If the tray is open and there is no medium inserted, this will be a no-op.
-#
-# @id: The name or QOM path of the guest device
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "blockdev-remove-medium",
-#      "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "error": { "class": "GenericError",
-#                 "desc": "Tray of device 'ide0-1-0' is not open" } }
-#
-# -> { "execute": "blockdev-open-tray",
-#      "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "timestamp": { "seconds": 1418751627,
-#                     "microseconds": 549958 },
-#      "event": "DEVICE_TRAY_MOVED",
-#      "data": { "device": "ide1-cd0",
-#                "id": "ide0-1-0",
-#                "tray-open": true } }
-#
-# <- { "return": {} }
-#
-# -> { "execute": "blockdev-remove-medium",
-#      "arguments": { "id": "ide0-1-0" } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-remove-medium',
-  'data': { 'id': 'str' } }
-
-##
-# @blockdev-insert-medium:
-#
-# Inserts a medium (a block driver state tree) into a block device. That block
-# device's tray must currently be open (unless there is no attached guest
-# device) and there must be no medium inserted already.
-#
-# @id: The name or QOM path of the guest device
-#
-# @node-name: name of a node in the block driver state graph
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "blockdev-add",
-#      "arguments": {
-#          "node-name": "node0",
-#          "driver": "raw",
-#          "file": { "driver": "file",
-#                    "filename": "fedora.iso" } } }
-# <- { "return": {} }
-#
-# -> { "execute": "blockdev-insert-medium",
-#      "arguments": { "id": "ide0-1-0",
-#                     "node-name": "node0" } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-insert-medium',
-  'data': { 'id': 'str',
-            'node-name': 'str'} }
-
-
-##
-# @BlockdevChangeReadOnlyMode:
-#
-# Specifies the new read-only mode of a block device subject to the
-# @blockdev-change-medium command.
-#
-# @retain: Retains the current read-only mode
-#
-# @read-only: Makes the device read-only
-#
-# @read-write: Makes the device writable
-#
-# Since: 2.3
-#
-##
-{ 'enum': 'BlockdevChangeReadOnlyMode',
-  'data': ['retain', 'read-only', 'read-write'] }
-
-
-##
-# @blockdev-change-medium:
-#
-# Changes the medium inserted into a block device by ejecting the current medium
-# and loading a new image file which is inserted as the new medium (this command
-# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
-# and blockdev-close-tray).
-#
-# @device: Block device name (deprecated, use @id instead)
-#
-# @id: The name or QOM path of the guest device
-#      (since: 2.8)
-#
-# @filename: filename of the new image to be loaded
-#
-# @format: format to open the new image with (defaults to
-#          the probed format)
-#
-# @read-only-mode: change the read-only mode of the device; defaults
-#                  to 'retain'
-#
-# Since: 2.5
-#
-# Examples:
-#
-# 1. Change a removable medium
-#
-# -> { "execute": "blockdev-change-medium",
-#      "arguments": { "id": "ide0-1-0",
-#                     "filename": "/srv/images/Fedora-12-x86_64-DVD.iso",
-#                     "format": "raw" } }
-# <- { "return": {} }
-#
-# 2. Load a read-only medium into a writable drive
-#
-# -> { "execute": "blockdev-change-medium",
-#      "arguments": { "id": "floppyA",
-#                     "filename": "/srv/images/ro.img",
-#                     "format": "raw",
-#                     "read-only-mode": "retain" } }
-#
-# <- { "error":
-#      { "class": "GenericError",
-#        "desc": "Could not open '/srv/images/ro.img': Permission denied" } }
-#
-# -> { "execute": "blockdev-change-medium",
-#      "arguments": { "id": "floppyA",
-#                     "filename": "/srv/images/ro.img",
-#                     "format": "raw",
-#                     "read-only-mode": "read-only" } }
-#
-# <- { "return": {} }
-#
-##
-{ 'command': 'blockdev-change-medium',
-  'data': { '*device': 'str',
-            '*id': 'str',
-            'filename': 'str',
-            '*format': 'str',
-            '*read-only-mode': 'BlockdevChangeReadOnlyMode' } }
-
-
 ##
 # @BlockErrorAction:
 #
   'data' : { 'node-name': 'str',
              'iothread': 'StrOrNull',
              '*force': 'bool' } }
+
+##
+# @NbdServerOptions:
+#
+# @addr: Address on which to listen.
+# @tls-creds: ID of the TLS credentials object (since 2.6).
+# @tls-authz: ID of the QAuthZ authorization object used to validate
+#             the client's x509 distinguished name. This object is
+#             is only resolved at time of use, so can be deleted and
+#             recreated on the fly while the NBD server is active.
+#             If missing, it will default to denying access (since 4.0).
+#
+# Keep this type consistent with the nbd-server-start arguments. The only
+# intended difference is using SocketAddress instead of SocketAddressLegacy.
+#
+# Since: 4.2
+##
+{ 'struct': 'NbdServerOptions',
+  'data': { 'addr': 'SocketAddress',
+            '*tls-creds': 'str',
+            '*tls-authz': 'str'} }
+
+##
+# @nbd-server-start:
+#
+# Start an NBD server listening on the given host and port.  Block
+# devices can then be exported using @nbd-server-add.  The NBD
+# server will present them as named exports; for example, another
+# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
+#
+# @addr: Address on which to listen.
+# @tls-creds: ID of the TLS credentials object (since 2.6).
+# @tls-authz: ID of the QAuthZ authorization object used to validate
+#             the client's x509 distinguished name. This object is
+#             is only resolved at time of use, so can be deleted and
+#             recreated on the fly while the NBD server is active.
+#             If missing, it will default to denying access (since 4.0).
+#
+# Returns: error if the server is already running.
+#
+# Keep this type consistent with the NbdServerOptions type. The only intended
+# difference is using SocketAddressLegacy instead of SocketAddress.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-start',
+  'data': { 'addr': 'SocketAddressLegacy',
+            '*tls-creds': 'str',
+            '*tls-authz': 'str'} }
+
+##
+# @BlockExportNbd:
+#
+# An NBD block export.
+#
+# @device: The device name or node name of the node to be exported
+#
+# @name: Export name. If unspecified, the @device parameter is used as the
+#        export name. (Since 2.12)
+#
+# @description: Free-form description of the export, up to 4096 bytes.
+#               (Since 5.0)
+#
+# @writable: Whether clients should be able to write to the device via the
+#            NBD connection (default false).
+#
+# @bitmap: Also export the dirty bitmap reachable from @device, so the
+#          NBD client can use NBD_OPT_SET_META_CONTEXT with
+#          "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
+#
+# Since: 5.0
+##
+{ 'struct': 'BlockExportNbd',
+  'data': {'device': 'str', '*name': 'str', '*description': 'str',
+           '*writable': 'bool', '*bitmap': 'str' } }
+
+##
+# @nbd-server-add:
+#
+# Export a block node to QEMU's embedded NBD server.
+#
+# Returns: error if the server is not running, or export with the same name
+#          already exists.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-add',
+  'data': 'BlockExportNbd', 'boxed': true }
+
+##
+# @NbdServerRemoveMode:
+#
+# Mode for removing an NBD export.
+#
+# @safe: Remove export if there are no existing connections, fail otherwise.
+#
+# @hard: Drop all connections immediately and remove export.
+#
+# Potential additional modes to be added in the future:
+#
+# hide: Just hide export from new clients, leave existing connections as is.
+# Remove export after all clients are disconnected.
+#
+# soft: Hide export from new clients, answer with ESHUTDOWN for all further
+# requests from existing clients.
+#
+# Since: 2.12
+##
+{'enum': 'NbdServerRemoveMode', 'data': ['safe', 'hard']}
+
+##
+# @nbd-server-remove:
+#
+# Remove NBD export by name.
+#
+# @name: Export name.
+#
+# @mode: Mode of command operation. See @NbdServerRemoveMode description.
+#        Default is 'safe'.
+#
+# Returns: error if
+#            - the server is not running
+#            - export is not found
+#            - mode is 'safe' and there are existing connections
+#
+# Since: 2.12
+##
+{ 'command': 'nbd-server-remove',
+  'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} }
+
+##
+# @nbd-server-stop:
+#
+# Stop QEMU's embedded NBD server, and unregister all devices previously
+# added via @nbd-server-add.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-stop' }
+
+##
+# @BlockExportType:
+#
+# An enumeration of block export types
+#
+# @nbd: NBD export
+#
+# Since: 4.2
+##
+{ 'enum': 'BlockExportType',
+  'data': [ 'nbd' ] }
+
+##
+# @BlockExport:
+#
+# Describes a block export, i.e. how single node should be exported on an
+# external interface.
+#
+# Since: 4.2
+##
+{ 'union': 'BlockExport',
+  'base': { 'type': 'BlockExportType' },
+  'discriminator': 'type',
+  'data': {
+      'nbd': 'BlockExportNbd'
+   } }
+
+##
+# @QuorumOpType:
+#
+# An enumeration of the quorum operation types
+#
+# @read: read operation
+#
+# @write: write operation
+#
+# @flush: flush operation
+#
+# Since: 2.6
+##
+{ 'enum': 'QuorumOpType',
+  'data': [ 'read', 'write', 'flush' ] }
+
+##
+# @QUORUM_FAILURE:
+#
+# Emitted by the Quorum block driver if it fails to establish a quorum
+#
+# @reference: device name if defined else node name
+#
+# @sector-num: number of the first sector of the failed read operation
+#
+# @sectors-count: failed read operation sector count
+#
+# Note: This event is rate-limited.
+#
+# Since: 2.0
+#
+# Example:
+#
+# <- { "event": "QUORUM_FAILURE",
+#      "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 },
+#      "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+#
+##
+{ 'event': 'QUORUM_FAILURE',
+  'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } }
+
+##
+# @QUORUM_REPORT_BAD:
+#
+# Emitted to report a corruption of a Quorum file
+#
+# @type: quorum operation type (Since 2.6)
+#
+# @error: error message. Only present on failure. This field
+#         contains a human-readable error message. There are no semantics other
+#         than that the block layer reported an error and clients should not
+#         try to interpret the error string.
+#
+# @node-name: the graph node name of the block driver state
+#
+# @sector-num: number of the first sector of the failed read operation
+#
+# @sectors-count: failed read operation sector count
+#
+# Note: This event is rate-limited.
+#
+# Since: 2.0
+#
+# Example:
+#
+# 1. Read operation
+#
+# { "event": "QUORUM_REPORT_BAD",
+#      "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5,
+#                "type": "read" },
+#      "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+#
+# 2. Flush operation
+#
+# { "event": "QUORUM_REPORT_BAD",
+#      "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120,
+#                "type": "flush", "error": "Broken pipe" },
+#      "timestamp": { "seconds": 1456406829, "microseconds": 291763 } }
+#
+##
+{ 'event': 'QUORUM_REPORT_BAD',
+  'data': { 'type': 'QuorumOpType', '*error': 'str', 'node-name': 'str',
+            'sector-num': 'int', 'sectors-count': 'int' } }
+
+##
+# @BlockdevSnapshotInternal:
+#
+# @device: the device name or node-name of a root node to generate the snapshot
+#          from
+#
+# @name: the name of the internal snapshot to be created
+#
+# Notes: In transaction, if @name is empty, or any snapshot matching @name
+#        exists, the operation will fail. Only some image formats support it,
+#        for example, qcow2, rbd, and sheepdog.
+#
+# Since: 1.7
+##
+{ 'struct': 'BlockdevSnapshotInternal',
+  'data': { 'device': 'str', 'name': 'str' } }
+
+##
+# @blockdev-snapshot-internal-sync:
+#
+# Synchronously take an internal snapshot of a block device, when the
+# format of the image used supports it. If the name is an empty
+# string, or a snapshot with name already exists, the operation will
+# fail.
+#
+# For the arguments, see the documentation of BlockdevSnapshotInternal.
+#
+# Returns: - nothing on success
+#          - If @device is not a valid block device, GenericError
+#          - If any snapshot matching @name exists, or @name is empty,
+#            GenericError
+#          - If the format of the image used does not support it,
+#            BlockFormatFeatureNotSupported
+#
+# Since: 1.7
+#
+# Example:
+#
+# -> { "execute": "blockdev-snapshot-internal-sync",
+#      "arguments": { "device": "ide-hd0",
+#                     "name": "snapshot0" }
+#    }
+# <- { "return": {} }
+#
+##
+{ 'command': 'blockdev-snapshot-internal-sync',
+  'data': 'BlockdevSnapshotInternal' }
+
+##
+# @blockdev-snapshot-delete-internal-sync:
+#
+# Synchronously delete an internal snapshot of a block device, when the format
+# of the image used support it. The snapshot is identified by name or id or
+# both. One of the name or id is required. Return SnapshotInfo for the
+# successfully deleted snapshot.
+#
+# @device: the device name or node-name of a root node to delete the snapshot
+#          from
+#
+# @id: optional the snapshot's ID to be deleted
+#
+# @name: optional the snapshot's name to be deleted
+#
+# Returns: - SnapshotInfo on success
+#          - If @device is not a valid block device, GenericError
+#          - If snapshot not found, GenericError
+#          - If the format of the image used does not support it,
+#            BlockFormatFeatureNotSupported
+#          - If @id and @name are both not specified, GenericError
+#
+# Since: 1.7
+#
+# Example:
+#
+# -> { "execute": "blockdev-snapshot-delete-internal-sync",
+#      "arguments": { "device": "ide-hd0",
+#                     "name": "snapshot0" }
+#    }
+# <- { "return": {
+#                    "id": "1",
+#                    "name": "snapshot0",
+#                    "vm-state-size": 0,
+#                    "date-sec": 1000012,
+#                    "date-nsec": 10,
+#                    "vm-clock-sec": 100,
+#                    "vm-clock-nsec": 20
+#      }
+#    }
+#
+##
+{ 'command': 'blockdev-snapshot-delete-internal-sync',
+  'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
+  'returns': 'SnapshotInfo' }
index da19834db415758477d5ac7b07d429d194d148a6..97bf52b7c7cc9094ff82ecc74d1cd7fa5daf336d 100644 (file)
 { 'enum': 'FloppyDriveType',
   'data': ['144', '288', '120', 'none', 'auto']}
 
-##
-# @BlockdevSnapshotInternal:
-#
-# @device: the device name or node-name of a root node to generate the snapshot
-#          from
-#
-# @name: the name of the internal snapshot to be created
-#
-# Notes: In transaction, if @name is empty, or any snapshot matching @name
-#        exists, the operation will fail. Only some image formats support it,
-#        for example, qcow2, rbd, and sheepdog.
-#
-# Since: 1.7
-##
-{ 'struct': 'BlockdevSnapshotInternal',
-  'data': { 'device': 'str', 'name': 'str' } }
-
 ##
 # @PRManagerInfo:
 #
 { 'command': 'query-pr-managers', 'returns': ['PRManagerInfo'],
   'allow-preconfig': true }
 
-
 ##
-# @blockdev-snapshot-internal-sync:
+# @eject:
+#
+# Ejects a device from a removable drive.
 #
-# Synchronously take an internal snapshot of a block device, when the
-# format of the image used supports it. If the name is an empty
-# string, or a snapshot with name already exists, the operation will
-# fail.
+# @device: Block device name (deprecated, use @id instead)
 #
-# For the arguments, see the documentation of BlockdevSnapshotInternal.
+# @id: The name or QOM path of the guest device (since: 2.8)
+#
+# @force: If true, eject regardless of whether the drive is locked.
+#         If not specified, the default value is false.
 #
-# Returns: - nothing on success
-#          - If @device is not a valid block device, GenericError
-#          - If any snapshot matching @name exists, or @name is empty,
-#            GenericError
-#          - If the format of the image used does not support it,
-#            BlockFormatFeatureNotSupported
+# Returns: - Nothing on success
+#          - If @device is not a valid block device, DeviceNotFound
+# Notes:    Ejecting a device with no media results in success
 #
-# Since: 1.7
+# Since: 0.14.0
 #
 # Example:
 #
-# -> { "execute": "blockdev-snapshot-internal-sync",
-#      "arguments": { "device": "ide-hd0",
-#                     "name": "snapshot0" }
-#    }
+# -> { "execute": "eject", "arguments": { "id": "ide1-0-1" } }
 # <- { "return": {} }
-#
 ##
-{ 'command': 'blockdev-snapshot-internal-sync',
-  'data': 'BlockdevSnapshotInternal' }
+{ 'command': 'eject',
+  'data': { '*device': 'str',
+            '*id': 'str',
+            '*force': 'bool' } }
 
 ##
-# @blockdev-snapshot-delete-internal-sync:
+# @blockdev-open-tray:
+#
+# Opens a block device's tray. If there is a block driver state tree inserted as
+# a medium, it will become inaccessible to the guest (but it will remain
+# associated to the block device, so closing the tray will make it accessible
+# again).
 #
-# Synchronously delete an internal snapshot of a block device, when the format
-# of the image used support it. The snapshot is identified by name or id or
-# both. One of the name or id is required. Return SnapshotInfo for the
-# successfully deleted snapshot.
+# If the tray was already open before, this will be a no-op.
 #
-# @device: the device name or node-name of a root node to delete the snapshot
-#          from
+# Once the tray opens, a DEVICE_TRAY_MOVED event is emitted. There are cases in
+# which no such event will be generated, these include:
 #
-# @id: optional the snapshot's ID to be deleted
+# - if the guest has locked the tray, @force is false and the guest does not
+#   respond to the eject request
+# - if the BlockBackend denoted by @device does not have a guest device attached
+#   to it
+# - if the guest device does not have an actual tray
 #
-# @name: optional the snapshot's name to be deleted
+# @device: Block device name (deprecated, use @id instead)
+#
+# @id: The name or QOM path of the guest device (since: 2.8)
 #
-# Returns: - SnapshotInfo on success
-#          - If @device is not a valid block device, GenericError
-#          - If snapshot not found, GenericError
-#          - If the format of the image used does not support it,
-#            BlockFormatFeatureNotSupported
-#          - If @id and @name are both not specified, GenericError
+# @force: if false (the default), an eject request will be sent to
+#         the guest if it has locked the tray (and the tray will not be opened
+#         immediately); if true, the tray will be opened regardless of whether
+#         it is locked
 #
-# Since: 1.7
+# Since: 2.5
 #
 # Example:
 #
-# -> { "execute": "blockdev-snapshot-delete-internal-sync",
-#      "arguments": { "device": "ide-hd0",
-#                     "name": "snapshot0" }
-#    }
-# <- { "return": {
-#                    "id": "1",
-#                    "name": "snapshot0",
-#                    "vm-state-size": 0,
-#                    "date-sec": 1000012,
-#                    "date-nsec": 10,
-#                    "vm-clock-sec": 100,
-#                    "vm-clock-nsec": 20
-#      }
-#    }
-#
-##
-{ 'command': 'blockdev-snapshot-delete-internal-sync',
-  'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
-  'returns': 'SnapshotInfo' }
+# -> { "execute": "blockdev-open-tray",
+#      "arguments": { "id": "ide0-1-0" } }
+#
+# <- { "timestamp": { "seconds": 1418751016,
+#                     "microseconds": 716996 },
+#      "event": "DEVICE_TRAY_MOVED",
+#      "data": { "device": "ide1-cd0",
+#                "id": "ide0-1-0",
+#                "tray-open": true } }
+#
+# <- { "return": {} }
+#
+##
+{ 'command': 'blockdev-open-tray',
+  'data': { '*device': 'str',
+            '*id': 'str',
+            '*force': 'bool' } }
 
 ##
-# @eject:
+# @blockdev-close-tray:
 #
-# Ejects a device from a removable drive.
+# Closes a block device's tray. If there is a block driver state tree associated
+# with the block device (which is currently ejected), that tree will be loaded
+# as the medium.
+#
+# If the tray was already closed before, this will be a no-op.
 #
 # @device: Block device name (deprecated, use @id instead)
 #
 # @id: The name or QOM path of the guest device (since: 2.8)
 #
-# @force: If true, eject regardless of whether the drive is locked.
-#         If not specified, the default value is false.
+# Since: 2.5
 #
-# Returns: - Nothing on success
-#          - If @device is not a valid block device, DeviceNotFound
-# Notes:    Ejecting a device with no media results in success
+# Example:
 #
-# Since: 0.14.0
+# -> { "execute": "blockdev-close-tray",
+#      "arguments": { "id": "ide0-1-0" } }
 #
-# Example:
+# <- { "timestamp": { "seconds": 1418751345,
+#                     "microseconds": 272147 },
+#      "event": "DEVICE_TRAY_MOVED",
+#      "data": { "device": "ide1-cd0",
+#                "id": "ide0-1-0",
+#                "tray-open": false } }
 #
-# -> { "execute": "eject", "arguments": { "id": "ide1-0-1" } }
 # <- { "return": {} }
+#
 ##
-{ 'command': 'eject',
+{ 'command': 'blockdev-close-tray',
   'data': { '*device': 'str',
-            '*id': 'str',
-            '*force': 'bool' } }
+            '*id': 'str' } }
 
 ##
-# @nbd-server-start:
+# @blockdev-remove-medium:
 #
-# Start an NBD server listening on the given host and port.  Block
-# devices can then be exported using @nbd-server-add.  The NBD
-# server will present them as named exports; for example, another
-# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
+# Removes a medium (a block driver state tree) from a block device. That block
+# device's tray must currently be open (unless there is no attached guest
+# device).
 #
-# @addr: Address on which to listen.
-# @tls-creds: ID of the TLS credentials object (since 2.6).
-# @tls-authz: ID of the QAuthZ authorization object used to validate
-#             the client's x509 distinguished name. This object is
-#             is only resolved at time of use, so can be deleted and
-#             recreated on the fly while the NBD server is active.
-#             If missing, it will default to denying access (since 4.0).
+# If the tray is open and there is no medium inserted, this will be a no-op.
 #
-# Returns: error if the server is already running.
+# @id: The name or QOM path of the guest device
 #
-# Since: 1.3.0
-##
-{ 'command': 'nbd-server-start',
-  'data': { 'addr': 'SocketAddressLegacy',
-            '*tls-creds': 'str',
-            '*tls-authz': 'str'} }
-
-##
-# @nbd-server-add:
+# Since: 2.12
+#
+# Example:
 #
-# Export a block node to QEMU's embedded NBD server.
+# -> { "execute": "blockdev-remove-medium",
+#      "arguments": { "id": "ide0-1-0" } }
 #
-# @device: The device name or node name of the node to be exported
+# <- { "error": { "class": "GenericError",
+#                 "desc": "Tray of device 'ide0-1-0' is not open" } }
 #
-# @name: Export name. If unspecified, the @device parameter is used as the
-#        export name. (Since 2.12)
+# -> { "execute": "blockdev-open-tray",
+#      "arguments": { "id": "ide0-1-0" } }
 #
-# @description: Free-form description of the export, up to 4096 bytes.
-#               (Since 5.0)
+# <- { "timestamp": { "seconds": 1418751627,
+#                     "microseconds": 549958 },
+#      "event": "DEVICE_TRAY_MOVED",
+#      "data": { "device": "ide1-cd0",
+#                "id": "ide0-1-0",
+#                "tray-open": true } }
 #
-# @writable: Whether clients should be able to write to the device via the
-#            NBD connection (default false).
+# <- { "return": {} }
 #
-# @bitmap: Also export the dirty bitmap reachable from @device, so the
-#          NBD client can use NBD_OPT_SET_META_CONTEXT with
-#          "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
+# -> { "execute": "blockdev-remove-medium",
+#      "arguments": { "id": "ide0-1-0" } }
 #
-# Returns: error if the server is not running, or export with the same name
-#          already exists.
+# <- { "return": {} }
 #
-# Since: 1.3.0
 ##
-{ 'command': 'nbd-server-add',
-  'data': {'device': 'str', '*name': 'str', '*description': 'str',
-           '*writable': 'bool', '*bitmap': 'str' } }
+{ 'command': 'blockdev-remove-medium',
+  'data': { 'id': 'str' } }
 
 ##
-# @NbdServerRemoveMode:
+# @blockdev-insert-medium:
 #
-# Mode for removing an NBD export.
+# Inserts a medium (a block driver state tree) into a block device. That block
+# device's tray must currently be open (unless there is no attached guest
+# device) and there must be no medium inserted already.
 #
-# @safe: Remove export if there are no existing connections, fail otherwise.
+# @id: The name or QOM path of the guest device
 #
-# @hard: Drop all connections immediately and remove export.
+# @node-name: name of a node in the block driver state graph
 #
-# Potential additional modes to be added in the future:
+# Since: 2.12
 #
-# hide: Just hide export from new clients, leave existing connections as is.
-# Remove export after all clients are disconnected.
+# Example:
 #
-# soft: Hide export from new clients, answer with ESHUTDOWN for all further
-# requests from existing clients.
+# -> { "execute": "blockdev-add",
+#      "arguments": {
+#          "node-name": "node0",
+#          "driver": "raw",
+#          "file": { "driver": "file",
+#                    "filename": "fedora.iso" } } }
+# <- { "return": {} }
+#
+# -> { "execute": "blockdev-insert-medium",
+#      "arguments": { "id": "ide0-1-0",
+#                     "node-name": "node0" } }
+#
+# <- { "return": {} }
 #
-# Since: 2.12
 ##
-{'enum': 'NbdServerRemoveMode', 'data': ['safe', 'hard']}
+{ 'command': 'blockdev-insert-medium',
+  'data': { 'id': 'str',
+            'node-name': 'str'} }
+
 
 ##
-# @nbd-server-remove:
+# @BlockdevChangeReadOnlyMode:
 #
-# Remove NBD export by name.
+# Specifies the new read-only mode of a block device subject to the
+# @blockdev-change-medium command.
 #
-# @name: Export name.
+# @retain: Retains the current read-only mode
 #
-# @mode: Mode of command operation. See @NbdServerRemoveMode description.
-#        Default is 'safe'.
+# @read-only: Makes the device read-only
 #
-# Returns: error if
-#            - the server is not running
-#            - export is not found
-#            - mode is 'safe' and there are existing connections
+# @read-write: Makes the device writable
+#
+# Since: 2.3
 #
-# Since: 2.12
 ##
-{ 'command': 'nbd-server-remove',
-  'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} }
+{ 'enum': 'BlockdevChangeReadOnlyMode',
+  'data': ['retain', 'read-only', 'read-write'] }
+
 
 ##
-# @nbd-server-stop:
+# @blockdev-change-medium:
+#
+# Changes the medium inserted into a block device by ejecting the current medium
+# and loading a new image file which is inserted as the new medium (this command
+# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
+# and blockdev-close-tray).
+#
+# @device: Block device name (deprecated, use @id instead)
+#
+# @id: The name or QOM path of the guest device
+#      (since: 2.8)
+#
+# @filename: filename of the new image to be loaded
+#
+# @format: format to open the new image with (defaults to
+#          the probed format)
+#
+# @read-only-mode: change the read-only mode of the device; defaults
+#                  to 'retain'
+#
+# Since: 2.5
+#
+# Examples:
+#
+# 1. Change a removable medium
+#
+# -> { "execute": "blockdev-change-medium",
+#      "arguments": { "id": "ide0-1-0",
+#                     "filename": "/srv/images/Fedora-12-x86_64-DVD.iso",
+#                     "format": "raw" } }
+# <- { "return": {} }
+#
+# 2. Load a read-only medium into a writable drive
 #
-# Stop QEMU's embedded NBD server, and unregister all devices previously
-# added via @nbd-server-add.
+# -> { "execute": "blockdev-change-medium",
+#      "arguments": { "id": "floppyA",
+#                     "filename": "/srv/images/ro.img",
+#                     "format": "raw",
+#                     "read-only-mode": "retain" } }
+#
+# <- { "error":
+#      { "class": "GenericError",
+#        "desc": "Could not open '/srv/images/ro.img': Permission denied" } }
+#
+# -> { "execute": "blockdev-change-medium",
+#      "arguments": { "id": "floppyA",
+#                     "filename": "/srv/images/ro.img",
+#                     "format": "raw",
+#                     "read-only-mode": "read-only" } }
+#
+# <- { "return": {} }
 #
-# Since: 1.3.0
 ##
-{ 'command': 'nbd-server-stop' }
+{ 'command': 'blockdev-change-medium',
+  'data': { '*device': 'str',
+            '*id': 'str',
+            'filename': 'str',
+            '*format': 'str',
+            '*read-only-mode': 'BlockdevChangeReadOnlyMode' } }
+
 
 ##
 # @DEVICE_TRAY_MOVED:
   'data': { 'id': 'str', 'connected': 'bool' } }
 
 ##
-# @QuorumOpType:
+# @block_set_io_throttle:
 #
-# An enumeration of the quorum operation types
+# Change I/O throttle limits for a block drive.
 #
-# @read: read operation
+# Since QEMU 2.4, each device with I/O limits is member of a throttle
+# group.
 #
-# @write: write operation
+# If two or more devices are members of the same group, the limits
+# will apply to the combined I/O of the whole group in a round-robin
+# fashion. Therefore, setting new I/O limits to a device will affect
+# the whole group.
 #
-# @flush: flush operation
+# The name of the group can be specified using the 'group' parameter.
+# If the parameter is unset, it is assumed to be the current group of
+# that device. If it's not in any group yet, the name of the device
+# will be used as the name for its group.
 #
-# Since: 2.6
-##
-{ 'enum': 'QuorumOpType',
-  'data': [ 'read', 'write', 'flush' ] }
-
-##
-# @QUORUM_FAILURE:
-#
-# Emitted by the Quorum block driver if it fails to establish a quorum
+# The 'group' parameter can also be used to move a device to a
+# different group. In this case the limits specified in the parameters
+# will be applied to the new group only.
 #
-# @reference: device name if defined else node name
+# I/O limits can be disabled by setting all of them to 0. In this case
+# the device will be removed from its group and the rest of its
+# members will not be affected. The 'group' parameter is ignored.
 #
-# @sector-num: number of the first sector of the failed read operation
-#
-# @sectors-count: failed read operation sector count
-#
-# Note: This event is rate-limited.
+# Returns: - Nothing on success
+#          - If @device is not a valid block device, DeviceNotFound
 #
-# Since: 2.0
+# Since: 1.1
 #
 # Example:
 #
-# <- { "event": "QUORUM_FAILURE",
-#      "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 },
-#      "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+# -> { "execute": "block_set_io_throttle",
+#      "arguments": { "id": "virtio-blk-pci0/virtio-backend",
+#                     "bps": 0,
+#                     "bps_rd": 0,
+#                     "bps_wr": 0,
+#                     "iops": 512,
+#                     "iops_rd": 0,
+#                     "iops_wr": 0,
+#                     "bps_max": 0,
+#                     "bps_rd_max": 0,
+#                     "bps_wr_max": 0,
+#                     "iops_max": 0,
+#                     "iops_rd_max": 0,
+#                     "iops_wr_max": 0,
+#                     "bps_max_length": 0,
+#                     "iops_size": 0 } }
+# <- { "return": {} }
 #
+# -> { "execute": "block_set_io_throttle",
+#      "arguments": { "id": "ide0-1-0",
+#                     "bps": 1000000,
+#                     "bps_rd": 0,
+#                     "bps_wr": 0,
+#                     "iops": 0,
+#                     "iops_rd": 0,
+#                     "iops_wr": 0,
+#                     "bps_max": 8000000,
+#                     "bps_rd_max": 0,
+#                     "bps_wr_max": 0,
+#                     "iops_max": 0,
+#                     "iops_rd_max": 0,
+#                     "iops_wr_max": 0,
+#                     "bps_max_length": 60,
+#                     "iops_size": 0 } }
+# <- { "return": {} }
 ##
-{ 'event': 'QUORUM_FAILURE',
-  'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } }
+{ 'command': 'block_set_io_throttle', 'boxed': true,
+  'data': 'BlockIOThrottle' }
 
 ##
-# @QUORUM_REPORT_BAD:
+# @block-latency-histogram-set:
 #
-# Emitted to report a corruption of a Quorum file
+# Manage read, write and flush latency histograms for the device.
 #
-# @type: quorum operation type (Since 2.6)
+# If only @id parameter is specified, remove all present latency histograms
+# for the device. Otherwise, add/reset some of (or all) latency histograms.
 #
-# @error: error message. Only present on failure. This field
-#         contains a human-readable error message. There are no semantics other
-#         than that the block layer reported an error and clients should not
-#         try to interpret the error string.
+# @id: The name or QOM path of the guest device.
 #
-# @node-name: the graph node name of the block driver state
+# @boundaries: list of interval boundary values (see description in
+#              BlockLatencyHistogramInfo definition). If specified, all
+#              latency histograms are removed, and empty ones created for all
+#              io types with intervals corresponding to @boundaries (except for
+#              io types, for which specific boundaries are set through the
+#              following parameters).
 #
-# @sector-num: number of the first sector of the failed read operation
+# @boundaries-read: list of interval boundary values for read latency
+#                   histogram. If specified, old read latency histogram is
+#                   removed, and empty one created with intervals
+#                   corresponding to @boundaries-read. The parameter has higher
+#                   priority then @boundaries.
 #
-# @sectors-count: failed read operation sector count
+# @boundaries-write: list of interval boundary values for write latency
+#                    histogram.
 #
-# Note: This event is rate-limited.
+# @boundaries-flush: list of interval boundary values for flush latency
+#                    histogram.
 #
-# Since: 2.0
+# Returns: error if device is not found or any boundary arrays are invalid.
 #
-# Example:
+# Since: 4.0
 #
-# 1. Read operation
+# Example: set new histograms for all io types with intervals
+# [0, 10), [10, 50), [50, 100), [100, +inf):
 #
-# { "event": "QUORUM_REPORT_BAD",
-#      "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5,
-#                "type": "read" },
-#      "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+# -> { "execute": "block-latency-histogram-set",
+#      "arguments": { "id": "drive0",
+#                     "boundaries": [10, 50, 100] } }
+# <- { "return": {} }
+#
+# Example: set new histogram only for write, other histograms will remain
+# not changed (or not created):
 #
-# 2. Flush operation
+# -> { "execute": "block-latency-histogram-set",
+#      "arguments": { "id": "drive0",
+#                     "boundaries-write": [10, 50, 100] } }
+# <- { "return": {} }
 #
-# { "event": "QUORUM_REPORT_BAD",
-#      "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120,
-#                "type": "flush", "error": "Broken pipe" },
-#      "timestamp": { "seconds": 1456406829, "microseconds": 291763 } }
+# Example: set new histograms with the following intervals:
+#   read, flush: [0, 10), [10, 50), [50, 100), [100, +inf)
+#   write: [0, 1000), [1000, 5000), [5000, +inf)
 #
+# -> { "execute": "block-latency-histogram-set",
+#      "arguments": { "id": "drive0",
+#                     "boundaries": [10, 50, 100],
+#                     "boundaries-write": [1000, 5000] } }
+# <- { "return": {} }
+#
+# Example: remove all latency histograms:
+#
+# -> { "execute": "block-latency-histogram-set",
+#      "arguments": { "id": "drive0" } }
+# <- { "return": {} }
 ##
-{ 'event': 'QUORUM_REPORT_BAD',
-  'data': { 'type': 'QuorumOpType', '*error': 'str', 'node-name': 'str',
-            'sector-num': 'int', 'sectors-count': 'int' } }
+{ 'command': 'block-latency-histogram-set',
+  'data': {'id': 'str',
+           '*boundaries': ['uint64'],
+           '*boundaries-read': ['uint64'],
+           '*boundaries-write': ['uint64'],
+           '*boundaries-flush': ['uint64'] } }
index 759c20e76f5607cf2c8c5348f64db7bcb055a544..85b12fe0fb468e3b5b67fe4579646cf2f2abfa49 100644 (file)
 # <- { "return": {} }
 ##
 { 'command': 'quit' }
+
+##
+# @MonitorMode:
+#
+# An enumeration of monitor modes.
+#
+# @readline: HMP monitor (human-oriented command line interface)
+#
+# @control: QMP monitor (JSON-based machine interface)
+#
+# Since: 5.0
+##
+{ 'enum': 'MonitorMode', 'data': [ 'readline', 'control' ] }
+
+##
+# @MonitorOptions:
+#
+# Options to be used for adding a new monitor.
+#
+# @id:          Name of the monitor
+#
+# @mode:        Selects the monitor mode (default: readline in the system
+#               emulator, control in qemu-storage-daemon)
+#
+# @pretty:      Enables pretty printing (QMP only)
+#
+# @chardev:     Name of a character device to expose the monitor on
+#
+# Since: 5.0
+##
+{ 'struct': 'MonitorOptions',
+  'data': {
+      '*id': 'str',
+      '*mode': 'MonitorMode',
+      '*pretty': 'bool',
+      'chardev': 'str'
+  } }
diff --git a/qapi/pragma.json b/qapi/pragma.json
new file mode 100644 (file)
index 0000000..cffae27
--- /dev/null
@@ -0,0 +1,24 @@
+{ 'pragma': { 'doc-required': true } }
+
+# Whitelists to permit QAPI rule violations; think twice before you
+# add to them!
+{ 'pragma': {
+    # Commands allowed to return a non-dictionary:
+    'returns-whitelist': [
+        'human-monitor-command',
+        'qom-get',
+        'query-migrate-cache-size',
+        'query-tpm-models',
+        'query-tpm-types',
+        'ringbuf-read' ],
+    'name-case-whitelist': [
+        'ACPISlotType',             # DIMM, visible through query-acpi-ospm-status
+        'CpuInfoMIPS',              # PC, visible through query-cpu
+        'CpuInfoTricore',           # PC, visible through query-cpu
+        'BlockdevVmdkSubformat',    # all members, to match VMDK spec spellings
+        'BlockdevVmdkAdapterType',  # legacyESX, to match VMDK spec spellings
+        'QapiErrorClass',           # all members, visible through errors
+        'UuidInfo',                 # UUID, visible through query-uuid
+        'X86CPURegister32',         # all members, visible indirectly through qom-get
+        'CpuInfo'                   # CPU, visible through query-cpu
+    ] } }
index fe980ce43701b5d1302ee10d07d1aef1cdf0a8b1..43b0ba0dea22fe626f105cd2b7808ad6d5d2229c 100644 (file)
 #
 ##
 
-{ 'pragma': { 'doc-required': true } }
-
-# Whitelists to permit QAPI rule violations; think twice before you
-# add to them!
-{ 'pragma': {
-    # Commands allowed to return a non-dictionary:
-    'returns-whitelist': [
-        'human-monitor-command',
-        'qom-get',
-        'query-migrate-cache-size',
-        'query-tpm-models',
-        'query-tpm-types',
-        'ringbuf-read' ],
-    'name-case-whitelist': [
-        'ACPISlotType',             # DIMM, visible through query-acpi-ospm-status
-        'CpuInfoMIPS',              # PC, visible through query-cpu
-        'CpuInfoTricore',           # PC, visible through query-cpu
-        'BlockdevVmdkSubformat',    # all members, to match VMDK spec spellings
-        'BlockdevVmdkAdapterType',  # legacyESX, to match VMDK spec spellings
-        'QapiErrorClass',           # all members, visible through errors
-        'UuidInfo',                 # UUID, visible through query-uuid
-        'X86CPURegister32',         # all members, visible indirectly through qom-get
-        'CpuInfo'                   # CPU, visible through query-cpu
-    ] } }
+{ 'include': 'pragma.json' }
 
 # Documentation generated with qapi-gen.py is in source order, with
 # included sub-schemas inserted at the first include directive
index ecc60c4401c94b87dea6797be89b711ef7cf3961..8abe998962b369c390e41706126a4b4bc07843e5 100644 (file)
 #
 # @id: the name of the new object
 #
-# @props: a dictionary of properties to be passed to the backend
+# @props: a dictionary of properties to be passed to the backend. Deprecated
+#         since 5.0, specify the properties on the top level instead. It is an
+#         error to specify the same option both on the top level and in @props.
+#
+# Additional arguments depend on qom-type and are passed to the backend
+# unchanged.
 #
 # Returns: Nothing on success
 #          Error if @qom-type is not a valid class name
 #
 # -> { "execute": "object-add",
 #      "arguments": { "qom-type": "rng-random", "id": "rng1",
-#                     "props": { "filename": "/dev/hwrng" } } }
+#                     "filename": "/dev/hwrng" } }
 # <- { "return": {} }
 #
 ##
 { 'command': 'object-add',
-  'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'} }
+  'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'},
+  'gen': false } # so we can get the additional arguments
 
 ##
 # @object-del:
index 04301f1be7930874174fab65c377f306238bf8a0..b6c11158f0b63f847ecb6cd655f8a79d593a8cf9 100644 (file)
@@ -5,7 +5,7 @@
 # = Transactions
 ##
 
-{ 'include': 'block.json' }
+{ 'include': 'block-core.json' }
 
 ##
 # @Abort:
diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
deleted file mode 100644 (file)
index 66eca3a..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-@node Deprecated features
-@appendix Deprecated features
-
-In general features are intended to be supported indefinitely once
-introduced into QEMU. In the event that a feature needs to be removed,
-it will be listed in this appendix. The feature will remain functional
-for 2 releases prior to actual removal. Deprecated features may also
-generate warnings on the console when QEMU starts up, or if activated
-via a monitor command, however, this is not a mandatory requirement.
-
-Prior to the 2.10.0 release there was no official policy on how
-long features would be deprecated prior to their removal, nor
-any documented list of which features were deprecated. Thus
-any features deprecated prior to 2.10.0 will be treated as if
-they were first deprecated in the 2.10.0 release.
-
-What follows is a list of all features currently marked as
-deprecated.
-
-@section System emulator command line arguments
-
-@subsection -machine enforce-config-section=on|off (since 3.1)
-
-The @option{enforce-config-section} parameter is replaced by the
-@option{-global migration.send-configuration=@var{on|off}} option.
-
-@subsection -no-kvm (since 1.3.0)
-
-The ``-no-kvm'' argument is now a synonym for setting ``-accel tcg''.
-
-@subsection -usbdevice (since 2.10.0)
-
-The ``-usbdevice DEV'' argument is now a synonym for setting
-the ``-device usb-DEV'' argument instead. The deprecated syntax
-would automatically enable USB support on the machine type.
-If using the new syntax, USB support must be explicitly
-enabled via the ``-machine usb=on'' argument.
-
-@subsection -drive file=json:@{...@{'driver':'file'@}@} (since 3.0)
-
-The 'file' driver for drives is no longer appropriate for character or host
-devices and will only accept regular files (S_IFREG). The correct driver
-for these file types is 'host_cdrom' or 'host_device' as appropriate.
-
-@subsection -net ...,name=@var{name} (since 3.1)
-
-The @option{name} parameter of the @option{-net} option is a synonym
-for the @option{id} parameter, which should now be used instead.
-
-@subsection -smp (invalid topologies) (since 3.1)
-
-CPU topology properties should describe whole machine topology including
-possible CPUs.
-
-However, historically it was possible to start QEMU with an incorrect topology
-where @math{@var{n} <= @var{sockets} * @var{cores} * @var{threads} < @var{maxcpus}},
-which could lead to an incorrect topology enumeration by the guest.
-Support for invalid topologies will be removed, the user must ensure
-topologies described with -smp include all possible cpus, i.e.
-  @math{@var{sockets} * @var{cores} * @var{threads} = @var{maxcpus}}.
-
-@subsection -vnc acl (since 4.0.0)
-
-The @code{acl} option to the @code{-vnc} argument has been replaced
-by the @code{tls-authz} and @code{sasl-authz} options.
-
-@subsection QEMU_AUDIO_ environment variables and -audio-help (since 4.0)
-
-The ``-audiodev'' argument is now the preferred way to specify audio
-backend settings instead of environment variables.  To ease migration to
-the new format, the ``-audiodev-help'' option can be used to convert
-the current values of the environment variables to ``-audiodev'' options.
-
-@subsection Creating sound card devices and vnc without audiodev= property (since 4.2)
-
-When not using the deprecated legacy audio config, each sound card
-should specify an @code{audiodev=} property.  Additionally, when using
-vnc, you should specify an @code{audiodev=} propery if you plan to
-transmit audio through the VNC protocol.
-
-@subsection -mon ...,control=readline,pretty=on|off (since 4.1)
-
-The @code{pretty=on|off} switch has no effect for HMP monitors, but is
-silently ignored. Using the switch with HMP monitors will become an
-error in the future.
-
-@subsection -realtime (since 4.1)
-
-The @code{-realtime mlock=on|off} argument has been replaced by the
-@code{-overcommit mem-lock=on|off} argument.
-
-@subsection -numa node,mem=@var{size} (since 4.1)
-
-The parameter @option{mem} of @option{-numa node} is used to assign a part of
-guest RAM to a NUMA node. But when using it, it's impossible to manage specified
-RAM chunk on the host side (like bind it to a host node, setting bind policy, ...),
-so guest end-ups with the fake NUMA configuration with suboptiomal performance.
-However since 2014 there is an alternative way to assign RAM to a NUMA node
-using parameter @option{memdev}, which does the same as @option{mem} and adds
-means to actualy manage node RAM on the host side. Use parameter @option{memdev}
-with @var{memory-backend-ram} backend as an replacement for parameter @option{mem}
-to achieve the same fake NUMA effect or a properly configured
-@var{memory-backend-file} backend to actually benefit from NUMA configuration.
-In future new machine versions will not accept the option but it will still
-work with old machine types. User can check QAPI schema to see if the legacy
-option is supported by looking at MachineInfo::numa-mem-supported property.
-
-@subsection -numa node (without memory specified) (since 4.1)
-
-Splitting RAM by default between NUMA nodes has the same issues as @option{mem}
-parameter described above with the difference that the role of the user plays
-QEMU using implicit generic or board specific splitting rule.
-Use @option{memdev} with @var{memory-backend-ram} backend or @option{mem} (if
-it's supported by used machine type) to define mapping explictly instead.
-
-@subsection RISC-V -bios (since 4.1)
-
-QEMU 4.1 introduced support for the -bios option in QEMU for RISC-V for the
-RISC-V virt machine and sifive_u machine.
-
-QEMU 4.1 has no changes to the default behaviour to avoid breakages. This
-default will change in a future QEMU release, so please prepare now. All users
-of the virt or sifive_u machine must change their command line usage.
-
-QEMU 4.1 has three options, please migrate to one of these three:
- 1. ``-bios none`` - This is the current default behavior if no -bios option
-      is included. QEMU will not automatically load any firmware. It is up
-      to the user to load all the images they need.
- 2. ``-bios default`` - In a future QEMU release this will become the default
-      behaviour if no -bios option is specified. This option will load the
-      default OpenSBI firmware automatically. The firmware is included with
-      the QEMU release and no user interaction is required. All a user needs
-      to do is specify the kernel they want to boot with the -kernel option
- 3. ``-bios <file>`` - Tells QEMU to load the specified file as the firmwrae.
-
-@subsection -tb-size option (since 5.0)
-
-QEMU 5.0 introduced an alternative syntax to specify the size of the translation
-block cache, @option{-accel tcg,tb-size=}.  The new syntax deprecates the
-previously available @option{-tb-size} option.
-
-@subsection -show-cursor option (since 5.0)
-
-Use @option{-display sdl,show-cursor=on} or
- @option{-display gtk,show-cursor=on} instead.
-
-@section QEMU Machine Protocol (QMP) commands
-
-@subsection change (since 2.5.0)
-
-Use ``blockdev-change-medium'' or ``change-vnc-password'' instead.
-
-@subsection migrate_set_downtime and migrate_set_speed (since 2.8.0)
-
-Use ``migrate-set-parameters'' instead.
-
-@subsection migrate-set-cache-size and query-migrate-cache-size (since 2.11.0)
-
-Use ``migrate-set-parameters'' and ``query-migrate-parameters'' instead.
-
-@subsection query-block result field dirty-bitmaps[i].status (since 4.0)
-
-The ``status'' field of the ``BlockDirtyInfo'' structure, returned by
-the query-block command is deprecated. Two new boolean fields,
-``recording'' and ``busy'' effectively replace it.
-
-@subsection query-block result field dirty-bitmaps (Since 4.2)
-
-The ``dirty-bitmaps`` field of the ``BlockInfo`` structure, returned by
-the query-block command is itself now deprecated. The ``dirty-bitmaps``
-field of the ``BlockDeviceInfo`` struct should be used instead, which is the
-type of the ``inserted`` field in query-block replies, as well as the
-type of array items in query-named-block-nodes.
-
-Since the ``dirty-bitmaps`` field is optionally present in both the old and
-new locations, clients must use introspection to learn where to anticipate
-the field if/when it does appear in command output.
-
-@subsection query-cpus (since 2.12.0)
-
-The ``query-cpus'' command is replaced by the ``query-cpus-fast'' command.
-
-@subsection query-cpus-fast "arch" output member (since 3.0.0)
-
-The ``arch'' output member of the ``query-cpus-fast'' command is
-replaced by the ``target'' output member.
-
-@subsection cpu-add (since 4.0)
-
-Use ``device_add'' for hotplugging vCPUs instead of ``cpu-add''.  See
-documentation of ``query-hotpluggable-cpus'' for additional
-details.
-
-@subsection query-events (since 4.0)
-
-The ``query-events'' command has been superseded by the more powerful
-and accurate ``query-qmp-schema'' command.
-
-@subsection chardev client socket with 'wait' option (since 4.0)
-
-Character devices creating sockets in client mode should not specify
-the 'wait' field, which is only applicable to sockets in server mode
-
-@section Human Monitor Protocol (HMP) commands
-
-@subsection The hub_id parameter of 'hostfwd_add' / 'hostfwd_remove' (since 3.1)
-
-The @option{[hub_id name]} parameter tuple of the 'hostfwd_add' and
-'hostfwd_remove' HMP commands has been replaced by @option{netdev_id}.
-
-@subsection cpu-add (since 4.0)
-
-Use ``device_add'' for hotplugging vCPUs instead of ``cpu-add''.  See
-documentation of ``query-hotpluggable-cpus'' for additional details.
-
-@subsection acl_show, acl_reset, acl_policy, acl_add, acl_remove (since 4.0.0)
-
-The ``acl_show'', ``acl_reset'', ``acl_policy'', ``acl_add'', and
-``acl_remove'' commands are deprecated with no replacement. Authorization
-for VNC should be performed using the pluggable QAuthZ objects.
-
-@section Guest Emulator ISAs
-
-@subsection RISC-V ISA privledge specification version 1.09.1 (since 4.1)
-
-The RISC-V ISA privledge specification version 1.09.1 has been deprecated.
-QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
-should be used instead of the 1.09.1 version.
-
-@section System emulator CPUS
-
-@subsection RISC-V ISA CPUs (since 4.1)
-
-The RISC-V cpus with the ISA version in the CPU name have been depcreated. The
-four CPUs are: ``rv32gcsu-v1.9.1``, ``rv32gcsu-v1.10.0``, ``rv64gcsu-v1.9.1`` and
-``rv64gcsu-v1.10.0``. Instead the version can be specified via the CPU ``priv_spec``
-option when using the ``rv32`` or ``rv64`` CPUs.
-
-@subsection RISC-V ISA CPUs (since 4.1)
-
-The RISC-V no MMU cpus have been depcreated. The two CPUs: ``rv32imacu-nommu`` and
-``rv64imacu-nommu`` should no longer be used. Instead the MMU status can be specified
-via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
-
-@section System emulator devices
-
-@subsection ide-drive (since 4.2)
-
-The 'ide-drive' device is deprecated. Users should use 'ide-hd' or
-'ide-cd' as appropriate to get an IDE hard disk or CD-ROM as needed.
-
-@subsection scsi-disk (since 4.2)
-
-The 'scsi-disk' device is deprecated. Users should use 'scsi-hd' or
-'scsi-cd' as appropriate to get a SCSI hard disk or CD-ROM as needed.
-
-@section System emulator machines
-
-@subsection mips r4k platform (since 5.0)
-
-This machine type is very old and unmaintained. Users should use the 'malta'
-machine type instead.
-
-@subsection pc-1.0, pc-1.1, pc-1.2 and pc-1.3 (since 5.0)
-
-These machine types are very old and likely can not be used for live migration
-from old QEMU versions anymore. A newer machine type should be used instead.
-
-@subsection spike_v1.9.1 and spike_v1.10 (since 4.1)
-
-The version specific Spike machines have been deprecated in favour of the
-generic ``spike`` machine. If you need to specify an older version of the RISC-V
-spec you can use the ``-cpu rv64gcsu,priv_spec=v1.9.1`` command line argument.
-
-@section Device options
-
-@subsection Emulated device options
-
-@subsubsection -device virtio-blk,scsi=on|off (since 5.0.0)
-
-The virtio-blk SCSI passthrough feature is a legacy VIRTIO feature.  VIRTIO 1.0
-and later do not support it because the virtio-scsi device was introduced for
-full SCSI support.  Use virtio-scsi instead when SCSI passthrough is required.
-
-Note this also applies to ``-device virtio-blk-pci,scsi=on|off'', which is an
-alias.
-
-@subsection Block device options
-
-@subsubsection "backing": "" (since 2.12.0)
-
-In order to prevent QEMU from automatically opening an image's backing
-chain, use ``"backing": null'' instead.
-
-@subsubsection rbd keyvalue pair encoded filenames: "" (since 3.1.0)
-
-Options for ``rbd'' should be specified according to its runtime options,
-like other block drivers.  Legacy parsing of keyvalue pair encoded
-filenames is useful to open images with the old format for backing files;
-These image files should be updated to use the current format.
-
-Example of legacy encoding:
-
-@code{json:@{"file.driver":"rbd", "file.filename":"rbd:rbd/name"@}}
-
-The above, converted to the current supported format:
-
-@code{json:@{"file.driver":"rbd", "file.pool":"rbd", "file.image":"name"@}}
-
-@section Related binaries
-
-@subsection qemu-img convert -n -o (since 4.2.0)
-
-All options specified in @option{-o} are image creation options, so
-they have no effect when used with @option{-n} to skip image creation.
-Silently ignored options can be confusing, so this combination of
-options will be made an error in future versions.
-
-@section Backwards compatibility
-
-@subsection Runnability guarantee of CPU models (since 4.1.0)
-
-Previous versions of QEMU never changed existing CPU models in
-ways that introduced additional host software or hardware
-requirements to the VM.  This allowed management software to
-safely change the machine type of an existing VM without
-introducing new requirements ("runnability guarantee").  This
-prevented CPU models from being updated to include CPU
-vulnerability mitigations, leaving guests vulnerable in the
-default configuration.
-
-The CPU model runnability guarantee won't apply anymore to
-existing CPU models.  Management software that needs runnability
-guarantees must resolve the CPU model aliases using te
-``alias-of'' field returned by the ``query-cpu-definitions'' QMP
-command.
-
-While those guarantees are kept, the return value of
-``query-cpu-definitions'' will have existing CPU model aliases
-point to a version that doesn't break runnability guarantees
-(specifically, version 1 of those CPU models).  In future QEMU
-versions, aliases will point to newer CPU model versions
-depending on the machine type, so management software must
-resolve CPU model aliases before starting a virtual machine.
-
-
-@node Recently removed features
-@appendix Recently removed features
-
-What follows is a record of recently removed, formerly deprecated
-features that serves as a record for users who have encountered
-trouble after a recent upgrade.
-
-@section QEMU Machine Protocol (QMP) commands
-
-@subsection block-dirty-bitmap-add "autoload" parameter (since 4.2.0)
-
-The "autoload" parameter has been ignored since 2.12.0. All bitmaps
-are automatically loaded from qcow2 images.
-
-@section Related binaries
-
-@subsection qemu-nbd --partition (removed in 5.0.0)
-
-The ``qemu-nbd --partition $digit'' code (also spelled @option{-P})
-could only handle MBR partitions, and never correctly handled logical
-partitions beyond partition 5.  Exporting a partition can still be
-done by utilizing the @option{--image-opts} option with a raw blockdev
-using the @code{offset} and @code{size} parameters layered on top of
-any other existing blockdev. For example, if partition 1 is 100MiB
-long starting at 1MiB, the old command:
-
-@code{qemu-nbd -t -P 1 -f qcow2 file.qcow2}
-
-can be rewritten as:
-
-@code{qemu-nbd -t --image-opts driver=raw,offset=1M,size=100M,file.driver=qcow2,file.file.driver=file,file.file.filename=file.qcow2}
diff --git a/qemu-doc.texi b/qemu-doc.texi
deleted file mode 100644 (file)
index 33b9597..0000000
+++ /dev/null
@@ -1,2967 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-@c %**start of header
-@setfilename qemu-doc.info
-@include version.texi
-
-@documentlanguage en
-@documentencoding UTF-8
-
-@settitle QEMU version @value{VERSION} User Documentation
-@exampleindent 0
-@paragraphindent 0
-@c %**end of header
-
-@set qemu_system qemu-system-x86_64
-@set qemu_system_x86 qemu-system-x86_64
-
-@ifinfo
-@direntry
-* QEMU: (qemu-doc).    The QEMU Emulator User Documentation.
-@end direntry
-@end ifinfo
-
-@iftex
-@titlepage
-@sp 7
-@center @titlefont{QEMU version @value{VERSION}}
-@sp 1
-@center @titlefont{User Documentation}
-@sp 3
-@end titlepage
-@end iftex
-
-@ifnottex
-@node Top
-@top
-
-@menu
-* Introduction::
-* QEMU PC System emulator::
-* QEMU System emulator for non PC targets::
-* QEMU User space emulator::
-* System requirements::
-* Security::
-* Implementation notes::
-* Deprecated features::
-* Recently removed features::
-* Supported build platforms::
-* License::
-* Index::
-@end menu
-@end ifnottex
-
-@contents
-
-@node Introduction
-@chapter Introduction
-
-@menu
-* intro_features:: Features
-@end menu
-
-@node intro_features
-@section Features
-
-QEMU is a FAST! processor emulator using dynamic translation to
-achieve good emulation speed.
-
-@cindex operating modes
-QEMU has two operating modes:
-
-@itemize
-@cindex system emulation
-@item Full system emulation. In this mode, QEMU emulates a full system (for
-example a PC), including one or several processors and various
-peripherals. It can be used to launch different Operating Systems
-without rebooting the PC or to debug system code.
-
-@cindex user mode emulation
-@item User mode emulation. In this mode, QEMU can launch
-processes compiled for one CPU on another CPU. It can be used to
-launch the Wine Windows API emulator (@url{https://www.winehq.org}) or
-to ease cross-compilation and cross-debugging.
-
-@end itemize
-
-QEMU has the following features:
-
-@itemize
-@item QEMU can run without a host kernel driver and yet gives acceptable
-performance.  It uses dynamic translation to native code for reasonable speed,
-with support for self-modifying code and precise exceptions.
-
-@item It is portable to several operating systems (GNU/Linux, *BSD, Mac OS X,
-Windows) and architectures.
-
-@item It performs accurate software emulation of the FPU.
-@end itemize
-
-QEMU user mode emulation has the following features:
-@itemize
-@item Generic Linux system call converter, including most ioctls.
-
-@item clone() emulation using native CPU clone() to use Linux scheduler for threads.
-
-@item Accurate signal handling by remapping host signals to target signals.
-@end itemize
-
-QEMU full system emulation has the following features:
-@itemize
-@item
-QEMU uses a full software MMU for maximum portability.
-
-@item
-QEMU can optionally use an in-kernel accelerator, like kvm. The accelerators
-execute most of the guest code natively, while
-continuing to emulate the rest of the machine.
-
-@item
-Various hardware devices can be emulated and in some cases, host
-devices (e.g. serial and parallel ports, USB, drives) can be used
-transparently by the guest Operating System. Host device passthrough
-can be used for talking to external physical peripherals (e.g. a
-webcam, modem or tape drive).
-
-@item
-Symmetric multiprocessing (SMP) support.  Currently, an in-kernel
-accelerator is required to use more than one host CPU for emulation.
-
-@end itemize
-
-
-@node QEMU PC System emulator
-@chapter QEMU PC System emulator
-@cindex system emulation (PC)
-
-@menu
-* pcsys_introduction:: Introduction
-* pcsys_quickstart::   Quick Start
-* sec_invocation::     Invocation
-* pcsys_keys::         Keys in the graphical frontends
-* mux_keys::           Keys in the character backend multiplexer
-* pcsys_monitor::      QEMU Monitor
-* cpu_models::         CPU models
-* disk_images::        Disk Images
-* pcsys_network::      Network emulation
-* pcsys_other_devs::   Other Devices
-* direct_linux_boot::  Direct Linux Boot
-* pcsys_usb::          USB emulation
-* vnc_security::       VNC security
-* network_tls::        TLS setup for network services
-* gdb_usage::          GDB usage
-* pcsys_os_specific::  Target OS specific information
-@end menu
-
-@node pcsys_introduction
-@section Introduction
-
-@c man begin DESCRIPTION
-
-The QEMU PC System emulator simulates the
-following peripherals:
-
-@itemize @minus
-@item
-i440FX host PCI bridge and PIIX3 PCI to ISA bridge
-@item
-Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA
-extensions (hardware level, including all non standard modes).
-@item
-PS/2 mouse and keyboard
-@item
-2 PCI IDE interfaces with hard disk and CD-ROM support
-@item
-Floppy disk
-@item
-PCI and ISA network adapters
-@item
-Serial ports
-@item
-IPMI BMC, either and internal or external one
-@item
-Creative SoundBlaster 16 sound card
-@item
-ENSONIQ AudioPCI ES1370 sound card
-@item
-Intel 82801AA AC97 Audio compatible sound card
-@item
-Intel HD Audio Controller and HDA codec
-@item
-Adlib (OPL2) - Yamaha YM3812 compatible chip
-@item
-Gravis Ultrasound GF1 sound card
-@item
-CS4231A compatible sound card
-@item
-PCI UHCI, OHCI, EHCI or XHCI USB controller and a virtual USB-1.1 hub.
-@end itemize
-
-SMP is supported with up to 255 CPUs.
-
-QEMU uses the PC BIOS from the Seabios project and the Plex86/Bochs LGPL
-VGA BIOS.
-
-QEMU uses YM3812 emulation by Tatsuyuki Satoh.
-
-QEMU uses GUS emulation (GUSEMU32 @url{http://www.deinmeister.de/gusemu/})
-by Tibor "TS" Schütz.
-
-Note that, by default, GUS shares IRQ(7) with parallel ports and so
-QEMU must be told to not have parallel ports to have working GUS.
-
-@example
-@value{qemu_system_x86} dos.img -soundhw gus -parallel none
-@end example
-
-Alternatively:
-@example
-@value{qemu_system_x86} dos.img -device gus,irq=5
-@end example
-
-Or some other unclaimed IRQ.
-
-CS4231A is the chip used in Windows Sound System and GUSMAX products
-
-@c man end
-
-@node pcsys_quickstart
-@section Quick Start
-@cindex quick start
-
-Download and uncompress a hard disk image with Linux installed (e.g.
-@file{linux.img}) and type:
-
-@example
-@value{qemu_system} linux.img
-@end example
-
-Linux should boot and give you a prompt.
-
-@node sec_invocation
-@section Invocation
-
-@example
-@c man begin SYNOPSIS
-@command{@value{qemu_system}} [@var{options}] [@var{disk_image}]
-@c man end
-@end example
-
-@c man begin OPTIONS
-@var{disk_image} is a raw hard disk image for IDE hard disk 0. Some
-targets do not need a disk image.
-
-@include qemu-options.texi
-
-@c man end
-
-@subsection Device URL Syntax
-@c TODO merge this with section Disk Images
-
-@c man begin NOTES
-
-In addition to using normal file images for the emulated storage devices,
-QEMU can also use networked resources such as iSCSI devices. These are
-specified using a special URL syntax.
-
-@table @option
-@item iSCSI
-iSCSI support allows QEMU to access iSCSI resources directly and use as
-images for the guest storage. Both disk and cdrom images are supported.
-
-Syntax for specifying iSCSI LUNs is
-``iscsi://<target-ip>[:<port>]/<target-iqn>/<lun>''
-
-By default qemu will use the iSCSI initiator-name
-'iqn.2008-11.org.linux-kvm[:<name>]' but this can also be set from the command
-line or a configuration file.
-
-Since version Qemu 2.4 it is possible to specify a iSCSI request timeout to detect
-stalled requests and force a reestablishment of the session. The timeout
-is specified in seconds. The default is 0 which means no timeout. Libiscsi
-1.15.0 or greater is required for this feature.
-
-Example (without authentication):
-@example
-@value{qemu_system} -iscsi initiator-name=iqn.2001-04.com.example:my-initiator \
-                 -cdrom iscsi://192.0.2.1/iqn.2001-04.com.example/2 \
-                 -drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1
-@end example
-
-Example (CHAP username/password via URL):
-@example
-@value{qemu_system} -drive file=iscsi://user%password@@192.0.2.1/iqn.2001-04.com.example/1
-@end example
-
-Example (CHAP username/password via environment variables):
-@example
-LIBISCSI_CHAP_USERNAME="user" \
-LIBISCSI_CHAP_PASSWORD="password" \
-@value{qemu_system} -drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1
-@end example
-
-@item NBD
-QEMU supports NBD (Network Block Devices) both using TCP protocol as well
-as Unix Domain Sockets.  With TCP, the default port is 10809.
-
-Syntax for specifying a NBD device using TCP, in preferred URI form:
-``nbd://<server-ip>[:<port>]/[<export>]''
-
-Syntax for specifying a NBD device using Unix Domain Sockets; remember
-that '?' is a shell glob character and may need quoting:
-``nbd+unix:///[<export>]?socket=<domain-socket>''
-
-Older syntax that is also recognized:
-``nbd:<server-ip>:<port>[:exportname=<export>]''
-
-Syntax for specifying a NBD device using Unix Domain Sockets
-``nbd:unix:<domain-socket>[:exportname=<export>]''
-
-Example for TCP
-@example
-@value{qemu_system} --drive file=nbd:192.0.2.1:30000
-@end example
-
-Example for Unix Domain Sockets
-@example
-@value{qemu_system} --drive file=nbd:unix:/tmp/nbd-socket
-@end example
-
-@item SSH
-QEMU supports SSH (Secure Shell) access to remote disks.
-
-Examples:
-@example
-@value{qemu_system} -drive file=ssh://user@@host/path/to/disk.img
-@value{qemu_system} -drive file.driver=ssh,file.user=user,file.host=host,file.port=22,file.path=/path/to/disk.img
-@end example
-
-Currently authentication must be done using ssh-agent.  Other
-authentication methods may be supported in future.
-
-@item Sheepdog
-Sheepdog is a distributed storage system for QEMU.
-QEMU supports using either local sheepdog devices or remote networked
-devices.
-
-Syntax for specifying a sheepdog device
-@example
-sheepdog[+tcp|+unix]://[host:port]/vdiname[?socket=path][#snapid|#tag]
-@end example
-
-Example
-@example
-@value{qemu_system} --drive file=sheepdog://192.0.2.1:30000/MyVirtualMachine
-@end example
-
-See also @url{https://sheepdog.github.io/sheepdog/}.
-
-@item GlusterFS
-GlusterFS is a user space distributed file system.
-QEMU supports the use of GlusterFS volumes for hosting VM disk images using
-TCP, Unix Domain Sockets and RDMA transport protocols.
-
-Syntax for specifying a VM disk image on GlusterFS volume is
-@example
-
-URI:
-gluster[+type]://[host[:port]]/volume/path[?socket=...][,debug=N][,logfile=...]
-
-JSON:
-'json:@{"driver":"qcow2","file":@{"driver":"gluster","volume":"testvol","path":"a.img","debug":N,"logfile":"...",
-@                                 "server":[@{"type":"tcp","host":"...","port":"..."@},
-@                                           @{"type":"unix","socket":"..."@}]@}@}'
-@end example
-
-
-Example
-@example
-URI:
-@value{qemu_system} --drive file=gluster://192.0.2.1/testvol/a.img,
-@                               file.debug=9,file.logfile=/var/log/qemu-gluster.log
-
-JSON:
-@value{qemu_system} 'json:@{"driver":"qcow2",
-@                          "file":@{"driver":"gluster",
-@                                   "volume":"testvol","path":"a.img",
-@                                   "debug":9,"logfile":"/var/log/qemu-gluster.log",
-@                                   "server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
-@                                             @{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
-@value{qemu_system} -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
-@                                      file.debug=9,file.logfile=/var/log/qemu-gluster.log,
-@                                      file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
-@                                      file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
-@end example
-
-See also @url{http://www.gluster.org}.
-
-@item HTTP/HTTPS/FTP/FTPS
-QEMU supports read-only access to files accessed over http(s) and ftp(s).
-
-Syntax using a single filename:
-@example
-<protocol>://[<username>[:<password>]@@]<host>/<path>
-@end example
-
-where:
-@table @option
-@item protocol
-'http', 'https', 'ftp', or 'ftps'.
-
-@item username
-Optional username for authentication to the remote server.
-
-@item password
-Optional password for authentication to the remote server.
-
-@item host
-Address of the remote server.
-
-@item path
-Path on the remote server, including any query string.
-@end table
-
-The following options are also supported:
-@table @option
-@item url
-The full URL when passing options to the driver explicitly.
-
-@item readahead
-The amount of data to read ahead with each range request to the remote server.
-This value may optionally have the suffix 'T', 'G', 'M', 'K', 'k' or 'b'. If it
-does not have a suffix, it will be assumed to be in bytes. The value must be a
-multiple of 512 bytes. It defaults to 256k.
-
-@item sslverify
-Whether to verify the remote server's certificate when connecting over SSL. It
-can have the value 'on' or 'off'. It defaults to 'on'.
-
-@item cookie
-Send this cookie (it can also be a list of cookies separated by ';') with
-each outgoing request.  Only supported when using protocols such as HTTP
-which support cookies, otherwise ignored.
-
-@item timeout
-Set the timeout in seconds of the CURL connection. This timeout is the time
-that CURL waits for a response from the remote server to get the size of the
-image to be downloaded. If not set, the default timeout of 5 seconds is used.
-@end table
-
-Note that when passing options to qemu explicitly, @option{driver} is the value
-of <protocol>.
-
-Example: boot from a remote Fedora 20 live ISO image
-@example
-@value{qemu_system_x86} --drive media=cdrom,file=https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
-
-@value{qemu_system_x86} --drive media=cdrom,file.driver=http,file.url=http://archives.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
-@end example
-
-Example: boot from a remote Fedora 20 cloud image using a local overlay for
-writes, copy-on-read, and a readahead of 64k
-@example
-qemu-img create -f qcow2 -o backing_file='json:@{"file.driver":"http",, "file.url":"http://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Images/x86_64/Fedora-x86_64-20-20131211.1-sda.qcow2",, "file.readahead":"64k"@}' /tmp/Fedora-x86_64-20-20131211.1-sda.qcow2
-
-@value{qemu_system_x86} -drive file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-on-read=on
-@end example
-
-Example: boot from an image stored on a VMware vSphere server with a self-signed
-certificate using a local overlay for writes, a readahead of 64k and a timeout
-of 10 seconds.
-@example
-qemu-img create -f qcow2 -o backing_file='json:@{"file.driver":"https",, "file.url":"https://user:password@@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=Datacenter&dsName=datastore1",, "file.sslverify":"off",, "file.readahead":"64k",, "file.timeout":10@}' /tmp/test.qcow2
-
-@value{qemu_system_x86} -drive file=/tmp/test.qcow2
-@end example
-
-@end table
-
-@c man end
-
-@node pcsys_keys
-@section Keys in the graphical frontends
-
-@c man begin OPTIONS
-
-During the graphical emulation, you can use special key combinations to change
-modes. The default key mappings are shown below, but if you use @code{-alt-grab}
-then the modifier is Ctrl-Alt-Shift (instead of Ctrl-Alt) and if you use
-@code{-ctrl-grab} then the modifier is the right Ctrl key (instead of Ctrl-Alt):
-
-@table @key
-@item Ctrl-Alt-f
-@kindex Ctrl-Alt-f
-Toggle full screen
-
-@item Ctrl-Alt-+
-@kindex Ctrl-Alt-+
-Enlarge the screen
-
-@item Ctrl-Alt--
-@kindex Ctrl-Alt--
-Shrink the screen
-
-@item Ctrl-Alt-u
-@kindex Ctrl-Alt-u
-Restore the screen's un-scaled dimensions
-
-@item Ctrl-Alt-n
-@kindex Ctrl-Alt-n
-Switch to virtual console 'n'. Standard console mappings are:
-@table @emph
-@item 1
-Target system display
-@item 2
-Monitor
-@item 3
-Serial port
-@end table
-
-@item Ctrl-Alt
-@kindex Ctrl-Alt
-Toggle mouse and keyboard grab.
-@end table
-
-@kindex Ctrl-Up
-@kindex Ctrl-Down
-@kindex Ctrl-PageUp
-@kindex Ctrl-PageDown
-In the virtual consoles, you can use @key{Ctrl-Up}, @key{Ctrl-Down},
-@key{Ctrl-PageUp} and @key{Ctrl-PageDown} to move in the back log.
-
-@c man end
-
-@node mux_keys
-@section Keys in the character backend multiplexer
-
-@c man begin OPTIONS
-
-During emulation, if you are using a character backend multiplexer
-(which is the default if you are using @option{-nographic}) then
-several commands are available via an escape sequence. These
-key sequences all start with an escape character, which is @key{Ctrl-a}
-by default, but can be changed with @option{-echr}. The list below assumes
-you're using the default.
-
-@table @key
-@item Ctrl-a h
-@kindex Ctrl-a h
-Print this help
-@item Ctrl-a x
-@kindex Ctrl-a x
-Exit emulator
-@item Ctrl-a s
-@kindex Ctrl-a s
-Save disk data back to file (if -snapshot)
-@item Ctrl-a t
-@kindex Ctrl-a t
-Toggle console timestamps
-@item Ctrl-a b
-@kindex Ctrl-a b
-Send break (magic sysrq in Linux)
-@item Ctrl-a c
-@kindex Ctrl-a c
-Rotate between the frontends connected to the multiplexer (usually
-this switches between the monitor and the console)
-@item Ctrl-a Ctrl-a
-@kindex Ctrl-a Ctrl-a
-Send the escape character to the frontend
-@end table
-@c man end
-
-@ignore
-
-@c man begin SEEALSO
-The HTML documentation of QEMU for more precise information and Linux
-user mode emulator invocation.
-@c man end
-
-@c man begin AUTHOR
-Fabrice Bellard
-@c man end
-
-@end ignore
-
-@node pcsys_monitor
-@section QEMU Monitor
-@cindex QEMU monitor
-
-The QEMU monitor is used to give complex commands to the QEMU
-emulator. You can use it to:
-
-@itemize @minus
-
-@item
-Remove or insert removable media images
-(such as CD-ROM or floppies).
-
-@item
-Freeze/unfreeze the Virtual Machine (VM) and save or restore its state
-from a disk file.
-
-@item Inspect the VM state without an external debugger.
-
-@end itemize
-
-@subsection Commands
-
-The following commands are available:
-
-@include qemu-monitor.texi
-
-@include qemu-monitor-info.texi
-
-@subsection Integer expressions
-
-The monitor understands integers expressions for every integer
-argument. You can use register names to get the value of specifics
-CPU registers by prefixing them with @emph{$}.
-
-@node cpu_models
-@section CPU models
-
-@include docs/qemu-cpu-models.texi
-
-@node disk_images
-@section Disk Images
-
-QEMU supports many disk image formats, including growable disk images
-(their size increase as non empty sectors are written), compressed and
-encrypted disk images.
-
-@menu
-* disk_images_quickstart::    Quick start for disk image creation
-* disk_images_snapshot_mode:: Snapshot mode
-* vm_snapshots::              VM snapshots
-@end menu
-
-@node disk_images_quickstart
-@subsection Quick start for disk image creation
-
-You can create a disk image with the command:
-@example
-qemu-img create myimage.img mysize
-@end example
-where @var{myimage.img} is the disk image filename and @var{mysize} is its
-size in kilobytes. You can add an @code{M} suffix to give the size in
-megabytes and a @code{G} suffix for gigabytes.
-
-@c When this document is converted to rst we should make this into
-@c a proper linked reference to the qemu-img documentation again:
-See the qemu-img invocation documentation for more information.
-
-@node disk_images_snapshot_mode
-@subsection Snapshot mode
-
-If you use the option @option{-snapshot}, all disk images are
-considered as read only. When sectors in written, they are written in
-a temporary file created in @file{/tmp}. You can however force the
-write back to the raw disk images by using the @code{commit} monitor
-command (or @key{C-a s} in the serial console).
-
-@node vm_snapshots
-@subsection VM snapshots
-
-VM snapshots are snapshots of the complete virtual machine including
-CPU state, RAM, device state and the content of all the writable
-disks. In order to use VM snapshots, you must have at least one non
-removable and writable block device using the @code{qcow2} disk image
-format. Normally this device is the first virtual hard drive.
-
-Use the monitor command @code{savevm} to create a new VM snapshot or
-replace an existing one. A human readable name can be assigned to each
-snapshot in addition to its numerical ID.
-
-Use @code{loadvm} to restore a VM snapshot and @code{delvm} to remove
-a VM snapshot. @code{info snapshots} lists the available snapshots
-with their associated information:
-
-@example
-(qemu) info snapshots
-Snapshot devices: hda
-Snapshot list (from hda):
-ID        TAG                 VM SIZE                DATE       VM CLOCK
-1         start                   41M 2006-08-06 12:38:02   00:00:14.954
-2                                 40M 2006-08-06 12:43:29   00:00:18.633
-3         msys                    40M 2006-08-06 12:44:04   00:00:23.514
-@end example
-
-A VM snapshot is made of a VM state info (its size is shown in
-@code{info snapshots}) and a snapshot of every writable disk image.
-The VM state info is stored in the first @code{qcow2} non removable
-and writable block device. The disk image snapshots are stored in
-every disk image. The size of a snapshot in a disk image is difficult
-to evaluate and is not shown by @code{info snapshots} because the
-associated disk sectors are shared among all the snapshots to save
-disk space (otherwise each snapshot would need a full copy of all the
-disk images).
-
-When using the (unrelated) @code{-snapshot} option
-(@ref{disk_images_snapshot_mode}), you can always make VM snapshots,
-but they are deleted as soon as you exit QEMU.
-
-VM snapshots currently have the following known limitations:
-@itemize
-@item
-They cannot cope with removable devices if they are removed or
-inserted after a snapshot is done.
-@item
-A few device drivers still have incomplete snapshot support so their
-state is not saved or restored properly (in particular USB).
-@end itemize
-
-@node pcsys_network
-@section Network emulation
-
-QEMU can simulate several network cards (e.g. PCI or ISA cards on the PC
-target) and can connect them to a network backend on the host or an emulated
-hub. The various host network backends can either be used to connect the NIC of
-the guest to a real network (e.g. by using a TAP devices or the non-privileged
-user mode network stack), or to other guest instances running in another QEMU
-process (e.g. by using the socket host network backend).
-
-@subsection Using TAP network interfaces
-
-This is the standard way to connect QEMU to a real network. QEMU adds
-a virtual network device on your host (called @code{tapN}), and you
-can then configure it as if it was a real ethernet card.
-
-@subsubsection Linux host
-
-As an example, you can download the @file{linux-test-xxx.tar.gz}
-archive and copy the script @file{qemu-ifup} in @file{/etc} and
-configure properly @code{sudo} so that the command @code{ifconfig}
-contained in @file{qemu-ifup} can be executed as root. You must verify
-that your host kernel supports the TAP network interfaces: the
-device @file{/dev/net/tun} must be present.
-
-See @ref{sec_invocation} to have examples of command lines using the
-TAP network interfaces.
-
-@subsubsection Windows host
-
-There is a virtual ethernet driver for Windows 2000/XP systems, called
-TAP-Win32. But it is not included in standard QEMU for Windows,
-so you will need to get it separately. It is part of OpenVPN package,
-so download OpenVPN from : @url{https://openvpn.net/}.
-
-@subsection Using the user mode network stack
-
-By using the option @option{-net user} (default configuration if no
-@option{-net} option is specified), QEMU uses a completely user mode
-network stack (you don't need root privilege to use the virtual
-network). The virtual network configuration is the following:
-
-@example
-
-     guest (10.0.2.15)  <------>  Firewall/DHCP server <-----> Internet
-                           |          (10.0.2.2)
-                           |
-                           ---->  DNS server (10.0.2.3)
-                           |
-                           ---->  SMB server (10.0.2.4)
-@end example
-
-The QEMU VM behaves as if it was behind a firewall which blocks all
-incoming connections. You can use a DHCP client to automatically
-configure the network in the QEMU VM. The DHCP server assign addresses
-to the hosts starting from 10.0.2.15.
-
-In order to check that the user mode network is working, you can ping
-the address 10.0.2.2 and verify that you got an address in the range
-10.0.2.x from the QEMU virtual DHCP server.
-
-Note that ICMP traffic in general does not work with user mode networking.
-@code{ping}, aka. ICMP echo, to the local router (10.0.2.2) shall work,
-however. If you're using QEMU on Linux >= 3.0, it can use unprivileged ICMP
-ping sockets to allow @code{ping} to the Internet. The host admin has to set
-the ping_group_range in order to grant access to those sockets. To allow ping
-for GID 100 (usually users group):
-
-@example
-echo 100 100 > /proc/sys/net/ipv4/ping_group_range
-@end example
-
-When using the built-in TFTP server, the router is also the TFTP
-server.
-
-When using the @option{'-netdev user,hostfwd=...'} option, TCP or UDP
-connections can be redirected from the host to the guest. It allows for
-example to redirect X11, telnet or SSH connections.
-
-@subsection Hubs
-
-QEMU can simulate several hubs. A hub can be thought of as a virtual connection
-between several network devices. These devices can be for example QEMU virtual
-ethernet cards or virtual Host ethernet devices (TAP devices). You can connect
-guest NICs or host network backends to such a hub using the @option{-netdev
-hubport} or @option{-nic hubport} options. The legacy @option{-net} option
-also connects the given device to the emulated hub with ID 0 (i.e. the default
-hub) unless you specify a netdev with @option{-net nic,netdev=xxx} here.
-
-@subsection Connecting emulated networks between QEMU instances
-
-Using the @option{-netdev socket} (or @option{-nic socket} or
-@option{-net socket}) option, it is possible to create emulated
-networks that span several QEMU instances.
-See the description of the @option{-netdev socket} option in the
-@ref{sec_invocation,,Invocation chapter} to have a basic example.
-
-@node pcsys_other_devs
-@section Other Devices
-
-@subsection Inter-VM Shared Memory device
-
-On Linux hosts, a shared memory device is available.  The basic syntax
-is:
-
-@example
-@value{qemu_system_x86} -device ivshmem-plain,memdev=@var{hostmem}
-@end example
-
-where @var{hostmem} names a host memory backend.  For a POSIX shared
-memory backend, use something like
-
-@example
--object memory-backend-file,size=1M,share,mem-path=/dev/shm/ivshmem,id=@var{hostmem}
-@end example
-
-If desired, interrupts can be sent between guest VMs accessing the same shared
-memory region.  Interrupt support requires using a shared memory server and
-using a chardev socket to connect to it.  The code for the shared memory server
-is qemu.git/contrib/ivshmem-server.  An example syntax when using the shared
-memory server is:
-
-@example
-# First start the ivshmem server once and for all
-ivshmem-server -p @var{pidfile} -S @var{path} -m @var{shm-name} -l @var{shm-size} -n @var{vectors}
-
-# Then start your qemu instances with matching arguments
-@value{qemu_system_x86} -device ivshmem-doorbell,vectors=@var{vectors},chardev=@var{id}
-                 -chardev socket,path=@var{path},id=@var{id}
-@end example
-
-When using the server, the guest will be assigned a VM ID (>=0) that allows guests
-using the same server to communicate via interrupts.  Guests can read their
-VM ID from a device register (see ivshmem-spec.txt).
-
-@subsubsection Migration with ivshmem
-
-With device property @option{master=on}, the guest will copy the shared
-memory on migration to the destination host.  With @option{master=off},
-the guest will not be able to migrate with the device attached.  In the
-latter case, the device should be detached and then reattached after
-migration using the PCI hotplug support.
-
-At most one of the devices sharing the same memory can be master.  The
-master must complete migration before you plug back the other devices.
-
-@subsubsection ivshmem and hugepages
-
-Instead of specifying the <shm size> using POSIX shm, you may specify
-a memory backend that has hugepage support:
-
-@example
-@value{qemu_system_x86} -object memory-backend-file,size=1G,mem-path=/dev/hugepages/my-shmem-file,share,id=mb1
-                 -device ivshmem-plain,memdev=mb1
-@end example
-
-ivshmem-server also supports hugepages mount points with the
-@option{-m} memory path argument.
-
-@node direct_linux_boot
-@section Direct Linux Boot
-
-This section explains how to launch a Linux kernel inside QEMU without
-having to make a full bootable image. It is very useful for fast Linux
-kernel testing.
-
-The syntax is:
-@example
-@value{qemu_system} -kernel bzImage -hda rootdisk.img -append "root=/dev/hda"
-@end example
-
-Use @option{-kernel} to provide the Linux kernel image and
-@option{-append} to give the kernel command line arguments. The
-@option{-initrd} option can be used to provide an INITRD image.
-
-If you do not need graphical output, you can disable it and redirect
-the virtual serial port and the QEMU monitor to the console with the
-@option{-nographic} option. The typical command line is:
-@example
-@value{qemu_system} -kernel bzImage -hda rootdisk.img \
-                 -append "root=/dev/hda console=ttyS0" -nographic
-@end example
-
-Use @key{Ctrl-a c} to switch between the serial console and the
-monitor (@pxref{pcsys_keys}).
-
-@node pcsys_usb
-@section USB emulation
-
-QEMU can emulate a PCI UHCI, OHCI, EHCI or XHCI USB controller. You can
-plug virtual USB devices or real host USB devices (only works with certain
-host operating systems). QEMU will automatically create and connect virtual
-USB hubs as necessary to connect multiple USB devices.
-
-@menu
-* usb_devices::
-* host_usb_devices::
-@end menu
-@node usb_devices
-@subsection Connecting USB devices
-
-USB devices can be connected with the @option{-device usb-...} command line
-option or the @code{device_add} monitor command. Available devices are:
-
-@table @code
-@item usb-mouse
-Virtual Mouse.  This will override the PS/2 mouse emulation when activated.
-@item usb-tablet
-Pointer device that uses absolute coordinates (like a touchscreen).
-This means QEMU is able to report the mouse position without having
-to grab the mouse.  Also overrides the PS/2 mouse emulation when activated.
-@item usb-storage,drive=@var{drive_id}
-Mass storage device backed by @var{drive_id} (@pxref{disk_images})
-@item usb-uas
-USB attached SCSI device, see
-@url{https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt,usb-storage.txt}
-for details
-@item usb-bot
-Bulk-only transport storage device, see
-@url{https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt,usb-storage.txt}
-for details here, too
-@item usb-mtp,rootdir=@var{dir}
-Media transfer protocol device, using @var{dir} as root of the file tree
-that is presented to the guest.
-@item usb-host,hostbus=@var{bus},hostaddr=@var{addr}
-Pass through the host device identified by @var{bus} and @var{addr}
-@item usb-host,vendorid=@var{vendor},productid=@var{product}
-Pass through the host device identified by @var{vendor} and @var{product} ID
-@item usb-wacom-tablet
-Virtual Wacom PenPartner tablet.  This device is similar to the @code{tablet}
-above but it can be used with the tslib library because in addition to touch
-coordinates it reports touch pressure.
-@item usb-kbd
-Standard USB keyboard.  Will override the PS/2 keyboard (if present).
-@item usb-serial,chardev=@var{id}
-Serial converter. This emulates an FTDI FT232BM chip connected to host character
-device @var{id}.
-@item usb-braille,chardev=@var{id}
-Braille device.  This will use BrlAPI to display the braille output on a real
-or fake device referenced by @var{id}.
-@item usb-net[,netdev=@var{id}]
-Network adapter that supports CDC ethernet and RNDIS protocols.  @var{id}
-specifies a netdev defined with @code{-netdev @dots{},id=@var{id}}.
-For instance, user-mode networking can be used with
-@example
-@value{qemu_system} [...] -netdev user,id=net0 -device usb-net,netdev=net0
-@end example
-@item usb-ccid
-Smartcard reader device
-@item usb-audio
-USB audio device
-@end table
-
-@node host_usb_devices
-@subsection Using host USB devices on a Linux host
-
-WARNING: this is an experimental feature. QEMU will slow down when
-using it. USB devices requiring real time streaming (i.e. USB Video
-Cameras) are not supported yet.
-
-@enumerate
-@item If you use an early Linux 2.4 kernel, verify that no Linux driver
-is actually using the USB device. A simple way to do that is simply to
-disable the corresponding kernel module by renaming it from @file{mydriver.o}
-to @file{mydriver.o.disabled}.
-
-@item Verify that @file{/proc/bus/usb} is working (most Linux distributions should enable it by default). You should see something like that:
-@example
-ls /proc/bus/usb
-001  devices  drivers
-@end example
-
-@item Since only root can access to the USB devices directly, you can either launch QEMU as root or change the permissions of the USB devices you want to use. For testing, the following suffices:
-@example
-chown -R myuid /proc/bus/usb
-@end example
-
-@item Launch QEMU and do in the monitor:
-@example
-info usbhost
-  Device 1.2, speed 480 Mb/s
-    Class 00: USB device 1234:5678, USB DISK
-@end example
-You should see the list of the devices you can use (Never try to use
-hubs, it won't work).
-
-@item Add the device in QEMU by using:
-@example
-device_add usb-host,vendorid=0x1234,productid=0x5678
-@end example
-
-Normally the guest OS should report that a new USB device is plugged.
-You can use the option @option{-device usb-host,...} to do the same.
-
-@item Now you can try to use the host USB device in QEMU.
-
-@end enumerate
-
-When relaunching QEMU, you may have to unplug and plug again the USB
-device to make it work again (this is a bug).
-
-@node vnc_security
-@section VNC security
-
-The VNC server capability provides access to the graphical console
-of the guest VM across the network. This has a number of security
-considerations depending on the deployment scenarios.
-
-@menu
-* vnc_sec_none::
-* vnc_sec_password::
-* vnc_sec_certificate::
-* vnc_sec_certificate_verify::
-* vnc_sec_certificate_pw::
-* vnc_sec_sasl::
-* vnc_sec_certificate_sasl::
-* vnc_setup_sasl::
-@end menu
-@node vnc_sec_none
-@subsection Without passwords
-
-The simplest VNC server setup does not include any form of authentication.
-For this setup it is recommended to restrict it to listen on a UNIX domain
-socket only. For example
-
-@example
-@value{qemu_system} [...OPTIONS...] -vnc unix:/home/joebloggs/.qemu-myvm-vnc
-@end example
-
-This ensures that only users on local box with read/write access to that
-path can access the VNC server. To securely access the VNC server from a
-remote machine, a combination of netcat+ssh can be used to provide a secure
-tunnel.
-
-@node vnc_sec_password
-@subsection With passwords
-
-The VNC protocol has limited support for password based authentication. Since
-the protocol limits passwords to 8 characters it should not be considered
-to provide high security. The password can be fairly easily brute-forced by
-a client making repeat connections. For this reason, a VNC server using password
-authentication should be restricted to only listen on the loopback interface
-or UNIX domain sockets. Password authentication is not supported when operating
-in FIPS 140-2 compliance mode as it requires the use of the DES cipher. Password
-authentication is requested with the @code{password} option, and then once QEMU
-is running the password is set with the monitor. Until the monitor is used to
-set the password all clients will be rejected.
-
-@example
-@value{qemu_system} [...OPTIONS...] -vnc :1,password -monitor stdio
-(qemu) change vnc password
-Password: ********
-(qemu)
-@end example
-
-@node vnc_sec_certificate
-@subsection With x509 certificates
-
-The QEMU VNC server also implements the VeNCrypt extension allowing use of
-TLS for encryption of the session, and x509 certificates for authentication.
-The use of x509 certificates is strongly recommended, because TLS on its
-own is susceptible to man-in-the-middle attacks. Basic x509 certificate
-support provides a secure session, but no authentication. This allows any
-client to connect, and provides an encrypted session.
-
-@example
-@value{qemu_system} [...OPTIONS...] \
-  -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=no \
-  -vnc :1,tls-creds=tls0 -monitor stdio
-@end example
-
-In the above example @code{/etc/pki/qemu} should contain at least three files,
-@code{ca-cert.pem}, @code{server-cert.pem} and @code{server-key.pem}. Unprivileged
-users will want to use a private directory, for example @code{$HOME/.pki/qemu}.
-NB the @code{server-key.pem} file should be protected with file mode 0600 to
-only be readable by the user owning it.
-
-@node vnc_sec_certificate_verify
-@subsection With x509 certificates and client verification
-
-Certificates can also provide a means to authenticate the client connecting.
-The server will request that the client provide a certificate, which it will
-then validate against the CA certificate. This is a good choice if deploying
-in an environment with a private internal certificate authority. It uses the
-same syntax as previously, but with @code{verify-peer} set to @code{yes}
-instead.
-
-@example
-@value{qemu_system} [...OPTIONS...] \
-  -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
-  -vnc :1,tls-creds=tls0 -monitor stdio
-@end example
-
-
-@node vnc_sec_certificate_pw
-@subsection With x509 certificates, client verification and passwords
-
-Finally, the previous method can be combined with VNC password authentication
-to provide two layers of authentication for clients.
-
-@example
-@value{qemu_system} [...OPTIONS...] \
-  -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
-  -vnc :1,tls-creds=tls0,password -monitor stdio
-(qemu) change vnc password
-Password: ********
-(qemu)
-@end example
-
-
-@node vnc_sec_sasl
-@subsection With SASL authentication
-
-The SASL authentication method is a VNC extension, that provides an
-easily extendable, pluggable authentication method. This allows for
-integration with a wide range of authentication mechanisms, such as
-PAM, GSSAPI/Kerberos, LDAP, SQL databases, one-time keys and more.
-The strength of the authentication depends on the exact mechanism
-configured. If the chosen mechanism also provides a SSF layer, then
-it will encrypt the datastream as well.
-
-Refer to the later docs on how to choose the exact SASL mechanism
-used for authentication, but assuming use of one supporting SSF,
-then QEMU can be launched with:
-
-@example
-@value{qemu_system} [...OPTIONS...] -vnc :1,sasl -monitor stdio
-@end example
-
-@node vnc_sec_certificate_sasl
-@subsection With x509 certificates and SASL authentication
-
-If the desired SASL authentication mechanism does not supported
-SSF layers, then it is strongly advised to run it in combination
-with TLS and x509 certificates. This provides securely encrypted
-data stream, avoiding risk of compromising of the security
-credentials. This can be enabled, by combining the 'sasl' option
-with the aforementioned TLS + x509 options:
-
-@example
-@value{qemu_system} [...OPTIONS...] \
-  -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server,verify-peer=yes \
-  -vnc :1,tls-creds=tls0,sasl -monitor stdio
-@end example
-
-@node vnc_setup_sasl
-
-@subsection Configuring SASL mechanisms
-
-The following documentation assumes use of the Cyrus SASL implementation on a
-Linux host, but the principles should apply to any other SASL implementation
-or host. When SASL is enabled, the mechanism configuration will be loaded from
-system default SASL service config /etc/sasl2/qemu.conf. If running QEMU as an
-unprivileged user, an environment variable SASL_CONF_PATH can be used to make
-it search alternate locations for the service config file.
-
-If the TLS option is enabled for VNC, then it will provide session encryption,
-otherwise the SASL mechanism will have to provide encryption. In the latter
-case the list of possible plugins that can be used is drastically reduced. In
-fact only the GSSAPI SASL mechanism provides an acceptable level of security
-by modern standards. Previous versions of QEMU referred to the DIGEST-MD5
-mechanism, however, it has multiple serious flaws described in detail in
-RFC 6331 and thus should never be used any more. The SCRAM-SHA-1 mechanism
-provides a simple username/password auth facility similar to DIGEST-MD5, but
-does not support session encryption, so can only be used in combination with
-TLS.
-
-When not using TLS the recommended configuration is
-
-@example
-mech_list: gssapi
-keytab: /etc/qemu/krb5.tab
-@end example
-
-This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol, with
-the server principal stored in /etc/qemu/krb5.tab. For this to work the
-administrator of your KDC must generate a Kerberos principal for the server,
-with a name of 'qemu/somehost.example.com@@EXAMPLE.COM' replacing
-'somehost.example.com' with the fully qualified host name of the machine
-running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm.
-
-When using TLS, if username+password authentication is desired, then a
-reasonable configuration is
-
-@example
-mech_list: scram-sha-1
-sasldb_path: /etc/qemu/passwd.db
-@end example
-
-The @code{saslpasswd2} program can be used to populate the @code{passwd.db}
-file with accounts.
-
-Other SASL configurations will be left as an exercise for the reader. Note that
-all mechanisms, except GSSAPI, should be combined with use of TLS to ensure a
-secure data channel.
-
-
-@node network_tls
-@section TLS setup for network services
-
-Almost all network services in QEMU have the ability to use TLS for
-session data encryption, along with x509 certificates for simple
-client authentication. What follows is a description of how to
-generate certificates suitable for usage with QEMU, and applies to
-the VNC server, character devices with the TCP backend, NBD server
-and client, and migration server and client.
-
-At a high level, QEMU requires certificates and private keys to be
-provided in PEM format. Aside from the core fields, the certificates
-should include various extension data sets, including v3 basic
-constraints data, key purpose, key usage and subject alt name.
-
-The GnuTLS package includes a command called @code{certtool} which can
-be used to easily generate certificates and keys in the required format
-with expected data present. Alternatively a certificate management
-service may be used.
-
-At a minimum it is necessary to setup a certificate authority, and
-issue certificates to each server. If using x509 certificates for
-authentication, then each client will also need to be issued a
-certificate.
-
-Assuming that the QEMU network services will only ever be exposed to
-clients on a private intranet, there is no need to use a commercial
-certificate authority to create certificates. A self-signed CA is
-sufficient, and in fact likely to be more secure since it removes
-the ability of malicious 3rd parties to trick the CA into mis-issuing
-certs for impersonating your services. The only likely exception
-where a commercial CA might be desirable is if enabling the VNC
-websockets server and exposing it directly to remote browser clients.
-In such a case it might be useful to use a commercial CA to avoid
-needing to install custom CA certs in the web browsers.
-
-The recommendation is for the server to keep its certificates in either
-@code{/etc/pki/qemu} or for unprivileged users in @code{$HOME/.pki/qemu}.
-
-@menu
-* tls_generate_ca::
-* tls_generate_server::
-* tls_generate_client::
-* tls_creds_setup::
-* tls_psk::
-@end menu
-@node tls_generate_ca
-@subsection Setup the Certificate Authority
-
-This step only needs to be performed once per organization / organizational
-unit. First the CA needs a private key. This key must be kept VERY secret
-and secure. If this key is compromised the entire trust chain of the certificates
-issued with it is lost.
-
-@example
-# certtool --generate-privkey > ca-key.pem
-@end example
-
-To generate a self-signed certificate requires one core piece of information,
-the name of the organization. A template file @code{ca.info} should be
-populated with the desired data to avoid having to deal with interactive
-prompts from certtool:
-@example
-# cat > ca.info <<EOF
-cn = Name of your organization
-ca
-cert_signing_key
-EOF
-# certtool --generate-self-signed \
-           --load-privkey ca-key.pem
-           --template ca.info \
-           --outfile ca-cert.pem
-@end example
-
-The @code{ca} keyword in the template sets the v3 basic constraints extension
-to indicate this certificate is for a CA, while @code{cert_signing_key} sets
-the key usage extension to indicate this will be used for signing other keys.
-The generated @code{ca-cert.pem} file should be copied to all servers and
-clients wishing to utilize TLS support in the VNC server. The @code{ca-key.pem}
-must not be disclosed/copied anywhere except the host responsible for issuing
-certificates.
-
-@node tls_generate_server
-@subsection Issuing server certificates
-
-Each server (or host) needs to be issued with a key and certificate. When connecting
-the certificate is sent to the client which validates it against the CA certificate.
-The core pieces of information for a server certificate are the hostnames and/or IP
-addresses that will be used by clients when connecting. The hostname / IP address
-that the client specifies when connecting will be validated against the hostname(s)
-and IP address(es) recorded in the server certificate, and if no match is found
-the client will close the connection.
-
-Thus it is recommended that the server certificate include both the fully qualified
-and unqualified hostnames. If the server will have permanently assigned IP address(es),
-and clients are likely to use them when connecting, they may also be included in the
-certificate. Both IPv4 and IPv6 addresses are supported. Historically certificates
-only included 1 hostname in the @code{CN} field, however, usage of this field for
-validation is now deprecated. Instead modern TLS clients will validate against the
-Subject Alt Name extension data, which allows for multiple entries. In the future
-usage of the @code{CN} field may be discontinued entirely, so providing SAN
-extension data is strongly recommended.
-
-On the host holding the CA, create template files containing the information
-for each server, and use it to issue server certificates.
-
-@example
-# cat > server-hostNNN.info <<EOF
-organization = Name  of your organization
-cn = hostNNN.foo.example.com
-dns_name = hostNNN
-dns_name = hostNNN.foo.example.com
-ip_address = 10.0.1.87
-ip_address = 192.8.0.92
-ip_address = 2620:0:cafe::87
-ip_address = 2001:24::92
-tls_www_server
-encryption_key
-signing_key
-EOF
-# certtool --generate-privkey > server-hostNNN-key.pem
-# certtool --generate-certificate \
-           --load-ca-certificate ca-cert.pem \
-           --load-ca-privkey ca-key.pem \
-           --load-privkey server-hostNNN-key.pem \
-           --template server-hostNNN.info \
-           --outfile server-hostNNN-cert.pem
-@end example
-
-The @code{dns_name} and @code{ip_address} fields in the template are setting
-the subject alt name extension data. The @code{tls_www_server} keyword is the
-key purpose extension to indicate this certificate is intended for usage in
-a web server. Although QEMU network services are not in fact HTTP servers
-(except for VNC websockets), setting this key purpose is still recommended.
-The @code{encryption_key} and @code{signing_key} keyword is the key usage
-extension to indicate this certificate is intended for usage in the data
-session.
-
-The @code{server-hostNNN-key.pem} and @code{server-hostNNN-cert.pem} files
-should now be securely copied to the server for which they were generated,
-and renamed to @code{server-key.pem} and @code{server-cert.pem} when added
-to the @code{/etc/pki/qemu} directory on the target host. The @code{server-key.pem}
-file is security sensitive and should be kept protected with file mode 0600
-to prevent disclosure.
-
-@node tls_generate_client
-@subsection Issuing client certificates
-
-The QEMU x509 TLS credential setup defaults to enabling client verification
-using certificates, providing a simple authentication mechanism. If this
-default is used, each client also needs to be issued a certificate. The client
-certificate contains enough metadata to uniquely identify the client with the
-scope of the certificate authority. The client certificate would typically
-include fields for organization, state, city, building, etc.
-
-Once again on the host holding the CA, create template files containing the
-information for each client, and use it to issue client certificates.
-
-
-@example
-# cat > client-hostNNN.info <<EOF
-country = GB
-state = London
-locality = City Of London
-organization = Name of your organization
-cn = hostNNN.foo.example.com
-tls_www_client
-encryption_key
-signing_key
-EOF
-# certtool --generate-privkey > client-hostNNN-key.pem
-# certtool --generate-certificate \
-           --load-ca-certificate ca-cert.pem \
-           --load-ca-privkey ca-key.pem \
-           --load-privkey client-hostNNN-key.pem \
-           --template client-hostNNN.info \
-           --outfile client-hostNNN-cert.pem
-@end example
-
-The subject alt name extension data is not required for clients, so the
-the @code{dns_name} and @code{ip_address} fields are not included.
-The @code{tls_www_client} keyword is the key purpose extension to indicate
-this certificate is intended for usage in a web client. Although QEMU
-network clients are not in fact HTTP clients, setting this key purpose is
-still recommended. The @code{encryption_key} and @code{signing_key} keyword
-is the key usage extension to indicate this certificate is intended for
-usage in the data session.
-
-The @code{client-hostNNN-key.pem} and @code{client-hostNNN-cert.pem} files
-should now be securely copied to the client for which they were generated,
-and renamed to @code{client-key.pem} and @code{client-cert.pem} when added
-to the @code{/etc/pki/qemu} directory on the target host. The @code{client-key.pem}
-file is security sensitive and should be kept protected with file mode 0600
-to prevent disclosure.
-
-If a single host is going to be using TLS in both a client and server
-role, it is possible to create a single certificate to cover both roles.
-This would be quite common for the migration and NBD services, where a
-QEMU process will be started by accepting a TLS protected incoming migration,
-and later itself be migrated out to another host. To generate a single
-certificate, simply include the template data from both the client and server
-instructions in one.
-
-@example
-# cat > both-hostNNN.info <<EOF
-country = GB
-state = London
-locality = City Of London
-organization = Name of your organization
-cn = hostNNN.foo.example.com
-dns_name = hostNNN
-dns_name = hostNNN.foo.example.com
-ip_address = 10.0.1.87
-ip_address = 192.8.0.92
-ip_address = 2620:0:cafe::87
-ip_address = 2001:24::92
-tls_www_server
-tls_www_client
-encryption_key
-signing_key
-EOF
-# certtool --generate-privkey > both-hostNNN-key.pem
-# certtool --generate-certificate \
-           --load-ca-certificate ca-cert.pem \
-           --load-ca-privkey ca-key.pem \
-           --load-privkey both-hostNNN-key.pem \
-           --template both-hostNNN.info \
-           --outfile both-hostNNN-cert.pem
-@end example
-
-When copying the PEM files to the target host, save them twice,
-once as @code{server-cert.pem} and @code{server-key.pem}, and
-again as @code{client-cert.pem} and @code{client-key.pem}.
-
-@node tls_creds_setup
-@subsection TLS x509 credential configuration
-
-QEMU has a standard mechanism for loading x509 credentials that will be
-used for network services and clients. It requires specifying the
-@code{tls-creds-x509} class name to the @code{--object} command line
-argument for the system emulators.  Each set of credentials loaded should
-be given a unique string identifier via the @code{id} parameter. A single
-set of TLS credentials can be used for multiple network backends, so VNC,
-migration, NBD, character devices can all share the same credentials. Note,
-however, that credentials for use in a client endpoint must be loaded
-separately from those used in a server endpoint.
-
-When specifying the object, the @code{dir} parameters specifies which
-directory contains the credential files. This directory is expected to
-contain files with the names mentioned previously, @code{ca-cert.pem},
-@code{server-key.pem}, @code{server-cert.pem}, @code{client-key.pem}
-and @code{client-cert.pem} as appropriate. It is also possible to
-include a set of pre-generated Diffie-Hellman (DH) parameters in a file
-@code{dh-params.pem}, which can be created using the
-@code{certtool --generate-dh-params} command. If omitted, QEMU will
-dynamically generate DH parameters when loading the credentials.
-
-The @code{endpoint} parameter indicates whether the credentials will
-be used for a network client or server, and determines which PEM
-files are loaded.
-
-The @code{verify} parameter determines whether x509 certificate
-validation should be performed. This defaults to enabled, meaning
-clients will always validate the server hostname against the
-certificate subject alt name fields and/or CN field. It also
-means that servers will request that clients provide a certificate
-and validate them. Verification should never be turned off for
-client endpoints, however, it may be turned off for server endpoints
-if an alternative mechanism is used to authenticate clients. For
-example, the VNC server can use SASL to authenticate clients
-instead.
-
-To load server credentials with client certificate validation
-enabled
-
-@example
-@value{qemu_system} -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server
-@end example
-
-while to load client credentials use
-
-@example
-@value{qemu_system} -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=client
-@end example
-
-Network services which support TLS will all have a @code{tls-creds}
-parameter which expects the ID of the TLS credentials object. For
-example with VNC:
-
-@example
-@value{qemu_system} -vnc 0.0.0.0:0,tls-creds=tls0
-@end example
-
-@node tls_psk
-@subsection TLS Pre-Shared Keys (PSK)
-
-Instead of using certificates, you may also use TLS Pre-Shared Keys
-(TLS-PSK).  This can be simpler to set up than certificates but is
-less scalable.
-
-Use the GnuTLS @code{psktool} program to generate a @code{keys.psk}
-file containing one or more usernames and random keys:
-
-@example
-mkdir -m 0700 /tmp/keys
-psktool -u rich -p /tmp/keys/keys.psk
-@end example
-
-TLS-enabled servers such as qemu-nbd can use this directory like so:
-
-@example
-qemu-nbd \
-  -t -x / \
-  --object tls-creds-psk,id=tls0,endpoint=server,dir=/tmp/keys \
-  --tls-creds tls0 \
-  image.qcow2
-@end example
-
-When connecting from a qemu-based client you must specify the
-directory containing @code{keys.psk} and an optional @var{username}
-(defaults to ``qemu''):
-
-@example
-qemu-img info \
-  --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=rich,endpoint=client \
-  --image-opts \
-  file.driver=nbd,file.host=localhost,file.port=10809,file.tls-creds=tls0,file.export=/
-@end example
-
-@node gdb_usage
-@section GDB usage
-
-QEMU has a primitive support to work with gdb, so that you can do
-'Ctrl-C' while the virtual machine is running and inspect its state.
-
-In order to use gdb, launch QEMU with the '-s' option. It will wait for a
-gdb connection:
-@example
-@value{qemu_system} -s -kernel bzImage -hda rootdisk.img -append "root=/dev/hda"
-Connected to host network interface: tun0
-Waiting gdb connection on port 1234
-@end example
-
-Then launch gdb on the 'vmlinux' executable:
-@example
-> gdb vmlinux
-@end example
-
-In gdb, connect to QEMU:
-@example
-(gdb) target remote localhost:1234
-@end example
-
-Then you can use gdb normally. For example, type 'c' to launch the kernel:
-@example
-(gdb) c
-@end example
-
-Here are some useful tips in order to use gdb on system code:
-
-@enumerate
-@item
-Use @code{info reg} to display all the CPU registers.
-@item
-Use @code{x/10i $eip} to display the code at the PC position.
-@item
-Use @code{set architecture i8086} to dump 16 bit code. Then use
-@code{x/10i $cs*16+$eip} to dump the code at the PC position.
-@end enumerate
-
-Advanced debugging options:
-
-The default single stepping behavior is step with the IRQs and timer service routines off.  It is set this way because when gdb executes a single step it expects to advance beyond the current instruction.  With the IRQs and timer service routines on, a single step might jump into the one of the interrupt or exception vectors instead of executing the current instruction. This means you may hit the same breakpoint a number of times before executing the instruction gdb wants to have executed.  Because there are rare circumstances where you want to single step into an interrupt vector the behavior can be controlled from GDB.  There are three commands you can query and set the single step behavior:
-@table @code
-@item maintenance packet qqemu.sstepbits
-
-This will display the MASK bits used to control the single stepping IE:
-@example
-(gdb) maintenance packet qqemu.sstepbits
-sending: "qqemu.sstepbits"
-received: "ENABLE=1,NOIRQ=2,NOTIMER=4"
-@end example
-@item maintenance packet qqemu.sstep
-
-This will display the current value of the mask used when single stepping IE:
-@example
-(gdb) maintenance packet qqemu.sstep
-sending: "qqemu.sstep"
-received: "0x7"
-@end example
-@item maintenance packet Qqemu.sstep=HEX_VALUE
-
-This will change the single step mask, so if wanted to enable IRQs on the single step, but not timers, you would use:
-@example
-(gdb) maintenance packet Qqemu.sstep=0x5
-sending: "qemu.sstep=0x5"
-received: "OK"
-@end example
-@end table
-
-@node pcsys_os_specific
-@section Target OS specific information
-
-@subsection Linux
-
-To have access to SVGA graphic modes under X11, use the @code{vesa} or
-the @code{cirrus} X11 driver. For optimal performances, use 16 bit
-color depth in the guest and the host OS.
-
-When using a 2.6 guest Linux kernel, you should add the option
-@code{clock=pit} on the kernel command line because the 2.6 Linux
-kernels make very strict real time clock checks by default that QEMU
-cannot simulate exactly.
-
-When using a 2.6 guest Linux kernel, verify that the 4G/4G patch is
-not activated because QEMU is slower with this patch. The QEMU
-Accelerator Module is also much slower in this case. Earlier Fedora
-Core 3 Linux kernel (< 2.6.9-1.724_FC3) were known to incorporate this
-patch by default. Newer kernels don't have it.
-
-@subsection Windows
-
-If you have a slow host, using Windows 95 is better as it gives the
-best speed. Windows 2000 is also a good choice.
-
-@subsubsection SVGA graphic modes support
-
-QEMU emulates a Cirrus Logic GD5446 Video
-card. All Windows versions starting from Windows 95 should recognize
-and use this graphic card. For optimal performances, use 16 bit color
-depth in the guest and the host OS.
-
-If you are using Windows XP as guest OS and if you want to use high
-resolution modes which the Cirrus Logic BIOS does not support (i.e. >=
-1280x1024x16), then you should use the VESA VBE virtual graphic card
-(option @option{-std-vga}).
-
-@subsubsection CPU usage reduction
-
-Windows 9x does not correctly use the CPU HLT
-instruction. The result is that it takes host CPU cycles even when
-idle. You can install the utility from
-@url{https://web.archive.org/web/20060212132151/http://www.user.cityline.ru/~maxamn/amnhltm.zip}
-to solve this problem. Note that no such tool is needed for NT, 2000 or XP.
-
-@subsubsection Windows 2000 disk full problem
-
-Windows 2000 has a bug which gives a disk full problem during its
-installation. When installing it, use the @option{-win2k-hack} QEMU
-option to enable a specific workaround. After Windows 2000 is
-installed, you no longer need this option (this option slows down the
-IDE transfers).
-
-@subsubsection Windows 2000 shutdown
-
-Windows 2000 cannot automatically shutdown in QEMU although Windows 98
-can. It comes from the fact that Windows 2000 does not automatically
-use the APM driver provided by the BIOS.
-
-In order to correct that, do the following (thanks to Struan
-Bartlett): go to the Control Panel => Add/Remove Hardware & Next =>
-Add/Troubleshoot a device => Add a new device & Next => No, select the
-hardware from a list & Next => NT Apm/Legacy Support & Next => Next
-(again) a few times. Now the driver is installed and Windows 2000 now
-correctly instructs QEMU to shutdown at the appropriate moment.
-
-@subsubsection Share a directory between Unix and Windows
-
-See @ref{sec_invocation} about the help of the option
-@option{'-netdev user,smb=...'}.
-
-@subsubsection Windows XP security problem
-
-Some releases of Windows XP install correctly but give a security
-error when booting:
-@example
-A problem is preventing Windows from accurately checking the
-license for this computer. Error code: 0x800703e6.
-@end example
-
-The workaround is to install a service pack for XP after a boot in safe
-mode. Then reboot, and the problem should go away. Since there is no
-network while in safe mode, its recommended to download the full
-installation of SP1 or SP2 and transfer that via an ISO or using the
-vvfat block device ("-hdb fat:directory_which_holds_the_SP").
-
-@subsection MS-DOS and FreeDOS
-
-@subsubsection CPU usage reduction
-
-DOS does not correctly use the CPU HLT instruction. The result is that
-it takes host CPU cycles even when idle. You can install the utility from
-@url{https://web.archive.org/web/20051222085335/http://www.vmware.com/software/dosidle210.zip}
-to solve this problem.
-
-@node QEMU System emulator for non PC targets
-@chapter QEMU System emulator for non PC targets
-
-QEMU is a generic emulator and it emulates many non PC
-machines. Most of the options are similar to the PC emulator. The
-differences are mentioned in the following sections.
-
-@menu
-* PowerPC System emulator::
-* Sparc32 System emulator::
-* Sparc64 System emulator::
-* MIPS System emulator::
-* ARM System emulator::
-* ColdFire System emulator::
-* Cris System emulator::
-* Microblaze System emulator::
-* SH4 System emulator::
-* Xtensa System emulator::
-@end menu
-
-@node PowerPC System emulator
-@section PowerPC System emulator
-@cindex system emulation (PowerPC)
-
-Use the executable @file{qemu-system-ppc} to simulate a complete 40P (PREP)
-or PowerMac PowerPC system.
-
-QEMU emulates the following PowerMac peripherals:
-
-@itemize @minus
-@item
-UniNorth or Grackle PCI Bridge
-@item
-PCI VGA compatible card with VESA Bochs Extensions
-@item
-2 PMAC IDE interfaces with hard disk and CD-ROM support
-@item
-NE2000 PCI adapters
-@item
-Non Volatile RAM
-@item
-VIA-CUDA with ADB keyboard and mouse.
-@end itemize
-
-QEMU emulates the following 40P (PREP) peripherals:
-
-@itemize @minus
-@item
-PCI Bridge
-@item
-PCI VGA compatible card with VESA Bochs Extensions
-@item
-2 IDE interfaces with hard disk and CD-ROM support
-@item
-Floppy disk
-@item
-PCnet network adapters
-@item
-Serial port
-@item
-PREP Non Volatile RAM
-@item
-PC compatible keyboard and mouse.
-@end itemize
-
-Since version 0.9.1, QEMU uses OpenBIOS @url{https://www.openbios.org/}
-for the g3beige and mac99 PowerMac and the 40p machines. OpenBIOS is a free
-(GPL v2) portable firmware implementation. The goal is to implement a 100%
-IEEE 1275-1994 (referred to as Open Firmware) compliant firmware.
-
-@c man begin OPTIONS
-
-The following options are specific to the PowerPC emulation:
-
-@table @option
-
-@item -g @var{W}x@var{H}[x@var{DEPTH}]
-
-Set the initial VGA graphic mode. The default is 800x600x32.
-
-@item -prom-env @var{string}
-
-Set OpenBIOS variables in NVRAM, for example:
-
-@example
-qemu-system-ppc -prom-env 'auto-boot?=false' \
- -prom-env 'boot-device=hd:2,\yaboot' \
- -prom-env 'boot-args=conf=hd:2,\yaboot.conf'
-@end example
-
-@end table
-
-@c man end
-
-
-More information is available at
-@url{http://perso.magic.fr/l_indien/qemu-ppc/}.
-
-@node Sparc32 System emulator
-@section Sparc32 System emulator
-@cindex system emulation (Sparc32)
-
-Use the executable @file{qemu-system-sparc} to simulate the following
-Sun4m architecture machines:
-@itemize @minus
-@item
-SPARCstation 4
-@item
-SPARCstation 5
-@item
-SPARCstation 10
-@item
-SPARCstation 20
-@item
-SPARCserver 600MP
-@item
-SPARCstation LX
-@item
-SPARCstation Voyager
-@item
-SPARCclassic
-@item
-SPARCbook
-@end itemize
-
-The emulation is somewhat complete. SMP up to 16 CPUs is supported,
-but Linux limits the number of usable CPUs to 4.
-
-QEMU emulates the following sun4m peripherals:
-
-@itemize @minus
-@item
-IOMMU
-@item
-TCX or cgthree Frame buffer
-@item
-Lance (Am7990) Ethernet
-@item
-Non Volatile RAM M48T02/M48T08
-@item
-Slave I/O: timers, interrupt controllers, Zilog serial ports, keyboard
-and power/reset logic
-@item
-ESP SCSI controller with hard disk and CD-ROM support
-@item
-Floppy drive (not on SS-600MP)
-@item
-CS4231 sound device (only on SS-5, not working yet)
-@end itemize
-
-The number of peripherals is fixed in the architecture.  Maximum
-memory size depends on the machine type, for SS-5 it is 256MB and for
-others 2047MB.
-
-Since version 0.8.2, QEMU uses OpenBIOS
-@url{https://www.openbios.org/}. OpenBIOS is a free (GPL v2) portable
-firmware implementation. The goal is to implement a 100% IEEE
-1275-1994 (referred to as Open Firmware) compliant firmware.
-
-A sample Linux 2.6 series kernel and ram disk image are available on
-the QEMU web site. There are still issues with NetBSD and OpenBSD, but
-most kernel versions work. Please note that currently older Solaris kernels
-don't work probably due to interface issues between OpenBIOS and
-Solaris.
-
-@c man begin OPTIONS
-
-The following options are specific to the Sparc32 emulation:
-
-@table @option
-
-@item -g @var{W}x@var{H}x[x@var{DEPTH}]
-
-Set the initial graphics mode. For TCX, the default is 1024x768x8 with the
-option of 1024x768x24. For cgthree, the default is 1024x768x8 with the option
-of 1152x900x8 for people who wish to use OBP.
-
-@item -prom-env @var{string}
-
-Set OpenBIOS variables in NVRAM, for example:
-
-@example
-qemu-system-sparc -prom-env 'auto-boot?=false' \
- -prom-env 'boot-device=sd(0,2,0):d' -prom-env 'boot-args=linux single'
-@end example
-
-@item -M [SS-4|SS-5|SS-10|SS-20|SS-600MP|LX|Voyager|SPARCClassic] [|SPARCbook]
-
-Set the emulated machine type. Default is SS-5.
-
-@end table
-
-@c man end
-
-@node Sparc64 System emulator
-@section Sparc64 System emulator
-@cindex system emulation (Sparc64)
-
-Use the executable @file{qemu-system-sparc64} to simulate a Sun4u
-(UltraSPARC PC-like machine), Sun4v (T1 PC-like machine), or generic
-Niagara (T1) machine. The Sun4u emulator is mostly complete, being
-able to run Linux, NetBSD and OpenBSD in headless (-nographic) mode. The
-Sun4v emulator is still a work in progress.
-
-The Niagara T1 emulator makes use of firmware and OS binaries supplied in the S10image/ directory
-of the OpenSPARC T1 project @url{http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2}
-and is able to boot the disk.s10hw2 Solaris image.
-@example
-qemu-system-sparc64 -M niagara -L /path-to/S10image/ \
-                    -nographic -m 256 \
-                    -drive if=pflash,readonly=on,file=/S10image/disk.s10hw2
-@end example
-
-
-QEMU emulates the following peripherals:
-
-@itemize @minus
-@item
-UltraSparc IIi APB PCI Bridge
-@item
-PCI VGA compatible card with VESA Bochs Extensions
-@item
-PS/2 mouse and keyboard
-@item
-Non Volatile RAM M48T59
-@item
-PC-compatible serial ports
-@item
-2 PCI IDE interfaces with hard disk and CD-ROM support
-@item
-Floppy disk
-@end itemize
-
-@c man begin OPTIONS
-
-The following options are specific to the Sparc64 emulation:
-
-@table @option
-
-@item -prom-env @var{string}
-
-Set OpenBIOS variables in NVRAM, for example:
-
-@example
-qemu-system-sparc64 -prom-env 'auto-boot?=false'
-@end example
-
-@item -M [sun4u|sun4v|niagara]
-
-Set the emulated machine type. The default is sun4u.
-
-@end table
-
-@c man end
-
-@node MIPS System emulator
-@section MIPS System emulator
-@cindex system emulation (MIPS)
-
-@menu
-* nanoMIPS System emulator ::
-@end menu
-
-Four executables cover simulation of 32 and 64-bit MIPS systems in
-both endian options, @file{qemu-system-mips}, @file{qemu-system-mipsel}
-@file{qemu-system-mips64} and @file{qemu-system-mips64el}.
-Five different machine types are emulated:
-
-@itemize @minus
-@item
-A generic ISA PC-like machine "mips"
-@item
-The MIPS Malta prototype board "malta"
-@item
-An ACER Pica "pica61". This machine needs the 64-bit emulator.
-@item
-MIPS emulator pseudo board "mipssim"
-@item
-A MIPS Magnum R4000 machine "magnum". This machine needs the 64-bit emulator.
-@end itemize
-
-The generic emulation is supported by Debian 'Etch' and is able to
-install Debian into a virtual disk image. The following devices are
-emulated:
-
-@itemize @minus
-@item
-A range of MIPS CPUs, default is the 24Kf
-@item
-PC style serial port
-@item
-PC style IDE disk
-@item
-NE2000 network card
-@end itemize
-
-The Malta emulation supports the following devices:
-
-@itemize @minus
-@item
-Core board with MIPS 24Kf CPU and Galileo system controller
-@item
-PIIX4 PCI/USB/SMbus controller
-@item
-The Multi-I/O chip's serial device
-@item
-PCI network cards (PCnet32 and others)
-@item
-Malta FPGA serial device
-@item
-Cirrus (default) or any other PCI VGA graphics card
-@end itemize
-
-The Boston board emulation supports the following devices:
-
-@itemize @minus
-@item
-Xilinx FPGA, which includes a PCIe root port and an UART
-@item
-Intel EG20T PCH connects the I/O peripherals, but only the SATA bus is emulated
-@end itemize
-
-The ACER Pica emulation supports:
-
-@itemize @minus
-@item
-MIPS R4000 CPU
-@item
-PC-style IRQ and DMA controllers
-@item
-PC Keyboard
-@item
-IDE controller
-@end itemize
-
-The MIPS Magnum R4000 emulation supports:
-
-@itemize @minus
-@item
-MIPS R4000 CPU
-@item
-PC-style IRQ controller
-@item
-PC Keyboard
-@item
-SCSI controller
-@item
-G364 framebuffer
-@end itemize
-
-The Fulong 2E emulation supports:
-
-@itemize @minus
-@item
-Loongson 2E CPU
-@item
-Bonito64 system controller as North Bridge
-@item
-VT82C686 chipset as South Bridge
-@item
-RTL8139D as a network card chipset
-@end itemize
-
-The mipssim pseudo board emulation provides an environment similar
-to what the proprietary MIPS emulator uses for running Linux.
-It supports:
-
-@itemize @minus
-@item
-A range of MIPS CPUs, default is the 24Kf
-@item
-PC style serial port
-@item
-MIPSnet network emulation
-@end itemize
-
-@node nanoMIPS System emulator
-@subsection nanoMIPS System emulator
-@cindex system emulation (nanoMIPS)
-
-Executable @file{qemu-system-mipsel} also covers simulation of
-32-bit nanoMIPS system in little endian mode:
-
-@itemize @minus
-@item
-nanoMIPS I7200 CPU
-@end itemize
-
-Example of @file{qemu-system-mipsel} usage for nanoMIPS is shown below:
-
-Download @code{<disk_image_file>} from @url{https://mipsdistros.mips.com/LinuxDistro/nanomips/buildroot/index.html}.
-
-Download @code{<kernel_image_file>} from @url{https://mipsdistros.mips.com/LinuxDistro/nanomips/kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/index.html}.
-
-Start system emulation of Malta board with nanoMIPS I7200 CPU:
-@example
-qemu-system-mipsel -cpu I7200 -kernel @code{<kernel_image_file>} \
-    -M malta -serial stdio -m @code{<memory_size>} -hda @code{<disk_image_file>} \
-    -append "mem=256m@@0x0 rw console=ttyS0 vga=cirrus vesa=0x111 root=/dev/sda"
-@end example
-
-
-@node ARM System emulator
-@section ARM System emulator
-@cindex system emulation (ARM)
-
-Use the executable @file{qemu-system-arm} to simulate a ARM
-machine. The ARM Integrator/CP board is emulated with the following
-devices:
-
-@itemize @minus
-@item
-ARM926E, ARM1026E, ARM946E, ARM1136 or Cortex-A8 CPU
-@item
-Two PL011 UARTs
-@item
-SMC 91c111 Ethernet adapter
-@item
-PL110 LCD controller
-@item
-PL050 KMI with PS/2 keyboard and mouse.
-@item
-PL181 MultiMedia Card Interface with SD card.
-@end itemize
-
-The ARM Versatile baseboard is emulated with the following devices:
-
-@itemize @minus
-@item
-ARM926E, ARM1136 or Cortex-A8 CPU
-@item
-PL190 Vectored Interrupt Controller
-@item
-Four PL011 UARTs
-@item
-SMC 91c111 Ethernet adapter
-@item
-PL110 LCD controller
-@item
-PL050 KMI with PS/2 keyboard and mouse.
-@item
-PCI host bridge.  Note the emulated PCI bridge only provides access to
-PCI memory space.  It does not provide access to PCI IO space.
-This means some devices (eg. ne2k_pci NIC) are not usable, and others
-(eg. rtl8139 NIC) are only usable when the guest drivers use the memory
-mapped control registers.
-@item
-PCI OHCI USB controller.
-@item
-LSI53C895A PCI SCSI Host Bus Adapter with hard disk and CD-ROM devices.
-@item
-PL181 MultiMedia Card Interface with SD card.
-@end itemize
-
-Several variants of the ARM RealView baseboard are emulated,
-including the EB, PB-A8 and PBX-A9.  Due to interactions with the
-bootloader, only certain Linux kernel configurations work out
-of the box on these boards.
-
-Kernels for the PB-A8 board should have CONFIG_REALVIEW_HIGH_PHYS_OFFSET
-enabled in the kernel, and expect 512M RAM.  Kernels for The PBX-A9 board
-should have CONFIG_SPARSEMEM enabled, CONFIG_REALVIEW_HIGH_PHYS_OFFSET
-disabled and expect 1024M RAM.
-
-The following devices are emulated:
-
-@itemize @minus
-@item
-ARM926E, ARM1136, ARM11MPCore, Cortex-A8 or Cortex-A9 MPCore CPU
-@item
-ARM AMBA Generic/Distributed Interrupt Controller
-@item
-Four PL011 UARTs
-@item
-SMC 91c111 or SMSC LAN9118 Ethernet adapter
-@item
-PL110 LCD controller
-@item
-PL050 KMI with PS/2 keyboard and mouse
-@item
-PCI host bridge
-@item
-PCI OHCI USB controller
-@item
-LSI53C895A PCI SCSI Host Bus Adapter with hard disk and CD-ROM devices
-@item
-PL181 MultiMedia Card Interface with SD card.
-@end itemize
-
-The XScale-based clamshell PDA models ("Spitz", "Akita", "Borzoi"
-and "Terrier") emulation includes the following peripherals:
-
-@itemize @minus
-@item
-Intel PXA270 System-on-chip (ARM V5TE core)
-@item
-NAND Flash memory
-@item
-IBM/Hitachi DSCM microdrive in a PXA PCMCIA slot - not in "Akita"
-@item
-On-chip OHCI USB controller
-@item
-On-chip LCD controller
-@item
-On-chip Real Time Clock
-@item
-TI ADS7846 touchscreen controller on SSP bus
-@item
-Maxim MAX1111 analog-digital converter on I@math{^2}C bus
-@item
-GPIO-connected keyboard controller and LEDs
-@item
-Secure Digital card connected to PXA MMC/SD host
-@item
-Three on-chip UARTs
-@item
-WM8750 audio CODEC on I@math{^2}C and I@math{^2}S busses
-@end itemize
-
-The Palm Tungsten|E PDA (codename "Cheetah") emulation includes the
-following elements:
-
-@itemize @minus
-@item
-Texas Instruments OMAP310 System-on-chip (ARM 925T core)
-@item
-ROM and RAM memories (ROM firmware image can be loaded with -option-rom)
-@item
-On-chip LCD controller
-@item
-On-chip Real Time Clock
-@item
-TI TSC2102i touchscreen controller / analog-digital converter / Audio
-CODEC, connected through MicroWire and I@math{^2}S busses
-@item
-GPIO-connected matrix keypad
-@item
-Secure Digital card connected to OMAP MMC/SD host
-@item
-Three on-chip UARTs
-@end itemize
-
-Nokia N800 and N810 internet tablets (known also as RX-34 and RX-44 / 48)
-emulation supports the following elements:
-
-@itemize @minus
-@item
-Texas Instruments OMAP2420 System-on-chip (ARM 1136 core)
-@item
-RAM and non-volatile OneNAND Flash memories
-@item
-Display connected to EPSON remote framebuffer chip and OMAP on-chip
-display controller and a LS041y3 MIPI DBI-C controller
-@item
-TI TSC2301 (in N800) and TI TSC2005 (in N810) touchscreen controllers
-driven through SPI bus
-@item
-National Semiconductor LM8323-controlled qwerty keyboard driven
-through I@math{^2}C bus
-@item
-Secure Digital card connected to OMAP MMC/SD host
-@item
-Three OMAP on-chip UARTs and on-chip STI debugging console
-@item
-Mentor Graphics "Inventra" dual-role USB controller embedded in a TI
-TUSB6010 chip - only USB host mode is supported
-@item
-TI TMP105 temperature sensor driven through I@math{^2}C bus
-@item
-TI TWL92230C power management companion with an RTC on I@math{^2}C bus
-@item
-Nokia RETU and TAHVO multi-purpose chips with an RTC, connected
-through CBUS
-@end itemize
-
-The Luminary Micro Stellaris LM3S811EVB emulation includes the following
-devices:
-
-@itemize @minus
-@item
-Cortex-M3 CPU core.
-@item
-64k Flash and 8k SRAM.
-@item
-Timers, UARTs, ADC and I@math{^2}C interface.
-@item
-OSRAM Pictiva 96x16 OLED with SSD0303 controller on I@math{^2}C bus.
-@end itemize
-
-The Luminary Micro Stellaris LM3S6965EVB emulation includes the following
-devices:
-
-@itemize @minus
-@item
-Cortex-M3 CPU core.
-@item
-256k Flash and 64k SRAM.
-@item
-Timers, UARTs, ADC, I@math{^2}C and SSI interfaces.
-@item
-OSRAM Pictiva 128x64 OLED with SSD0323 controller connected via SSI.
-@end itemize
-
-The Freecom MusicPal internet radio emulation includes the following
-elements:
-
-@itemize @minus
-@item
-Marvell MV88W8618 ARM core.
-@item
-32 MB RAM, 256 KB SRAM, 8 MB flash.
-@item
-Up to 2 16550 UARTs
-@item
-MV88W8xx8 Ethernet controller
-@item
-MV88W8618 audio controller, WM8750 CODEC and mixer
-@item
-128×64 display with brightness control
-@item
-2 buttons, 2 navigation wheels with button function
-@end itemize
-
-The Siemens SX1 models v1 and v2 (default) basic emulation.
-The emulation includes the following elements:
-
-@itemize @minus
-@item
-Texas Instruments OMAP310 System-on-chip (ARM 925T core)
-@item
-ROM and RAM memories (ROM firmware image can be loaded with -pflash)
-V1
-1 Flash of 16MB and 1 Flash of 8MB
-V2
-1 Flash of 32MB
-@item
-On-chip LCD controller
-@item
-On-chip Real Time Clock
-@item
-Secure Digital card connected to OMAP MMC/SD host
-@item
-Three on-chip UARTs
-@end itemize
-
-A Linux 2.6 test image is available on the QEMU web site. More
-information is available in the QEMU mailing-list archive.
-
-@c man begin OPTIONS
-
-The following options are specific to the ARM emulation:
-
-@table @option
-
-@item -semihosting
-Enable semihosting syscall emulation.
-
-On ARM this implements the "Angel" interface.
-
-Note that this allows guest direct access to the host filesystem,
-so should only be used with trusted guest OS.
-
-@end table
-
-@c man end
-
-@node ColdFire System emulator
-@section ColdFire System emulator
-@cindex system emulation (ColdFire)
-@cindex system emulation (M68K)
-
-Use the executable @file{qemu-system-m68k} to simulate a ColdFire machine.
-The emulator is able to boot a uClinux kernel.
-
-The M5208EVB emulation includes the following devices:
-
-@itemize @minus
-@item
-MCF5208 ColdFire V2 Microprocessor (ISA A+ with EMAC).
-@item
-Three Two on-chip UARTs.
-@item
-Fast Ethernet Controller (FEC)
-@end itemize
-
-The AN5206 emulation includes the following devices:
-
-@itemize @minus
-@item
-MCF5206 ColdFire V2 Microprocessor.
-@item
-Two on-chip UARTs.
-@end itemize
-
-@c man begin OPTIONS
-
-The following options are specific to the ColdFire emulation:
-
-@table @option
-
-@item -semihosting
-Enable semihosting syscall emulation.
-
-On M68K this implements the "ColdFire GDB" interface used by libgloss.
-
-Note that this allows guest direct access to the host filesystem,
-so should only be used with trusted guest OS.
-
-@end table
-
-@c man end
-
-@node Cris System emulator
-@section Cris System emulator
-@cindex system emulation (Cris)
-
-TODO
-
-@node Microblaze System emulator
-@section Microblaze System emulator
-@cindex system emulation (Microblaze)
-
-TODO
-
-@node SH4 System emulator
-@section SH4 System emulator
-@cindex system emulation (SH4)
-
-TODO
-
-@node Xtensa System emulator
-@section Xtensa System emulator
-@cindex system emulation (Xtensa)
-
-Two executables cover simulation of both Xtensa endian options,
-@file{qemu-system-xtensa} and @file{qemu-system-xtensaeb}.
-Two different machine types are emulated:
-
-@itemize @minus
-@item
-Xtensa emulator pseudo board "sim"
-@item
-Avnet LX60/LX110/LX200 board
-@end itemize
-
-The sim pseudo board emulation provides an environment similar
-to one provided by the proprietary Tensilica ISS.
-It supports:
-
-@itemize @minus
-@item
-A range of Xtensa CPUs, default is the DC232B
-@item
-Console and filesystem access via semihosting calls
-@end itemize
-
-The Avnet LX60/LX110/LX200 emulation supports:
-
-@itemize @minus
-@item
-A range of Xtensa CPUs, default is the DC232B
-@item
-16550 UART
-@item
-OpenCores 10/100 Mbps Ethernet MAC
-@end itemize
-
-@c man begin OPTIONS
-
-The following options are specific to the Xtensa emulation:
-
-@table @option
-
-@item -semihosting
-Enable semihosting syscall emulation.
-
-Xtensa semihosting provides basic file IO calls, such as open/read/write/seek/select.
-Tensilica baremetal libc for ISS and linux platform "sim" use this interface.
-
-Note that this allows guest direct access to the host filesystem,
-so should only be used with trusted guest OS.
-
-@end table
-
-@c man end
-
-@node QEMU User space emulator
-@chapter QEMU User space emulator
-
-@menu
-* Supported Operating Systems ::
-* Features::
-* Linux User space emulator::
-* BSD User space emulator ::
-@end menu
-
-@node Supported Operating Systems
-@section Supported Operating Systems
-
-The following OS are supported in user space emulation:
-
-@itemize @minus
-@item
-Linux (referred as qemu-linux-user)
-@item
-BSD (referred as qemu-bsd-user)
-@end itemize
-
-@node Features
-@section Features
-
-QEMU user space emulation has the following notable features:
-
-@table @strong
-@item System call translation:
-QEMU includes a generic system call translator.  This means that
-the parameters of the system calls can be converted to fix
-endianness and 32/64-bit mismatches between hosts and targets.
-IOCTLs can be converted too.
-
-@item POSIX signal handling:
-QEMU can redirect to the running program all signals coming from
-the host (such as @code{SIGALRM}), as well as synthesize signals from
-virtual CPU exceptions (for example @code{SIGFPE} when the program
-executes a division by zero).
-
-QEMU relies on the host kernel to emulate most signal system
-calls, for example to emulate the signal mask.  On Linux, QEMU
-supports both normal and real-time signals.
-
-@item Threading:
-On Linux, QEMU can emulate the @code{clone} syscall and create a real
-host thread (with a separate virtual CPU) for each emulated thread.
-Note that not all targets currently emulate atomic operations correctly.
-x86 and ARM use a global lock in order to preserve their semantics.
-@end table
-
-QEMU was conceived so that ultimately it can emulate itself. Although
-it is not very useful, it is an important test to show the power of the
-emulator.
-
-@node Linux User space emulator
-@section Linux User space emulator
-
-@menu
-* Quick Start::
-* Wine launch::
-* Command line options::
-* Other binaries::
-@end menu
-
-@node Quick Start
-@subsection Quick Start
-
-In order to launch a Linux process, QEMU needs the process executable
-itself and all the target (x86) dynamic libraries used by it.
-
-@itemize
-
-@item On x86, you can just try to launch any process by using the native
-libraries:
-
-@example
-qemu-i386 -L / /bin/ls
-@end example
-
-@code{-L /} tells that the x86 dynamic linker must be searched with a
-@file{/} prefix.
-
-@item Since QEMU is also a linux process, you can launch QEMU with
-QEMU (NOTE: you can only do that if you compiled QEMU from the sources):
-
-@example
-qemu-i386 -L / qemu-i386 -L / /bin/ls
-@end example
-
-@item On non x86 CPUs, you need first to download at least an x86 glibc
-(@file{qemu-runtime-i386-XXX-.tar.gz} on the QEMU web page). Ensure that
-@code{LD_LIBRARY_PATH} is not set:
-
-@example
-unset LD_LIBRARY_PATH
-@end example
-
-Then you can launch the precompiled @file{ls} x86 executable:
-
-@example
-qemu-i386 tests/i386/ls
-@end example
-You can look at @file{scripts/qemu-binfmt-conf.sh} so that
-QEMU is automatically launched by the Linux kernel when you try to
-launch x86 executables. It requires the @code{binfmt_misc} module in the
-Linux kernel.
-
-@item The x86 version of QEMU is also included. You can try weird things such as:
-@example
-qemu-i386 /usr/local/qemu-i386/bin/qemu-i386 \
-          /usr/local/qemu-i386/bin/ls-i386
-@end example
-
-@end itemize
-
-@node Wine launch
-@subsection Wine launch
-
-@itemize
-
-@item Ensure that you have a working QEMU with the x86 glibc
-distribution (see previous section). In order to verify it, you must be
-able to do:
-
-@example
-qemu-i386 /usr/local/qemu-i386/bin/ls-i386
-@end example
-
-@item Download the binary x86 Wine install
-(@file{qemu-XXX-i386-wine.tar.gz} on the QEMU web page).
-
-@item Configure Wine on your account. Look at the provided script
-@file{/usr/local/qemu-i386/@/bin/wine-conf.sh}. Your previous
-@code{$@{HOME@}/.wine} directory is saved to @code{$@{HOME@}/.wine.org}.
-
-@item Then you can try the example @file{putty.exe}:
-
-@example
-qemu-i386 /usr/local/qemu-i386/wine/bin/wine \
-          /usr/local/qemu-i386/wine/c/Program\ Files/putty.exe
-@end example
-
-@end itemize
-
-@node Command line options
-@subsection Command line options
-
-@example
-@command{qemu-i386} [@option{-h]} [@option{-d]} [@option{-L} @var{path}] [@option{-s} @var{size}] [@option{-cpu} @var{model}] [@option{-g} @var{port}] [@option{-B} @var{offset}] [@option{-R} @var{size}] @var{program} [@var{arguments}...]
-@end example
-
-@table @option
-@item -h
-Print the help
-@item -L path
-Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
-@item -s size
-Set the x86 stack size in bytes (default=524288)
-@item -cpu model
-Select CPU model (-cpu help for list and additional feature selection)
-@item -E @var{var}=@var{value}
-Set environment @var{var} to @var{value}.
-@item -U @var{var}
-Remove @var{var} from the environment.
-@item -B offset
-Offset guest address by the specified number of bytes.  This is useful when
-the address region required by guest applications is reserved on the host.
-This option is currently only supported on some hosts.
-@item -R size
-Pre-allocate a guest virtual address space of the given size (in bytes).
-"G", "M", and "k" suffixes may be used when specifying the size.
-@end table
-
-Debug options:
-
-@table @option
-@item -d item1,...
-Activate logging of the specified items (use '-d help' for a list of log items)
-@item -p pagesize
-Act as if the host page size was 'pagesize' bytes
-@item -g port
-Wait gdb connection to port
-@item -singlestep
-Run the emulation in single step mode.
-@end table
-
-Environment variables:
-
-@table @env
-@item QEMU_STRACE
-Print system calls and arguments similar to the 'strace' program
-(NOTE: the actual 'strace' program will not work because the user
-space emulator hasn't implemented ptrace).  At the moment this is
-incomplete.  All system calls that don't have a specific argument
-format are printed with information for six arguments.  Many
-flag-style arguments don't have decoders and will show up as numbers.
-@end table
-
-@node Other binaries
-@subsection Other binaries
-
-@cindex user mode (Alpha)
-@command{qemu-alpha} TODO.
-
-@cindex user mode (ARM)
-@command{qemu-armeb} TODO.
-
-@cindex user mode (ARM)
-@command{qemu-arm} is also capable of running ARM "Angel" semihosted ELF
-binaries (as implemented by the arm-elf and arm-eabi Newlib/GDB
-configurations), and arm-uclinux bFLT format binaries.
-
-@cindex user mode (ColdFire)
-@cindex user mode (M68K)
-@command{qemu-m68k} is capable of running semihosted binaries using the BDM
-(m5xxx-ram-hosted.ld) or m68k-sim (sim.ld) syscall interfaces, and
-coldfire uClinux bFLT format binaries.
-
-The binary format is detected automatically.
-
-@cindex user mode (Cris)
-@command{qemu-cris} TODO.
-
-@cindex user mode (i386)
-@command{qemu-i386} TODO.
-@command{qemu-x86_64} TODO.
-
-@cindex user mode (Microblaze)
-@command{qemu-microblaze} TODO.
-
-@cindex user mode (MIPS)
-@command{qemu-mips} executes 32-bit big endian MIPS binaries (MIPS O32 ABI).
-
-@command{qemu-mipsel} executes 32-bit little endian MIPS binaries (MIPS O32 ABI).
-
-@command{qemu-mips64} executes 64-bit big endian MIPS binaries (MIPS N64 ABI).
-
-@command{qemu-mips64el} executes 64-bit little endian MIPS binaries (MIPS N64 ABI).
-
-@command{qemu-mipsn32} executes 32-bit big endian MIPS binaries (MIPS N32 ABI).
-
-@command{qemu-mipsn32el} executes 32-bit little endian MIPS binaries (MIPS N32 ABI).
-
-@cindex user mode (NiosII)
-@command{qemu-nios2} TODO.
-
-@cindex user mode (PowerPC)
-@command{qemu-ppc64abi32} TODO.
-@command{qemu-ppc64} TODO.
-@command{qemu-ppc} TODO.
-
-@cindex user mode (SH4)
-@command{qemu-sh4eb} TODO.
-@command{qemu-sh4} TODO.
-
-@cindex user mode (SPARC)
-@command{qemu-sparc} can execute Sparc32 binaries (Sparc32 CPU, 32 bit ABI).
-
-@command{qemu-sparc32plus} can execute Sparc32 and SPARC32PLUS binaries
-(Sparc64 CPU, 32 bit ABI).
-
-@command{qemu-sparc64} can execute some Sparc64 (Sparc64 CPU, 64 bit ABI) and
-SPARC32PLUS binaries (Sparc64 CPU, 32 bit ABI).
-
-@node BSD User space emulator
-@section BSD User space emulator
-
-@menu
-* BSD Status::
-* BSD Quick Start::
-* BSD Command line options::
-@end menu
-
-@node BSD Status
-@subsection BSD Status
-
-@itemize @minus
-@item
-target Sparc64 on Sparc64: Some trivial programs work.
-@end itemize
-
-@node BSD Quick Start
-@subsection Quick Start
-
-In order to launch a BSD process, QEMU needs the process executable
-itself and all the target dynamic libraries used by it.
-
-@itemize
-
-@item On Sparc64, you can just try to launch any process by using the native
-libraries:
-
-@example
-qemu-sparc64 /bin/ls
-@end example
-
-@end itemize
-
-@node BSD Command line options
-@subsection Command line options
-
-@example
-@command{qemu-sparc64} [@option{-h]} [@option{-d]} [@option{-L} @var{path}] [@option{-s} @var{size}] [@option{-bsd} @var{type}] @var{program} [@var{arguments}...]
-@end example
-
-@table @option
-@item -h
-Print the help
-@item -L path
-Set the library root path (default=/)
-@item -s size
-Set the stack size in bytes (default=524288)
-@item -ignore-environment
-Start with an empty environment. Without this option,
-the initial environment is a copy of the caller's environment.
-@item -E @var{var}=@var{value}
-Set environment @var{var} to @var{value}.
-@item -U @var{var}
-Remove @var{var} from the environment.
-@item -bsd type
-Set the type of the emulated BSD Operating system. Valid values are
-FreeBSD, NetBSD and OpenBSD (default).
-@end table
-
-Debug options:
-
-@table @option
-@item -d item1,...
-Activate logging of the specified items (use '-d help' for a list of log items)
-@item -p pagesize
-Act as if the host page size was 'pagesize' bytes
-@item -singlestep
-Run the emulation in single step mode.
-@end table
-
-@node System requirements
-@chapter System requirements
-
-@section KVM kernel module
-
-On x86_64 hosts, the default set of CPU features enabled by the KVM accelerator
-require the host to be running Linux v4.5 or newer.
-
-The OpteronG[345] CPU models require KVM support for RDTSCP, which was
-added with Linux 4.5 which is supported by the major distros. And even
-if RHEL7 has kernel 3.10, KVM there has the required functionality there
-to make it close to a 4.5 or newer kernel.
-
-@include docs/security.texi
-
-@include qemu-tech.texi
-
-@include qemu-deprecated.texi
-
-@node Supported build platforms
-@appendix Supported build platforms
-
-QEMU aims to support building and executing on multiple host OS platforms.
-This appendix outlines which platforms are the major build targets. These
-platforms are used as the basis for deciding upon the minimum required
-versions of 3rd party software QEMU depends on. The supported platforms
-are the targets for automated testing performed by the project when patches
-are submitted for review, and tested before and after merge.
-
-If a platform is not listed here, it does not imply that QEMU won't work.
-If an unlisted platform has comparable software versions to a listed platform,
-there is every expectation that it will work. Bug reports are welcome for
-problems encountered on unlisted platforms unless they are clearly older
-vintage than what is described here.
-
-Note that when considering software versions shipped in distros as support
-targets, QEMU considers only the version number, and assumes the features in
-that distro match the upstream release with the same version. In other words,
-if a distro backports extra features to the software in their distro, QEMU
-upstream code will not add explicit support for those backports, unless the
-feature is auto-detectable in a manner that works for the upstream releases
-too.
-
-The Repology site @url{https://repology.org} is a useful resource to identify
-currently shipped versions of software in various operating systems, though
-it does not cover all distros listed below.
-
-@section Linux OS
-
-For distributions with frequent, short-lifetime releases, the project will
-aim to support all versions that are not end of life by their respective
-vendors. For the purposes of identifying supported software versions, the
-project will look at Fedora, Ubuntu, and openSUSE distros. Other short-
-lifetime distros will be assumed to ship similar software versions.
-
-For distributions with long-lifetime releases, the project will aim to support
-the most recent major version at all times. Support for the previous major
-version will be dropped 2 years after the new major version is released,
-or when it reaches ``end of life''. For the purposes of identifying
-supported software versions, the project will look at RHEL, Debian,
-Ubuntu LTS, and SLES distros. Other long-lifetime distros will be
-assumed to ship similar software versions.
-
-@section Windows
-
-The project supports building with current versions of the MinGW toolchain,
-hosted on Linux.
-
-@section macOS
-
-The project supports building with the two most recent versions of macOS, with
-the current homebrew package set available.
-
-@section FreeBSD
-
-The project aims to support the all the versions which are not end of life.
-
-@section NetBSD
-
-The project aims to support the most recent major version at all times. Support
-for the previous major version will be dropped 2 years after the new major
-version is released.
-
-@section OpenBSD
-
-The project aims to support the all the versions which are not end of life.
-
-@node License
-@appendix License
-
-QEMU is a trademark of Fabrice Bellard.
-
-QEMU is released under the
-@url{https://www.gnu.org/licenses/gpl-2.0.txt,GNU General Public License},
-version 2. Parts of QEMU have specific licenses, see file
-@url{https://git.qemu.org/?p=qemu.git;a=blob_plain;f=LICENSE,LICENSE}.
-
-@node Index
-@appendix Index
-@menu
-* Concept Index::
-* Function Index::
-* Keystroke Index::
-* Program Index::
-* Data Type Index::
-* Variable Index::
-@end menu
-
-@node Concept Index
-@section Concept Index
-This is the main index. Should we combine all keywords in one index? TODO
-@printindex cp
-
-@node Function Index
-@section Function Index
-This index could be used for command line options and monitor functions.
-@printindex fn
-
-@node Keystroke Index
-@section Keystroke Index
-
-This is a list of all keystrokes which have a special function
-in system emulation.
-
-@printindex ky
-
-@node Program Index
-@section Program Index
-@printindex pg
-
-@node Data Type Index
-@section Data Type Index
-
-This index could be used for qdev device names and options.
-
-@printindex tp
-
-@node Variable Index
-@section Variable Index
-@printindex vr
-
-@bye
index 804630a368d6ad22cdd65aae9edb6156a5dc202d..afddf33f08c66b0c2ad1946655f119fa1feb7c0f 100644 (file)
@@ -817,6 +817,8 @@ static int img_check(int argc, char **argv)
                     check->corruptions_fixed);
         }
 
+        qapi_free_ImageCheck(check);
+        check = g_new0(ImageCheck, 1);
         ret = collect_image_check(bs, check, filename, fmt, 0);
 
         check->leaks_fixed          = leaks_fixed;
@@ -882,9 +884,9 @@ static void run_block_job(BlockJob *job, Error **errp)
     do {
         float progress = 0.0f;
         aio_poll(aio_context, true);
-        if (job->job.progress_total) {
-            progress = (float)job->job.progress_current /
-                       job->job.progress_total * 100.f;
+        if (job->job.progress.total) {
+            progress = (float)job->job.progress.current /
+                       job->job.progress.total * 100.f;
         }
         qemu_progress_print(progress, 0);
     } while (!job_is_ready(&job->job) && !job_is_completed(&job->job));
@@ -4932,10 +4934,8 @@ static int img_measure(int argc, char **argv)
         filename = argv[optind];
     }
 
-    if (!filename &&
-        (object_opts || image_opts || fmt || snapshot_name || sn_opts)) {
-        error_report("--object, --image-opts, -f, and -l "
-                     "require a filename argument.");
+    if (!filename && (image_opts || fmt || snapshot_name || sn_opts)) {
+        error_report("--image-opts, -f, and -l require a filename argument.");
         goto out;
     }
     if (filename && img_size != UINT64_MAX) {
diff --git a/qemu-option-trace.texi b/qemu-option-trace.texi
deleted file mode 100644 (file)
index 162f152..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-@c The contents of this file must be kept in sync with qemu-option-trace.rst.inc
-@c until all the users of the texi file have been converted to rst and
-@c the texi file can be removed.
-
-Specify tracing options.
-
-@table @option
-@item [enable=]@var{pattern}
-Immediately enable events matching @var{pattern}
-(either event name or a globbing pattern).  This option is only
-available if QEMU has been compiled with the @var{simple}, @var{log}
-or @var{ftrace} tracing backend.  To specify multiple events or patterns,
-specify the @option{-trace} option multiple times.
-
-Use @code{-trace help} to print a list of names of trace points.
-
-@item events=@var{file}
-Immediately enable events listed in @var{file}.
-The file must contain one event name (as listed in the @file{trace-events-all}
-file) per line; globbing patterns are accepted too.  This option is only
-available if QEMU has been compiled with the @var{simple}, @var{log} or
-@var{ftrace} tracing backend.
-
-@item file=@var{file}
-Log output traces to @var{file}.
-This option is only available if QEMU has been compiled with
-the @var{simple} tracing backend.
-@end table
index 084a1c1f8c921041a7fb9498e5b381913a911816..1d8f852d89695916a45eb58011d1b388f2cc76f0 100644 (file)
@@ -1,31 +1,26 @@
-HXCOMM Use DEFHEADING() to define headings in both help text and texi
-HXCOMM Text between STEXI and ETEXI are copied to texi version and
-HXCOMM discarded from C version
+HXCOMM Use DEFHEADING() to define headings in both help text and rST.
+HXCOMM Text between SRST and ERST is copied to the rST version and
+HXCOMM discarded from C version.
 HXCOMM DEF(option, HAS_ARG/0, opt_enum, opt_help, arch_mask) is used to
 HXCOMM construct option structures, enums and help message for specified
 HXCOMM architectures.
-HXCOMM HXCOMM can be used for comments, discarded from both texi and C
+HXCOMM HXCOMM can be used for comments, discarded from both rST and C.
 
 DEFHEADING(Standard options:)
-STEXI
-@table @option
-ETEXI
 
 DEF("help", 0, QEMU_OPTION_h,
     "-h or -help     display this help and exit\n", QEMU_ARCH_ALL)
-STEXI
-@item -h
-@findex -h
-Display help and exit
-ETEXI
+SRST
+``-h``
+    Display help and exit
+ERST
 
 DEF("version", 0, QEMU_OPTION_version,
     "-version        display version information and exit\n", QEMU_ARCH_ALL)
-STEXI
-@item -version
-@findex -version
-Display version information and exit
-ETEXI
+SRST
+``-version``
+    Display version information and exit
+ERST
 
 DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
     "-machine [type=]name[,prop[=value][,...]]\n"
@@ -43,74 +38,84 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
     "                memory-encryption=@var{} memory encryption object to use (default=none)\n"
     "                hmat=on|off controls ACPI HMAT support (default=off)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
-@findex -machine
-Select the emulated machine by @var{name}. Use @code{-machine help} to list
-available machines.
-
-For architectures which aim to support live migration compatibility
-across releases, each release will introduce a new versioned machine
-type. For example, the 2.8.0 release introduced machine types
-``pc-i440fx-2.8'' and ``pc-q35-2.8'' for the x86_64/i686 architectures.
-
-To allow live migration of guests from QEMU version 2.8.0, to QEMU
-version 2.9.0, the 2.9.0 version must support the ``pc-i440fx-2.8''
-and ``pc-q35-2.8'' machines too. To allow users live migrating VMs
-to skip multiple intermediate releases when upgrading, new releases
-of QEMU will support machine types from many previous versions.
-
-Supported machine properties are:
-@table @option
-@item accel=@var{accels1}[:@var{accels2}[:...]]
-This is used to enable an accelerator. Depending on the target architecture,
-kvm, xen, hax, hvf, whpx or tcg can be available. By default, tcg is used. If there is
-more than one accelerator specified, the next one is used if the previous one
-fails to initialize.
-@item vmport=on|off|auto
-Enables emulation of VMWare IO port, for vmmouse etc. auto says to select the
-value based on accel. For accel=xen the default is off otherwise the default
-is on.
-@item dump-guest-core=on|off
-Include guest memory in a core dump. The default is on.
-@item mem-merge=on|off
-Enables or disables memory merge support. This feature, when supported by
-the host, de-duplicates identical memory pages among VMs instances
-(enabled by default).
-@item aes-key-wrap=on|off
-Enables or disables AES key wrapping support on s390-ccw hosts. This feature
-controls whether AES wrapping keys will be created to allow
-execution of AES cryptographic functions.  The default is on.
-@item dea-key-wrap=on|off
-Enables or disables DEA key wrapping support on s390-ccw hosts. This feature
-controls whether DEA wrapping keys will be created to allow
-execution of DEA cryptographic functions.  The default is on.
-@item nvdimm=on|off
-Enables or disables NVDIMM support. The default is off.
-@item enforce-config-section=on|off
-If @option{enforce-config-section} is set to @var{on}, force migration
-code to send configuration section even if the machine-type sets the
-@option{migration.send-configuration} property to @var{off}.
-NOTE: this parameter is deprecated. Please use @option{-global}
-@option{migration.send-configuration}=@var{on|off} instead.
-@item memory-encryption=@var{}
-Memory encryption object to use. The default is none.
-@item hmat=on|off
-Enables or disables ACPI Heterogeneous Memory Attribute Table (HMAT) support.
-The default is off.
-@end table
-ETEXI
+SRST
+``-machine [type=]name[,prop=value[,...]]``
+    Select the emulated machine by name. Use ``-machine help`` to list
+    available machines.
+
+    For architectures which aim to support live migration compatibility
+    across releases, each release will introduce a new versioned machine
+    type. For example, the 2.8.0 release introduced machine types
+    "pc-i440fx-2.8" and "pc-q35-2.8" for the x86\_64/i686 architectures.
+
+    To allow live migration of guests from QEMU version 2.8.0, to QEMU
+    version 2.9.0, the 2.9.0 version must support the "pc-i440fx-2.8"
+    and "pc-q35-2.8" machines too. To allow users live migrating VMs to
+    skip multiple intermediate releases when upgrading, new releases of
+    QEMU will support machine types from many previous versions.
+
+    Supported machine properties are:
+
+    ``accel=accels1[:accels2[:...]]``
+        This is used to enable an accelerator. Depending on the target
+        architecture, kvm, xen, hax, hvf, whpx or tcg can be available.
+        By default, tcg is used. If there is more than one accelerator
+        specified, the next one is used if the previous one fails to
+        initialize.
+
+    ``vmport=on|off|auto``
+        Enables emulation of VMWare IO port, for vmmouse etc. auto says
+        to select the value based on accel. For accel=xen the default is
+        off otherwise the default is on.
+
+    ``dump-guest-core=on|off``
+        Include guest memory in a core dump. The default is on.
+
+    ``mem-merge=on|off``
+        Enables or disables memory merge support. This feature, when
+        supported by the host, de-duplicates identical memory pages
+        among VMs instances (enabled by default).
+
+    ``aes-key-wrap=on|off``
+        Enables or disables AES key wrapping support on s390-ccw hosts.
+        This feature controls whether AES wrapping keys will be created
+        to allow execution of AES cryptographic functions. The default
+        is on.
+
+    ``dea-key-wrap=on|off``
+        Enables or disables DEA key wrapping support on s390-ccw hosts.
+        This feature controls whether DEA wrapping keys will be created
+        to allow execution of DEA cryptographic functions. The default
+        is on.
+
+    ``nvdimm=on|off``
+        Enables or disables NVDIMM support. The default is off.
+
+    ``enforce-config-section=on|off``
+        If ``enforce-config-section`` is set to on, force migration code
+        to send configuration section even if the machine-type sets the
+        ``migration.send-configuration`` property to off. NOTE: this
+        parameter is deprecated. Please use ``-global``
+        ``migration.send-configuration``\ =on\|off instead.
+
+    ``memory-encryption=``
+        Memory encryption object to use. The default is none.
+
+    ``hmat=on|off``
+        Enables or disables ACPI Heterogeneous Memory Attribute Table
+        (HMAT) support. The default is off.
+ERST
 
 HXCOMM Deprecated by -machine
 DEF("M", HAS_ARG, QEMU_OPTION_M, "", QEMU_ARCH_ALL)
 
 DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
     "-cpu cpu        select CPU ('-cpu help' for list)\n", QEMU_ARCH_ALL)
-STEXI
-@item -cpu @var{model}
-@findex -cpu
-Select CPU model (@code{-cpu help} for list and additional feature selection)
-ETEXI
+SRST
+``-cpu model``
+    Select CPU model (``-cpu help`` for list and additional feature
+    selection)
+ERST
 
 DEF("accel", HAS_ARG, QEMU_OPTION_accel,
     "-accel [accel=]accelerator[,prop[=value][,...]]\n"
@@ -120,33 +125,40 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
     "                kvm-shadow-mem=size of KVM shadow MMU in bytes\n"
     "                tb-size=n (TCG translation block cache size)\n"
     "                thread=single|multi (enable multi-threaded TCG)\n", QEMU_ARCH_ALL)
-STEXI
-@item -accel @var{name}[,prop=@var{value}[,...]]
-@findex -accel
-This is used to enable an accelerator. Depending on the target architecture,
-kvm, xen, hax, hvf, whpx or tcg can be available. By default, tcg is used. If there is
-more than one accelerator specified, the next one is used if the previous one
-fails to initialize.
-@table @option
-@item igd-passthru=on|off
-When Xen is in use, this option controls whether Intel integrated graphics
-devices can be passed through to the guest (default=off)
-@item kernel-irqchip=on|off|split
-Controls KVM in-kernel irqchip support.  The default is full acceleration of the
-interrupt controllers.  On x86, split irqchip reduces the kernel attack
-surface, at a performance cost for non-MSI interrupts.  Disabling the in-kernel
-irqchip completely is not recommended except for debugging purposes.
-@item kvm-shadow-mem=size
-Defines the size of the KVM shadow MMU.
-@item tb-size=@var{n}
-Controls the size (in MiB) of the TCG translation block cache.
-@item thread=single|multi
-Controls number of TCG threads. When the TCG is multi-threaded there will be one
-thread per vCPU therefor taking advantage of additional host cores. The default
-is to enable multi-threading where both the back-end and front-ends support it and
-no incompatible TCG features have been enabled (e.g. icount/replay).
-@end table
-ETEXI
+SRST
+``-accel name[,prop=value[,...]]``
+    This is used to enable an accelerator. Depending on the target
+    architecture, kvm, xen, hax, hvf, whpx or tcg can be available. By
+    default, tcg is used. If there is more than one accelerator
+    specified, the next one is used if the previous one fails to
+    initialize.
+
+    ``igd-passthru=on|off``
+        When Xen is in use, this option controls whether Intel
+        integrated graphics devices can be passed through to the guest
+        (default=off)
+
+    ``kernel-irqchip=on|off|split``
+        Controls KVM in-kernel irqchip support. The default is full
+        acceleration of the interrupt controllers. On x86, split irqchip
+        reduces the kernel attack surface, at a performance cost for
+        non-MSI interrupts. Disabling the in-kernel irqchip completely
+        is not recommended except for debugging purposes.
+
+    ``kvm-shadow-mem=size``
+        Defines the size of the KVM shadow MMU.
+
+    ``tb-size=n``
+        Controls the size (in MiB) of the TCG translation block cache.
+
+    ``thread=single|multi``
+        Controls number of TCG threads. When the TCG is multi-threaded
+        there will be one thread per vCPU therefor taking advantage of
+        additional host cores. The default is to enable multi-threading
+        where both the back-end and front-ends support it and no
+        incompatible TCG features have been enabled (e.g.
+        icount/replay).
+ERST
 
 DEF("smp", HAS_ARG, QEMU_OPTION_smp,
     "-smp [cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,dies=dies][,sockets=sockets]\n"
@@ -158,18 +170,17 @@ DEF("smp", HAS_ARG, QEMU_OPTION_smp,
     "                dies= number of CPU dies on one socket (for PC only)\n"
     "                sockets= number of discrete sockets in the system\n",
         QEMU_ARCH_ALL)
-STEXI
-@item -smp [cpus=]@var{n}[,cores=@var{cores}][,threads=@var{threads}][,dies=dies][,sockets=@var{sockets}][,maxcpus=@var{maxcpus}]
-@findex -smp
-Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255
-CPUs are supported. On Sparc32 target, Linux limits the number of usable CPUs
-to 4.
-For the PC target, the number of @var{cores} per die, the number of @var{threads}
-per cores, the number of @var{dies} per packages and the total number of
-@var{sockets} can be specified. Missing values will be computed.
-If any on the three values is given, the total number of CPUs @var{n} can be omitted.
-@var{maxcpus} specifies the maximum number of hotpluggable CPUs.
-ETEXI
+SRST
+``-smp [cpus=]n[,cores=cores][,threads=threads][,dies=dies][,sockets=sockets][,maxcpus=maxcpus]``
+    Simulate an SMP system with n CPUs. On the PC target, up to 255 CPUs
+    are supported. On Sparc32 target, Linux limits the number of usable
+    CPUs to 4. For the PC target, the number of cores per die, the
+    number of threads per cores, the number of dies per packages and the
+    total number of sockets can be specified. Missing values will be
+    computed. If any on the three values is given, the total number of
+    CPUs n can be omitted. maxcpus specifies the maximum number of
+    hotpluggable CPUs.
+ERST
 
 DEF("numa", HAS_ARG, QEMU_OPTION_numa,
     "-numa node[,mem=size][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=node]\n"
@@ -179,211 +190,227 @@ DEF("numa", HAS_ARG, QEMU_OPTION_numa,
     "-numa hmat-lb,initiator=node,target=node,hierarchy=memory|first-level|second-level|third-level,data-type=access-latency|read-latency|write-latency[,latency=lat][,bandwidth=bw]\n"
     "-numa hmat-cache,node-id=node,size=size,level=level[,associativity=none|direct|complex][,policy=none|write-back|write-through][,line=size]\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -numa node[,mem=@var{size}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}][,initiator=@var{initiator}]
-@itemx -numa node[,memdev=@var{id}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}][,initiator=@var{initiator}]
-@itemx -numa dist,src=@var{source},dst=@var{destination},val=@var{distance}
-@itemx -numa cpu,node-id=@var{node}[,socket-id=@var{x}][,core-id=@var{y}][,thread-id=@var{z}]
-@itemx -numa hmat-lb,initiator=@var{node},target=@var{node},hierarchy=@var{hierarchy},data-type=@var{tpye}[,latency=@var{lat}][,bandwidth=@var{bw}]
-@itemx -numa hmat-cache,node-id=@var{node},size=@var{size},level=@var{level}[,associativity=@var{str}][,policy=@var{str}][,line=@var{size}]
-@findex -numa
-Define a NUMA node and assign RAM and VCPUs to it.
-Set the NUMA distance from a source node to a destination node.
-Set the ACPI Heterogeneous Memory Attributes for the given nodes.
-
-Legacy VCPU assignment uses @samp{cpus} option where
-@var{firstcpu} and @var{lastcpu} are CPU indexes. Each
-@samp{cpus} option represent a contiguous range of CPU indexes
-(or a single VCPU if @var{lastcpu} is omitted). A non-contiguous
-set of VCPUs can be represented by providing multiple @samp{cpus}
-options. If @samp{cpus} is omitted on all nodes, VCPUs are automatically
-split between them.
-
-For example, the following option assigns VCPUs 0, 1, 2 and 5 to
-a NUMA node:
-@example
--numa node,cpus=0-2,cpus=5
-@end example
-
-@samp{cpu} option is a new alternative to @samp{cpus} option
-which uses @samp{socket-id|core-id|thread-id} properties to assign
-CPU objects to a @var{node} using topology layout properties of CPU.
-The set of properties is machine specific, and depends on used
-machine type/@samp{smp} options. It could be queried with
-@samp{hotpluggable-cpus} monitor command.
-@samp{node-id} property specifies @var{node} to which CPU object
-will be assigned, it's required for @var{node} to be declared
-with @samp{node} option before it's used with @samp{cpu} option.
-
-For example:
-@example
--M pc \
--smp 1,sockets=2,maxcpus=2 \
--numa node,nodeid=0 -numa node,nodeid=1 \
--numa cpu,node-id=0,socket-id=0 -numa cpu,node-id=1,socket-id=1
-@end example
-
-@samp{mem} assigns a given RAM amount to a node. @samp{memdev}
-assigns RAM from a given memory backend device to a node. If
-@samp{mem} and @samp{memdev} are omitted in all nodes, RAM is
-split equally between them.
-
-@samp{mem} and @samp{memdev} are mutually exclusive. Furthermore,
-if one node uses @samp{memdev}, all of them have to use it.
-
-@samp{initiator} is an additional option that points to an @var{initiator}
-NUMA node that has best performance (the lowest latency or largest bandwidth)
-to this NUMA @var{node}. Note that this option can be set only when
-the machine property 'hmat' is set to 'on'.
-
-Following example creates a machine with 2 NUMA nodes, node 0 has CPU.
-node 1 has only memory, and its initiator is node 0. Note that because
-node 0 has CPU, by default the initiator of node 0 is itself and must be
-itself.
-@example
--machine hmat=on \
--m 2G,slots=2,maxmem=4G \
--object memory-backend-ram,size=1G,id=m0 \
--object memory-backend-ram,size=1G,id=m1 \
--numa node,nodeid=0,memdev=m0 \
--numa node,nodeid=1,memdev=m1,initiator=0 \
--smp 2,sockets=2,maxcpus=2  \
--numa cpu,node-id=0,socket-id=0 \
--numa cpu,node-id=0,socket-id=1
-@end example
-
-@var{source} and @var{destination} are NUMA node IDs.
-@var{distance} is the NUMA distance from @var{source} to @var{destination}.
-The distance from a node to itself is always 10. If any pair of nodes is
-given a distance, then all pairs must be given distances. Although, when
-distances are only given in one direction for each pair of nodes, then
-the distances in the opposite directions are assumed to be the same. If,
-however, an asymmetrical pair of distances is given for even one node
-pair, then all node pairs must be provided distance values for both
-directions, even when they are symmetrical. When a node is unreachable
-from another node, set the pair's distance to 255.
-
-Note that the -@option{numa} option doesn't allocate any of the
-specified resources, it just assigns existing resources to NUMA
-nodes. This means that one still has to use the @option{-m},
-@option{-smp} options to allocate RAM and VCPUs respectively.
-
-Use @samp{hmat-lb} to set System Locality Latency and Bandwidth Information
-between initiator and target NUMA nodes in ACPI Heterogeneous Attribute Memory Table (HMAT).
-Initiator NUMA node can create memory requests, usually it has one or more processors.
-Target NUMA node contains addressable memory.
-
-In @samp{hmat-lb} option, @var{node} are NUMA node IDs. @var{hierarchy} is the memory
-hierarchy of the target NUMA node: if @var{hierarchy} is 'memory', the structure
-represents the memory performance; if @var{hierarchy} is 'first-level|second-level|third-level',
-this structure represents aggregated performance of memory side caches for each domain.
-@var{type} of 'data-type' is type of data represented by this structure instance:
-if 'hierarchy' is 'memory', 'data-type' is 'access|read|write' latency or 'access|read|write'
-bandwidth of the target memory; if 'hierarchy' is 'first-level|second-level|third-level',
-'data-type' is 'access|read|write' hit latency or 'access|read|write' hit bandwidth of the
-target memory side cache.
-
-@var{lat} is latency value in nanoseconds. @var{bw} is bandwidth value,
-the possible value and units are NUM[M|G|T], mean that the bandwidth value are
-NUM byte per second (or MB/s, GB/s or TB/s depending on used suffix).
-Note that if latency or bandwidth value is 0, means the corresponding latency or
-bandwidth information is not provided.
-
-In @samp{hmat-cache} option, @var{node-id} is the NUMA-id of the memory belongs.
-@var{size} is the size of memory side cache in bytes. @var{level} is the cache
-level described in this structure, note that the cache level 0 should not be used
-with @samp{hmat-cache} option. @var{associativity} is the cache associativity,
-the possible value is 'none/direct(direct-mapped)/complex(complex cache indexing)'.
-@var{policy} is the write policy. @var{line} is the cache Line size in bytes.
-
-For example, the following options describe 2 NUMA nodes. Node 0 has 2 cpus and
-a ram, node 1 has only a ram. The processors in node 0 access memory in node
-0 with access-latency 5 nanoseconds, access-bandwidth is 200 MB/s;
-The processors in NUMA node 0 access memory in NUMA node 1 with access-latency 10
-nanoseconds, access-bandwidth is 100 MB/s.
-And for memory side cache information, NUMA node 0 and 1 both have 1 level memory
-cache, size is 10KB, policy is write-back, the cache Line size is 8 bytes:
-@example
--machine hmat=on \
--m 2G \
--object memory-backend-ram,size=1G,id=m0 \
--object memory-backend-ram,size=1G,id=m1 \
--smp 2 \
--numa node,nodeid=0,memdev=m0 \
--numa node,nodeid=1,memdev=m1,initiator=0 \
--numa cpu,node-id=0,socket-id=0 \
--numa cpu,node-id=0,socket-id=1 \
--numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=5 \
--numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=200M \
--numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=10 \
--numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M \
--numa hmat-cache,node-id=0,size=10K,level=1,associativity=direct,policy=write-back,line=8 \
--numa hmat-cache,node-id=1,size=10K,level=1,associativity=direct,policy=write-back,line=8
-@end example
-
-ETEXI
+SRST
+``-numa node[,mem=size][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=initiator]``
+  \ 
+``-numa node[,memdev=id][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=initiator]``
+  \
+``-numa dist,src=source,dst=destination,val=distance``
+  \ 
+``-numa cpu,node-id=node[,socket-id=x][,core-id=y][,thread-id=z]``
+  \ 
+``-numa hmat-lb,initiator=node,target=node,hierarchy=hierarchy,data-type=tpye[,latency=lat][,bandwidth=bw]``
+  \ 
+``-numa hmat-cache,node-id=node,size=size,level=level[,associativity=str][,policy=str][,line=size]``
+    Define a NUMA node and assign RAM and VCPUs to it. Set the NUMA
+    distance from a source node to a destination node. Set the ACPI
+    Heterogeneous Memory Attributes for the given nodes.
+
+    Legacy VCPU assignment uses '\ ``cpus``\ ' option where firstcpu and
+    lastcpu are CPU indexes. Each '\ ``cpus``\ ' option represent a
+    contiguous range of CPU indexes (or a single VCPU if lastcpu is
+    omitted). A non-contiguous set of VCPUs can be represented by
+    providing multiple '\ ``cpus``\ ' options. If '\ ``cpus``\ ' is
+    omitted on all nodes, VCPUs are automatically split between them.
+
+    For example, the following option assigns VCPUs 0, 1, 2 and 5 to a
+    NUMA node:
+
+    ::
+
+        -numa node,cpus=0-2,cpus=5
+
+    '\ ``cpu``\ ' option is a new alternative to '\ ``cpus``\ ' option
+    which uses '\ ``socket-id|core-id|thread-id``\ ' properties to
+    assign CPU objects to a node using topology layout properties of
+    CPU. The set of properties is machine specific, and depends on used
+    machine type/'\ ``smp``\ ' options. It could be queried with
+    '\ ``hotpluggable-cpus``\ ' monitor command. '\ ``node-id``\ '
+    property specifies node to which CPU object will be assigned, it's
+    required for node to be declared with '\ ``node``\ ' option before
+    it's used with '\ ``cpu``\ ' option.
+
+    For example:
+
+    ::
+
+        -M pc \
+        -smp 1,sockets=2,maxcpus=2 \
+        -numa node,nodeid=0 -numa node,nodeid=1 \
+        -numa cpu,node-id=0,socket-id=0 -numa cpu,node-id=1,socket-id=1
+
+    '\ ``mem``\ ' assigns a given RAM amount to a node. '\ ``memdev``\ '
+    assigns RAM from a given memory backend device to a node. If
+    '\ ``mem``\ ' and '\ ``memdev``\ ' are omitted in all nodes, RAM is
+    split equally between them.
+
+    '\ ``mem``\ ' and '\ ``memdev``\ ' are mutually exclusive.
+    Furthermore, if one node uses '\ ``memdev``\ ', all of them have to
+    use it.
+
+    '\ ``initiator``\ ' is an additional option that points to an
+    initiator NUMA node that has best performance (the lowest latency or
+    largest bandwidth) to this NUMA node. Note that this option can be
+    set only when the machine property 'hmat' is set to 'on'.
+
+    Following example creates a machine with 2 NUMA nodes, node 0 has
+    CPU. node 1 has only memory, and its initiator is node 0. Note that
+    because node 0 has CPU, by default the initiator of node 0 is itself
+    and must be itself.
+
+    ::
+
+        -machine hmat=on \
+        -m 2G,slots=2,maxmem=4G \
+        -object memory-backend-ram,size=1G,id=m0 \
+        -object memory-backend-ram,size=1G,id=m1 \
+        -numa node,nodeid=0,memdev=m0 \
+        -numa node,nodeid=1,memdev=m1,initiator=0 \
+        -smp 2,sockets=2,maxcpus=2  \
+        -numa cpu,node-id=0,socket-id=0 \
+        -numa cpu,node-id=0,socket-id=1
+
+    source and destination are NUMA node IDs. distance is the NUMA
+    distance from source to destination. The distance from a node to
+    itself is always 10. If any pair of nodes is given a distance, then
+    all pairs must be given distances. Although, when distances are only
+    given in one direction for each pair of nodes, then the distances in
+    the opposite directions are assumed to be the same. If, however, an
+    asymmetrical pair of distances is given for even one node pair, then
+    all node pairs must be provided distance values for both directions,
+    even when they are symmetrical. When a node is unreachable from
+    another node, set the pair's distance to 255.
+
+    Note that the -``numa`` option doesn't allocate any of the specified
+    resources, it just assigns existing resources to NUMA nodes. This
+    means that one still has to use the ``-m``, ``-smp`` options to
+    allocate RAM and VCPUs respectively.
+
+    Use '\ ``hmat-lb``\ ' to set System Locality Latency and Bandwidth
+    Information between initiator and target NUMA nodes in ACPI
+    Heterogeneous Attribute Memory Table (HMAT). Initiator NUMA node can
+    create memory requests, usually it has one or more processors.
+    Target NUMA node contains addressable memory.
+
+    In '\ ``hmat-lb``\ ' option, node are NUMA node IDs. hierarchy is
+    the memory hierarchy of the target NUMA node: if hierarchy is
+    'memory', the structure represents the memory performance; if
+    hierarchy is 'first-level\|second-level\|third-level', this
+    structure represents aggregated performance of memory side caches
+    for each domain. type of 'data-type' is type of data represented by
+    this structure instance: if 'hierarchy' is 'memory', 'data-type' is
+    'access\|read\|write' latency or 'access\|read\|write' bandwidth of
+    the target memory; if 'hierarchy' is
+    'first-level\|second-level\|third-level', 'data-type' is
+    'access\|read\|write' hit latency or 'access\|read\|write' hit
+    bandwidth of the target memory side cache.
+
+    lat is latency value in nanoseconds. bw is bandwidth value, the
+    possible value and units are NUM[M\|G\|T], mean that the bandwidth
+    value are NUM byte per second (or MB/s, GB/s or TB/s depending on
+    used suffix). Note that if latency or bandwidth value is 0, means
+    the corresponding latency or bandwidth information is not provided.
+
+    In '\ ``hmat-cache``\ ' option, node-id is the NUMA-id of the memory
+    belongs. size is the size of memory side cache in bytes. level is
+    the cache level described in this structure, note that the cache
+    level 0 should not be used with '\ ``hmat-cache``\ ' option.
+    associativity is the cache associativity, the possible value is
+    'none/direct(direct-mapped)/complex(complex cache indexing)'. policy
+    is the write policy. line is the cache Line size in bytes.
+
+    For example, the following options describe 2 NUMA nodes. Node 0 has
+    2 cpus and a ram, node 1 has only a ram. The processors in node 0
+    access memory in node 0 with access-latency 5 nanoseconds,
+    access-bandwidth is 200 MB/s; The processors in NUMA node 0 access
+    memory in NUMA node 1 with access-latency 10 nanoseconds,
+    access-bandwidth is 100 MB/s. And for memory side cache information,
+    NUMA node 0 and 1 both have 1 level memory cache, size is 10KB,
+    policy is write-back, the cache Line size is 8 bytes:
+
+    ::
+
+        -machine hmat=on \
+        -m 2G \
+        -object memory-backend-ram,size=1G,id=m0 \
+        -object memory-backend-ram,size=1G,id=m1 \
+        -smp 2 \
+        -numa node,nodeid=0,memdev=m0 \
+        -numa node,nodeid=1,memdev=m1,initiator=0 \
+        -numa cpu,node-id=0,socket-id=0 \
+        -numa cpu,node-id=0,socket-id=1 \
+        -numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=5 \
+        -numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=200M \
+        -numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=10 \
+        -numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M \
+        -numa hmat-cache,node-id=0,size=10K,level=1,associativity=direct,policy=write-back,line=8 \
+        -numa hmat-cache,node-id=1,size=10K,level=1,associativity=direct,policy=write-back,line=8
+ERST
 
 DEF("add-fd", HAS_ARG, QEMU_OPTION_add_fd,
     "-add-fd fd=fd,set=set[,opaque=opaque]\n"
     "                Add 'fd' to fd 'set'\n", QEMU_ARCH_ALL)
-STEXI
-@item -add-fd fd=@var{fd},set=@var{set}[,opaque=@var{opaque}]
-@findex -add-fd
-
-Add a file descriptor to an fd set.  Valid options are:
-
-@table @option
-@item fd=@var{fd}
-This option defines the file descriptor of which a duplicate is added to fd set.
-The file descriptor cannot be stdin, stdout, or stderr.
-@item set=@var{set}
-This option defines the ID of the fd set to add the file descriptor to.
-@item opaque=@var{opaque}
-This option defines a free-form string that can be used to describe @var{fd}.
-@end table
-
-You can open an image using pre-opened file descriptors from an fd set:
-@example
-@value{qemu_system} \
- -add-fd fd=3,set=2,opaque="rdwr:/path/to/file" \
- -add-fd fd=4,set=2,opaque="rdonly:/path/to/file" \
- -drive file=/dev/fdset/2,index=0,media=disk
-@end example
-ETEXI
+SRST
+``-add-fd fd=fd,set=set[,opaque=opaque]``
+    Add a file descriptor to an fd set. Valid options are:
+
+    ``fd=fd``
+        This option defines the file descriptor of which a duplicate is
+        added to fd set. The file descriptor cannot be stdin, stdout, or
+        stderr.
+
+    ``set=set``
+        This option defines the ID of the fd set to add the file
+        descriptor to.
+
+    ``opaque=opaque``
+        This option defines a free-form string that can be used to
+        describe fd.
+
+    You can open an image using pre-opened file descriptors from an fd
+    set:
+
+    .. parsed-literal::
+
+        |qemu_system| \
+         -add-fd fd=3,set=2,opaque="rdwr:/path/to/file" \
+         -add-fd fd=4,set=2,opaque="rdonly:/path/to/file" \
+         -drive file=/dev/fdset/2,index=0,media=disk
+ERST
 
 DEF("set", HAS_ARG, QEMU_OPTION_set,
     "-set group.id.arg=value\n"
     "                set <arg> parameter for item <id> of type <group>\n"
     "                i.e. -set drive.$id.file=/path/to/image\n", QEMU_ARCH_ALL)
-STEXI
-@item -set @var{group}.@var{id}.@var{arg}=@var{value}
-@findex -set
-Set parameter @var{arg} for item @var{id} of type @var{group}
-ETEXI
+SRST
+``-set group.id.arg=value``
+    Set parameter arg for item id of type group
+ERST
 
 DEF("global", HAS_ARG, QEMU_OPTION_global,
     "-global driver.property=value\n"
     "-global driver=driver,property=property,value=value\n"
     "                set a global default for a driver property\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -global @var{driver}.@var{prop}=@var{value}
-@itemx -global driver=@var{driver},property=@var{property},value=@var{value}
-@findex -global
-Set default value of @var{driver}'s property @var{prop} to @var{value}, e.g.:
+SRST
+``-global driver.prop=value``
+  \ 
+``-global driver=driver,property=property,value=value``
+    Set default value of driver's property prop to value, e.g.:
+
+    .. parsed-literal::
 
-@example
-@value{qemu_system_x86} -global ide-hd.physical_block_size=4096 disk-image.img
-@end example
+        |qemu_system_x86| -global ide-hd.physical_block_size=4096 disk-image.img
 
-In particular, you can use this to set driver properties for devices which are
-created automatically by the machine model. To create a device which is not
-created automatically and set properties on it, use -@option{device}.
+    In particular, you can use this to set driver properties for devices
+    which are created automatically by the machine model. To create a
+    device which is not created automatically and set properties on it,
+    use -``device``.
 
--global @var{driver}.@var{prop}=@var{value} is shorthand for -global
-driver=@var{driver},property=@var{prop},value=@var{value}.  The
-longhand syntax works even when @var{driver} contains a dot.
-ETEXI
+    -global driver.prop=value is shorthand for -global
+    driver=driver,property=prop,value=value. The longhand syntax works
+    even when driver contains a dot.
+ERST
 
 DEF("boot", HAS_ARG, QEMU_OPTION_boot,
     "-boot [order=drives][,once=drives][,menu=on|off]\n"
@@ -393,50 +420,50 @@ DEF("boot", HAS_ARG, QEMU_OPTION_boot,
     "                'sp_time': the period that splash picture last if menu=on, unit is ms\n"
     "                'rb_timeout': the timeout before guest reboot when boot failed, unit is ms\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -boot [order=@var{drives}][,once=@var{drives}][,menu=on|off][,splash=@var{sp_name}][,splash-time=@var{sp_time}][,reboot-timeout=@var{rb_timeout}][,strict=on|off]
-@findex -boot
-Specify boot order @var{drives} as a string of drive letters. Valid
-drive letters depend on the target architecture. The x86 PC uses: a, b
-(floppy 1 and 2), c (first hard disk), d (first CD-ROM), n-p (Etherboot
-from network adapter 1-4), hard disk boot is the default. To apply a
-particular boot order only on the first startup, specify it via
-@option{once}. Note that the @option{order} or @option{once} parameter
-should not be used together with the @option{bootindex} property of
-devices, since the firmware implementations normally do not support both
-at the same time.
-
-Interactive boot menus/prompts can be enabled via @option{menu=on} as far
-as firmware/BIOS supports them. The default is non-interactive boot.
-
-A splash picture could be passed to bios, enabling user to show it as logo,
-when option splash=@var{sp_name} is given and menu=on, If firmware/BIOS
-supports them. Currently Seabios for X86 system support it.
-limitation: The splash file could be a jpeg file or a BMP file in 24 BPP
-format(true color). The resolution should be supported by the SVGA mode, so
-the recommended is 320x240, 640x480, 800x640.
-
-A timeout could be passed to bios, guest will pause for @var{rb_timeout} ms
-when boot failed, then reboot. If @var{rb_timeout} is '-1', guest will not
-reboot, qemu passes '-1' to bios by default. Currently Seabios for X86
-system support it.
-
-Do strict boot via @option{strict=on} as far as firmware/BIOS
-supports it. This only effects when boot priority is changed by
-bootindex options. The default is non-strict boot.
-
-@example
-# try to boot from network first, then from hard disk
-@value{qemu_system_x86} -boot order=nc
-# boot from CD-ROM first, switch back to default order after reboot
-@value{qemu_system_x86} -boot once=d
-# boot with a splash picture for 5 seconds.
-@value{qemu_system_x86} -boot menu=on,splash=/root/boot.bmp,splash-time=5000
-@end example
-
-Note: The legacy format '-boot @var{drives}' is still supported but its
-use is discouraged as it may be removed from future versions.
-ETEXI
+SRST
+``-boot [order=drives][,once=drives][,menu=on|off][,splash=sp_name][,splash-time=sp_time][,reboot-timeout=rb_timeout][,strict=on|off]``
+    Specify boot order drives as a string of drive letters. Valid drive
+    letters depend on the target architecture. The x86 PC uses: a, b
+    (floppy 1 and 2), c (first hard disk), d (first CD-ROM), n-p
+    (Etherboot from network adapter 1-4), hard disk boot is the default.
+    To apply a particular boot order only on the first startup, specify
+    it via ``once``. Note that the ``order`` or ``once`` parameter
+    should not be used together with the ``bootindex`` property of
+    devices, since the firmware implementations normally do not support
+    both at the same time.
+
+    Interactive boot menus/prompts can be enabled via ``menu=on`` as far
+    as firmware/BIOS supports them. The default is non-interactive boot.
+
+    A splash picture could be passed to bios, enabling user to show it
+    as logo, when option splash=sp\_name is given and menu=on, If
+    firmware/BIOS supports them. Currently Seabios for X86 system
+    support it. limitation: The splash file could be a jpeg file or a
+    BMP file in 24 BPP format(true color). The resolution should be
+    supported by the SVGA mode, so the recommended is 320x240, 640x480,
+    800x640.
+
+    A timeout could be passed to bios, guest will pause for rb\_timeout
+    ms when boot failed, then reboot. If rb\_timeout is '-1', guest will
+    not reboot, qemu passes '-1' to bios by default. Currently Seabios
+    for X86 system support it.
+
+    Do strict boot via ``strict=on`` as far as firmware/BIOS supports
+    it. This only effects when boot priority is changed by bootindex
+    options. The default is non-strict boot.
+
+    .. parsed-literal::
+
+        # try to boot from network first, then from hard disk
+        |qemu_system_x86| -boot order=nc
+        # boot from CD-ROM first, switch back to default order after reboot
+        |qemu_system_x86| -boot once=d
+        # boot with a splash picture for 5 seconds.
+        |qemu_system_x86| -boot menu=on,splash=/root/boot.bmp,splash-time=5000
+
+    Note: The legacy format '-boot drives' is still supported but its
+    use is discouraged as it may be removed from future versions.
+ERST
 
 DEF("m", HAS_ARG, QEMU_OPTION_m,
     "-m [size=]megs[,slots=n,maxmem=size]\n"
@@ -446,77 +473,73 @@ DEF("m", HAS_ARG, QEMU_OPTION_m,
     "                maxmem: maximum amount of guest memory (default: none)\n"
     "NOTE: Some architectures might enforce a specific granularity\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -m [size=]@var{megs}[,slots=n,maxmem=size]
-@findex -m
-Sets guest startup RAM size to @var{megs} megabytes. Default is 128 MiB.
-Optionally, a suffix of ``M'' or ``G'' can be used to signify a value in
-megabytes or gigabytes respectively. Optional pair @var{slots}, @var{maxmem}
-could be used to set amount of hotpluggable memory slots and maximum amount of
-memory. Note that @var{maxmem} must be aligned to the page size.
-
-For example, the following command-line sets the guest startup RAM size to
-1GB, creates 3 slots to hotplug additional memory and sets the maximum
-memory the guest can reach to 4GB:
-
-@example
-@value{qemu_system} -m 1G,slots=3,maxmem=4G
-@end example
-
-If @var{slots} and @var{maxmem} are not specified, memory hotplug won't
-be enabled and the guest startup RAM will never increase.
-ETEXI
+SRST
+``-m [size=]megs[,slots=n,maxmem=size]``
+    Sets guest startup RAM size to megs megabytes. Default is 128 MiB.
+    Optionally, a suffix of "M" or "G" can be used to signify a value in
+    megabytes or gigabytes respectively. Optional pair slots, maxmem
+    could be used to set amount of hotpluggable memory slots and maximum
+    amount of memory. Note that maxmem must be aligned to the page size.
+
+    For example, the following command-line sets the guest startup RAM
+    size to 1GB, creates 3 slots to hotplug additional memory and sets
+    the maximum memory the guest can reach to 4GB:
+
+    .. parsed-literal::
+
+        |qemu_system| -m 1G,slots=3,maxmem=4G
+
+    If slots and maxmem are not specified, memory hotplug won't be
+    enabled and the guest startup RAM will never increase.
+ERST
 
 DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
     "-mem-path FILE  provide backing storage for guest RAM\n", QEMU_ARCH_ALL)
-STEXI
-@item -mem-path @var{path}
-@findex -mem-path
-Allocate guest RAM from a temporarily created file in @var{path}.
-ETEXI
+SRST
+``-mem-path path``
+    Allocate guest RAM from a temporarily created file in path.
+ERST
 
 DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc,
     "-mem-prealloc   preallocate guest memory (use with -mem-path)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -mem-prealloc
-@findex -mem-prealloc
-Preallocate memory when using -mem-path.
-ETEXI
+SRST
+``-mem-prealloc``
+    Preallocate memory when using -mem-path.
+ERST
 
 DEF("k", HAS_ARG, QEMU_OPTION_k,
     "-k language     use keyboard layout (for example 'fr' for French)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -k @var{language}
-@findex -k
-Use keyboard layout @var{language} (for example @code{fr} for
-French). This option is only needed where it is not easy to get raw PC
-keycodes (e.g. on Macs, with some X11 servers or with a VNC or curses
-display). You don't normally need to use it on PC/Linux or PC/Windows
-hosts.
-
-The available layouts are:
-@example
-ar  de-ch  es  fo     fr-ca  hu  ja  mk     no  pt-br  sv
-da  en-gb  et  fr     fr-ch  is  lt  nl     pl  ru     th
-de  en-us  fi  fr-be  hr     it  lv  nl-be  pt  sl     tr
-@end example
-
-The default is @code{en-us}.
-ETEXI
+SRST
+``-k language``
+    Use keyboard layout language (for example ``fr`` for French). This
+    option is only needed where it is not easy to get raw PC keycodes
+    (e.g. on Macs, with some X11 servers or with a VNC or curses
+    display). You don't normally need to use it on PC/Linux or
+    PC/Windows hosts.
+
+    The available layouts are:
+
+    ::
+
+        ar  de-ch  es  fo     fr-ca  hu  ja  mk     no  pt-br  sv
+        da  en-gb  et  fr     fr-ch  is  lt  nl     pl  ru     th
+        de  en-us  fi  fr-be  hr     it  lv  nl-be  pt  sl     tr
+
+    The default is ``en-us``.
+ERST
 
 
 HXCOMM Deprecated by -audiodev
 DEF("audio-help", 0, QEMU_OPTION_audio_help,
     "-audio-help     show -audiodev equivalent of the currently specified audio settings\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -audio-help
-@findex -audio-help
-Will show the -audiodev equivalent of the currently specified
-(deprecated) environment variables.
-ETEXI
+SRST
+``-audio-help``
+    Will show the -audiodev equivalent of the currently specified
+    (deprecated) environment variables.
+ERST
 
 DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev,
     "-audiodev [driver=]driver,id=id[,prop[=value][,...]]\n"
@@ -572,228 +595,200 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev,
     "-audiodev wav,id=id[,prop[=value][,...]]\n"
     "                path= path of wav file to record\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -audiodev [driver=]@var{driver},id=@var{id}[,@var{prop}[=@var{value}][,...]]
-@findex -audiodev
-Adds a new audio backend @var{driver} identified by @var{id}.  There are
-global and driver specific properties.  Some values can be set
-differently for input and output, they're marked with @code{in|out.}.
-You can set the input's property with @code{in.@var{prop}} and the
-output's property with @code{out.@var{prop}}. For example:
-@example
--audiodev alsa,id=example,in.frequency=44110,out.frequency=8000
--audiodev alsa,id=example,out.channels=1 # leaves in.channels unspecified
-@end example
-
-NOTE: parameter validation is known to be incomplete, in many cases
-specifying an invalid option causes QEMU to print an error message and
-continue emulation without sound.
-
-Valid global options are:
-
-@table @option
-@item id=@var{identifier}
-Identifies the audio backend.
+SRST
+``-audiodev [driver=]driver,id=id[,prop[=value][,...]]``
+    Adds a new audio backend driver identified by id. There are global
+    and driver specific properties. Some values can be set differently
+    for input and output, they're marked with ``in|out.``. You can set
+    the input's property with ``in.prop`` and the output's property with
+    ``out.prop``. For example:
 
-@item timer-period=@var{period}
-Sets the timer @var{period} used by the audio subsystem in microseconds.
-Default is 10000 (10 ms).
+    ::
 
-@item in|out.mixing-engine=on|off
-Use QEMU's mixing engine to mix all streams inside QEMU and convert
-audio formats when not supported by the backend.  When off,
-@var{fixed-settings} must be off too.  Note that disabling this option
-means that the selected backend must support multiple streams and the
-audio formats used by the virtual cards, otherwise you'll get no sound.
-It's not recommended to disable this option unless you want to use 5.1
-or 7.1 audio, as mixing engine only supports mono and stereo audio.
-Default is on.
+        -audiodev alsa,id=example,in.frequency=44110,out.frequency=8000
+        -audiodev alsa,id=example,out.channels=1 # leaves in.channels unspecified
 
-@item in|out.fixed-settings=on|off
-Use fixed settings for host audio.  When off, it will change based on
-how the guest opens the sound card.  In this case you must not specify
-@var{frequency}, @var{channels} or @var{format}.  Default is on.
+    NOTE: parameter validation is known to be incomplete, in many cases
+    specifying an invalid option causes QEMU to print an error message
+    and continue emulation without sound.
 
-@item in|out.frequency=@var{frequency}
-Specify the @var{frequency} to use when using @var{fixed-settings}.
-Default is 44100Hz.
+    Valid global options are:
 
-@item in|out.channels=@var{channels}
-Specify the number of @var{channels} to use when using
-@var{fixed-settings}. Default is 2 (stereo).
+    ``id=identifier``
+        Identifies the audio backend.
 
-@item in|out.format=@var{format}
-Specify the sample @var{format} to use when using @var{fixed-settings}.
-Valid values are: @code{s8}, @code{s16}, @code{s32}, @code{u8},
-@code{u16}, @code{u32}. Default is @code{s16}.
+    ``timer-period=period``
+        Sets the timer period used by the audio subsystem in
+        microseconds. Default is 10000 (10 ms).
 
-@item in|out.voices=@var{voices}
-Specify the number of @var{voices} to use.  Default is 1.
+    ``in|out.mixing-engine=on|off``
+        Use QEMU's mixing engine to mix all streams inside QEMU and
+        convert audio formats when not supported by the backend. When
+        off, fixed-settings must be off too. Note that disabling this
+        option means that the selected backend must support multiple
+        streams and the audio formats used by the virtual cards,
+        otherwise you'll get no sound. It's not recommended to disable
+        this option unless you want to use 5.1 or 7.1 audio, as mixing
+        engine only supports mono and stereo audio. Default is on.
 
-@item in|out.buffer-length=@var{usecs}
-Sets the size of the buffer in microseconds.
+    ``in|out.fixed-settings=on|off``
+        Use fixed settings for host audio. When off, it will change
+        based on how the guest opens the sound card. In this case you
+        must not specify frequency, channels or format. Default is on.
 
-@end table
+    ``in|out.frequency=frequency``
+        Specify the frequency to use when using fixed-settings. Default
+        is 44100Hz.
 
-@item -audiodev none,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates a dummy backend that discards all outputs.  This backend has no
-backend specific properties.
+    ``in|out.channels=channels``
+        Specify the number of channels to use when using fixed-settings.
+        Default is 2 (stereo).
 
-@item -audiodev alsa,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates backend using the ALSA.  This backend is only available on
-Linux.
+    ``in|out.format=format``
+        Specify the sample format to use when using fixed-settings.
+        Valid values are: ``s8``, ``s16``, ``s32``, ``u8``, ``u16``,
+        ``u32``. Default is ``s16``.
 
-ALSA specific options are:
+    ``in|out.voices=voices``
+        Specify the number of voices to use. Default is 1.
 
-@table @option
+    ``in|out.buffer-length=usecs``
+        Sets the size of the buffer in microseconds.
 
-@item in|out.dev=@var{device}
-Specify the ALSA @var{device} to use for input and/or output.  Default
-is @code{default}.
+``-audiodev none,id=id[,prop[=value][,...]]``
+    Creates a dummy backend that discards all outputs. This backend has
+    no backend specific properties.
 
-@item in|out.period-length=@var{usecs}
-Sets the period length in microseconds.
+``-audiodev alsa,id=id[,prop[=value][,...]]``
+    Creates backend using the ALSA. This backend is only available on
+    Linux.
 
-@item in|out.try-poll=on|off
-Attempt to use poll mode with the device.  Default is on.
+    ALSA specific options are:
 
-@item threshold=@var{threshold}
-Threshold (in microseconds) when playback starts.  Default is 0.
+    ``in|out.dev=device``
+        Specify the ALSA device to use for input and/or output. Default
+        is ``default``.
 
-@end table
+    ``in|out.period-length=usecs``
+        Sets the period length in microseconds.
 
-@item -audiodev coreaudio,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates a backend using Apple's Core Audio.  This backend is only
-available on Mac OS and only supports playback.
+    ``in|out.try-poll=on|off``
+        Attempt to use poll mode with the device. Default is on.
 
-Core Audio specific options are:
+    ``threshold=threshold``
+        Threshold (in microseconds) when playback starts. Default is 0.
 
-@table @option
+``-audiodev coreaudio,id=id[,prop[=value][,...]]``
+    Creates a backend using Apple's Core Audio. This backend is only
+    available on Mac OS and only supports playback.
 
-@item in|out.buffer-count=@var{count}
-Sets the @var{count} of the buffers.
+    Core Audio specific options are:
 
-@end table
+    ``in|out.buffer-count=count``
+        Sets the count of the buffers.
 
-@item -audiodev dsound,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates a backend using Microsoft's DirectSound.  This backend is only
-available on Windows and only supports playback.
+``-audiodev dsound,id=id[,prop[=value][,...]]``
+    Creates a backend using Microsoft's DirectSound. This backend is
+    only available on Windows and only supports playback.
 
-DirectSound specific options are:
+    DirectSound specific options are:
 
-@table @option
+    ``latency=usecs``
+        Add extra usecs microseconds latency to playback. Default is
+        10000 (10 ms).
 
-@item latency=@var{usecs}
-Add extra @var{usecs} microseconds latency to playback.  Default is
-10000 (10 ms).
+``-audiodev oss,id=id[,prop[=value][,...]]``
+    Creates a backend using OSS. This backend is available on most
+    Unix-like systems.
 
-@end table
+    OSS specific options are:
 
-@item -audiodev oss,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates a backend using OSS.  This backend is available on most
-Unix-like systems.
+    ``in|out.dev=device``
+        Specify the file name of the OSS device to use. Default is
+        ``/dev/dsp``.
 
-OSS specific options are:
+    ``in|out.buffer-count=count``
+        Sets the count of the buffers.
 
-@table @option
+    ``in|out.try-poll=on|of``
+        Attempt to use poll mode with the device. Default is on.
 
-@item in|out.dev=@var{device}
-Specify the file name of the OSS @var{device} to use.  Default is
-@code{/dev/dsp}.
+    ``try-mmap=on|off``
+        Try using memory mapped device access. Default is off.
 
-@item in|out.buffer-count=@var{count}
-Sets the @var{count} of the buffers.
+    ``exclusive=on|off``
+        Open the device in exclusive mode (vmix won't work in this
+        case). Default is off.
 
-@item in|out.try-poll=on|of
-Attempt to use poll mode with the device.  Default is on.
+    ``dsp-policy=policy``
+        Sets the timing policy (between 0 and 10, where smaller number
+        means smaller latency but higher CPU usage). Use -1 to use
+        buffer sizes specified by ``buffer`` and ``buffer-count``. This
+        option is ignored if you do not have OSS 4. Default is 5.
 
-@item try-mmap=on|off
-Try using memory mapped device access.  Default is off.
+``-audiodev pa,id=id[,prop[=value][,...]]``
+    Creates a backend using PulseAudio. This backend is available on
+    most systems.
 
-@item exclusive=on|off
-Open the device in exclusive mode (vmix won't work in this case).
-Default is off.
+    PulseAudio specific options are:
 
-@item dsp-policy=@var{policy}
-Sets the timing policy (between 0 and 10, where smaller number means
-smaller latency but higher CPU usage).  Use -1 to use buffer sizes
-specified by @code{buffer} and @code{buffer-count}.  This option is
-ignored if you do not have OSS 4. Default is 5.
+    ``server=server``
+        Sets the PulseAudio server to connect to.
 
-@end table
+    ``in|out.name=sink``
+        Use the specified source/sink for recording/playback.
 
-@item -audiodev pa,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates a backend using PulseAudio.  This backend is available on most
-systems.
+    ``in|out.latency=usecs``
+        Desired latency in microseconds. The PulseAudio server will try
+        to honor this value but actual latencies may be lower or higher.
 
-PulseAudio specific options are:
+``-audiodev sdl,id=id[,prop[=value][,...]]``
+    Creates a backend using SDL. This backend is available on most
+    systems, but you should use your platform's native backend if
+    possible. This backend has no backend specific properties.
 
-@table @option
+``-audiodev spice,id=id[,prop[=value][,...]]``
+    Creates a backend that sends audio through SPICE. This backend
+    requires ``-spice`` and automatically selected in that case, so
+    usually you can ignore this option. This backend has no backend
+    specific properties.
 
-@item server=@var{server}
-Sets the PulseAudio @var{server} to connect to.
+``-audiodev wav,id=id[,prop[=value][,...]]``
+    Creates a backend that writes audio to a WAV file.
 
-@item in|out.name=@var{sink}
-Use the specified source/sink for recording/playback.
+    Backend specific options are:
 
-@item in|out.latency=@var{usecs}
-Desired latency in microseconds.  The PulseAudio server will try to honor this
-value but actual latencies may be lower or higher.
-
-@end table
-
-@item -audiodev sdl,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates a backend using SDL.  This backend is available on most systems,
-but you should use your platform's native backend if possible.  This
-backend has no backend specific properties.
-
-@item -audiodev spice,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates a backend that sends audio through SPICE.  This backend requires
-@code{-spice} and automatically selected in that case, so usually you
-can ignore this option.  This backend has no backend specific
-properties.
-
-@item -audiodev wav,id=@var{id}[,@var{prop}[=@var{value}][,...]]
-Creates a backend that writes audio to a WAV file.
-
-Backend specific options are:
-
-@table @option
-
-@item path=@var{path}
-Write recorded audio into the specified file.  Default is
-@code{qemu.wav}.
-
-@end table
-ETEXI
+    ``path=path``
+        Write recorded audio into the specified file. Default is
+        ``qemu.wav``.
+ERST
 
 DEF("soundhw", HAS_ARG, QEMU_OPTION_soundhw,
     "-soundhw c1,... enable audio support\n"
     "                and only specified sound cards (comma separated list)\n"
     "                use '-soundhw help' to get the list of supported cards\n"
     "                use '-soundhw all' to enable all of them\n", QEMU_ARCH_ALL)
-STEXI
-@item -soundhw @var{card1}[,@var{card2},...] or -soundhw all
-@findex -soundhw
-Enable audio and selected sound hardware. Use 'help' to print all
-available sound hardware. For example:
-
-@example
-@value{qemu_system_x86} -soundhw sb16,adlib disk.img
-@value{qemu_system_x86} -soundhw es1370 disk.img
-@value{qemu_system_x86} -soundhw ac97 disk.img
-@value{qemu_system_x86} -soundhw hda disk.img
-@value{qemu_system_x86} -soundhw all disk.img
-@value{qemu_system_x86} -soundhw help
-@end example
-
-Note that Linux's i810_audio OSS kernel (for AC97) module might
-require manually specifying clocking.
-
-@example
-modprobe i810_audio clocking=48000
-@end example
-ETEXI
+SRST
+``-soundhw card1[,card2,...] or -soundhw all``
+    Enable audio and selected sound hardware. Use 'help' to print all
+    available sound hardware. For example:
+
+    .. parsed-literal::
+
+        |qemu_system_x86| -soundhw sb16,adlib disk.img
+        |qemu_system_x86| -soundhw es1370 disk.img
+        |qemu_system_x86| -soundhw ac97 disk.img
+        |qemu_system_x86| -soundhw hda disk.img
+        |qemu_system_x86| -soundhw all disk.img
+        |qemu_system_x86| -soundhw help
+
+    Note that Linux's i810\_audio OSS kernel (for AC97) module might
+    require manually specifying clocking.
+
+    ::
+
+        modprobe i810_audio clocking=48000
+ERST
 
 DEF("device", HAS_ARG, QEMU_OPTION_device,
     "-device driver[,prop[=value][,...]]\n"
@@ -802,83 +797,85 @@ DEF("device", HAS_ARG, QEMU_OPTION_device,
     "                use '-device help' to print all possible drivers\n"
     "                use '-device driver,help' to print all possible properties\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -device @var{driver}[,@var{prop}[=@var{value}][,...]]
-@findex -device
-Add device @var{driver}.  @var{prop}=@var{value} sets driver
-properties.  Valid properties depend on the driver.  To get help on
-possible drivers and properties, use @code{-device help} and
-@code{-device @var{driver},help}.
-
-Some drivers are:
-@item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}][,sdrfile=@var{file}][,furareasize=@var{val}][,furdatafile=@var{file}][,guid=@var{uuid}]
-
-Add an IPMI BMC.  This is a simulation of a hardware management
-interface processor that normally sits on a system.  It provides
-a watchdog and the ability to reset and power control the system.
-You need to connect this to an IPMI interface to make it useful
-
-The IPMI slave address to use for the BMC.  The default is 0x20.
-This address is the BMC's address on the I2C network of management
-controllers.  If you don't know what this means, it is safe to ignore
-it.
-
-@table @option
-@item id=@var{id}
-The BMC id for interfaces to use this device.
-@item slave_addr=@var{val}
-Define slave address to use for the BMC.  The default is 0x20.
-@item sdrfile=@var{file}
-file containing raw Sensor Data Records (SDR) data. The default is none.
-@item fruareasize=@var{val}
-size of a Field Replaceable Unit (FRU) area.  The default is 1024.
-@item frudatafile=@var{file}
-file containing raw Field Replaceable Unit (FRU) inventory data. The default is none.
-@item guid=@var{uuid}
-value for the GUID for the BMC, in standard UUID format.  If this is set,
-get "Get GUID" command to the BMC will return it.  Otherwise "Get GUID"
-will return an error.
-@end table
-
-@item -device ipmi-bmc-extern,id=@var{id},chardev=@var{id}[,slave_addr=@var{val}]
-
-Add a connection to an external IPMI BMC simulator.  Instead of
-locally emulating the BMC like the above item, instead connect
-to an external entity that provides the IPMI services.
-
-A connection is made to an external BMC simulator.  If you do this, it
-is strongly recommended that you use the "reconnect=" chardev option
-to reconnect to the simulator if the connection is lost.  Note that if
-this is not used carefully, it can be a security issue, as the
-interface has the ability to send resets, NMIs, and power off the VM.
-It's best if QEMU makes a connection to an external simulator running
-on a secure port on localhost, so neither the simulator nor QEMU is
-exposed to any outside network.
-
-See the "lanserv/README.vm" file in the OpenIPMI library for more
-details on the external interface.
-
-@item -device isa-ipmi-kcs,bmc=@var{id}[,ioport=@var{val}][,irq=@var{val}]
-
-Add a KCS IPMI interafce on the ISA bus.  This also adds a
-corresponding ACPI and SMBIOS entries, if appropriate.
-
-@table @option
-@item bmc=@var{id}
-The BMC to connect to, one of ipmi-bmc-sim or ipmi-bmc-extern above.
-@item ioport=@var{val}
-Define the I/O address of the interface.  The default is 0xca0 for KCS.
-@item irq=@var{val}
-Define the interrupt to use.  The default is 5.  To disable interrupts,
-set this to 0.
-@end table
-
-@item -device isa-ipmi-bt,bmc=@var{id}[,ioport=@var{val}][,irq=@var{val}]
-
-Like the KCS interface, but defines a BT interface.  The default port is
-0xe4 and the default interrupt is 5.
-
-ETEXI
+SRST
+``-device driver[,prop[=value][,...]]``
+    Add device driver. prop=value sets driver properties. Valid
+    properties depend on the driver. To get help on possible drivers and
+    properties, use ``-device help`` and ``-device driver,help``.
+
+    Some drivers are:
+
+``-device ipmi-bmc-sim,id=id[,slave_addr=val][,sdrfile=file][,furareasize=val][,furdatafile=file][,guid=uuid]``
+    Add an IPMI BMC. This is a simulation of a hardware management
+    interface processor that normally sits on a system. It provides a
+    watchdog and the ability to reset and power control the system. You
+    need to connect this to an IPMI interface to make it useful
+
+    The IPMI slave address to use for the BMC. The default is 0x20. This
+    address is the BMC's address on the I2C network of management
+    controllers. If you don't know what this means, it is safe to ignore
+    it.
+
+    ``id=id``
+        The BMC id for interfaces to use this device.
+
+    ``slave_addr=val``
+        Define slave address to use for the BMC. The default is 0x20.
+
+    ``sdrfile=file``
+        file containing raw Sensor Data Records (SDR) data. The default
+        is none.
+
+    ``fruareasize=val``
+        size of a Field Replaceable Unit (FRU) area. The default is
+        1024.
+
+    ``frudatafile=file``
+        file containing raw Field Replaceable Unit (FRU) inventory data.
+        The default is none.
+
+    ``guid=uuid``
+        value for the GUID for the BMC, in standard UUID format. If this
+        is set, get "Get GUID" command to the BMC will return it.
+        Otherwise "Get GUID" will return an error.
+
+``-device ipmi-bmc-extern,id=id,chardev=id[,slave_addr=val]``
+    Add a connection to an external IPMI BMC simulator. Instead of
+    locally emulating the BMC like the above item, instead connect to an
+    external entity that provides the IPMI services.
+
+    A connection is made to an external BMC simulator. If you do this,
+    it is strongly recommended that you use the "reconnect=" chardev
+    option to reconnect to the simulator if the connection is lost. Note
+    that if this is not used carefully, it can be a security issue, as
+    the interface has the ability to send resets, NMIs, and power off
+    the VM. It's best if QEMU makes a connection to an external
+    simulator running on a secure port on localhost, so neither the
+    simulator nor QEMU is exposed to any outside network.
+
+    See the "lanserv/README.vm" file in the OpenIPMI library for more
+    details on the external interface.
+
+``-device isa-ipmi-kcs,bmc=id[,ioport=val][,irq=val]``
+    Add a KCS IPMI interafce on the ISA bus. This also adds a
+    corresponding ACPI and SMBIOS entries, if appropriate.
+
+    ``bmc=id``
+        The BMC to connect to, one of ipmi-bmc-sim or ipmi-bmc-extern
+        above.
+
+    ``ioport=val``
+        Define the I/O address of the interface. The default is 0xca0
+        for KCS.
+
+    ``irq=val``
+        Define the interrupt to use. The default is 5. To disable
+        interrupts, set this to 0.
+
+``-device isa-ipmi-bt,bmc=id[,ioport=val][,irq=val]``
+    Like the KCS interface, but defines a BT interface. The default port
+    is 0xe4 and the default interrupt is 5.
+ERST
 
 DEF("name", HAS_ARG, QEMU_OPTION_name,
     "-name string1[,process=string2][,debug-threads=on|off]\n"
@@ -887,45 +884,36 @@ DEF("name", HAS_ARG, QEMU_OPTION_name,
     "                When debug-threads is enabled, individual threads are given a separate name\n"
     "                NOTE: The thread names are for debugging and not a stable API.\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -name @var{name}
-@findex -name
-Sets the @var{name} of the guest.
-This name will be displayed in the SDL window caption.
-The @var{name} will also be used for the VNC server.
-Also optionally set the top visible process name in Linux.
-Naming of individual threads can also be enabled on Linux to aid debugging.
-ETEXI
+SRST
+``-name name``
+    Sets the name of the guest. This name will be displayed in the SDL
+    window caption. The name will also be used for the VNC server. Also
+    optionally set the top visible process name in Linux. Naming of
+    individual threads can also be enabled on Linux to aid debugging.
+ERST
 
 DEF("uuid", HAS_ARG, QEMU_OPTION_uuid,
     "-uuid %08x-%04x-%04x-%04x-%012x\n"
     "                specify machine UUID\n", QEMU_ARCH_ALL)
-STEXI
-@item -uuid @var{uuid}
-@findex -uuid
-Set system UUID.
-ETEXI
-
-STEXI
-@end table
-ETEXI
+SRST
+``-uuid uuid``
+    Set system UUID.
+ERST
+
 DEFHEADING()
 
 DEFHEADING(Block device options:)
-STEXI
-@table @option
-ETEXI
 
 DEF("fda", HAS_ARG, QEMU_OPTION_fda,
     "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
 DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
-STEXI
-@item -fda @var{file}
-@itemx -fdb @var{file}
-@findex -fda
-@findex -fdb
-Use @var{file} as floppy disk 0/1 image (@pxref{disk_images}).
-ETEXI
+SRST
+``-fda file``
+  \
+``-fdb file``
+    Use file as floppy disk 0/1 image (see
+    :ref:`disk_005fimages`).
+ERST
 
 DEF("hda", HAS_ARG, QEMU_OPTION_hda,
     "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n", QEMU_ARCH_ALL)
@@ -933,28 +921,27 @@ DEF("hdb", HAS_ARG, QEMU_OPTION_hdb, "", QEMU_ARCH_ALL)
 DEF("hdc", HAS_ARG, QEMU_OPTION_hdc,
     "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n", QEMU_ARCH_ALL)
 DEF("hdd", HAS_ARG, QEMU_OPTION_hdd, "", QEMU_ARCH_ALL)
-STEXI
-@item -hda @var{file}
-@itemx -hdb @var{file}
-@itemx -hdc @var{file}
-@itemx -hdd @var{file}
-@findex -hda
-@findex -hdb
-@findex -hdc
-@findex -hdd
-Use @var{file} as hard disk 0, 1, 2 or 3 image (@pxref{disk_images}).
-ETEXI
+SRST
+``-hda file``
+  \
+``-hdb file``
+  \ 
+``-hdc file``
+  \ 
+``-hdd file``
+    Use file as hard disk 0, 1, 2 or 3 image (see
+    :ref:`disk_005fimages`).
+ERST
 
 DEF("cdrom", HAS_ARG, QEMU_OPTION_cdrom,
     "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -cdrom @var{file}
-@findex -cdrom
-Use @var{file} as CD-ROM image (you cannot use @option{-hdc} and
-@option{-cdrom} at the same time). You can use the host CD-ROM by
-using @file{/dev/cdrom} as filename.
-ETEXI
+SRST
+``-cdrom file``
+    Use file as CD-ROM image (you cannot use ``-hdc`` and ``-cdrom`` at
+    the same time). You can use the host CD-ROM by using ``/dev/cdrom``
+    as filename.
+ERST
 
 DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
     "-blockdev [driver=]driver[,node-name=N][,discard=ignore|unmap]\n"
@@ -963,193 +950,216 @@ DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
     "          [,force-share=on|off][,detect-zeroes=on|off|unmap]\n"
     "          [,driver specific parameters...]\n"
     "                configure a block backend\n", QEMU_ARCH_ALL)
-STEXI
-@item -blockdev @var{option}[,@var{option}[,@var{option}[,...]]]
-@findex -blockdev
-
-Define a new block driver node. Some of the options apply to all block drivers,
-other options are only accepted for a specific block driver. See below for a
-list of generic options and options for the most common block drivers.
-
-Options that expect a reference to another node (e.g. @code{file}) can be
-given in two ways. Either you specify the node name of an already existing node
-(file=@var{node-name}), or you define a new node inline, adding options
-for the referenced node after a dot (file.filename=@var{path},file.aio=native).
-
-A block driver node created with @option{-blockdev} can be used for a guest
-device by specifying its node name for the @code{drive} property in a
-@option{-device} argument that defines a block device.
-
-@table @option
-@item Valid options for any block driver node:
-
-@table @code
-@item driver
-Specifies the block driver to use for the given node.
-@item node-name
-This defines the name of the block driver node by which it will be referenced
-later. The name must be unique, i.e. it must not match the name of a different
-block driver node, or (if you use @option{-drive} as well) the ID of a drive.
-
-If no node name is specified, it is automatically generated. The generated node
-name is not intended to be predictable and changes between QEMU invocations.
-For the top level, an explicit node name must be specified.
-@item read-only
-Open the node read-only. Guest write attempts will fail.
-
-Note that some block drivers support only read-only access, either generally or
-in certain configurations. In this case, the default value
-@option{read-only=off} does not work and the option must be specified
-explicitly.
-@item auto-read-only
-If @option{auto-read-only=on} is set, QEMU may fall back to read-only usage
-even when @option{read-only=off} is requested, or even switch between modes as
-needed, e.g. depending on whether the image file is writable or whether a
-writing user is attached to the node.
-@item force-share
-Override the image locking system of QEMU by forcing the node to utilize
-weaker shared access for permissions where it would normally request exclusive
-access.  When there is the potential for multiple instances to have the same
-file open (whether this invocation of QEMU is the first or the second
-instance), both instances must permit shared access for the second instance to
-succeed at opening the file.
-
-Enabling @option{force-share=on} requires @option{read-only=on}.
-@item cache.direct
-The host page cache can be avoided with @option{cache.direct=on}. This will
-attempt to do disk IO directly to the guest's memory. QEMU may still perform an
-internal copy of the data.
-@item cache.no-flush
-In case you don't care about data integrity over host failures, you can use
-@option{cache.no-flush=on}. This option tells QEMU that it never needs to write
-any data to the disk but can instead keep things in cache. If anything goes
-wrong, like your host losing power, the disk storage getting disconnected
-accidentally, etc. your image will most probably be rendered unusable.
-@item discard=@var{discard}
-@var{discard} is one of "ignore" (or "off") or "unmap" (or "on") and controls
-whether @code{discard} (also known as @code{trim} or @code{unmap}) requests are
-ignored or passed to the filesystem. Some machine types may not support
-discard requests.
-@item detect-zeroes=@var{detect-zeroes}
-@var{detect-zeroes} is "off", "on" or "unmap" and enables the automatic
-conversion of plain zero writes by the OS to driver specific optimized
-zero write commands. You may even choose "unmap" if @var{discard} is set
-to "unmap" to allow a zero write to be converted to an @code{unmap} operation.
-@end table
-
-@item Driver-specific options for @code{file}
-
-This is the protocol-level block driver for accessing regular files.
-
-@table @code
-@item filename
-The path to the image file in the local filesystem
-@item aio
-Specifies the AIO backend (threads/native, default: threads)
-@item locking
-Specifies whether the image file is protected with Linux OFD / POSIX locks. The
-default is to use the Linux Open File Descriptor API if available, otherwise no
-lock is applied.  (auto/on/off, default: auto)
-@end table
-Example:
-@example
--blockdev driver=file,node-name=disk,filename=disk.img
-@end example
-
-@item Driver-specific options for @code{raw}
-
-This is the image format block driver for raw images. It is usually
-stacked on top of a protocol level block driver such as @code{file}.
-
-@table @code
-@item file
-Reference to or definition of the data source block driver node
-(e.g. a @code{file} driver node)
-@end table
-Example 1:
-@example
--blockdev driver=file,node-name=disk_file,filename=disk.img
--blockdev driver=raw,node-name=disk,file=disk_file
-@end example
-Example 2:
-@example
--blockdev driver=raw,node-name=disk,file.driver=file,file.filename=disk.img
-@end example
-
-@item Driver-specific options for @code{qcow2}
-
-This is the image format block driver for qcow2 images. It is usually
-stacked on top of a protocol level block driver such as @code{file}.
-
-@table @code
-@item file
-Reference to or definition of the data source block driver node
-(e.g. a @code{file} driver node)
-
-@item backing
-Reference to or definition of the backing file block device (default is taken
-from the image file). It is allowed to pass @code{null} here in order to disable
-the default backing file.
-
-@item lazy-refcounts
-Whether to enable the lazy refcounts feature (on/off; default is taken from the
-image file)
-
-@item cache-size
-The maximum total size of the L2 table and refcount block caches in bytes
-(default: the sum of l2-cache-size and refcount-cache-size)
-
-@item l2-cache-size
-The maximum size of the L2 table cache in bytes
-(default: if cache-size is not specified - 32M on Linux platforms, and 8M on
-non-Linux platforms; otherwise, as large as possible within the cache-size,
-while permitting the requested or the minimal refcount cache size)
-
-@item refcount-cache-size
-The maximum size of the refcount block cache in bytes
-(default: 4 times the cluster size; or if cache-size is specified, the part of
-it which is not used for the L2 cache)
-
-@item cache-clean-interval
-Clean unused entries in the L2 and refcount caches. The interval is in seconds.
-The default value is 600 on supporting platforms, and 0 on other platforms.
-Setting it to 0 disables this feature.
-
-@item pass-discard-request
-Whether discard requests to the qcow2 device should be forwarded to the data
-source (on/off; default: on if discard=unmap is specified, off otherwise)
-
-@item pass-discard-snapshot
-Whether discard requests for the data source should be issued when a snapshot
-operation (e.g. deleting a snapshot) frees clusters in the qcow2 file (on/off;
-default: on)
-
-@item pass-discard-other
-Whether discard requests for the data source should be issued on other
-occasions where a cluster gets freed (on/off; default: off)
-
-@item overlap-check
-Which overlap checks to perform for writes to the image
-(none/constant/cached/all; default: cached). For details or finer
-granularity control refer to the QAPI documentation of @code{blockdev-add}.
-@end table
-
-Example 1:
-@example
--blockdev driver=file,node-name=my_file,filename=/tmp/disk.qcow2
--blockdev driver=qcow2,node-name=hda,file=my_file,overlap-check=none,cache-size=16777216
-@end example
-Example 2:
-@example
--blockdev driver=qcow2,node-name=disk,file.driver=http,file.filename=http://example.com/image.qcow2
-@end example
-
-@item Driver-specific options for other drivers
-Please refer to the QAPI documentation of the @code{blockdev-add} QMP command.
-
-@end table
-
-ETEXI
+SRST
+``-blockdev option[,option[,option[,...]]]``
+    Define a new block driver node. Some of the options apply to all
+    block drivers, other options are only accepted for a specific block
+    driver. See below for a list of generic options and options for the
+    most common block drivers.
+
+    Options that expect a reference to another node (e.g. ``file``) can
+    be given in two ways. Either you specify the node name of an already
+    existing node (file=node-name), or you define a new node inline,
+    adding options for the referenced node after a dot
+    (file.filename=path,file.aio=native).
+
+    A block driver node created with ``-blockdev`` can be used for a
+    guest device by specifying its node name for the ``drive`` property
+    in a ``-device`` argument that defines a block device.
+
+    ``Valid options for any block driver node:``
+        ``driver``
+            Specifies the block driver to use for the given node.
+
+        ``node-name``
+            This defines the name of the block driver node by which it
+            will be referenced later. The name must be unique, i.e. it
+            must not match the name of a different block driver node, or
+            (if you use ``-drive`` as well) the ID of a drive.
+
+            If no node name is specified, it is automatically generated.
+            The generated node name is not intended to be predictable
+            and changes between QEMU invocations. For the top level, an
+            explicit node name must be specified.
+
+        ``read-only``
+            Open the node read-only. Guest write attempts will fail.
+
+            Note that some block drivers support only read-only access,
+            either generally or in certain configurations. In this case,
+            the default value ``read-only=off`` does not work and the
+            option must be specified explicitly.
+
+        ``auto-read-only``
+            If ``auto-read-only=on`` is set, QEMU may fall back to
+            read-only usage even when ``read-only=off`` is requested, or
+            even switch between modes as needed, e.g. depending on
+            whether the image file is writable or whether a writing user
+            is attached to the node.
+
+        ``force-share``
+            Override the image locking system of QEMU by forcing the
+            node to utilize weaker shared access for permissions where
+            it would normally request exclusive access. When there is
+            the potential for multiple instances to have the same file
+            open (whether this invocation of QEMU is the first or the
+            second instance), both instances must permit shared access
+            for the second instance to succeed at opening the file.
+
+            Enabling ``force-share=on`` requires ``read-only=on``.
+
+        ``cache.direct``
+            The host page cache can be avoided with ``cache.direct=on``.
+            This will attempt to do disk IO directly to the guest's
+            memory. QEMU may still perform an internal copy of the data.
+
+        ``cache.no-flush``
+            In case you don't care about data integrity over host
+            failures, you can use ``cache.no-flush=on``. This option
+            tells QEMU that it never needs to write any data to the disk
+            but can instead keep things in cache. If anything goes
+            wrong, like your host losing power, the disk storage getting
+            disconnected accidentally, etc. your image will most
+            probably be rendered unusable.
+
+        ``discard=discard``
+            discard is one of "ignore" (or "off") or "unmap" (or "on")
+            and controls whether ``discard`` (also known as ``trim`` or
+            ``unmap``) requests are ignored or passed to the filesystem.
+            Some machine types may not support discard requests.
+
+        ``detect-zeroes=detect-zeroes``
+            detect-zeroes is "off", "on" or "unmap" and enables the
+            automatic conversion of plain zero writes by the OS to
+            driver specific optimized zero write commands. You may even
+            choose "unmap" if discard is set to "unmap" to allow a zero
+            write to be converted to an ``unmap`` operation.
+
+    ``Driver-specific options for file``
+        This is the protocol-level block driver for accessing regular
+        files.
+
+        ``filename``
+            The path to the image file in the local filesystem
+
+        ``aio``
+            Specifies the AIO backend (threads/native, default: threads)
+
+        ``locking``
+            Specifies whether the image file is protected with Linux OFD
+            / POSIX locks. The default is to use the Linux Open File
+            Descriptor API if available, otherwise no lock is applied.
+            (auto/on/off, default: auto)
+
+        Example:
+
+        ::
+
+            -blockdev driver=file,node-name=disk,filename=disk.img
+
+    ``Driver-specific options for raw``
+        This is the image format block driver for raw images. It is
+        usually stacked on top of a protocol level block driver such as
+        ``file``.
+
+        ``file``
+            Reference to or definition of the data source block driver
+            node (e.g. a ``file`` driver node)
+
+        Example 1:
+
+        ::
+
+            -blockdev driver=file,node-name=disk_file,filename=disk.img
+            -blockdev driver=raw,node-name=disk,file=disk_file
+
+        Example 2:
+
+        ::
+
+            -blockdev driver=raw,node-name=disk,file.driver=file,file.filename=disk.img
+
+    ``Driver-specific options for qcow2``
+        This is the image format block driver for qcow2 images. It is
+        usually stacked on top of a protocol level block driver such as
+        ``file``.
+
+        ``file``
+            Reference to or definition of the data source block driver
+            node (e.g. a ``file`` driver node)
+
+        ``backing``
+            Reference to or definition of the backing file block device
+            (default is taken from the image file). It is allowed to
+            pass ``null`` here in order to disable the default backing
+            file.
+
+        ``lazy-refcounts``
+            Whether to enable the lazy refcounts feature (on/off;
+            default is taken from the image file)
+
+        ``cache-size``
+            The maximum total size of the L2 table and refcount block
+            caches in bytes (default: the sum of l2-cache-size and
+            refcount-cache-size)
+
+        ``l2-cache-size``
+            The maximum size of the L2 table cache in bytes (default: if
+            cache-size is not specified - 32M on Linux platforms, and 8M
+            on non-Linux platforms; otherwise, as large as possible
+            within the cache-size, while permitting the requested or the
+            minimal refcount cache size)
+
+        ``refcount-cache-size``
+            The maximum size of the refcount block cache in bytes
+            (default: 4 times the cluster size; or if cache-size is
+            specified, the part of it which is not used for the L2
+            cache)
+
+        ``cache-clean-interval``
+            Clean unused entries in the L2 and refcount caches. The
+            interval is in seconds. The default value is 600 on
+            supporting platforms, and 0 on other platforms. Setting it
+            to 0 disables this feature.
+
+        ``pass-discard-request``
+            Whether discard requests to the qcow2 device should be
+            forwarded to the data source (on/off; default: on if
+            discard=unmap is specified, off otherwise)
+
+        ``pass-discard-snapshot``
+            Whether discard requests for the data source should be
+            issued when a snapshot operation (e.g. deleting a snapshot)
+            frees clusters in the qcow2 file (on/off; default: on)
+
+        ``pass-discard-other``
+            Whether discard requests for the data source should be
+            issued on other occasions where a cluster gets freed
+            (on/off; default: off)
+
+        ``overlap-check``
+            Which overlap checks to perform for writes to the image
+            (none/constant/cached/all; default: cached). For details or
+            finer granularity control refer to the QAPI documentation of
+            ``blockdev-add``.
+
+        Example 1:
+
+        ::
+
+            -blockdev driver=file,node-name=my_file,filename=/tmp/disk.qcow2
+            -blockdev driver=qcow2,node-name=hda,file=my_file,overlap-check=none,cache-size=16777216
+
+        Example 2:
+
+        ::
+
+            -blockdev driver=qcow2,node-name=disk,file.driver=http,file.filename=http://example.com/image.qcow2
+
+    ``Driver-specific options for other drivers``
+        Please refer to the QAPI documentation of the ``blockdev-add``
+        QMP command.
+ERST
 
 DEF("drive", HAS_ARG, QEMU_OPTION_drive,
     "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
@@ -1165,206 +1175,230 @@ DEF("drive", HAS_ARG, QEMU_OPTION_drive,
     "       [[,iops_size=is]]\n"
     "       [[,group=g]]\n"
     "                use 'file' as a drive image\n", QEMU_ARCH_ALL)
-STEXI
-@item -drive @var{option}[,@var{option}[,@var{option}[,...]]]
-@findex -drive
-
-Define a new drive. This includes creating a block driver node (the backend) as
-well as a guest device, and is mostly a shortcut for defining the corresponding
-@option{-blockdev} and @option{-device} options.
-
-@option{-drive} accepts all options that are accepted by @option{-blockdev}. In
-addition, it knows the following options:
-
-@table @option
-@item file=@var{file}
-This option defines which disk image (@pxref{disk_images}) to use with
-this drive. If the filename contains comma, you must double it
-(for instance, "file=my,,file" to use file "my,file").
-
-Special files such as iSCSI devices can be specified using protocol
-specific URLs. See the section for "Device URL Syntax" for more information.
-@item if=@var{interface}
-This option defines on which type on interface the drive is connected.
-Available types are: ide, scsi, sd, mtd, floppy, pflash, virtio, none.
-@item bus=@var{bus},unit=@var{unit}
-These options define where is connected the drive by defining the bus number and
-the unit id.
-@item index=@var{index}
-This option defines where is connected the drive by using an index in the list
-of available connectors of a given interface type.
-@item media=@var{media}
-This option defines the type of the media: disk or cdrom.
-@item snapshot=@var{snapshot}
-@var{snapshot} is "on" or "off" and controls snapshot mode for the given drive
-(see @option{-snapshot}).
-@item cache=@var{cache}
-@var{cache} is "none", "writeback", "unsafe", "directsync" or "writethrough"
-and controls how the host cache is used to access block data. This is a
-shortcut that sets the @option{cache.direct} and @option{cache.no-flush}
-options (as in @option{-blockdev}), and additionally @option{cache.writeback},
-which provides a default for the @option{write-cache} option of block guest
-devices (as in @option{-device}). The modes correspond to the following
-settings:
-
-@c Our texi2pod.pl script doesn't support @multitable, so fall back to using
-@c plain ASCII art (well, UTF-8 art really). This looks okay both in the manpage
-@c and the HTML output.
-@example
-@             │ cache.writeback   cache.direct   cache.no-flush
-─────────────┼─────────────────────────────────────────────────
-writeback    │ on                off            off
-none         │ on                on             off
-writethrough │ off               off            off
-directsync   │ off               on             off
-unsafe       │ on                off            on
-@end example
-
-The default mode is @option{cache=writeback}.
-
-@item aio=@var{aio}
-@var{aio} is "threads", or "native" and selects between pthread based disk I/O and native Linux AIO.
-@item format=@var{format}
-Specify which disk @var{format} will be used rather than detecting
-the format.  Can be used to specify format=raw to avoid interpreting
-an untrusted format header.
-@item werror=@var{action},rerror=@var{action}
-Specify which @var{action} to take on write and read errors. Valid actions are:
-"ignore" (ignore the error and try to continue), "stop" (pause QEMU),
-"report" (report the error to the guest), "enospc" (pause QEMU only if the
-host disk is full; report the error to the guest otherwise).
-The default setting is @option{werror=enospc} and @option{rerror=report}.
-@item copy-on-read=@var{copy-on-read}
-@var{copy-on-read} is "on" or "off" and enables whether to copy read backing
-file sectors into the image file.
-@item bps=@var{b},bps_rd=@var{r},bps_wr=@var{w}
-Specify bandwidth throttling limits in bytes per second, either for all request
-types or for reads or writes only.  Small values can lead to timeouts or hangs
-inside the guest.  A safe minimum for disks is 2 MB/s.
-@item bps_max=@var{bm},bps_rd_max=@var{rm},bps_wr_max=@var{wm}
-Specify bursts in bytes per second, either for all request types or for reads
-or writes only.  Bursts allow the guest I/O to spike above the limit
-temporarily.
-@item iops=@var{i},iops_rd=@var{r},iops_wr=@var{w}
-Specify request rate limits in requests per second, either for all request
-types or for reads or writes only.
-@item iops_max=@var{bm},iops_rd_max=@var{rm},iops_wr_max=@var{wm}
-Specify bursts in requests per second, either for all request types or for reads
-or writes only.  Bursts allow the guest I/O to spike above the limit
-temporarily.
-@item iops_size=@var{is}
-Let every @var{is} bytes of a request count as a new request for iops
-throttling purposes.  Use this option to prevent guests from circumventing iops
-limits by sending fewer but larger requests.
-@item group=@var{g}
-Join a throttling quota group with given name @var{g}.  All drives that are
-members of the same group are accounted for together.  Use this option to
-prevent guests from circumventing throttling limits by using many small disks
-instead of a single larger disk.
-@end table
-
-By default, the @option{cache.writeback=on} mode is used. It will report data
-writes as completed as soon as the data is present in the host page cache.
-This is safe as long as your guest OS makes sure to correctly flush disk caches
-where needed. If your guest OS does not handle volatile disk write caches
-correctly and your host crashes or loses power, then the guest may experience
-data corruption.
-
-For such guests, you should consider using @option{cache.writeback=off}. This
-means that the host page cache will be used to read and write data, but write
-notification will be sent to the guest only after QEMU has made sure to flush
-each write to the disk. Be aware that this has a major impact on performance.
-
-When using the @option{-snapshot} option, unsafe caching is always used.
-
-Copy-on-read avoids accessing the same backing file sectors repeatedly and is
-useful when the backing file is over a slow network.  By default copy-on-read
-is off.
-
-Instead of @option{-cdrom} you can use:
-@example
-@value{qemu_system} -drive file=file,index=2,media=cdrom
-@end example
-
-Instead of @option{-hda}, @option{-hdb}, @option{-hdc}, @option{-hdd}, you can
-use:
-@example
-@value{qemu_system} -drive file=file,index=0,media=disk
-@value{qemu_system} -drive file=file,index=1,media=disk
-@value{qemu_system} -drive file=file,index=2,media=disk
-@value{qemu_system} -drive file=file,index=3,media=disk
-@end example
-
-You can open an image using pre-opened file descriptors from an fd set:
-@example
-@value{qemu_system} \
- -add-fd fd=3,set=2,opaque="rdwr:/path/to/file" \
- -add-fd fd=4,set=2,opaque="rdonly:/path/to/file" \
- -drive file=/dev/fdset/2,index=0,media=disk
-@end example
-
-You can connect a CDROM to the slave of ide0:
-@example
-@value{qemu_system_x86} -drive file=file,if=ide,index=1,media=cdrom
-@end example
-
-If you don't specify the "file=" argument, you define an empty drive:
-@example
-@value{qemu_system_x86} -drive if=ide,index=1,media=cdrom
-@end example
-
-Instead of @option{-fda}, @option{-fdb}, you can use:
-@example
-@value{qemu_system_x86} -drive file=file,index=0,if=floppy
-@value{qemu_system_x86} -drive file=file,index=1,if=floppy
-@end example
-
-By default, @var{interface} is "ide" and @var{index} is automatically
-incremented:
-@example
-@value{qemu_system_x86} -drive file=a -drive file=b"
-@end example
-is interpreted like:
-@example
-@value{qemu_system_x86} -hda a -hdb b
-@end example
-ETEXI
+SRST
+``-drive option[,option[,option[,...]]]``
+    Define a new drive. This includes creating a block driver node (the
+    backend) as well as a guest device, and is mostly a shortcut for
+    defining the corresponding ``-blockdev`` and ``-device`` options.
+
+    ``-drive`` accepts all options that are accepted by ``-blockdev``.
+    In addition, it knows the following options:
+
+    ``file=file``
+        This option defines which disk image (see
+        :ref:`disk_005fimages`) to use with this drive. If
+        the filename contains comma, you must double it (for instance,
+        "file=my,,file" to use file "my,file").
+
+        Special files such as iSCSI devices can be specified using
+        protocol specific URLs. See the section for "Device URL Syntax"
+        for more information.
+
+    ``if=interface``
+        This option defines on which type on interface the drive is
+        connected. Available types are: ide, scsi, sd, mtd, floppy,
+        pflash, virtio, none.
+
+    ``bus=bus,unit=unit``
+        These options define where is connected the drive by defining
+        the bus number and the unit id.
+
+    ``index=index``
+        This option defines where is connected the drive by using an
+        index in the list of available connectors of a given interface
+        type.
+
+    ``media=media``
+        This option defines the type of the media: disk or cdrom.
+
+    ``snapshot=snapshot``
+        snapshot is "on" or "off" and controls snapshot mode for the
+        given drive (see ``-snapshot``).
+
+    ``cache=cache``
+        cache is "none", "writeback", "unsafe", "directsync" or
+        "writethrough" and controls how the host cache is used to access
+        block data. This is a shortcut that sets the ``cache.direct``
+        and ``cache.no-flush`` options (as in ``-blockdev``), and
+        additionally ``cache.writeback``, which provides a default for
+        the ``write-cache`` option of block guest devices (as in
+        ``-device``). The modes correspond to the following settings:
+
+        =============  ===============   ============   ==============
+        \              cache.writeback   cache.direct   cache.no-flush
+        =============  ===============   ============   ==============
+        writeback      on                off            off
+        none           on                on             off
+        writethrough   off               off            off
+        directsync     off               on             off
+        unsafe         on                off            on
+        =============  ===============   ============   ==============
+
+        The default mode is ``cache=writeback``.
+
+    ``aio=aio``
+        aio is "threads", or "native" and selects between pthread based
+        disk I/O and native Linux AIO.
+
+    ``format=format``
+        Specify which disk format will be used rather than detecting the
+        format. Can be used to specify format=raw to avoid interpreting
+        an untrusted format header.
+
+    ``werror=action,rerror=action``
+        Specify which action to take on write and read errors. Valid
+        actions are: "ignore" (ignore the error and try to continue),
+        "stop" (pause QEMU), "report" (report the error to the guest),
+        "enospc" (pause QEMU only if the host disk is full; report the
+        error to the guest otherwise). The default setting is
+        ``werror=enospc`` and ``rerror=report``.
+
+    ``copy-on-read=copy-on-read``
+        copy-on-read is "on" or "off" and enables whether to copy read
+        backing file sectors into the image file.
+
+    ``bps=b,bps_rd=r,bps_wr=w``
+        Specify bandwidth throttling limits in bytes per second, either
+        for all request types or for reads or writes only. Small values
+        can lead to timeouts or hangs inside the guest. A safe minimum
+        for disks is 2 MB/s.
+
+    ``bps_max=bm,bps_rd_max=rm,bps_wr_max=wm``
+        Specify bursts in bytes per second, either for all request types
+        or for reads or writes only. Bursts allow the guest I/O to spike
+        above the limit temporarily.
+
+    ``iops=i,iops_rd=r,iops_wr=w``
+        Specify request rate limits in requests per second, either for
+        all request types or for reads or writes only.
+
+    ``iops_max=bm,iops_rd_max=rm,iops_wr_max=wm``
+        Specify bursts in requests per second, either for all request
+        types or for reads or writes only. Bursts allow the guest I/O to
+        spike above the limit temporarily.
+
+    ``iops_size=is``
+        Let every is bytes of a request count as a new request for iops
+        throttling purposes. Use this option to prevent guests from
+        circumventing iops limits by sending fewer but larger requests.
+
+    ``group=g``
+        Join a throttling quota group with given name g. All drives that
+        are members of the same group are accounted for together. Use
+        this option to prevent guests from circumventing throttling
+        limits by using many small disks instead of a single larger
+        disk.
+
+    By default, the ``cache.writeback=on`` mode is used. It will report
+    data writes as completed as soon as the data is present in the host
+    page cache. This is safe as long as your guest OS makes sure to
+    correctly flush disk caches where needed. If your guest OS does not
+    handle volatile disk write caches correctly and your host crashes or
+    loses power, then the guest may experience data corruption.
+
+    For such guests, you should consider using ``cache.writeback=off``.
+    This means that the host page cache will be used to read and write
+    data, but write notification will be sent to the guest only after
+    QEMU has made sure to flush each write to the disk. Be aware that
+    this has a major impact on performance.
+
+    When using the ``-snapshot`` option, unsafe caching is always used.
+
+    Copy-on-read avoids accessing the same backing file sectors
+    repeatedly and is useful when the backing file is over a slow
+    network. By default copy-on-read is off.
+
+    Instead of ``-cdrom`` you can use:
+
+    .. parsed-literal::
+
+        |qemu_system| -drive file=file,index=2,media=cdrom
+
+    Instead of ``-hda``, ``-hdb``, ``-hdc``, ``-hdd``, you can use:
+
+    .. parsed-literal::
+
+        |qemu_system| -drive file=file,index=0,media=disk
+        |qemu_system| -drive file=file,index=1,media=disk
+        |qemu_system| -drive file=file,index=2,media=disk
+        |qemu_system| -drive file=file,index=3,media=disk
+
+    You can open an image using pre-opened file descriptors from an fd
+    set:
+
+    .. parsed-literal::
+
+        |qemu_system| \
+         -add-fd fd=3,set=2,opaque="rdwr:/path/to/file" \
+         -add-fd fd=4,set=2,opaque="rdonly:/path/to/file" \
+         -drive file=/dev/fdset/2,index=0,media=disk
+
+    You can connect a CDROM to the slave of ide0:
+
+    .. parsed-literal::
+
+        |qemu_system_x86| -drive file=file,if=ide,index=1,media=cdrom
+
+    If you don't specify the "file=" argument, you define an empty
+    drive:
+
+    .. parsed-literal::
+
+        |qemu_system_x86| -drive if=ide,index=1,media=cdrom
+
+    Instead of ``-fda``, ``-fdb``, you can use:
+
+    .. parsed-literal::
+
+        |qemu_system_x86| -drive file=file,index=0,if=floppy
+        |qemu_system_x86| -drive file=file,index=1,if=floppy
+
+    By default, interface is "ide" and index is automatically
+    incremented:
+
+    .. parsed-literal::
+
+        |qemu_system_x86| -drive file=a -drive file=b"
+
+    is interpreted like:
+
+    .. parsed-literal::
+
+        |qemu_system_x86| -hda a -hdb b
+ERST
 
 DEF("mtdblock", HAS_ARG, QEMU_OPTION_mtdblock,
     "-mtdblock file  use 'file' as on-board Flash memory image\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -mtdblock @var{file}
-@findex -mtdblock
-Use @var{file} as on-board Flash memory image.
-ETEXI
+SRST
+``-mtdblock file``
+    Use file as on-board Flash memory image.
+ERST
 
 DEF("sd", HAS_ARG, QEMU_OPTION_sd,
     "-sd file        use 'file' as SecureDigital card image\n", QEMU_ARCH_ALL)
-STEXI
-@item -sd @var{file}
-@findex -sd
-Use @var{file} as SecureDigital card image.
-ETEXI
+SRST
+``-sd file``
+    Use file as SecureDigital card image.
+ERST
 
 DEF("pflash", HAS_ARG, QEMU_OPTION_pflash,
     "-pflash file    use 'file' as a parallel flash image\n", QEMU_ARCH_ALL)
-STEXI
-@item -pflash @var{file}
-@findex -pflash
-Use @var{file} as a parallel flash image.
-ETEXI
+SRST
+``-pflash file``
+    Use file as a parallel flash image.
+ERST
 
 DEF("snapshot", 0, QEMU_OPTION_snapshot,
     "-snapshot       write to temporary files instead of disk image files\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -snapshot
-@findex -snapshot
-Write to temporary files instead of disk image files. In this case,
-the raw disk image you use is not written back. You can however force
-the write back by pressing @key{C-a s} (@pxref{disk_images}).
-ETEXI
+SRST
+``-snapshot``
+    Write to temporary files instead of disk image files. In this case,
+    the raw disk image you use is not written back. You can however
+    force the write back by pressing C-a s (see
+    :ref:`disk_005fimages`).
+ERST
 
 DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
     "-fsdev local,id=id,path=path,security_model=mapped-xattr|mapped-file|passthrough|none\n"
@@ -1379,93 +1413,118 @@ DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
     "-fsdev synth,id=id\n",
     QEMU_ARCH_ALL)
 
-STEXI
-
-@item -fsdev local,id=@var{id},path=@var{path},security_model=@var{security_model} [,writeout=@var{writeout}][,readonly][,fmode=@var{fmode}][,dmode=@var{dmode}] [,throttling.@var{option}=@var{value}[,throttling.@var{option}=@var{value}[,...]]]
-@itemx -fsdev proxy,id=@var{id},socket=@var{socket}[,writeout=@var{writeout}][,readonly]
-@itemx -fsdev proxy,id=@var{id},sock_fd=@var{sock_fd}[,writeout=@var{writeout}][,readonly]
-@itemx -fsdev synth,id=@var{id}[,readonly]
-@findex -fsdev
-Define a new file system device. Valid options are:
-@table @option
-@item local
-Accesses to the filesystem are done by QEMU.
-@item proxy
-Accesses to the filesystem are done by virtfs-proxy-helper(1).
-@item synth
-Synthetic filesystem, only used by QTests.
-@item id=@var{id}
-Specifies identifier for this device.
-@item path=@var{path}
-Specifies the export path for the file system device. Files under
-this path will be available to the 9p client on the guest.
-@item security_model=@var{security_model}
-Specifies the security model to be used for this export path.
-Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".
-In "passthrough" security model, files are stored using the same
-credentials as they are created on the guest. This requires QEMU
-to run as root. In "mapped-xattr" security model, some of the file
-attributes like uid, gid, mode bits and link target are stored as
-file attributes. For "mapped-file" these attributes are stored in the
-hidden .virtfs_metadata directory. Directories exported by this security model cannot
-interact with other unix tools. "none" security model is same as
-passthrough except the sever won't report failures if it fails to
-set file attributes like ownership. Security model is mandatory
-only for local fsdriver. Other fsdrivers (like proxy) don't take
-security model as a parameter.
-@item writeout=@var{writeout}
-This is an optional argument. The only supported value is "immediate".
-This means that host page cache will be used to read and write data but
-write notification will be sent to the guest only when the data has been
-reported as written by the storage subsystem.
-@item readonly
-Enables exporting 9p share as a readonly mount for guests. By default
-read-write access is given.
-@item socket=@var{socket}
-Enables proxy filesystem driver to use passed socket file for communicating
-with virtfs-proxy-helper(1).
-@item sock_fd=@var{sock_fd}
-Enables proxy filesystem driver to use passed socket descriptor for
-communicating with virtfs-proxy-helper(1). Usually a helper like libvirt
-will create socketpair and pass one of the fds as sock_fd.
-@item fmode=@var{fmode}
-Specifies the default mode for newly created files on the host. Works only
-with security models "mapped-xattr" and "mapped-file".
-@item dmode=@var{dmode}
-Specifies the default mode for newly created directories on the host. Works
-only with security models "mapped-xattr" and "mapped-file".
-@item throttling.bps-total=@var{b},throttling.bps-read=@var{r},throttling.bps-write=@var{w}
-Specify bandwidth throttling limits in bytes per second, either for all request
-types or for reads or writes only.
-@item throttling.bps-total-max=@var{bm},bps-read-max=@var{rm},bps-write-max=@var{wm}
-Specify bursts in bytes per second, either for all request types or for reads
-or writes only.  Bursts allow the guest I/O to spike above the limit
-temporarily.
-@item throttling.iops-total=@var{i},throttling.iops-read=@var{r}, throttling.iops-write=@var{w}
-Specify request rate limits in requests per second, either for all request
-types or for reads or writes only.
-@item throttling.iops-total-max=@var{im},throttling.iops-read-max=@var{irm}, throttling.iops-write-max=@var{iwm}
-Specify bursts in requests per second, either for all request types or for reads
-or writes only.  Bursts allow the guest I/O to spike above the limit temporarily.
-@item throttling.iops-size=@var{is}
-Let every @var{is} bytes of a request count as a new request for iops
-throttling purposes.
-@end table
-
--fsdev option is used along with -device driver "virtio-9p-...".
-@item -device virtio-9p-@var{type},fsdev=@var{id},mount_tag=@var{mount_tag}
-Options for virtio-9p-... driver are:
-@table @option
-@item @var{type}
-Specifies the variant to be used. Supported values are "pci", "ccw" or "device",
-depending on the machine type.
-@item fsdev=@var{id}
-Specifies the id value specified along with -fsdev option.
-@item mount_tag=@var{mount_tag}
-Specifies the tag name to be used by the guest to mount this export point.
-@end table
-
-ETEXI
+SRST
+``-fsdev local,id=id,path=path,security_model=security_model [,writeout=writeout][,readonly][,fmode=fmode][,dmode=dmode] [,throttling.option=value[,throttling.option=value[,...]]]``
+  \ 
+``-fsdev proxy,id=id,socket=socket[,writeout=writeout][,readonly]``
+  \
+``-fsdev proxy,id=id,sock_fd=sock_fd[,writeout=writeout][,readonly]``
+  \
+``-fsdev synth,id=id[,readonly]``
+    Define a new file system device. Valid options are:
+
+    ``local``
+        Accesses to the filesystem are done by QEMU.
+
+    ``proxy``
+        Accesses to the filesystem are done by virtfs-proxy-helper(1).
+
+    ``synth``
+        Synthetic filesystem, only used by QTests.
+
+    ``id=id``
+        Specifies identifier for this device.
+
+    ``path=path``
+        Specifies the export path for the file system device. Files
+        under this path will be available to the 9p client on the guest.
+
+    ``security_model=security_model``
+        Specifies the security model to be used for this export path.
+        Supported security models are "passthrough", "mapped-xattr",
+        "mapped-file" and "none". In "passthrough" security model, files
+        are stored using the same credentials as they are created on the
+        guest. This requires QEMU to run as root. In "mapped-xattr"
+        security model, some of the file attributes like uid, gid, mode
+        bits and link target are stored as file attributes. For
+        "mapped-file" these attributes are stored in the hidden
+        .virtfs\_metadata directory. Directories exported by this
+        security model cannot interact with other unix tools. "none"
+        security model is same as passthrough except the sever won't
+        report failures if it fails to set file attributes like
+        ownership. Security model is mandatory only for local fsdriver.
+        Other fsdrivers (like proxy) don't take security model as a
+        parameter.
+
+    ``writeout=writeout``
+        This is an optional argument. The only supported value is
+        "immediate". This means that host page cache will be used to
+        read and write data but write notification will be sent to the
+        guest only when the data has been reported as written by the
+        storage subsystem.
+
+    ``readonly``
+        Enables exporting 9p share as a readonly mount for guests. By
+        default read-write access is given.
+
+    ``socket=socket``
+        Enables proxy filesystem driver to use passed socket file for
+        communicating with virtfs-proxy-helper(1).
+
+    ``sock_fd=sock_fd``
+        Enables proxy filesystem driver to use passed socket descriptor
+        for communicating with virtfs-proxy-helper(1). Usually a helper
+        like libvirt will create socketpair and pass one of the fds as
+        sock\_fd.
+
+    ``fmode=fmode``
+        Specifies the default mode for newly created files on the host.
+        Works only with security models "mapped-xattr" and
+        "mapped-file".
+
+    ``dmode=dmode``
+        Specifies the default mode for newly created directories on the
+        host. Works only with security models "mapped-xattr" and
+        "mapped-file".
+
+    ``throttling.bps-total=b,throttling.bps-read=r,throttling.bps-write=w``
+        Specify bandwidth throttling limits in bytes per second, either
+        for all request types or for reads or writes only.
+
+    ``throttling.bps-total-max=bm,bps-read-max=rm,bps-write-max=wm``
+        Specify bursts in bytes per second, either for all request types
+        or for reads or writes only. Bursts allow the guest I/O to spike
+        above the limit temporarily.
+
+    ``throttling.iops-total=i,throttling.iops-read=r, throttling.iops-write=w``
+        Specify request rate limits in requests per second, either for
+        all request types or for reads or writes only.
+
+    ``throttling.iops-total-max=im,throttling.iops-read-max=irm, throttling.iops-write-max=iwm``
+        Specify bursts in requests per second, either for all request
+        types or for reads or writes only. Bursts allow the guest I/O to
+        spike above the limit temporarily.
+
+    ``throttling.iops-size=is``
+        Let every is bytes of a request count as a new request for iops
+        throttling purposes.
+
+    -fsdev option is used along with -device driver "virtio-9p-...".
+
+``-device virtio-9p-type,fsdev=id,mount_tag=mount_tag``
+    Options for virtio-9p-... driver are:
+
+    ``type``
+        Specifies the variant to be used. Supported values are "pci",
+        "ccw" or "device", depending on the machine type.
+
+    ``fsdev=id``
+        Specifies the id value specified along with -fsdev option.
+
+    ``mount_tag=mount_tag``
+        Specifies the tag name to be used by the guest to mount this
+        export point.
+ERST
 
 DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs,
     "-virtfs local,path=path,mount_tag=tag,security_model=mapped-xattr|mapped-file|passthrough|none\n"
@@ -1475,88 +1534,113 @@ DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs,
     "-virtfs synth,mount_tag=tag[,id=id][,readonly]\n",
     QEMU_ARCH_ALL)
 
-STEXI
-
-@item -virtfs local,path=@var{path},mount_tag=@var{mount_tag} ,security_model=@var{security_model}[,writeout=@var{writeout}][,readonly] [,fmode=@var{fmode}][,dmode=@var{dmode}][,multidevs=@var{multidevs}]
-@itemx -virtfs proxy,socket=@var{socket},mount_tag=@var{mount_tag} [,writeout=@var{writeout}][,readonly]
-@itemx -virtfs proxy,sock_fd=@var{sock_fd},mount_tag=@var{mount_tag} [,writeout=@var{writeout}][,readonly]
-@itemx -virtfs synth,mount_tag=@var{mount_tag}
-@findex -virtfs
-
-Define a new filesystem device and expose it to the guest using a virtio-9p-device. The general form of a Virtual File system pass-through options are:
-@table @option
-@item local
-Accesses to the filesystem are done by QEMU.
-@item proxy
-Accesses to the filesystem are done by virtfs-proxy-helper(1).
-@item synth
-Synthetic filesystem, only used by QTests.
-@item id=@var{id}
-Specifies identifier for the filesystem device
-@item path=@var{path}
-Specifies the export path for the file system device. Files under
-this path will be available to the 9p client on the guest.
-@item security_model=@var{security_model}
-Specifies the security model to be used for this export path.
-Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".
-In "passthrough" security model, files are stored using the same
-credentials as they are created on the guest. This requires QEMU
-to run as root. In "mapped-xattr" security model, some of the file
-attributes like uid, gid, mode bits and link target are stored as
-file attributes. For "mapped-file" these attributes are stored in the
-hidden .virtfs_metadata directory. Directories exported by this security model cannot
-interact with other unix tools. "none" security model is same as
-passthrough except the sever won't report failures if it fails to
-set file attributes like ownership. Security model is mandatory only
-for local fsdriver. Other fsdrivers (like proxy) don't take security
-model as a parameter.
-@item writeout=@var{writeout}
-This is an optional argument. The only supported value is "immediate".
-This means that host page cache will be used to read and write data but
-write notification will be sent to the guest only when the data has been
-reported as written by the storage subsystem.
-@item readonly
-Enables exporting 9p share as a readonly mount for guests. By default
-read-write access is given.
-@item socket=@var{socket}
-Enables proxy filesystem driver to use passed socket file for
-communicating with virtfs-proxy-helper(1). Usually a helper like libvirt
-will create socketpair and pass one of the fds as sock_fd.
-@item sock_fd
-Enables proxy filesystem driver to use passed 'sock_fd' as the socket
-descriptor for interfacing with virtfs-proxy-helper(1).
-@item fmode=@var{fmode}
-Specifies the default mode for newly created files on the host. Works only
-with security models "mapped-xattr" and "mapped-file".
-@item dmode=@var{dmode}
-Specifies the default mode for newly created directories on the host. Works
-only with security models "mapped-xattr" and "mapped-file".
-@item mount_tag=@var{mount_tag}
-Specifies the tag name to be used by the guest to mount this export point.
-@item multidevs=@var{multidevs}
-Specifies how to deal with multiple devices being shared with a 9p export.
-Supported behaviours are either "remap", "forbid" or "warn". The latter is
-the default behaviour on which virtfs 9p expects only one device to be
-shared with the same export, and if more than one device is shared and
-accessed via the same 9p export then only a warning message is logged
-(once) by qemu on host side. In order to avoid file ID collisions on guest
-you should either create a separate virtfs export for each device to be
-shared with guests (recommended way) or you might use "remap" instead which
-allows you to share multiple devices with only one export instead, which is
-achieved by remapping the original inode numbers from host to guest in a
-way that would prevent such collisions. Remapping inodes in such use cases
-is required because the original device IDs from host are never passed and
-exposed on guest. Instead all files of an export shared with virtfs always
-share the same device id on guest. So two files with identical inode
-numbers but from actually different devices on host would otherwise cause a
-file ID collision and hence potential misbehaviours on guest. "forbid" on
-the other hand assumes like "warn" that only one device is shared by the
-same export, however it will not only log a warning message but also
-deny access to additional devices on guest. Note though that "forbid" does
-currently not block all possible file access operations (e.g. readdir()
-would still return entries from other devices).
-@end table
-ETEXI
+SRST
+``-virtfs local,path=path,mount_tag=mount_tag ,security_model=security_model[,writeout=writeout][,readonly] [,fmode=fmode][,dmode=dmode][,multidevs=multidevs]``
+  \ 
+``-virtfs proxy,socket=socket,mount_tag=mount_tag [,writeout=writeout][,readonly]``
+  \ 
+``-virtfs proxy,sock_fd=sock_fd,mount_tag=mount_tag [,writeout=writeout][,readonly]``
+  \
+``-virtfs synth,mount_tag=mount_tag``
+    Define a new filesystem device and expose it to the guest using a
+    virtio-9p-device. The general form of a Virtual File system
+    pass-through options are:
+
+    ``local``
+        Accesses to the filesystem are done by QEMU.
+
+    ``proxy``
+        Accesses to the filesystem are done by virtfs-proxy-helper(1).
+
+    ``synth``
+        Synthetic filesystem, only used by QTests.
+
+    ``id=id``
+        Specifies identifier for the filesystem device
+
+    ``path=path``
+        Specifies the export path for the file system device. Files
+        under this path will be available to the 9p client on the guest.
+
+    ``security_model=security_model``
+        Specifies the security model to be used for this export path.
+        Supported security models are "passthrough", "mapped-xattr",
+        "mapped-file" and "none". In "passthrough" security model, files
+        are stored using the same credentials as they are created on the
+        guest. This requires QEMU to run as root. In "mapped-xattr"
+        security model, some of the file attributes like uid, gid, mode
+        bits and link target are stored as file attributes. For
+        "mapped-file" these attributes are stored in the hidden
+        .virtfs\_metadata directory. Directories exported by this
+        security model cannot interact with other unix tools. "none"
+        security model is same as passthrough except the sever won't
+        report failures if it fails to set file attributes like
+        ownership. Security model is mandatory only for local fsdriver.
+        Other fsdrivers (like proxy) don't take security model as a
+        parameter.
+
+    ``writeout=writeout``
+        This is an optional argument. The only supported value is
+        "immediate". This means that host page cache will be used to
+        read and write data but write notification will be sent to the
+        guest only when the data has been reported as written by the
+        storage subsystem.
+
+    ``readonly``
+        Enables exporting 9p share as a readonly mount for guests. By
+        default read-write access is given.
+
+    ``socket=socket``
+        Enables proxy filesystem driver to use passed socket file for
+        communicating with virtfs-proxy-helper(1). Usually a helper like
+        libvirt will create socketpair and pass one of the fds as
+        sock\_fd.
+
+    ``sock_fd``
+        Enables proxy filesystem driver to use passed 'sock\_fd' as the
+        socket descriptor for interfacing with virtfs-proxy-helper(1).
+
+    ``fmode=fmode``
+        Specifies the default mode for newly created files on the host.
+        Works only with security models "mapped-xattr" and
+        "mapped-file".
+
+    ``dmode=dmode``
+        Specifies the default mode for newly created directories on the
+        host. Works only with security models "mapped-xattr" and
+        "mapped-file".
+
+    ``mount_tag=mount_tag``
+        Specifies the tag name to be used by the guest to mount this
+        export point.
+
+    ``multidevs=multidevs``
+        Specifies how to deal with multiple devices being shared with a
+        9p export. Supported behaviours are either "remap", "forbid" or
+        "warn". The latter is the default behaviour on which virtfs 9p
+        expects only one device to be shared with the same export, and
+        if more than one device is shared and accessed via the same 9p
+        export then only a warning message is logged (once) by qemu on
+        host side. In order to avoid file ID collisions on guest you
+        should either create a separate virtfs export for each device to
+        be shared with guests (recommended way) or you might use "remap"
+        instead which allows you to share multiple devices with only one
+        export instead, which is achieved by remapping the original
+        inode numbers from host to guest in a way that would prevent
+        such collisions. Remapping inodes in such use cases is required
+        because the original device IDs from host are never passed and
+        exposed on guest. Instead all files of an export shared with
+        virtfs always share the same device id on guest. So two files
+        with identical inode numbers but from actually different devices
+        on host would otherwise cause a file ID collision and hence
+        potential misbehaviours on guest. "forbid" on the other hand
+        assumes like "warn" that only one device is shared by the same
+        export, however it will not only log a warning message but also
+        deny access to additional devices on guest. Note though that
+        "forbid" does currently not block all possible file access
+        operations (e.g. readdir() would still return entries from other
+        devices).
+ERST
 
 DEF("iscsi", HAS_ARG, QEMU_OPTION_iscsi,
     "-iscsi [user=user][,password=password]\n"
@@ -1565,70 +1649,53 @@ DEF("iscsi", HAS_ARG, QEMU_OPTION_iscsi,
     "       [,timeout=timeout]\n"
     "                iSCSI session parameters\n", QEMU_ARCH_ALL)
 
-STEXI
-@item -iscsi
-@findex -iscsi
-Configure iSCSI session parameters.
-ETEXI
+SRST
+``-iscsi``
+    Configure iSCSI session parameters.
+ERST
 
-STEXI
-@end table
-ETEXI
 DEFHEADING()
 
 DEFHEADING(USB options:)
-STEXI
-@table @option
-ETEXI
 
 DEF("usb", 0, QEMU_OPTION_usb,
     "-usb            enable on-board USB host controller (if not enabled by default)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -usb
-@findex -usb
-Enable USB emulation on machine types with an on-board USB host controller (if
-not enabled by default).  Note that on-board USB host controllers may not
-support USB 3.0.  In this case @option{-device qemu-xhci} can be used instead
-on machines with PCI.
-ETEXI
+SRST
+``-usb``
+    Enable USB emulation on machine types with an on-board USB host
+    controller (if not enabled by default). Note that on-board USB host
+    controllers may not support USB 3.0. In this case
+    ``-device qemu-xhci`` can be used instead on machines with PCI.
+ERST
 
 DEF("usbdevice", HAS_ARG, QEMU_OPTION_usbdevice,
     "-usbdevice name add the host or guest USB device 'name'\n",
     QEMU_ARCH_ALL)
-STEXI
-
-@item -usbdevice @var{devname}
-@findex -usbdevice
-Add the USB device @var{devname}. Note that this option is deprecated,
-please use @code{-device usb-...} instead. @xref{usb_devices}.
-
-@table @option
-
-@item mouse
-Virtual Mouse. This will override the PS/2 mouse emulation when activated.
-
-@item tablet
-Pointer device that uses absolute coordinates (like a touchscreen). This
-means QEMU is able to report the mouse position without having to grab the
-mouse. Also overrides the PS/2 mouse emulation when activated.
+SRST
+``-usbdevice devname``
+    Add the USB device devname. Note that this option is deprecated,
+    please use ``-device usb-...`` instead. See
+    :ref:`usb_005fdevices`.
+
+    ``mouse``
+        Virtual Mouse. This will override the PS/2 mouse emulation when
+        activated.
+
+    ``tablet``
+        Pointer device that uses absolute coordinates (like a
+        touchscreen). This means QEMU is able to report the mouse
+        position without having to grab the mouse. Also overrides the
+        PS/2 mouse emulation when activated.
+
+    ``braille``
+        Braille device. This will use BrlAPI to display the braille
+        output on a real or fake device.
+ERST
 
-@item braille
-Braille device.  This will use BrlAPI to display the braille output on a real
-or fake device.
-
-@end table
-ETEXI
-
-STEXI
-@end table
-ETEXI
 DEFHEADING()
 
 DEFHEADING(Display options:)
-STEXI
-@table @option
-ETEXI
 
 DEF("display", HAS_ARG, QEMU_OPTION_display,
 #if defined(CONFIG_SPICE)
@@ -1665,111 +1732,114 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
             "\"-display none\"\n"
 #endif
     , QEMU_ARCH_ALL)
-STEXI
-@item -display @var{type}
-@findex -display
-Select type of display to use. This option is a replacement for the
-old style -sdl/-curses/... options. Use @code{-display help} to list
-the available display types. Valid values for @var{type} are
-@table @option
-@item sdl
-Display video output via SDL (usually in a separate graphics
-window; see the SDL documentation for other possibilities).
-@item curses
-Display video output via curses. For graphics device models which
-support a text mode, QEMU can display this output using a
-curses/ncurses interface. Nothing is displayed when the graphics
-device is in graphical mode or if the graphics device does not support
-a text mode. Generally only the VGA device models support text mode.
-The font charset used by the guest can be specified with the
-@code{charset} option, for example @code{charset=CP850} for IBM CP850
-encoding. The default is @code{CP437}.
-@item none
-Do not display video output. The guest will still see an emulated
-graphics card, but its output will not be displayed to the QEMU
-user. This option differs from the -nographic option in that it
-only affects what is done with video output; -nographic also changes
-the destination of the serial and parallel port data.
-@item gtk
-Display video output in a GTK window. This interface provides drop-down
-menus and other UI elements to configure and control the VM during
-runtime.
-@item vnc
-Start a VNC server on display <arg>
-@item egl-headless
-Offload all OpenGL operations to a local DRI device. For any graphical display,
-this display needs to be paired with either VNC or SPICE displays.
-@item spice-app
-Start QEMU as a Spice server and launch the default Spice client
-application. The Spice server will redirect the serial consoles and
-QEMU monitors. (Since 4.0)
-@end table
-ETEXI
+SRST
+``-display type``
+    Select type of display to use. This option is a replacement for the
+    old style -sdl/-curses/... options. Use ``-display help`` to list
+    the available display types. Valid values for type are
+
+    ``sdl``
+        Display video output via SDL (usually in a separate graphics
+        window; see the SDL documentation for other possibilities).
+
+    ``curses``
+        Display video output via curses. For graphics device models
+        which support a text mode, QEMU can display this output using a
+        curses/ncurses interface. Nothing is displayed when the graphics
+        device is in graphical mode or if the graphics device does not
+        support a text mode. Generally only the VGA device models
+        support text mode. The font charset used by the guest can be
+        specified with the ``charset`` option, for example
+        ``charset=CP850`` for IBM CP850 encoding. The default is
+        ``CP437``.
+
+    ``none``
+        Do not display video output. The guest will still see an
+        emulated graphics card, but its output will not be displayed to
+        the QEMU user. This option differs from the -nographic option in
+        that it only affects what is done with video output; -nographic
+        also changes the destination of the serial and parallel port
+        data.
+
+    ``gtk``
+        Display video output in a GTK window. This interface provides
+        drop-down menus and other UI elements to configure and control
+        the VM during runtime.
+
+    ``vnc``
+        Start a VNC server on display <arg>
+
+    ``egl-headless``
+        Offload all OpenGL operations to a local DRI device. For any
+        graphical display, this display needs to be paired with either
+        VNC or SPICE displays.
+
+    ``spice-app``
+        Start QEMU as a Spice server and launch the default Spice client
+        application. The Spice server will redirect the serial consoles
+        and QEMU monitors. (Since 4.0)
+ERST
 
 DEF("nographic", 0, QEMU_OPTION_nographic,
     "-nographic      disable graphical output and redirect serial I/Os to console\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -nographic
-@findex -nographic
-Normally, if QEMU is compiled with graphical window support, it displays
-output such as guest graphics, guest console, and the QEMU monitor in a
-window. With this option, you can totally disable graphical output so
-that QEMU is a simple command line application. The emulated serial port
-is redirected on the console and muxed with the monitor (unless
-redirected elsewhere explicitly). Therefore, you can still use QEMU to
-debug a Linux kernel with a serial console. Use @key{C-a h} for help on
-switching between the console and monitor.
-ETEXI
+SRST
+``-nographic``
+    Normally, if QEMU is compiled with graphical window support, it
+    displays output such as guest graphics, guest console, and the QEMU
+    monitor in a window. With this option, you can totally disable
+    graphical output so that QEMU is a simple command line application.
+    The emulated serial port is redirected on the console and muxed with
+    the monitor (unless redirected elsewhere explicitly). Therefore, you
+    can still use QEMU to debug a Linux kernel with a serial console.
+    Use C-a h for help on switching between the console and monitor.
+ERST
 
 DEF("curses", 0, QEMU_OPTION_curses,
     "-curses         shorthand for -display curses\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -curses
-@findex -curses
-Normally, if QEMU is compiled with graphical window support, it displays
-output such as guest graphics, guest console, and the QEMU monitor in a
-window. With this option, QEMU can display the VGA output when in text
-mode using a curses/ncurses interface. Nothing is displayed in graphical
-mode.
-ETEXI
+SRST
+``-curses``
+    Normally, if QEMU is compiled with graphical window support, it
+    displays output such as guest graphics, guest console, and the QEMU
+    monitor in a window. With this option, QEMU can display the VGA
+    output when in text mode using a curses/ncurses interface. Nothing
+    is displayed in graphical mode.
+ERST
 
 DEF("alt-grab", 0, QEMU_OPTION_alt_grab,
     "-alt-grab       use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -alt-grab
-@findex -alt-grab
-Use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt). Note that this also
-affects the special keys (for fullscreen, monitor-mode switching, etc).
-ETEXI
+SRST
+``-alt-grab``
+    Use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt). Note that
+    this also affects the special keys (for fullscreen, monitor-mode
+    switching, etc).
+ERST
 
 DEF("ctrl-grab", 0, QEMU_OPTION_ctrl_grab,
     "-ctrl-grab      use Right-Ctrl to grab mouse (instead of Ctrl-Alt)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -ctrl-grab
-@findex -ctrl-grab
-Use Right-Ctrl to grab mouse (instead of Ctrl-Alt). Note that this also
-affects the special keys (for fullscreen, monitor-mode switching, etc).
-ETEXI
+SRST
+``-ctrl-grab``
+    Use Right-Ctrl to grab mouse (instead of Ctrl-Alt). Note that this
+    also affects the special keys (for fullscreen, monitor-mode
+    switching, etc).
+ERST
 
 DEF("no-quit", 0, QEMU_OPTION_no_quit,
     "-no-quit        disable SDL window close capability\n", QEMU_ARCH_ALL)
-STEXI
-@item -no-quit
-@findex -no-quit
-Disable SDL window close capability.
-ETEXI
+SRST
+``-no-quit``
+    Disable SDL window close capability.
+ERST
 
 DEF("sdl", 0, QEMU_OPTION_sdl,
     "-sdl            shorthand for -display sdl\n", QEMU_ARCH_ALL)
-STEXI
-@item -sdl
-@findex -sdl
-Enable SDL.
-ETEXI
+SRST
+``-sdl``
+    Enable SDL.
+ERST
 
 DEF("spice", HAS_ARG, QEMU_OPTION_spice,
     "-spice [port=port][,tls-port=secured-port][,x509-dir=<dir>]\n"
@@ -1790,431 +1860,405 @@ DEF("spice", HAS_ARG, QEMU_OPTION_spice,
     "   enable spice\n"
     "   at least one of {port, tls-port} is mandatory\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -spice @var{option}[,@var{option}[,...]]
-@findex -spice
-Enable the spice remote desktop protocol. Valid options are
-
-@table @option
-
-@item port=<nr>
-Set the TCP port spice is listening on for plaintext channels.
+SRST
+``-spice option[,option[,...]]``
+    Enable the spice remote desktop protocol. Valid options are
 
-@item addr=<addr>
-Set the IP address spice is listening on.  Default is any address.
+    ``port=<nr>``
+        Set the TCP port spice is listening on for plaintext channels.
 
-@item ipv4
-@itemx ipv6
-@itemx unix
-Force using the specified IP version.
+    ``addr=<addr>``
+        Set the IP address spice is listening on. Default is any
+        address.
 
-@item password=<secret>
-Set the password you need to authenticate.
+    ``ipv4``; \ ``ipv6``; \ ``unix``
+        Force using the specified IP version.
 
-@item sasl
-Require that the client use SASL to authenticate with the spice.
-The exact choice of authentication method used is controlled from the
-system / user's SASL configuration file for the 'qemu' service. This
-is typically found in /etc/sasl2/qemu.conf. If running QEMU as an
-unprivileged user, an environment variable SASL_CONF_PATH can be used
-to make it search alternate locations for the service config.
-While some SASL auth methods can also provide data encryption (eg GSSAPI),
-it is recommended that SASL always be combined with the 'tls' and
-'x509' settings to enable use of SSL and server certificates. This
-ensures a data encryption preventing compromise of authentication
-credentials.
+    ``password=<secret>``
+        Set the password you need to authenticate.
 
-@item disable-ticketing
-Allow client connects without authentication.
+    ``sasl``
+        Require that the client use SASL to authenticate with the spice.
+        The exact choice of authentication method used is controlled
+        from the system / user's SASL configuration file for the 'qemu'
+        service. This is typically found in /etc/sasl2/qemu.conf. If
+        running QEMU as an unprivileged user, an environment variable
+        SASL\_CONF\_PATH can be used to make it search alternate
+        locations for the service config. While some SASL auth methods
+        can also provide data encryption (eg GSSAPI), it is recommended
+        that SASL always be combined with the 'tls' and 'x509' settings
+        to enable use of SSL and server certificates. This ensures a
+        data encryption preventing compromise of authentication
+        credentials.
 
-@item disable-copy-paste
-Disable copy paste between the client and the guest.
+    ``disable-ticketing``
+        Allow client connects without authentication.
 
-@item disable-agent-file-xfer
-Disable spice-vdagent based file-xfer between the client and the guest.
+    ``disable-copy-paste``
+        Disable copy paste between the client and the guest.
 
-@item tls-port=<nr>
-Set the TCP port spice is listening on for encrypted channels.
+    ``disable-agent-file-xfer``
+        Disable spice-vdagent based file-xfer between the client and the
+        guest.
 
-@item x509-dir=<dir>
-Set the x509 file directory. Expects same filenames as -vnc $display,x509=$dir
+    ``tls-port=<nr>``
+        Set the TCP port spice is listening on for encrypted channels.
 
-@item x509-key-file=<file>
-@itemx x509-key-password=<file>
-@itemx x509-cert-file=<file>
-@itemx x509-cacert-file=<file>
-@itemx x509-dh-key-file=<file>
-The x509 file names can also be configured individually.
+    ``x509-dir=<dir>``
+        Set the x509 file directory. Expects same filenames as -vnc
+        $display,x509=$dir
 
-@item tls-ciphers=<list>
-Specify which ciphers to use.
+    ``x509-key-file=<file>``; \ ``x509-key-password=<file>``; \ ``x509-cert-file=<file>``; \ ``x509-cacert-file=<file>``; \ ``x509-dh-key-file=<file>``
+        The x509 file names can also be configured individually.
 
-@item tls-channel=[main|display|cursor|inputs|record|playback]
-@itemx plaintext-channel=[main|display|cursor|inputs|record|playback]
-Force specific channel to be used with or without TLS encryption.  The
-options can be specified multiple times to configure multiple
-channels.  The special name "default" can be used to set the default
-mode.  For channels which are not explicitly forced into one mode the
-spice client is allowed to pick tls/plaintext as he pleases.
+    ``tls-ciphers=<list>``
+        Specify which ciphers to use.
 
-@item image-compression=[auto_glz|auto_lz|quic|glz|lz|off]
-Configure image compression (lossless).
-Default is auto_glz.
+    ``tls-channel=[main|display|cursor|inputs|record|playback]``; \ ``plaintext-channel=[main|display|cursor|inputs|record|playback]``
+        Force specific channel to be used with or without TLS
+        encryption. The options can be specified multiple times to
+        configure multiple channels. The special name "default" can be
+        used to set the default mode. For channels which are not
+        explicitly forced into one mode the spice client is allowed to
+        pick tls/plaintext as he pleases.
 
-@item jpeg-wan-compression=[auto|never|always]
-@itemx zlib-glz-wan-compression=[auto|never|always]
-Configure wan image compression (lossy for slow links).
-Default is auto.
+    ``image-compression=[auto_glz|auto_lz|quic|glz|lz|off]``
+        Configure image compression (lossless). Default is auto\_glz.
 
-@item streaming-video=[off|all|filter]
-Configure video stream detection.  Default is off.
+    ``jpeg-wan-compression=[auto|never|always]``; \ ``zlib-glz-wan-compression=[auto|never|always]``
+        Configure wan image compression (lossy for slow links). Default
+        is auto.
 
-@item agent-mouse=[on|off]
-Enable/disable passing mouse events via vdagent.  Default is on.
+    ``streaming-video=[off|all|filter]``
+        Configure video stream detection. Default is off.
 
-@item playback-compression=[on|off]
-Enable/disable audio stream compression (using celt 0.5.1).  Default is on.
+    ``agent-mouse=[on|off]``
+        Enable/disable passing mouse events via vdagent. Default is on.
 
-@item seamless-migration=[on|off]
-Enable/disable spice seamless migration. Default is off.
+    ``playback-compression=[on|off]``
+        Enable/disable audio stream compression (using celt 0.5.1).
+        Default is on.
 
-@item gl=[on|off]
-Enable/disable OpenGL context. Default is off.
+    ``seamless-migration=[on|off]``
+        Enable/disable spice seamless migration. Default is off.
 
-@item rendernode=<file>
-DRM render node for OpenGL rendering. If not specified, it will pick
-the first available. (Since 2.9)
+    ``gl=[on|off]``
+        Enable/disable OpenGL context. Default is off.
 
-@end table
-ETEXI
+    ``rendernode=<file>``
+        DRM render node for OpenGL rendering. If not specified, it will
+        pick the first available. (Since 2.9)
+ERST
 
 DEF("portrait", 0, QEMU_OPTION_portrait,
     "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -portrait
-@findex -portrait
-Rotate graphical output 90 deg left (only PXA LCD).
-ETEXI
+SRST
+``-portrait``
+    Rotate graphical output 90 deg left (only PXA LCD).
+ERST
 
 DEF("rotate", HAS_ARG, QEMU_OPTION_rotate,
     "-rotate <deg>   rotate graphical output some deg left (only PXA LCD)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -rotate @var{deg}
-@findex -rotate
-Rotate graphical output some deg left (only PXA LCD).
-ETEXI
+SRST
+``-rotate deg``
+    Rotate graphical output some deg left (only PXA LCD).
+ERST
 
 DEF("vga", HAS_ARG, QEMU_OPTION_vga,
     "-vga [std|cirrus|vmware|qxl|xenfb|tcx|cg3|virtio|none]\n"
     "                select video card type\n", QEMU_ARCH_ALL)
-STEXI
-@item -vga @var{type}
-@findex -vga
-Select type of VGA card to emulate. Valid values for @var{type} are
-@table @option
-@item cirrus
-Cirrus Logic GD5446 Video card. All Windows versions starting from
-Windows 95 should recognize and use this graphic card. For optimal
-performances, use 16 bit color depth in the guest and the host OS.
-(This card was the default before QEMU 2.2)
-@item std
-Standard VGA card with Bochs VBE extensions.  If your guest OS
-supports the VESA 2.0 VBE extensions (e.g. Windows XP) and if you want
-to use high resolution modes (>= 1280x1024x16) then you should use
-this option. (This card is the default since QEMU 2.2)
-@item vmware
-VMWare SVGA-II compatible adapter. Use it if you have sufficiently
-recent XFree86/XOrg server or Windows guest with a driver for this
-card.
-@item qxl
-QXL paravirtual graphic card.  It is VGA compatible (including VESA
-2.0 VBE support).  Works best with qxl guest drivers installed though.
-Recommended choice when using the spice protocol.
-@item tcx
-(sun4m only) Sun TCX framebuffer. This is the default framebuffer for
-sun4m machines and offers both 8-bit and 24-bit colour depths at a
-fixed resolution of 1024x768.
-@item cg3
-(sun4m only) Sun cgthree framebuffer. This is a simple 8-bit framebuffer
-for sun4m machines available in both 1024x768 (OpenBIOS) and 1152x900 (OBP)
-resolutions aimed at people wishing to run older Solaris versions.
-@item virtio
-Virtio VGA card.
-@item none
-Disable VGA card.
-@end table
-ETEXI
+SRST
+``-vga type``
+    Select type of VGA card to emulate. Valid values for type are
+
+    ``cirrus``
+        Cirrus Logic GD5446 Video card. All Windows versions starting
+        from Windows 95 should recognize and use this graphic card. For
+        optimal performances, use 16 bit color depth in the guest and
+        the host OS. (This card was the default before QEMU 2.2)
+
+    ``std``
+        Standard VGA card with Bochs VBE extensions. If your guest OS
+        supports the VESA 2.0 VBE extensions (e.g. Windows XP) and if
+        you want to use high resolution modes (>= 1280x1024x16) then you
+        should use this option. (This card is the default since QEMU
+        2.2)
+
+    ``vmware``
+        VMWare SVGA-II compatible adapter. Use it if you have
+        sufficiently recent XFree86/XOrg server or Windows guest with a
+        driver for this card.
+
+    ``qxl``
+        QXL paravirtual graphic card. It is VGA compatible (including
+        VESA 2.0 VBE support). Works best with qxl guest drivers
+        installed though. Recommended choice when using the spice
+        protocol.
+
+    ``tcx``
+        (sun4m only) Sun TCX framebuffer. This is the default
+        framebuffer for sun4m machines and offers both 8-bit and 24-bit
+        colour depths at a fixed resolution of 1024x768.
+
+    ``cg3``
+        (sun4m only) Sun cgthree framebuffer. This is a simple 8-bit
+        framebuffer for sun4m machines available in both 1024x768
+        (OpenBIOS) and 1152x900 (OBP) resolutions aimed at people
+        wishing to run older Solaris versions.
+
+    ``virtio``
+        Virtio VGA card.
+
+    ``none``
+        Disable VGA card.
+ERST
 
 DEF("full-screen", 0, QEMU_OPTION_full_screen,
     "-full-screen    start in full screen\n", QEMU_ARCH_ALL)
-STEXI
-@item -full-screen
-@findex -full-screen
-Start in full screen.
-ETEXI
+SRST
+``-full-screen``
+    Start in full screen.
+ERST
 
 DEF("g", HAS_ARG, QEMU_OPTION_g ,
     "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n",
     QEMU_ARCH_PPC | QEMU_ARCH_SPARC | QEMU_ARCH_M68K)
-STEXI
-@item -g @var{width}x@var{height}[x@var{depth}]
-@findex -g
-Set the initial graphical resolution and depth (PPC, SPARC only).
-ETEXI
-
-DEF("vnc", HAS_ARG, QEMU_OPTION_vnc ,
-    "-vnc <display>  shorthand for -display vnc=<display>\n", QEMU_ARCH_ALL)
-STEXI
-@item -vnc @var{display}[,@var{option}[,@var{option}[,...]]]
-@findex -vnc
-Normally, if QEMU is compiled with graphical window support, it displays
-output such as guest graphics, guest console, and the QEMU monitor in a
-window. With this option, you can have QEMU listen on VNC display
-@var{display} and redirect the VGA display over the VNC session. It is
-very useful to enable the usb tablet device when using this option
-(option @option{-device usb-tablet}). When using the VNC display, you
-must use the @option{-k} parameter to set the keyboard layout if you are
-not using en-us. Valid syntax for the @var{display} is
-
-@table @option
-
-@item to=@var{L}
-
-With this option, QEMU will try next available VNC @var{display}s, until the
-number @var{L}, if the origianlly defined "-vnc @var{display}" is not
-available, e.g. port 5900+@var{display} is already used by another
-application. By default, to=0.
-
-@item @var{host}:@var{d}
-
-TCP connections will only be allowed from @var{host} on display @var{d}.
-By convention the TCP port is 5900+@var{d}. Optionally, @var{host} can
-be omitted in which case the server will accept connections from any host.
-
-@item unix:@var{path}
-
-Connections will be allowed over UNIX domain sockets where @var{path} is the
-location of a unix socket to listen for connections on.
-
-@item none
-
-VNC is initialized but not started. The monitor @code{change} command
-can be used to later start the VNC server.
-
-@end table
-
-Following the @var{display} value there may be one or more @var{option} flags
-separated by commas. Valid options are
-
-@table @option
-
-@item reverse
-
-Connect to a listening VNC client via a ``reverse'' connection. The
-client is specified by the @var{display}. For reverse network
-connections (@var{host}:@var{d},@code{reverse}), the @var{d} argument
-is a TCP port number, not a display number.
+SRST
+``-g`` *width*\ ``x``\ *height*\ ``[x``\ *depth*\ ``]``
+    Set the initial graphical resolution and depth (PPC, SPARC only).
 
-@item websocket
+    For PPC the default is 800x600x32.
 
-Opens an additional TCP listening port dedicated to VNC Websocket connections.
-If a bare @var{websocket} option is given, the Websocket port is
-5700+@var{display}. An alternative port can be specified with the
-syntax @code{websocket}=@var{port}.
+    For SPARC with the TCX graphics device, the default is 1024x768x8
+    with the option of 1024x768x24. For cgthree, the default is
+    1024x768x8 with the option of 1152x900x8 for people who wish to use
+    OBP.
+ERST
 
-If @var{host} is specified connections will only be allowed from this host.
-It is possible to control the websocket listen address independently, using
-the syntax @code{websocket}=@var{host}:@var{port}.
-
-If no TLS credentials are provided, the websocket connection runs in
-unencrypted mode. If TLS credentials are provided, the websocket connection
-requires encrypted client connections.
-
-@item password
-
-Require that password based authentication is used for client connections.
-
-The password must be set separately using the @code{set_password} command in
-the @ref{pcsys_monitor}. The syntax to change your password is:
-@code{set_password <protocol> <password>} where <protocol> could be either
-"vnc" or "spice".
-
-If you would like to change <protocol> password expiration, you should use
-@code{expire_password <protocol> <expiration-time>} where expiration time could
-be one of the following options: now, never, +seconds or UNIX time of
-expiration, e.g. +60 to make password expire in 60 seconds, or 1335196800
-to make password expire on "Mon Apr 23 12:00:00 EDT 2012" (UNIX time for this
-date and time).
-
-You can also use keywords "now" or "never" for the expiration time to
-allow <protocol> password to expire immediately or never expire.
-
-@item tls-creds=@var{ID}
-
-Provides the ID of a set of TLS credentials to use to secure the
-VNC server. They will apply to both the normal VNC server socket
-and the websocket socket (if enabled). Setting TLS credentials
-will cause the VNC server socket to enable the VeNCrypt auth
-mechanism.  The credentials should have been previously created
-using the @option{-object tls-creds} argument.
-
-@item tls-authz=@var{ID}
-
-Provides the ID of the QAuthZ authorization object against which
-the client's x509 distinguished name will validated. This object is
-only resolved at time of use, so can be deleted and recreated on the
-fly while the VNC server is active. If missing, it will default
-to denying access.
-
-@item sasl
-
-Require that the client use SASL to authenticate with the VNC server.
-The exact choice of authentication method used is controlled from the
-system / user's SASL configuration file for the 'qemu' service. This
-is typically found in /etc/sasl2/qemu.conf. If running QEMU as an
-unprivileged user, an environment variable SASL_CONF_PATH can be used
-to make it search alternate locations for the service config.
-While some SASL auth methods can also provide data encryption (eg GSSAPI),
-it is recommended that SASL always be combined with the 'tls' and
-'x509' settings to enable use of SSL and server certificates. This
-ensures a data encryption preventing compromise of authentication
-credentials. See the @ref{vnc_security} section for details on using
-SASL authentication.
-
-@item sasl-authz=@var{ID}
-
-Provides the ID of the QAuthZ authorization object against which
-the client's SASL username will validated. This object is
-only resolved at time of use, so can be deleted and recreated on the
-fly while the VNC server is active. If missing, it will default
-to denying access.
-
-@item acl
-
-Legacy method for enabling authorization of clients against the
-x509 distinguished name and SASL username. It results in the creation
-of two @code{authz-list} objects with IDs of @code{vnc.username} and
-@code{vnc.x509dname}. The rules for these objects must be configured
-with the HMP ACL commands.
-
-This option is deprecated and should no longer be used. The new
-@option{sasl-authz} and @option{tls-authz} options are a
-replacement.
+DEF("vnc", HAS_ARG, QEMU_OPTION_vnc ,
+    "-vnc <display>  shorthand for -display vnc=<display>\n", QEMU_ARCH_ALL)
+SRST
+``-vnc display[,option[,option[,...]]]``
+    Normally, if QEMU is compiled with graphical window support, it
+    displays output such as guest graphics, guest console, and the QEMU
+    monitor in a window. With this option, you can have QEMU listen on
+    VNC display display and redirect the VGA display over the VNC
+    session. It is very useful to enable the usb tablet device when
+    using this option (option ``-device usb-tablet``). When using the
+    VNC display, you must use the ``-k`` parameter to set the keyboard
+    layout if you are not using en-us. Valid syntax for the display is
+
+    ``to=L``
+        With this option, QEMU will try next available VNC displays,
+        until the number L, if the origianlly defined "-vnc display" is
+        not available, e.g. port 5900+display is already used by another
+        application. By default, to=0.
+
+    ``host:d``
+        TCP connections will only be allowed from host on display d. By
+        convention the TCP port is 5900+d. Optionally, host can be
+        omitted in which case the server will accept connections from
+        any host.
+
+    ``unix:path``
+        Connections will be allowed over UNIX domain sockets where path
+        is the location of a unix socket to listen for connections on.
+
+    ``none``
+        VNC is initialized but not started. The monitor ``change``
+        command can be used to later start the VNC server.
+
+    Following the display value there may be one or more option flags
+    separated by commas. Valid options are
+
+    ``reverse``
+        Connect to a listening VNC client via a "reverse" connection.
+        The client is specified by the display. For reverse network
+        connections (host:d,``reverse``), the d argument is a TCP port
+        number, not a display number.
+
+    ``websocket``
+        Opens an additional TCP listening port dedicated to VNC
+        Websocket connections. If a bare websocket option is given, the
+        Websocket port is 5700+display. An alternative port can be
+        specified with the syntax ``websocket``\ =port.
+
+        If host is specified connections will only be allowed from this
+        host. It is possible to control the websocket listen address
+        independently, using the syntax ``websocket``\ =host:port.
+
+        If no TLS credentials are provided, the websocket connection
+        runs in unencrypted mode. If TLS credentials are provided, the
+        websocket connection requires encrypted client connections.
+
+    ``password``
+        Require that password based authentication is used for client
+        connections.
+
+        The password must be set separately using the ``set_password``
+        command in the :ref:`pcsys_005fmonitor`. The
+        syntax to change your password is:
+        ``set_password <protocol> <password>`` where <protocol> could be
+        either "vnc" or "spice".
+
+        If you would like to change <protocol> password expiration, you
+        should use ``expire_password <protocol> <expiration-time>``
+        where expiration time could be one of the following options:
+        now, never, +seconds or UNIX time of expiration, e.g. +60 to
+        make password expire in 60 seconds, or 1335196800 to make
+        password expire on "Mon Apr 23 12:00:00 EDT 2012" (UNIX time for
+        this date and time).
+
+        You can also use keywords "now" or "never" for the expiration
+        time to allow <protocol> password to expire immediately or never
+        expire.
+
+    ``tls-creds=ID``
+        Provides the ID of a set of TLS credentials to use to secure the
+        VNC server. They will apply to both the normal VNC server socket
+        and the websocket socket (if enabled). Setting TLS credentials
+        will cause the VNC server socket to enable the VeNCrypt auth
+        mechanism. The credentials should have been previously created
+        using the ``-object tls-creds`` argument.
+
+    ``tls-authz=ID``
+        Provides the ID of the QAuthZ authorization object against which
+        the client's x509 distinguished name will validated. This object
+        is only resolved at time of use, so can be deleted and recreated
+        on the fly while the VNC server is active. If missing, it will
+        default to denying access.
+
+    ``sasl``
+        Require that the client use SASL to authenticate with the VNC
+        server. The exact choice of authentication method used is
+        controlled from the system / user's SASL configuration file for
+        the 'qemu' service. This is typically found in
+        /etc/sasl2/qemu.conf. If running QEMU as an unprivileged user,
+        an environment variable SASL\_CONF\_PATH can be used to make it
+        search alternate locations for the service config. While some
+        SASL auth methods can also provide data encryption (eg GSSAPI),
+        it is recommended that SASL always be combined with the 'tls'
+        and 'x509' settings to enable use of SSL and server
+        certificates. This ensures a data encryption preventing
+        compromise of authentication credentials. See the
+        :ref:`vnc_005fsecurity` section for details on
+        using SASL authentication.
+
+    ``sasl-authz=ID``
+        Provides the ID of the QAuthZ authorization object against which
+        the client's SASL username will validated. This object is only
+        resolved at time of use, so can be deleted and recreated on the
+        fly while the VNC server is active. If missing, it will default
+        to denying access.
+
+    ``acl``
+        Legacy method for enabling authorization of clients against the
+        x509 distinguished name and SASL username. It results in the
+        creation of two ``authz-list`` objects with IDs of
+        ``vnc.username`` and ``vnc.x509dname``. The rules for these
+        objects must be configured with the HMP ACL commands.
+
+        This option is deprecated and should no longer be used. The new
+        ``sasl-authz`` and ``tls-authz`` options are a replacement.
+
+    ``lossy``
+        Enable lossy compression methods (gradient, JPEG, ...). If this
+        option is set, VNC client may receive lossy framebuffer updates
+        depending on its encoding settings. Enabling this option can
+        save a lot of bandwidth at the expense of quality.
+
+    ``non-adaptive``
+        Disable adaptive encodings. Adaptive encodings are enabled by
+        default. An adaptive encoding will try to detect frequently
+        updated screen regions, and send updates in these regions using
+        a lossy encoding (like JPEG). This can be really helpful to save
+        bandwidth when playing videos. Disabling adaptive encodings
+        restores the original static behavior of encodings like Tight.
+
+    ``share=[allow-exclusive|force-shared|ignore]``
+        Set display sharing policy. 'allow-exclusive' allows clients to
+        ask for exclusive access. As suggested by the rfb spec this is
+        implemented by dropping other connections. Connecting multiple
+        clients in parallel requires all clients asking for a shared
+        session (vncviewer: -shared switch). This is the default.
+        'force-shared' disables exclusive client access. Useful for
+        shared desktop sessions, where you don't want someone forgetting
+        specify -shared disconnect everybody else. 'ignore' completely
+        ignores the shared flag and allows everybody connect
+        unconditionally. Doesn't conform to the rfb spec but is
+        traditional QEMU behavior.
+
+    ``key-delay-ms``
+        Set keyboard delay, for key down and key up events, in
+        milliseconds. Default is 10. Keyboards are low-bandwidth
+        devices, so this slowdown can help the device and guest to keep
+        up and not lose events in case events are arriving in bulk.
+        Possible causes for the latter are flaky network connections, or
+        scripts for automated testing.
+
+    ``audiodev=audiodev``
+        Use the specified audiodev when the VNC client requests audio
+        transmission. When not using an -audiodev argument, this option
+        must be omitted, otherwise is must be present and specify a
+        valid audiodev.
+ERST
 
-@item lossy
-
-Enable lossy compression methods (gradient, JPEG, ...). If this
-option is set, VNC client may receive lossy framebuffer updates
-depending on its encoding settings. Enabling this option can save
-a lot of bandwidth at the expense of quality.
-
-@item non-adaptive
-
-Disable adaptive encodings. Adaptive encodings are enabled by default.
-An adaptive encoding will try to detect frequently updated screen regions,
-and send updates in these regions using a lossy encoding (like JPEG).
-This can be really helpful to save bandwidth when playing videos. Disabling
-adaptive encodings restores the original static behavior of encodings
-like Tight.
-
-@item share=[allow-exclusive|force-shared|ignore]
-
-Set display sharing policy.  'allow-exclusive' allows clients to ask
-for exclusive access.  As suggested by the rfb spec this is
-implemented by dropping other connections.  Connecting multiple
-clients in parallel requires all clients asking for a shared session
-(vncviewer: -shared switch).  This is the default.  'force-shared'
-disables exclusive client access.  Useful for shared desktop sessions,
-where you don't want someone forgetting specify -shared disconnect
-everybody else.  'ignore' completely ignores the shared flag and
-allows everybody connect unconditionally.  Doesn't conform to the rfb
-spec but is traditional QEMU behavior.
-
-@item key-delay-ms
-
-Set keyboard delay, for key down and key up events, in milliseconds.
-Default is 10.  Keyboards are low-bandwidth devices, so this slowdown
-can help the device and guest to keep up and not lose events in case
-events are arriving in bulk.  Possible causes for the latter are flaky
-network connections, or scripts for automated testing.
-
-@item audiodev=@var{audiodev}
-
-Use the specified @var{audiodev} when the VNC client requests audio
-transmission. When not using an -audiodev argument, this option must
-be omitted, otherwise is must be present and specify a valid audiodev.
-
-@end table
-ETEXI
-
-STEXI
-@end table
-ETEXI
 ARCHHEADING(, QEMU_ARCH_I386)
 
 ARCHHEADING(i386 target only:, QEMU_ARCH_I386)
-STEXI
-@table @option
-ETEXI
 
 DEF("win2k-hack", 0, QEMU_OPTION_win2k_hack,
     "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n",
     QEMU_ARCH_I386)
-STEXI
-@item -win2k-hack
-@findex -win2k-hack
-Use it when installing Windows 2000 to avoid a disk full bug. After
-Windows 2000 is installed, you no longer need this option (this option
-slows down the IDE transfers).
-ETEXI
+SRST
+``-win2k-hack``
+    Use it when installing Windows 2000 to avoid a disk full bug. After
+    Windows 2000 is installed, you no longer need this option (this
+    option slows down the IDE transfers).
+ERST
 
 DEF("no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk,
     "-no-fd-bootchk  disable boot signature checking for floppy disks\n",
     QEMU_ARCH_I386)
-STEXI
-@item -no-fd-bootchk
-@findex -no-fd-bootchk
-Disable boot signature checking for floppy disks in BIOS. May
-be needed to boot from old floppy disks.
-ETEXI
+SRST
+``-no-fd-bootchk``
+    Disable boot signature checking for floppy disks in BIOS. May be
+    needed to boot from old floppy disks.
+ERST
 
 DEF("no-acpi", 0, QEMU_OPTION_no_acpi,
            "-no-acpi        disable ACPI\n", QEMU_ARCH_I386 | QEMU_ARCH_ARM)
-STEXI
-@item -no-acpi
-@findex -no-acpi
-Disable ACPI (Advanced Configuration and Power Interface) support. Use
-it if your guest OS complains about ACPI problems (PC target machine
-only).
-ETEXI
+SRST
+``-no-acpi``
+    Disable ACPI (Advanced Configuration and Power Interface) support.
+    Use it if your guest OS complains about ACPI problems (PC target
+    machine only).
+ERST
 
 DEF("no-hpet", 0, QEMU_OPTION_no_hpet,
     "-no-hpet        disable HPET\n", QEMU_ARCH_I386)
-STEXI
-@item -no-hpet
-@findex -no-hpet
-Disable HPET support.
-ETEXI
+SRST
+``-no-hpet``
+    Disable HPET support.
+ERST
 
 DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
     "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
     "                ACPI table description\n", QEMU_ARCH_I386)
-STEXI
-@item -acpitable [sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}][,data=@var{file1}[:@var{file2}]...]
-@findex -acpitable
-Add ACPI table with specified header fields and context from specified files.
-For file=, take whole ACPI table from the specified files, including all
-ACPI headers (possible overridden by other options).
-For data=, only data
-portion of the table is used, all header information is specified in the
-command line.
-If a SLIC table is supplied to QEMU, then the SLIC's oem_id and oem_table_id
-fields will override the same in the RSDT and the FADT (a.k.a. FACP), in order
-to ensure the field matches required by the Microsoft SLIC spec and the ACPI
-spec.
-ETEXI
+SRST
+``-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n] [,asl_compiler_id=str][,asl_compiler_rev=n][,data=file1[:file2]...]``
+    Add ACPI table with specified header fields and context from
+    specified files. For file=, take whole ACPI table from the specified
+    files, including all ACPI headers (possible overridden by other
+    options). For data=, only data portion of the table is used, all
+    header information is specified in the command line. If a SLIC table
+    is supplied to QEMU, then the SLIC's oem\_id and oem\_table\_id
+    fields will override the same in the RSDT and the FADT (a.k.a.
+    FACP), in order to ensure the field matches required by the
+    Microsoft SLIC spec and the ACPI spec.
+ERST
 
 DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
     "-smbios file=binary\n"
@@ -2238,39 +2282,32 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
     "               [,asset=str][,part=str][,speed=%d]\n"
     "                specify SMBIOS type 17 fields\n",
     QEMU_ARCH_I386 | QEMU_ARCH_ARM)
-STEXI
-@item -smbios file=@var{binary}
-@findex -smbios
-Load SMBIOS entry from binary file.
+SRST
+``-smbios file=binary``
+    Load SMBIOS entry from binary file.
 
-@item -smbios type=0[,vendor=@var{str}][,version=@var{str}][,date=@var{str}][,release=@var{%d.%d}][,uefi=on|off]
-Specify SMBIOS type 0 fields
+``-smbios type=0[,vendor=str][,version=str][,date=str][,release=%d.%d][,uefi=on|off]``
+    Specify SMBIOS type 0 fields
 
-@item -smbios type=1[,manufacturer=@var{str}][,product=@var{str}][,version=@var{str}][,serial=@var{str}][,uuid=@var{uuid}][,sku=@var{str}][,family=@var{str}]
-Specify SMBIOS type 1 fields
+``-smbios type=1[,manufacturer=str][,product=str][,version=str][,serial=str][,uuid=uuid][,sku=str][,family=str]``
+    Specify SMBIOS type 1 fields
 
-@item -smbios type=2[,manufacturer=@var{str}][,product=@var{str}][,version=@var{str}][,serial=@var{str}][,asset=@var{str}][,location=@var{str}]
-Specify SMBIOS type 2 fields
+``-smbios type=2[,manufacturer=str][,product=str][,version=str][,serial=str][,asset=str][,location=str]``
+    Specify SMBIOS type 2 fields
 
-@item -smbios type=3[,manufacturer=@var{str}][,version=@var{str}][,serial=@var{str}][,asset=@var{str}][,sku=@var{str}]
-Specify SMBIOS type 3 fields
+``-smbios type=3[,manufacturer=str][,version=str][,serial=str][,asset=str][,sku=str]``
+    Specify SMBIOS type 3 fields
 
-@item -smbios type=4[,sock_pfx=@var{str}][,manufacturer=@var{str}][,version=@var{str}][,serial=@var{str}][,asset=@var{str}][,part=@var{str}]
-Specify SMBIOS type 4 fields
+``-smbios type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str][,asset=str][,part=str]``
+    Specify SMBIOS type 4 fields
 
-@item -smbios type=17[,loc_pfx=@var{str}][,bank=@var{str}][,manufacturer=@var{str}][,serial=@var{str}][,asset=@var{str}][,part=@var{str}][,speed=@var{%d}]
-Specify SMBIOS type 17 fields
-ETEXI
+``-smbios type=17[,loc_pfx=str][,bank=str][,manufacturer=str][,serial=str][,asset=str][,part=str][,speed=%d]``
+    Specify SMBIOS type 17 fields
+ERST
 
-STEXI
-@end table
-ETEXI
 DEFHEADING()
 
 DEFHEADING(Network options:)
-STEXI
-@table @option
-ETEXI
 
 DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
 #ifdef CONFIG_SLIRP
@@ -2417,452 +2454,471 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
     "socket][,option][,option][,...]\n"
     "                old way to initialize a host network interface\n"
     "                (use the -netdev option if possible instead)\n", QEMU_ARCH_ALL)
-STEXI
-@item -nic [tap|bridge|user|l2tpv3|vde|netmap|vhost-user|socket][,...][,mac=macaddr][,model=mn]
-@findex -nic
-This option is a shortcut for configuring both the on-board (default) guest
-NIC hardware and the host network backend in one go. The host backend options
-are the same as with the corresponding @option{-netdev} options below.
-The guest NIC model can be set with @option{model=@var{modelname}}.
-Use @option{model=help} to list the available device types.
-The hardware MAC address can be set with @option{mac=@var{macaddr}}.
-
-The following two example do exactly the same, to show how @option{-nic} can
-be used to shorten the command line length:
-@example
-@value{qemu_system} -netdev user,id=n1,ipv6=off -device e1000,netdev=n1,mac=52:54:98:76:54:32
-@value{qemu_system} -nic user,ipv6=off,model=e1000,mac=52:54:98:76:54:32
-@end example
-
-@item -nic none
-Indicate that no network devices should be configured. It is used to override
-the default configuration (default NIC with ``user'' host network backend)
-which is activated if no other networking options are provided.
-
-@item -netdev user,id=@var{id}[,@var{option}][,@var{option}][,...]
-@findex -netdev
-Configure user mode host network backend which requires no administrator
-privilege to run. Valid options are:
-
-@table @option
-@item id=@var{id}
-Assign symbolic name for use in monitor commands.
-
-@item ipv4=on|off and ipv6=on|off
-Specify that either IPv4 or IPv6 must be enabled. If neither is specified
-both protocols are enabled.
-
-@item net=@var{addr}[/@var{mask}]
-Set IP network address the guest will see. Optionally specify the netmask,
-either in the form a.b.c.d or as number of valid top-most bits. Default is
-10.0.2.0/24.
-
-@item host=@var{addr}
-Specify the guest-visible address of the host. Default is the 2nd IP in the
-guest network, i.e. x.x.x.2.
-
-@item ipv6-net=@var{addr}[/@var{int}]
-Set IPv6 network address the guest will see (default is fec0::/64). The
-network prefix is given in the usual hexadecimal IPv6 address
-notation. The prefix size is optional, and is given as the number of
-valid top-most bits (default is 64).
-
-@item ipv6-host=@var{addr}
-Specify the guest-visible IPv6 address of the host. Default is the 2nd IPv6 in
-the guest network, i.e. xxxx::2.
-
-@item restrict=on|off
-If this option is enabled, the guest will be isolated, i.e. it will not be
-able to contact the host and no guest IP packets will be routed over the host
-to the outside. This option does not affect any explicitly set forwarding rules.
-
-@item hostname=@var{name}
-Specifies the client hostname reported by the built-in DHCP server.
-
-@item dhcpstart=@var{addr}
-Specify the first of the 16 IPs the built-in DHCP server can assign. Default
-is the 15th to 31st IP in the guest network, i.e. x.x.x.15 to x.x.x.31.
-
-@item dns=@var{addr}
-Specify the guest-visible address of the virtual nameserver. The address must
-be different from the host address. Default is the 3rd IP in the guest network,
-i.e. x.x.x.3.
-
-@item ipv6-dns=@var{addr}
-Specify the guest-visible address of the IPv6 virtual nameserver. The address
-must be different from the host address. Default is the 3rd IP in the guest
-network, i.e. xxxx::3.
-
-@item dnssearch=@var{domain}
-Provides an entry for the domain-search list sent by the built-in
-DHCP server. More than one domain suffix can be transmitted by specifying
-this option multiple times. If supported, this will cause the guest to
-automatically try to append the given domain suffix(es) in case a domain name
-can not be resolved.
-
-Example:
-@example
-@value{qemu_system} -nic user,dnssearch=mgmt.example.org,dnssearch=example.org
-@end example
-
-@item domainname=@var{domain}
-Specifies the client domain name reported by the built-in DHCP server.
-
-@item tftp=@var{dir}
-When using the user mode network stack, activate a built-in TFTP
-server. The files in @var{dir} will be exposed as the root of a TFTP server.
-The TFTP client on the guest must be configured in binary mode (use the command
-@code{bin} of the Unix TFTP client).
-
-@item tftp-server-name=@var{name}
-In BOOTP reply, broadcast @var{name} as the "TFTP server name" (RFC2132 option
-66). This can be used to advise the guest to load boot files or configurations
-from a different server than the host address.
-
-@item bootfile=@var{file}
-When using the user mode network stack, broadcast @var{file} as the BOOTP
-filename. In conjunction with @option{tftp}, this can be used to network boot
-a guest from a local directory.
-
-Example (using pxelinux):
-@example
-@value{qemu_system} -hda linux.img -boot n -device e1000,netdev=n1 \
-    -netdev user,id=n1,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
-@end example
-
-@item smb=@var{dir}[,smbserver=@var{addr}]
-When using the user mode network stack, activate a built-in SMB
-server so that Windows OSes can access to the host files in @file{@var{dir}}
-transparently. The IP address of the SMB server can be set to @var{addr}. By
-default the 4th IP in the guest network is used, i.e. x.x.x.4.
-
-In the guest Windows OS, the line:
-@example
-10.0.2.4 smbserver
-@end example
-must be added in the file @file{C:\WINDOWS\LMHOSTS} (for windows 9x/Me)
-or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000).
-
-Then @file{@var{dir}} can be accessed in @file{\\smbserver\qemu}.
-
-Note that a SAMBA server must be installed on the host OS.
-
-@item hostfwd=[tcp|udp]:[@var{hostaddr}]:@var{hostport}-[@var{guestaddr}]:@var{guestport}
-Redirect incoming TCP or UDP connections to the host port @var{hostport} to
-the guest IP address @var{guestaddr} on guest port @var{guestport}. If
-@var{guestaddr} is not specified, its value is x.x.x.15 (default first address
-given by the built-in DHCP server). By specifying @var{hostaddr}, the rule can
-be bound to a specific host interface. If no connection type is set, TCP is
-used. This option can be given multiple times.
-
-For example, to redirect host X11 connection from screen 1 to guest
-screen 0, use the following:
-
-@example
-# on the host
-@value{qemu_system} -nic user,hostfwd=tcp:127.0.0.1:6001-:6000
-# this host xterm should open in the guest X11 server
-xterm -display :1
-@end example
-
-To redirect telnet connections from host port 5555 to telnet port on
-the guest, use the following:
-
-@example
-# on the host
-@value{qemu_system} -nic user,hostfwd=tcp::5555-:23
-telnet localhost 5555
-@end example
-
-Then when you use on the host @code{telnet localhost 5555}, you
-connect to the guest telnet server.
-
-@item guestfwd=[tcp]:@var{server}:@var{port}-@var{dev}
-@itemx guestfwd=[tcp]:@var{server}:@var{port}-@var{cmd:command}
-Forward guest TCP connections to the IP address @var{server} on port @var{port}
-to the character device @var{dev} or to a program executed by @var{cmd:command}
-which gets spawned for each connection. This option can be given multiple times.
-
-You can either use a chardev directly and have that one used throughout QEMU's
-lifetime, like in the following example:
-
-@example
-# open 10.10.1.1:4321 on bootup, connect 10.0.2.100:1234 to it whenever
-# the guest accesses it
-@value{qemu_system} -nic user,guestfwd=tcp:10.0.2.100:1234-tcp:10.10.1.1:4321
-@end example
-
-Or you can execute a command on every TCP connection established by the guest,
-so that QEMU behaves similar to an inetd process for that virtual server:
-
-@example
-# call "netcat 10.10.1.1 4321" on every TCP connection to 10.0.2.100:1234
-# and connect the TCP stream to its stdin/stdout
-@value{qemu_system} -nic  'user,id=n1,guestfwd=tcp:10.0.2.100:1234-cmd:netcat 10.10.1.1 4321'
-@end example
-
-@end table
-
-@item -netdev tap,id=@var{id}[,fd=@var{h}][,ifname=@var{name}][,script=@var{file}][,downscript=@var{dfile}][,br=@var{bridge}][,helper=@var{helper}]
-Configure a host TAP network backend with ID @var{id}.
-
-Use the network script @var{file} to configure it and the network script
-@var{dfile} to deconfigure it. If @var{name} is not provided, the OS
-automatically provides one. The default network configure script is
-@file{/etc/qemu-ifup} and the default network deconfigure script is
-@file{/etc/qemu-ifdown}. Use @option{script=no} or @option{downscript=no}
-to disable script execution.
-
-If running QEMU as an unprivileged user, use the network helper
-@var{helper} to configure the TAP interface and attach it to the bridge.
-The default network helper executable is @file{/path/to/qemu-bridge-helper}
-and the default bridge device is @file{br0}.
-
-@option{fd}=@var{h} can be used to specify the handle of an already
-opened host TAP interface.
-
-Examples:
-
-@example
-#launch a QEMU instance with the default network script
-@value{qemu_system} linux.img -nic tap
-@end example
-
-@example
-#launch a QEMU instance with two NICs, each one connected
-#to a TAP device
-@value{qemu_system} linux.img \
-        -netdev tap,id=nd0,ifname=tap0 -device e1000,netdev=nd0 \
-        -netdev tap,id=nd1,ifname=tap1 -device rtl8139,netdev=nd1
-@end example
-
-@example
-#launch a QEMU instance with the default network helper to
-#connect a TAP device to bridge br0
-@value{qemu_system} linux.img -device virtio-net-pci,netdev=n1 \
-        -netdev tap,id=n1,"helper=/path/to/qemu-bridge-helper"
-@end example
-
-@item -netdev bridge,id=@var{id}[,br=@var{bridge}][,helper=@var{helper}]
-Connect a host TAP network interface to a host bridge device.
-
-Use the network helper @var{helper} to configure the TAP interface and
-attach it to the bridge. The default network helper executable is
-@file{/path/to/qemu-bridge-helper} and the default bridge
-device is @file{br0}.
-
-Examples:
-
-@example
-#launch a QEMU instance with the default network helper to
-#connect a TAP device to bridge br0
-@value{qemu_system} linux.img -netdev bridge,id=n1 -device virtio-net,netdev=n1
-@end example
-
-@example
-#launch a QEMU instance with the default network helper to
-#connect a TAP device to bridge qemubr0
-@value{qemu_system} linux.img -netdev bridge,br=qemubr0,id=n1 -device virtio-net,netdev=n1
-@end example
-
-@item -netdev socket,id=@var{id}[,fd=@var{h}][,listen=[@var{host}]:@var{port}][,connect=@var{host}:@var{port}]
-
-This host network backend can be used to connect the guest's network to
-another QEMU virtual machine using a TCP socket connection. If @option{listen}
-is specified, QEMU waits for incoming connections on @var{port}
-(@var{host} is optional). @option{connect} is used to connect to
-another QEMU instance using the @option{listen} option. @option{fd}=@var{h}
-specifies an already opened TCP socket.
-
-Example:
-@example
-# launch a first QEMU instance
-@value{qemu_system} linux.img \
-                 -device e1000,netdev=n1,mac=52:54:00:12:34:56 \
-                 -netdev socket,id=n1,listen=:1234
-# connect the network of this instance to the network of the first instance
-@value{qemu_system} linux.img \
-                 -device e1000,netdev=n2,mac=52:54:00:12:34:57 \
-                 -netdev socket,id=n2,connect=127.0.0.1:1234
-@end example
-
-@item -netdev socket,id=@var{id}[,fd=@var{h}][,mcast=@var{maddr}:@var{port}[,localaddr=@var{addr}]]
-
-Configure a socket host network backend to share the guest's network traffic
-with another QEMU virtual machines using a UDP multicast socket, effectively
-making a bus for every QEMU with same multicast address @var{maddr} and @var{port}.
-NOTES:
-@enumerate
-@item
-Several QEMU can be running on different hosts and share same bus (assuming
-correct multicast setup for these hosts).
-@item
-mcast support is compatible with User Mode Linux (argument @option{eth@var{N}=mcast}), see
-@url{http://user-mode-linux.sf.net}.
-@item
-Use @option{fd=h} to specify an already opened UDP multicast socket.
-@end enumerate
-
-Example:
-@example
-# launch one QEMU instance
-@value{qemu_system} linux.img \
-                 -device e1000,netdev=n1,mac=52:54:00:12:34:56 \
-                 -netdev socket,id=n1,mcast=230.0.0.1:1234
-# launch another QEMU instance on same "bus"
-@value{qemu_system} linux.img \
-                 -device e1000,netdev=n2,mac=52:54:00:12:34:57 \
-                 -netdev socket,id=n2,mcast=230.0.0.1:1234
-# launch yet another QEMU instance on same "bus"
-@value{qemu_system} linux.img \
-                 -device e1000,netdev=n3,mac=52:54:00:12:34:58 \
-                 -netdev socket,id=n3,mcast=230.0.0.1:1234
-@end example
-
-Example (User Mode Linux compat.):
-@example
-# launch QEMU instance (note mcast address selected is UML's default)
-@value{qemu_system} linux.img \
-                 -device e1000,netdev=n1,mac=52:54:00:12:34:56 \
-                 -netdev socket,id=n1,mcast=239.192.168.1:1102
-# launch UML
-/path/to/linux ubd0=/path/to/root_fs eth0=mcast
-@end example
-
-Example (send packets from host's 1.2.3.4):
-@example
-@value{qemu_system} linux.img \
-                 -device e1000,netdev=n1,mac=52:54:00:12:34:56 \
-                 -netdev socket,id=n1,mcast=239.192.168.1:1102,localaddr=1.2.3.4
-@end example
-
-@item -netdev l2tpv3,id=@var{id},src=@var{srcaddr},dst=@var{dstaddr}[,srcport=@var{srcport}][,dstport=@var{dstport}],txsession=@var{txsession}[,rxsession=@var{rxsession}][,ipv6][,udp][,cookie64][,counter][,pincounter][,txcookie=@var{txcookie}][,rxcookie=@var{rxcookie}][,offset=@var{offset}]
-Configure a L2TPv3 pseudowire host network backend. L2TPv3 (RFC3931) is a
-popular protocol to transport Ethernet (and other Layer 2) data frames between
-two systems. It is present in routers, firewalls and the Linux kernel
-(from version 3.3 onwards).
-
-This transport allows a VM to communicate to another VM, router or firewall directly.
-
-@table @option
-@item src=@var{srcaddr}
-    source address (mandatory)
-@item dst=@var{dstaddr}
-    destination address (mandatory)
-@item udp
-    select udp encapsulation (default is ip).
-@item srcport=@var{srcport}
-    source udp port.
-@item dstport=@var{dstport}
-    destination udp port.
-@item ipv6
-    force v6, otherwise defaults to v4.
-@item rxcookie=@var{rxcookie}
-@itemx txcookie=@var{txcookie}
-    Cookies are a weak form of security in the l2tpv3 specification.
-Their function is mostly to prevent misconfiguration. By default they are 32
-bit.
-@item cookie64
-    Set cookie size to 64 bit instead of the default 32
-@item counter=off
-    Force a 'cut-down' L2TPv3 with no counter as in
-draft-mkonstan-l2tpext-keyed-ipv6-tunnel-00
-@item pincounter=on
-    Work around broken counter handling in peer. This may also help on
-networks which have packet reorder.
-@item offset=@var{offset}
-    Add an extra offset between header and data
-@end table
-
-For example, to attach a VM running on host 4.3.2.1 via L2TPv3 to the bridge br-lan
-on the remote Linux host 1.2.3.4:
-@example
-# Setup tunnel on linux host using raw ip as encapsulation
-# on 1.2.3.4
-ip l2tp add tunnel remote 4.3.2.1 local 1.2.3.4 tunnel_id 1 peer_tunnel_id 1 \
-    encap udp udp_sport 16384 udp_dport 16384
-ip l2tp add session tunnel_id 1 name vmtunnel0 session_id \
-    0xFFFFFFFF peer_session_id 0xFFFFFFFF
-ifconfig vmtunnel0 mtu 1500
-ifconfig vmtunnel0 up
-brctl addif br-lan vmtunnel0
-
-
-# on 4.3.2.1
-# launch QEMU instance - if your network has reorder or is very lossy add ,pincounter
-
-@value{qemu_system} linux.img -device e1000,netdev=n1 \
-    -netdev l2tpv3,id=n1,src=4.2.3.1,dst=1.2.3.4,udp,srcport=16384,dstport=16384,rxsession=0xffffffff,txsession=0xffffffff,counter
-
-@end example
-
-@item -netdev vde,id=@var{id}[,sock=@var{socketpath}][,port=@var{n}][,group=@var{groupname}][,mode=@var{octalmode}]
-Configure VDE backend to connect to PORT @var{n} of a vde switch running on host and
-listening for incoming connections on @var{socketpath}. Use GROUP @var{groupname}
-and MODE @var{octalmode} to change default ownership and permissions for
-communication port. This option is only available if QEMU has been compiled
-with vde support enabled.
-
-Example:
-@example
-# launch vde switch
-vde_switch -F -sock /tmp/myswitch
-# launch QEMU instance
-@value{qemu_system} linux.img -nic vde,sock=/tmp/myswitch
-@end example
-
-@item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off][,queues=n]
-
-Establish a vhost-user netdev, backed by a chardev @var{id}. The chardev should
-be a unix domain socket backed one. The vhost-user uses a specifically defined
-protocol to pass vhost ioctl replacement messages to an application on the other
-end of the socket. On non-MSIX guests, the feature can be forced with
-@var{vhostforce}. Use 'queues=@var{n}' to specify the number of queues to
-be created for multiqueue vhost-user.
-
-Example:
-@example
-qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \
-     -numa node,memdev=mem \
-     -chardev socket,id=chr0,path=/path/to/socket \
-     -netdev type=vhost-user,id=net0,chardev=chr0 \
-     -device virtio-net-pci,netdev=net0
-@end example
-
-@item -netdev hubport,id=@var{id},hubid=@var{hubid}[,netdev=@var{nd}]
-
-Create a hub port on the emulated hub with ID @var{hubid}.
-
-The hubport netdev lets you connect a NIC to a QEMU emulated hub instead of a
-single netdev. Alternatively, you can also connect the hubport to another
-netdev with ID @var{nd} by using the @option{netdev=@var{nd}} option.
-
-@item -net nic[,netdev=@var{nd}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}]
-@findex -net
-Legacy option to configure or create an on-board (or machine default) Network
-Interface Card(NIC) and connect it either to the emulated hub with ID 0 (i.e.
-the default hub), or to the netdev @var{nd}.
-If @var{model} is omitted, then the default NIC model associated with
-the machine type is used. Note that the default NIC model may change in
-future QEMU releases, so it is highly recommended to always specify a model.
-Optionally, the MAC address can be changed to @var{mac}, the device
-address set to @var{addr} (PCI cards only), and a @var{name} can be
-assigned for use in monitor commands.
-Optionally, for PCI cards, you can specify the number @var{v} of MSI-X vectors
-that the card should have; this option currently only affects virtio cards; set
-@var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single
-NIC is created.  QEMU can emulate several different models of network card.
-Use @code{-net nic,model=help} for a list of available devices for your target.
-
-@item -net user|tap|bridge|socket|l2tpv3|vde[,...][,name=@var{name}]
-Configure a host network backend (with the options corresponding to the same
-@option{-netdev} option) and connect it to the emulated hub 0 (the default
-hub). Use @var{name} to specify the name of the hub port.
-ETEXI
-
-STEXI
-@end table
-ETEXI
+SRST
+``-nic [tap|bridge|user|l2tpv3|vde|netmap|vhost-user|socket][,...][,mac=macaddr][,model=mn]``
+    This option is a shortcut for configuring both the on-board
+    (default) guest NIC hardware and the host network backend in one go.
+    The host backend options are the same as with the corresponding
+    ``-netdev`` options below. The guest NIC model can be set with
+    ``model=modelname``. Use ``model=help`` to list the available device
+    types. The hardware MAC address can be set with ``mac=macaddr``.
+
+    The following two example do exactly the same, to show how ``-nic``
+    can be used to shorten the command line length:
+
+    .. parsed-literal::
+
+        |qemu_system| -netdev user,id=n1,ipv6=off -device e1000,netdev=n1,mac=52:54:98:76:54:32
+        |qemu_system| -nic user,ipv6=off,model=e1000,mac=52:54:98:76:54:32
+
+``-nic none``
+    Indicate that no network devices should be configured. It is used to
+    override the default configuration (default NIC with "user" host
+    network backend) which is activated if no other networking options
+    are provided.
+
+``-netdev user,id=id[,option][,option][,...]``
+    Configure user mode host network backend which requires no
+    administrator privilege to run. Valid options are:
+
+    ``id=id``
+        Assign symbolic name for use in monitor commands.
+
+    ``ipv4=on|off and ipv6=on|off``
+        Specify that either IPv4 or IPv6 must be enabled. If neither is
+        specified both protocols are enabled.
+
+    ``net=addr[/mask]``
+        Set IP network address the guest will see. Optionally specify
+        the netmask, either in the form a.b.c.d or as number of valid
+        top-most bits. Default is 10.0.2.0/24.
+
+    ``host=addr``
+        Specify the guest-visible address of the host. Default is the
+        2nd IP in the guest network, i.e. x.x.x.2.
+
+    ``ipv6-net=addr[/int]``
+        Set IPv6 network address the guest will see (default is
+        fec0::/64). The network prefix is given in the usual hexadecimal
+        IPv6 address notation. The prefix size is optional, and is given
+        as the number of valid top-most bits (default is 64).
+
+    ``ipv6-host=addr``
+        Specify the guest-visible IPv6 address of the host. Default is
+        the 2nd IPv6 in the guest network, i.e. xxxx::2.
+
+    ``restrict=on|off``
+        If this option is enabled, the guest will be isolated, i.e. it
+        will not be able to contact the host and no guest IP packets
+        will be routed over the host to the outside. This option does
+        not affect any explicitly set forwarding rules.
+
+    ``hostname=name``
+        Specifies the client hostname reported by the built-in DHCP
+        server.
+
+    ``dhcpstart=addr``
+        Specify the first of the 16 IPs the built-in DHCP server can
+        assign. Default is the 15th to 31st IP in the guest network,
+        i.e. x.x.x.15 to x.x.x.31.
+
+    ``dns=addr``
+        Specify the guest-visible address of the virtual nameserver. The
+        address must be different from the host address. Default is the
+        3rd IP in the guest network, i.e. x.x.x.3.
+
+    ``ipv6-dns=addr``
+        Specify the guest-visible address of the IPv6 virtual
+        nameserver. The address must be different from the host address.
+        Default is the 3rd IP in the guest network, i.e. xxxx::3.
+
+    ``dnssearch=domain``
+        Provides an entry for the domain-search list sent by the
+        built-in DHCP server. More than one domain suffix can be
+        transmitted by specifying this option multiple times. If
+        supported, this will cause the guest to automatically try to
+        append the given domain suffix(es) in case a domain name can not
+        be resolved.
+
+        Example:
+
+        .. parsed-literal::
+
+            |qemu_system| -nic user,dnssearch=mgmt.example.org,dnssearch=example.org
+
+    ``domainname=domain``
+        Specifies the client domain name reported by the built-in DHCP
+        server.
+
+    ``tftp=dir``
+        When using the user mode network stack, activate a built-in TFTP
+        server. The files in dir will be exposed as the root of a TFTP
+        server. The TFTP client on the guest must be configured in
+        binary mode (use the command ``bin`` of the Unix TFTP client).
+
+    ``tftp-server-name=name``
+        In BOOTP reply, broadcast name as the "TFTP server name"
+        (RFC2132 option 66). This can be used to advise the guest to
+        load boot files or configurations from a different server than
+        the host address.
+
+    ``bootfile=file``
+        When using the user mode network stack, broadcast file as the
+        BOOTP filename. In conjunction with ``tftp``, this can be used
+        to network boot a guest from a local directory.
+
+        Example (using pxelinux):
+
+        .. parsed-literal::
+
+            |qemu_system| -hda linux.img -boot n -device e1000,netdev=n1 \
+                -netdev user,id=n1,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
+
+    ``smb=dir[,smbserver=addr]``
+        When using the user mode network stack, activate a built-in SMB
+        server so that Windows OSes can access to the host files in
+        ``dir`` transparently. The IP address of the SMB server can be
+        set to addr. By default the 4th IP in the guest network is used,
+        i.e. x.x.x.4.
+
+        In the guest Windows OS, the line:
+
+        ::
+
+            10.0.2.4 smbserver
+
+        must be added in the file ``C:\WINDOWS\LMHOSTS`` (for windows
+        9x/Me) or ``C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS`` (Windows
+        NT/2000).
+
+        Then ``dir`` can be accessed in ``\\smbserver\qemu``.
+
+        Note that a SAMBA server must be installed on the host OS.
+
+    ``hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport``
+        Redirect incoming TCP or UDP connections to the host port
+        hostport to the guest IP address guestaddr on guest port
+        guestport. If guestaddr is not specified, its value is x.x.x.15
+        (default first address given by the built-in DHCP server). By
+        specifying hostaddr, the rule can be bound to a specific host
+        interface. If no connection type is set, TCP is used. This
+        option can be given multiple times.
+
+        For example, to redirect host X11 connection from screen 1 to
+        guest screen 0, use the following:
+
+        .. parsed-literal::
+
+            # on the host
+            |qemu_system| -nic user,hostfwd=tcp:127.0.0.1:6001-:6000
+            # this host xterm should open in the guest X11 server
+            xterm -display :1
+
+        To redirect telnet connections from host port 5555 to telnet
+        port on the guest, use the following:
+
+        .. parsed-literal::
+
+            # on the host
+            |qemu_system| -nic user,hostfwd=tcp::5555-:23
+            telnet localhost 5555
+
+        Then when you use on the host ``telnet localhost 5555``, you
+        connect to the guest telnet server.
+
+    ``guestfwd=[tcp]:server:port-dev``; \ ``guestfwd=[tcp]:server:port-cmd:command``
+        Forward guest TCP connections to the IP address server on port
+        port to the character device dev or to a program executed by
+        cmd:command which gets spawned for each connection. This option
+        can be given multiple times.
+
+        You can either use a chardev directly and have that one used
+        throughout QEMU's lifetime, like in the following example:
+
+        .. parsed-literal::
+
+            # open 10.10.1.1:4321 on bootup, connect 10.0.2.100:1234 to it whenever
+            # the guest accesses it
+            |qemu_system| -nic user,guestfwd=tcp:10.0.2.100:1234-tcp:10.10.1.1:4321
+
+        Or you can execute a command on every TCP connection established
+        by the guest, so that QEMU behaves similar to an inetd process
+        for that virtual server:
+
+        .. parsed-literal::
+
+            # call "netcat 10.10.1.1 4321" on every TCP connection to 10.0.2.100:1234
+            # and connect the TCP stream to its stdin/stdout
+            |qemu_system| -nic  'user,id=n1,guestfwd=tcp:10.0.2.100:1234-cmd:netcat 10.10.1.1 4321'
+
+``-netdev tap,id=id[,fd=h][,ifname=name][,script=file][,downscript=dfile][,br=bridge][,helper=helper]``
+    Configure a host TAP network backend with ID id.
+
+    Use the network script file to configure it and the network script
+    dfile to deconfigure it. If name is not provided, the OS
+    automatically provides one. The default network configure script is
+    ``/etc/qemu-ifup`` and the default network deconfigure script is
+    ``/etc/qemu-ifdown``. Use ``script=no`` or ``downscript=no`` to
+    disable script execution.
+
+    If running QEMU as an unprivileged user, use the network helper
+    helper to configure the TAP interface and attach it to the bridge.
+    The default network helper executable is
+    ``/path/to/qemu-bridge-helper`` and the default bridge device is
+    ``br0``.
+
+    ``fd``\ =h can be used to specify the handle of an already opened
+    host TAP interface.
+
+    Examples:
+
+    .. parsed-literal::
+
+        #launch a QEMU instance with the default network script
+        |qemu_system| linux.img -nic tap
+
+    .. parsed-literal::
+
+        #launch a QEMU instance with two NICs, each one connected
+        #to a TAP device
+        |qemu_system| linux.img \
+                -netdev tap,id=nd0,ifname=tap0 -device e1000,netdev=nd0 \
+                -netdev tap,id=nd1,ifname=tap1 -device rtl8139,netdev=nd1
+
+    .. parsed-literal::
+
+        #launch a QEMU instance with the default network helper to
+        #connect a TAP device to bridge br0
+        |qemu_system| linux.img -device virtio-net-pci,netdev=n1 \
+                -netdev tap,id=n1,"helper=/path/to/qemu-bridge-helper"
+
+``-netdev bridge,id=id[,br=bridge][,helper=helper]``
+    Connect a host TAP network interface to a host bridge device.
+
+    Use the network helper helper to configure the TAP interface and
+    attach it to the bridge. The default network helper executable is
+    ``/path/to/qemu-bridge-helper`` and the default bridge device is
+    ``br0``.
+
+    Examples:
+
+    .. parsed-literal::
+
+        #launch a QEMU instance with the default network helper to
+        #connect a TAP device to bridge br0
+        |qemu_system| linux.img -netdev bridge,id=n1 -device virtio-net,netdev=n1
+
+    .. parsed-literal::
+
+        #launch a QEMU instance with the default network helper to
+        #connect a TAP device to bridge qemubr0
+        |qemu_system| linux.img -netdev bridge,br=qemubr0,id=n1 -device virtio-net,netdev=n1
+
+``-netdev socket,id=id[,fd=h][,listen=[host]:port][,connect=host:port]``
+    This host network backend can be used to connect the guest's network
+    to another QEMU virtual machine using a TCP socket connection. If
+    ``listen`` is specified, QEMU waits for incoming connections on port
+    (host is optional). ``connect`` is used to connect to another QEMU
+    instance using the ``listen`` option. ``fd``\ =h specifies an
+    already opened TCP socket.
+
+    Example:
+
+    .. parsed-literal::
+
+        # launch a first QEMU instance
+        |qemu_system| linux.img \
+                         -device e1000,netdev=n1,mac=52:54:00:12:34:56 \
+                         -netdev socket,id=n1,listen=:1234
+        # connect the network of this instance to the network of the first instance
+        |qemu_system| linux.img \
+                         -device e1000,netdev=n2,mac=52:54:00:12:34:57 \
+                         -netdev socket,id=n2,connect=127.0.0.1:1234
+
+``-netdev socket,id=id[,fd=h][,mcast=maddr:port[,localaddr=addr]]``
+    Configure a socket host network backend to share the guest's network
+    traffic with another QEMU virtual machines using a UDP multicast
+    socket, effectively making a bus for every QEMU with same multicast
+    address maddr and port. NOTES:
+
+    1. Several QEMU can be running on different hosts and share same bus
+       (assuming correct multicast setup for these hosts).
+
+    2. mcast support is compatible with User Mode Linux (argument
+       ``ethN=mcast``), see http://user-mode-linux.sf.net.
+
+    3. Use ``fd=h`` to specify an already opened UDP multicast socket.
+
+    Example:
+
+    .. parsed-literal::
+
+        # launch one QEMU instance
+        |qemu_system| linux.img \
+                         -device e1000,netdev=n1,mac=52:54:00:12:34:56 \
+                         -netdev socket,id=n1,mcast=230.0.0.1:1234
+        # launch another QEMU instance on same "bus"
+        |qemu_system| linux.img \
+                         -device e1000,netdev=n2,mac=52:54:00:12:34:57 \
+                         -netdev socket,id=n2,mcast=230.0.0.1:1234
+        # launch yet another QEMU instance on same "bus"
+        |qemu_system| linux.img \
+                         -device e1000,netdev=n3,mac=52:54:00:12:34:58 \
+                         -netdev socket,id=n3,mcast=230.0.0.1:1234
+
+    Example (User Mode Linux compat.):
+
+    .. parsed-literal::
+
+        # launch QEMU instance (note mcast address selected is UML's default)
+        |qemu_system| linux.img \
+                         -device e1000,netdev=n1,mac=52:54:00:12:34:56 \
+                         -netdev socket,id=n1,mcast=239.192.168.1:1102
+        # launch UML
+        /path/to/linux ubd0=/path/to/root_fs eth0=mcast
+
+    Example (send packets from host's 1.2.3.4):
+
+    .. parsed-literal::
+
+        |qemu_system| linux.img \
+                         -device e1000,netdev=n1,mac=52:54:00:12:34:56 \
+                         -netdev socket,id=n1,mcast=239.192.168.1:1102,localaddr=1.2.3.4
+
+``-netdev l2tpv3,id=id,src=srcaddr,dst=dstaddr[,srcport=srcport][,dstport=dstport],txsession=txsession[,rxsession=rxsession][,ipv6][,udp][,cookie64][,counter][,pincounter][,txcookie=txcookie][,rxcookie=rxcookie][,offset=offset]``
+    Configure a L2TPv3 pseudowire host network backend. L2TPv3 (RFC3931)
+    is a popular protocol to transport Ethernet (and other Layer 2) data
+    frames between two systems. It is present in routers, firewalls and
+    the Linux kernel (from version 3.3 onwards).
+
+    This transport allows a VM to communicate to another VM, router or
+    firewall directly.
+
+    ``src=srcaddr``
+        source address (mandatory)
+
+    ``dst=dstaddr``
+        destination address (mandatory)
+
+    ``udp``
+        select udp encapsulation (default is ip).
+
+    ``srcport=srcport``
+        source udp port.
+
+    ``dstport=dstport``
+        destination udp port.
+
+    ``ipv6``
+        force v6, otherwise defaults to v4.
+
+    ``rxcookie=rxcookie``; \ ``txcookie=txcookie``
+        Cookies are a weak form of security in the l2tpv3 specification.
+        Their function is mostly to prevent misconfiguration. By default
+        they are 32 bit.
+
+    ``cookie64``
+        Set cookie size to 64 bit instead of the default 32
+
+    ``counter=off``
+        Force a 'cut-down' L2TPv3 with no counter as in
+        draft-mkonstan-l2tpext-keyed-ipv6-tunnel-00
+
+    ``pincounter=on``
+        Work around broken counter handling in peer. This may also help
+        on networks which have packet reorder.
+
+    ``offset=offset``
+        Add an extra offset between header and data
+
+    For example, to attach a VM running on host 4.3.2.1 via L2TPv3 to
+    the bridge br-lan on the remote Linux host 1.2.3.4:
+
+    .. parsed-literal::
+
+        # Setup tunnel on linux host using raw ip as encapsulation
+        # on 1.2.3.4
+        ip l2tp add tunnel remote 4.3.2.1 local 1.2.3.4 tunnel_id 1 peer_tunnel_id 1 \
+            encap udp udp_sport 16384 udp_dport 16384
+        ip l2tp add session tunnel_id 1 name vmtunnel0 session_id \
+            0xFFFFFFFF peer_session_id 0xFFFFFFFF
+        ifconfig vmtunnel0 mtu 1500
+        ifconfig vmtunnel0 up
+        brctl addif br-lan vmtunnel0
+
+
+        # on 4.3.2.1
+        # launch QEMU instance - if your network has reorder or is very lossy add ,pincounter
+
+        |qemu_system| linux.img -device e1000,netdev=n1 \
+            -netdev l2tpv3,id=n1,src=4.2.3.1,dst=1.2.3.4,udp,srcport=16384,dstport=16384,rxsession=0xffffffff,txsession=0xffffffff,counter
+
+``-netdev vde,id=id[,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]``
+    Configure VDE backend to connect to PORT n of a vde switch running
+    on host and listening for incoming connections on socketpath. Use
+    GROUP groupname and MODE octalmode to change default ownership and
+    permissions for communication port. This option is only available if
+    QEMU has been compiled with vde support enabled.
+
+    Example:
+
+    .. parsed-literal::
+
+        # launch vde switch
+        vde_switch -F -sock /tmp/myswitch
+        # launch QEMU instance
+        |qemu_system| linux.img -nic vde,sock=/tmp/myswitch
+
+``-netdev vhost-user,chardev=id[,vhostforce=on|off][,queues=n]``
+    Establish a vhost-user netdev, backed by a chardev id. The chardev
+    should be a unix domain socket backed one. The vhost-user uses a
+    specifically defined protocol to pass vhost ioctl replacement
+    messages to an application on the other end of the socket. On
+    non-MSIX guests, the feature can be forced with vhostforce. Use
+    'queues=n' to specify the number of queues to be created for
+    multiqueue vhost-user.
+
+    Example:
+
+    ::
+
+        qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \
+             -numa node,memdev=mem \
+             -chardev socket,id=chr0,path=/path/to/socket \
+             -netdev type=vhost-user,id=net0,chardev=chr0 \
+             -device virtio-net-pci,netdev=net0
+
+``-netdev hubport,id=id,hubid=hubid[,netdev=nd]``
+    Create a hub port on the emulated hub with ID hubid.
+
+    The hubport netdev lets you connect a NIC to a QEMU emulated hub
+    instead of a single netdev. Alternatively, you can also connect the
+    hubport to another netdev with ID nd by using the ``netdev=nd``
+    option.
+
+``-net nic[,netdev=nd][,macaddr=mac][,model=type] [,name=name][,addr=addr][,vectors=v]``
+    Legacy option to configure or create an on-board (or machine
+    default) Network Interface Card(NIC) and connect it either to the
+    emulated hub with ID 0 (i.e. the default hub), or to the netdev nd.
+    If model is omitted, then the default NIC model associated with the
+    machine type is used. Note that the default NIC model may change in
+    future QEMU releases, so it is highly recommended to always specify
+    a model. Optionally, the MAC address can be changed to mac, the
+    device address set to addr (PCI cards only), and a name can be
+    assigned for use in monitor commands. Optionally, for PCI cards, you
+    can specify the number v of MSI-X vectors that the card should have;
+    this option currently only affects virtio cards; set v = 0 to
+    disable MSI-X. If no ``-net`` option is specified, a single NIC is
+    created. QEMU can emulate several different models of network card.
+    Use ``-net nic,model=help`` for a list of available devices for your
+    target.
+
+``-net user|tap|bridge|socket|l2tpv3|vde[,...][,name=name]``
+    Configure a host network backend (with the options corresponding to
+    the same ``-netdev`` option) and connect it to the emulated hub 0
+    (the default hub). Use name to specify the name of the hub port.
+ERST
+
 DEFHEADING()
 
 DEFHEADING(Character device options:)
@@ -2910,302 +2966,267 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
     , QEMU_ARCH_ALL
 )
 
-STEXI
-
+SRST
 The general form of a character device option is:
-@table @option
-@item -chardev @var{backend},id=@var{id}[,mux=on|off][,@var{options}]
-@findex -chardev
-Backend is one of:
-@option{null},
-@option{socket},
-@option{udp},
-@option{msmouse},
-@option{vc},
-@option{ringbuf},
-@option{file},
-@option{pipe},
-@option{console},
-@option{serial},
-@option{pty},
-@option{stdio},
-@option{braille},
-@option{tty},
-@option{parallel},
-@option{parport},
-@option{spicevmc},
-@option{spiceport}.
-The specific backend will determine the applicable options.
-
-Use @code{-chardev help} to print all available chardev backend types.
-
-All devices must have an id, which can be any string up to 127 characters long.
-It is used to uniquely identify this device in other command line directives.
-
-A character device may be used in multiplexing mode by multiple front-ends.
-Specify @option{mux=on} to enable this mode.
-A multiplexer is a "1:N" device, and here the "1" end is your specified chardev
-backend, and the "N" end is the various parts of QEMU that can talk to a chardev.
-If you create a chardev with @option{id=myid} and @option{mux=on}, QEMU will
-create a multiplexer with your specified ID, and you can then configure multiple
-front ends to use that chardev ID for their input/output. Up to four different
-front ends can be connected to a single multiplexed chardev. (Without
-multiplexing enabled, a chardev can only be used by a single front end.)
-For instance you could use this to allow a single stdio chardev to be used by
-two serial ports and the QEMU monitor:
-
-@example
--chardev stdio,mux=on,id=char0 \
--mon chardev=char0,mode=readline \
--serial chardev:char0 \
--serial chardev:char0
-@end example
-
-You can have more than one multiplexer in a system configuration; for instance
-you could have a TCP port multiplexed between UART 0 and UART 1, and stdio
-multiplexed between the QEMU monitor and a parallel port:
-
-@example
--chardev stdio,mux=on,id=char0 \
--mon chardev=char0,mode=readline \
--parallel chardev:char0 \
--chardev tcp,...,mux=on,id=char1 \
--serial chardev:char1 \
--serial chardev:char1
-@end example
-
-When you're using a multiplexed character device, some escape sequences are
-interpreted in the input. @xref{mux_keys, Keys in the character backend
-multiplexer}.
-
-Note that some other command line options may implicitly create multiplexed
-character backends; for instance @option{-serial mon:stdio} creates a
-multiplexed stdio backend connected to the serial port and the QEMU monitor,
-and @option{-nographic} also multiplexes the console and the monitor to
-stdio.
-
-There is currently no support for multiplexing in the other direction
-(where a single QEMU front end takes input and output from multiple chardevs).
-
-Every backend supports the @option{logfile} option, which supplies the path
-to a file to record all data transmitted via the backend. The @option{logappend}
-option controls whether the log file will be truncated or appended to when
-opened.
-
-@end table
-
-The available backends are:
-
-@table @option
-@item -chardev null,id=@var{id}
-A void device. This device will not emit any data, and will drop any data it
-receives. The null backend does not take any options.
-
-@item -chardev socket,id=@var{id}[,@var{TCP options} or @var{unix options}][,server][,nowait][,telnet][,websocket][,reconnect=@var{seconds}][,tls-creds=@var{id}][,tls-authz=@var{id}]
-
-Create a two-way stream socket, which can be either a TCP or a unix socket. A
-unix socket will be created if @option{path} is specified. Behaviour is
-undefined if TCP options are specified for a unix socket.
-
-@option{server} specifies that the socket shall be a listening socket.
 
-@option{nowait} specifies that QEMU should not block waiting for a client to
-connect to a listening socket.
+``-chardev backend,id=id[,mux=on|off][,options]``
+    Backend is one of: ``null``, ``socket``, ``udp``, ``msmouse``,
+    ``vc``, ``ringbuf``, ``file``, ``pipe``, ``console``, ``serial``,
+    ``pty``, ``stdio``, ``braille``, ``tty``, ``parallel``, ``parport``,
+    ``spicevmc``, ``spiceport``. The specific backend will determine the
+    applicable options.
+
+    Use ``-chardev help`` to print all available chardev backend types.
+
+    All devices must have an id, which can be any string up to 127
+    characters long. It is used to uniquely identify this device in
+    other command line directives.
+
+    A character device may be used in multiplexing mode by multiple
+    front-ends. Specify ``mux=on`` to enable this mode. A multiplexer is
+    a "1:N" device, and here the "1" end is your specified chardev
+    backend, and the "N" end is the various parts of QEMU that can talk
+    to a chardev. If you create a chardev with ``id=myid`` and
+    ``mux=on``, QEMU will create a multiplexer with your specified ID,
+    and you can then configure multiple front ends to use that chardev
+    ID for their input/output. Up to four different front ends can be
+    connected to a single multiplexed chardev. (Without multiplexing
+    enabled, a chardev can only be used by a single front end.) For
+    instance you could use this to allow a single stdio chardev to be
+    used by two serial ports and the QEMU monitor:
+
+    ::
+
+        -chardev stdio,mux=on,id=char0 \
+        -mon chardev=char0,mode=readline \
+        -serial chardev:char0 \
+        -serial chardev:char0
+
+    You can have more than one multiplexer in a system configuration;
+    for instance you could have a TCP port multiplexed between UART 0
+    and UART 1, and stdio multiplexed between the QEMU monitor and a
+    parallel port:
+
+    ::
+
+        -chardev stdio,mux=on,id=char0 \
+        -mon chardev=char0,mode=readline \
+        -parallel chardev:char0 \
+        -chardev tcp,...,mux=on,id=char1 \
+        -serial chardev:char1 \
+        -serial chardev:char1
+
+    When you're using a multiplexed character device, some escape
+    sequences are interpreted in the input. See :ref:`mux_005fkeys`.
+
+    Note that some other command line options may implicitly create
+    multiplexed character backends; for instance ``-serial mon:stdio``
+    creates a multiplexed stdio backend connected to the serial port and
+    the QEMU monitor, and ``-nographic`` also multiplexes the console
+    and the monitor to stdio.
+
+    There is currently no support for multiplexing in the other
+    direction (where a single QEMU front end takes input and output from
+    multiple chardevs).
+
+    Every backend supports the ``logfile`` option, which supplies the
+    path to a file to record all data transmitted via the backend. The
+    ``logappend`` option controls whether the log file will be truncated
+    or appended to when opened.
 
-@option{telnet} specifies that traffic on the socket should interpret telnet
-escape sequences.
-
-@option{websocket} specifies that the socket uses WebSocket protocol for
-communication.
-
-@option{reconnect} sets the timeout for reconnecting on non-server sockets when
-the remote end goes away.  qemu will delay this many seconds and then attempt
-to reconnect.  Zero disables reconnecting, and is the default.
-
-@option{tls-creds} requests enablement of the TLS protocol for encryption,
-and specifies the id of the TLS credentials to use for the handshake. The
-credentials must be previously created with the @option{-object tls-creds}
-argument.
-
-@option{tls-auth} provides the ID of the QAuthZ authorization object against
-which the client's x509 distinguished name will be validated. This object is
-only resolved at time of use, so can be deleted and recreated on the fly
-while the chardev server is active. If missing, it will default to denying
-access.
-
-TCP and unix socket options are given below:
-
-@table @option
-
-@item TCP options: port=@var{port}[,host=@var{host}][,to=@var{to}][,ipv4][,ipv6][,nodelay]
-
-@option{host} for a listening socket specifies the local address to be bound.
-For a connecting socket species the remote host to connect to. @option{host} is
-optional for listening sockets. If not specified it defaults to @code{0.0.0.0}.
-
-@option{port} for a listening socket specifies the local port to be bound. For a
-connecting socket specifies the port on the remote host to connect to.
-@option{port} can be given as either a port number or a service name.
-@option{port} is required.
-
-@option{to} is only relevant to listening sockets. If it is specified, and
-@option{port} cannot be bound, QEMU will attempt to bind to subsequent ports up
-to and including @option{to} until it succeeds. @option{to} must be specified
-as a port number.
-
-@option{ipv4} and @option{ipv6} specify that either IPv4 or IPv6 must be used.
-If neither is specified the socket may use either protocol.
-
-@option{nodelay} disables the Nagle algorithm.
-
-@item unix options: path=@var{path}
+The available backends are:
 
-@option{path} specifies the local path of the unix socket. @option{path} is
-required.
+``-chardev null,id=id``
+    A void device. This device will not emit any data, and will drop any
+    data it receives. The null backend does not take any options.
 
-@end table
+``-chardev socket,id=id[,TCP options or unix options][,server][,nowait][,telnet][,websocket][,reconnect=seconds][,tls-creds=id][,tls-authz=id]``
+    Create a two-way stream socket, which can be either a TCP or a unix
+    socket. A unix socket will be created if ``path`` is specified.
+    Behaviour is undefined if TCP options are specified for a unix
+    socket.
 
-@item -chardev udp,id=@var{id}[,host=@var{host}],port=@var{port}[,localaddr=@var{localaddr}][,localport=@var{localport}][,ipv4][,ipv6]
+    ``server`` specifies that the socket shall be a listening socket.
 
-Sends all traffic from the guest to a remote host over UDP.
+    ``nowait`` specifies that QEMU should not block waiting for a client
+    to connect to a listening socket.
 
-@option{host} specifies the remote host to connect to. If not specified it
-defaults to @code{localhost}.
+    ``telnet`` specifies that traffic on the socket should interpret
+    telnet escape sequences.
 
-@option{port} specifies the port on the remote host to connect to. @option{port}
-is required.
+    ``websocket`` specifies that the socket uses WebSocket protocol for
+    communication.
 
-@option{localaddr} specifies the local address to bind to. If not specified it
-defaults to @code{0.0.0.0}.
+    ``reconnect`` sets the timeout for reconnecting on non-server
+    sockets when the remote end goes away. qemu will delay this many
+    seconds and then attempt to reconnect. Zero disables reconnecting,
+    and is the default.
 
-@option{localport} specifies the local port to bind to. If not specified any
-available local port will be used.
+    ``tls-creds`` requests enablement of the TLS protocol for
+    encryption, and specifies the id of the TLS credentials to use for
+    the handshake. The credentials must be previously created with the
+    ``-object tls-creds`` argument.
 
-@option{ipv4} and @option{ipv6} specify that either IPv4 or IPv6 must be used.
-If neither is specified the device may use either protocol.
+    ``tls-auth`` provides the ID of the QAuthZ authorization object
+    against which the client's x509 distinguished name will be
+    validated. This object is only resolved at time of use, so can be
+    deleted and recreated on the fly while the chardev server is active.
+    If missing, it will default to denying access.
 
-@item -chardev msmouse,id=@var{id}
+    TCP and unix socket options are given below:
 
-Forward QEMU's emulated msmouse events to the guest. @option{msmouse} does not
-take any options.
+    ``TCP options: port=port[,host=host][,to=to][,ipv4][,ipv6][,nodelay]``
+        ``host`` for a listening socket specifies the local address to
+        be bound. For a connecting socket species the remote host to
+        connect to. ``host`` is optional for listening sockets. If not
+        specified it defaults to ``0.0.0.0``.
 
-@item -chardev vc,id=@var{id}[[,width=@var{width}][,height=@var{height}]][[,cols=@var{cols}][,rows=@var{rows}]]
+        ``port`` for a listening socket specifies the local port to be
+        bound. For a connecting socket specifies the port on the remote
+        host to connect to. ``port`` can be given as either a port
+        number or a service name. ``port`` is required.
 
-Connect to a QEMU text console. @option{vc} may optionally be given a specific
-size.
+        ``to`` is only relevant to listening sockets. If it is
+        specified, and ``port`` cannot be bound, QEMU will attempt to
+        bind to subsequent ports up to and including ``to`` until it
+        succeeds. ``to`` must be specified as a port number.
 
-@option{width} and @option{height} specify the width and height respectively of
-the console, in pixels.
+        ``ipv4`` and ``ipv6`` specify that either IPv4 or IPv6 must be
+        used. If neither is specified the socket may use either
+        protocol.
 
-@option{cols} and @option{rows} specify that the console be sized to fit a text
-console with the given dimensions.
+        ``nodelay`` disables the Nagle algorithm.
 
-@item -chardev ringbuf,id=@var{id}[,size=@var{size}]
+    ``unix options: path=path``
+        ``path`` specifies the local path of the unix socket. ``path``
+        is required.
 
-Create a ring buffer with fixed size @option{size}.
-@var{size} must be a power of two and defaults to @code{64K}.
+``-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr][,localport=localport][,ipv4][,ipv6]``
+    Sends all traffic from the guest to a remote host over UDP.
 
-@item -chardev file,id=@var{id},path=@var{path}
+    ``host`` specifies the remote host to connect to. If not specified
+    it defaults to ``localhost``.
 
-Log all traffic received from the guest to a file.
+    ``port`` specifies the port on the remote host to connect to.
+    ``port`` is required.
 
-@option{path} specifies the path of the file to be opened. This file will be
-created if it does not already exist, and overwritten if it does. @option{path}
-is required.
+    ``localaddr`` specifies the local address to bind to. If not
+    specified it defaults to ``0.0.0.0``.
 
-@item -chardev pipe,id=@var{id},path=@var{path}
+    ``localport`` specifies the local port to bind to. If not specified
+    any available local port will be used.
 
-Create a two-way connection to the guest. The behaviour differs slightly between
-Windows hosts and other hosts:
+    ``ipv4`` and ``ipv6`` specify that either IPv4 or IPv6 must be used.
+    If neither is specified the device may use either protocol.
 
-On Windows, a single duplex pipe will be created at
-@file{\\.pipe\@option{path}}.
+``-chardev msmouse,id=id``
+    Forward QEMU's emulated msmouse events to the guest. ``msmouse``
+    does not take any options.
 
-On other hosts, 2 pipes will be created called @file{@option{path}.in} and
-@file{@option{path}.out}. Data written to @file{@option{path}.in} will be
-received by the guest. Data written by the guest can be read from
-@file{@option{path}.out}. QEMU will not create these fifos, and requires them to
-be present.
+``-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]``
+    Connect to a QEMU text console. ``vc`` may optionally be given a
+    specific size.
 
-@option{path} forms part of the pipe path as described above. @option{path} is
-required.
+    ``width`` and ``height`` specify the width and height respectively
+    of the console, in pixels.
 
-@item -chardev console,id=@var{id}
+    ``cols`` and ``rows`` specify that the console be sized to fit a
+    text console with the given dimensions.
 
-Send traffic from the guest to QEMU's standard output. @option{console} does not
-take any options.
+``-chardev ringbuf,id=id[,size=size]``
+    Create a ring buffer with fixed size ``size``. size must be a power
+    of two and defaults to ``64K``.
 
-@option{console} is only available on Windows hosts.
+``-chardev file,id=id,path=path``
+    Log all traffic received from the guest to a file.
 
-@item -chardev serial,id=@var{id},path=@option{path}
+    ``path`` specifies the path of the file to be opened. This file will
+    be created if it does not already exist, and overwritten if it does.
+    ``path`` is required.
 
-Send traffic from the guest to a serial device on the host.
+``-chardev pipe,id=id,path=path``
+    Create a two-way connection to the guest. The behaviour differs
+    slightly between Windows hosts and other hosts:
 
-On Unix hosts serial will actually accept any tty device,
-not only serial lines.
+    On Windows, a single duplex pipe will be created at
+    ``\\.pipe\path``.
 
-@option{path} specifies the name of the serial device to open.
+    On other hosts, 2 pipes will be created called ``path.in`` and
+    ``path.out``. Data written to ``path.in`` will be received by the
+    guest. Data written by the guest can be read from ``path.out``. QEMU
+    will not create these fifos, and requires them to be present.
 
-@item -chardev pty,id=@var{id}
+    ``path`` forms part of the pipe path as described above. ``path`` is
+    required.
 
-Create a new pseudo-terminal on the host and connect to it. @option{pty} does
-not take any options.
+``-chardev console,id=id``
+    Send traffic from the guest to QEMU's standard output. ``console``
+    does not take any options.
 
-@option{pty} is not available on Windows hosts.
+    ``console`` is only available on Windows hosts.
 
-@item -chardev stdio,id=@var{id}[,signal=on|off]
-Connect to standard input and standard output of the QEMU process.
+``-chardev serial,id=id,path=path``
+    Send traffic from the guest to a serial device on the host.
 
-@option{signal} controls if signals are enabled on the terminal, that includes
-exiting QEMU with the key sequence @key{Control-c}. This option is enabled by
-default, use @option{signal=off} to disable it.
+    On Unix hosts serial will actually accept any tty device, not only
+    serial lines.
 
-@item -chardev braille,id=@var{id}
+    ``path`` specifies the name of the serial device to open.
 
-Connect to a local BrlAPI server. @option{braille} does not take any options.
+``-chardev pty,id=id``
+    Create a new pseudo-terminal on the host and connect to it. ``pty``
+    does not take any options.
 
-@item -chardev tty,id=@var{id},path=@var{path}
+    ``pty`` is not available on Windows hosts.
 
-@option{tty} is only available on Linux, Sun, FreeBSD, NetBSD, OpenBSD and
-DragonFlyBSD hosts.  It is an alias for @option{serial}.
+``-chardev stdio,id=id[,signal=on|off]``
+    Connect to standard input and standard output of the QEMU process.
 
-@option{path} specifies the path to the tty. @option{path} is required.
+    ``signal`` controls if signals are enabled on the terminal, that
+    includes exiting QEMU with the key sequence Control-c. This option
+    is enabled by default, use ``signal=off`` to disable it.
 
-@item -chardev parallel,id=@var{id},path=@var{path}
-@itemx -chardev parport,id=@var{id},path=@var{path}
+``-chardev braille,id=id``
+    Connect to a local BrlAPI server. ``braille`` does not take any
+    options.
 
-@option{parallel} is only available on Linux, FreeBSD and DragonFlyBSD hosts.
+``-chardev tty,id=id,path=path``
+    ``tty`` is only available on Linux, Sun, FreeBSD, NetBSD, OpenBSD
+    and DragonFlyBSD hosts. It is an alias for ``serial``.
 
-Connect to a local parallel port.
+    ``path`` specifies the path to the tty. ``path`` is required.
 
-@option{path} specifies the path to the parallel port device. @option{path} is
-required.
+``-chardev parallel,id=id,path=path``
+  \
+``-chardev parport,id=id,path=path``
+    ``parallel`` is only available on Linux, FreeBSD and DragonFlyBSD
+    hosts.
 
-@item -chardev spicevmc,id=@var{id},debug=@var{debug},name=@var{name}
+    Connect to a local parallel port.
 
-@option{spicevmc} is only available when spice support is built in.
+    ``path`` specifies the path to the parallel port device. ``path`` is
+    required.
 
-@option{debug} debug level for spicevmc
+``-chardev spicevmc,id=id,debug=debug,name=name``
+    ``spicevmc`` is only available when spice support is built in.
 
-@option{name} name of spice channel to connect to
+    ``debug`` debug level for spicevmc
 
-Connect to a spice virtual machine channel, such as vdiport.
+    ``name`` name of spice channel to connect to
 
-@item -chardev spiceport,id=@var{id},debug=@var{debug},name=@var{name}
+    Connect to a spice virtual machine channel, such as vdiport.
 
-@option{spiceport} is only available when spice support is built in.
+``-chardev spiceport,id=id,debug=debug,name=name``
+    ``spiceport`` is only available when spice support is built in.
 
-@option{debug} debug level for spicevmc
+    ``debug`` debug level for spicevmc
 
-@option{name} name of spice port to connect to
+    ``name`` name of spice port to connect to
 
-Connect to a spice port, allowing a Spice client to handle the traffic
-identified by a name (preferably a fqdn).
-ETEXI
+    Connect to a spice port, allowing a Spice client to handle the
+    traffic identified by a name (preferably a fqdn).
+ERST
 
-STEXI
-@end table
-ETEXI
 DEFHEADING()
 
 #ifdef CONFIG_TPM
@@ -3219,146 +3240,122 @@ DEF("tpmdev", HAS_ARG, QEMU_OPTION_tpmdev, \
     "-tpmdev emulator,id=id,chardev=dev\n"
     "                configure the TPM device using chardev backend\n",
     QEMU_ARCH_ALL)
-STEXI
-
+SRST
 The general form of a TPM device option is:
-@table @option
-
-@item -tpmdev @var{backend},id=@var{id}[,@var{options}]
-@findex -tpmdev
 
-The specific backend type will determine the applicable options.
-The @code{-tpmdev} option creates the TPM backend and requires a
-@code{-device} option that specifies the TPM frontend interface model.
+``-tpmdev backend,id=id[,options]``
+    The specific backend type will determine the applicable options. The
+    ``-tpmdev`` option creates the TPM backend and requires a
+    ``-device`` option that specifies the TPM frontend interface model.
 
-Use @code{-tpmdev help} to print all available TPM backend types.
-
-@end table
+    Use ``-tpmdev help`` to print all available TPM backend types.
 
 The available backends are:
 
-@table @option
-
-@item -tpmdev passthrough,id=@var{id},path=@var{path},cancel-path=@var{cancel-path}
+``-tpmdev passthrough,id=id,path=path,cancel-path=cancel-path``
+    (Linux-host only) Enable access to the host's TPM using the
+    passthrough driver.
 
-(Linux-host only) Enable access to the host's TPM using the passthrough
-driver.
+    ``path`` specifies the path to the host's TPM device, i.e., on a
+    Linux host this would be ``/dev/tpm0``. ``path`` is optional and by
+    default ``/dev/tpm0`` is used.
 
-@option{path} specifies the path to the host's TPM device, i.e., on
-a Linux host this would be @code{/dev/tpm0}.
-@option{path} is optional and by default @code{/dev/tpm0} is used.
+    ``cancel-path`` specifies the path to the host TPM device's sysfs
+    entry allowing for cancellation of an ongoing TPM command.
+    ``cancel-path`` is optional and by default QEMU will search for the
+    sysfs entry to use.
 
-@option{cancel-path} specifies the path to the host TPM device's sysfs
-entry allowing for cancellation of an ongoing TPM command.
-@option{cancel-path} is optional and by default QEMU will search for the
-sysfs entry to use.
+    Some notes about using the host's TPM with the passthrough driver:
 
-Some notes about using the host's TPM with the passthrough driver:
+    The TPM device accessed by the passthrough driver must not be used
+    by any other application on the host.
 
-The TPM device accessed by the passthrough driver must not be
-used by any other application on the host.
+    Since the host's firmware (BIOS/UEFI) has already initialized the
+    TPM, the VM's firmware (BIOS/UEFI) will not be able to initialize
+    the TPM again and may therefore not show a TPM-specific menu that
+    would otherwise allow the user to configure the TPM, e.g., allow the
+    user to enable/disable or activate/deactivate the TPM. Further, if
+    TPM ownership is released from within a VM then the host's TPM will
+    get disabled and deactivated. To enable and activate the TPM again
+    afterwards, the host has to be rebooted and the user is required to
+    enter the firmware's menu to enable and activate the TPM. If the TPM
+    is left disabled and/or deactivated most TPM commands will fail.
 
-Since the host's firmware (BIOS/UEFI) has already initialized the TPM,
-the VM's firmware (BIOS/UEFI) will not be able to initialize the
-TPM again and may therefore not show a TPM-specific menu that would
-otherwise allow the user to configure the TPM, e.g., allow the user to
-enable/disable or activate/deactivate the TPM.
-Further, if TPM ownership is released from within a VM then the host's TPM
-will get disabled and deactivated. To enable and activate the
-TPM again afterwards, the host has to be rebooted and the user is
-required to enter the firmware's menu to enable and activate the TPM.
-If the TPM is left disabled and/or deactivated most TPM commands will fail.
+    To create a passthrough TPM use the following two options:
 
-To create a passthrough TPM use the following two options:
-@example
--tpmdev passthrough,id=tpm0 -device tpm-tis,tpmdev=tpm0
-@end example
-Note that the @code{-tpmdev} id is @code{tpm0} and is referenced by
-@code{tpmdev=tpm0} in the device option.
+    ::
 
-@item -tpmdev emulator,id=@var{id},chardev=@var{dev}
+        -tpmdev passthrough,id=tpm0 -device tpm-tis,tpmdev=tpm0
 
-(Linux-host only) Enable access to a TPM emulator using Unix domain socket based
-chardev backend.
+    Note that the ``-tpmdev`` id is ``tpm0`` and is referenced by
+    ``tpmdev=tpm0`` in the device option.
 
-@option{chardev} specifies the unique ID of a character device backend that provides connection to the software TPM server.
+``-tpmdev emulator,id=id,chardev=dev``
+    (Linux-host only) Enable access to a TPM emulator using Unix domain
+    socket based chardev backend.
 
-To create a TPM emulator backend device with chardev socket backend:
-@example
+    ``chardev`` specifies the unique ID of a character device backend
+    that provides connection to the software TPM server.
 
--chardev socket,id=chrtpm,path=/tmp/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0
+    To create a TPM emulator backend device with chardev socket backend:
 
-@end example
+    ::
 
-ETEXI
+        -chardev socket,id=chrtpm,path=/tmp/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0
+ERST
 
-STEXI
-@end table
-ETEXI
 DEFHEADING()
 
 #endif
 
 DEFHEADING(Linux/Multiboot boot specific:)
-STEXI
+SRST
+When using these options, you can use a given Linux or Multiboot kernel
+without installing it in the disk image. It can be useful for easier
+testing of various kernels.
 
-When using these options, you can use a given Linux or Multiboot
-kernel without installing it in the disk image. It can be useful
-for easier testing of various kernels.
 
-@table @option
-ETEXI
+ERST
 
 DEF("kernel", HAS_ARG, QEMU_OPTION_kernel, \
     "-kernel bzImage use 'bzImage' as kernel image\n", QEMU_ARCH_ALL)
-STEXI
-@item -kernel @var{bzImage}
-@findex -kernel
-Use @var{bzImage} as kernel image. The kernel can be either a Linux kernel
-or in multiboot format.
-ETEXI
+SRST
+``-kernel bzImage``
+    Use bzImage as kernel image. The kernel can be either a Linux kernel
+    or in multiboot format.
+ERST
 
 DEF("append", HAS_ARG, QEMU_OPTION_append, \
     "-append cmdline use 'cmdline' as kernel command line\n", QEMU_ARCH_ALL)
-STEXI
-@item -append @var{cmdline}
-@findex -append
-Use @var{cmdline} as kernel command line
-ETEXI
+SRST
+``-append cmdline``
+    Use cmdline as kernel command line
+ERST
 
 DEF("initrd", HAS_ARG, QEMU_OPTION_initrd, \
            "-initrd file    use 'file' as initial ram disk\n", QEMU_ARCH_ALL)
-STEXI
-@item -initrd @var{file}
-@findex -initrd
-Use @var{file} as initial ram disk.
+SRST
+``-initrd file``
+    Use file as initial ram disk.
 
-@item -initrd "@var{file1} arg=foo,@var{file2}"
+``-initrd "file1 arg=foo,file2"``
+    This syntax is only available with multiboot.
 
-This syntax is only available with multiboot.
-
-Use @var{file1} and @var{file2} as modules and pass arg=foo as parameter to the
-first module.
-ETEXI
+    Use file1 and file2 as modules and pass arg=foo as parameter to the
+    first module.
+ERST
 
 DEF("dtb", HAS_ARG, QEMU_OPTION_dtb, \
     "-dtb    file    use 'file' as device tree image\n", QEMU_ARCH_ALL)
-STEXI
-@item -dtb @var{file}
-@findex -dtb
-Use @var{file} as a device tree binary (dtb) image and pass it to the kernel
-on boot.
-ETEXI
-
-STEXI
-@end table
-ETEXI
+SRST
+``-dtb file``
+    Use file as a device tree binary (dtb) image and pass it to the
+    kernel on boot.
+ERST
+
 DEFHEADING()
 
 DEFHEADING(Debug/Expert options:)
-STEXI
-@table @option
-ETEXI
 
 DEF("fw_cfg", HAS_ARG, QEMU_OPTION_fwcfg,
     "-fw_cfg [name=]<name>,file=<file>\n"
@@ -3366,288 +3363,295 @@ DEF("fw_cfg", HAS_ARG, QEMU_OPTION_fwcfg,
     "-fw_cfg [name=]<name>,string=<str>\n"
     "                add named fw_cfg entry with contents from string\n",
     QEMU_ARCH_ALL)
-STEXI
+SRST
+``-fw_cfg [name=]name,file=file``
+    Add named fw\_cfg entry with contents from file file.
+
+``-fw_cfg [name=]name,string=str``
+    Add named fw\_cfg entry with contents from string str.
 
-@item -fw_cfg [name=]@var{name},file=@var{file}
-@findex -fw_cfg
-Add named fw_cfg entry with contents from file @var{file}.
+    The terminating NUL character of the contents of str will not be
+    included as part of the fw\_cfg item data. To insert contents with
+    embedded NUL characters, you have to use the file parameter.
 
-@item -fw_cfg [name=]@var{name},string=@var{str}
-Add named fw_cfg entry with contents from string @var{str}.
+    The fw\_cfg entries are passed by QEMU through to the guest.
 
-The terminating NUL character of the contents of @var{str} will not be
-included as part of the fw_cfg item data. To insert contents with
-embedded NUL characters, you have to use the @var{file} parameter.
+    Example:
 
-The fw_cfg entries are passed by QEMU through to the guest.
+    ::
 
-Example:
-@example
-    -fw_cfg name=opt/com.mycompany/blob,file=./my_blob.bin
-@end example
-creates an fw_cfg entry named opt/com.mycompany/blob with contents
-from ./my_blob.bin.
+            -fw_cfg name=opt/com.mycompany/blob,file=./my_blob.bin
 
-ETEXI
+    creates an fw\_cfg entry named opt/com.mycompany/blob with contents
+    from ./my\_blob.bin.
+ERST
 
 DEF("serial", HAS_ARG, QEMU_OPTION_serial, \
     "-serial dev     redirect the serial port to char device 'dev'\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -serial @var{dev}
-@findex -serial
-Redirect the virtual serial port to host character device
-@var{dev}. The default device is @code{vc} in graphical mode and
-@code{stdio} in non graphical mode.
-
-This option can be used several times to simulate up to 4 serial
-ports.
-
-Use @code{-serial none} to disable all serial ports.
-
-Available character devices are:
-@table @option
-@item vc[:@var{W}x@var{H}]
-Virtual console. Optionally, a width and height can be given in pixel with
-@example
-vc:800x600
-@end example
-It is also possible to specify width or height in characters:
-@example
-vc:80Cx24C
-@end example
-@item pty
-[Linux only] Pseudo TTY (a new PTY is automatically allocated)
-@item none
-No device is allocated.
-@item null
-void device
-@item chardev:@var{id}
-Use a named character device defined with the @code{-chardev} option.
-@item /dev/XXX
-[Linux only] Use host tty, e.g. @file{/dev/ttyS0}. The host serial port
-parameters are set according to the emulated ones.
-@item /dev/parport@var{N}
-[Linux only, parallel port only] Use host parallel port
-@var{N}. Currently SPP and EPP parallel port features can be used.
-@item file:@var{filename}
-Write output to @var{filename}. No character can be read.
-@item stdio
-[Unix only] standard input/output
-@item pipe:@var{filename}
-name pipe @var{filename}
-@item COM@var{n}
-[Windows only] Use host serial port @var{n}
-@item udp:[@var{remote_host}]:@var{remote_port}[@@[@var{src_ip}]:@var{src_port}]
-This implements UDP Net Console.
-When @var{remote_host} or @var{src_ip} are not specified
-they default to @code{0.0.0.0}.
-When not using a specified @var{src_port} a random port is automatically chosen.
-
-If you just want a simple readonly console you can use @code{netcat} or
-@code{nc}, by starting QEMU with: @code{-serial udp::4555} and nc as:
-@code{nc -u -l -p 4555}. Any time QEMU writes something to that port it
-will appear in the netconsole session.
-
-If you plan to send characters back via netconsole or you want to stop
-and start QEMU a lot of times, you should have QEMU use the same
-source port each time by using something like @code{-serial
-udp::4555@@:4556} to QEMU. Another approach is to use a patched
-version of netcat which can listen to a TCP port and send and receive
-characters via udp.  If you have a patched version of netcat which
-activates telnet remote echo and single char transfer, then you can
-use the following options to set up a netcat redirector to allow
-telnet on port 5555 to access the QEMU port.
-@table @code
-@item QEMU Options:
--serial udp::4555@@:4556
-@item netcat options:
--u -P 4555 -L 0.0.0.0:4556 -t -p 5555 -I -T
-@item telnet options:
-localhost 5555
-@end table
-
-@item tcp:[@var{host}]:@var{port}[,@var{server}][,nowait][,nodelay][,reconnect=@var{seconds}]
-The TCP Net Console has two modes of operation.  It can send the serial
-I/O to a location or wait for a connection from a location.  By default
-the TCP Net Console is sent to @var{host} at the @var{port}.  If you use
-the @var{server} option QEMU will wait for a client socket application
-to connect to the port before continuing, unless the @code{nowait}
-option was specified.  The @code{nodelay} option disables the Nagle buffering
-algorithm.  The @code{reconnect} option only applies if @var{noserver} is
-set, if the connection goes down it will attempt to reconnect at the
-given interval.  If @var{host} is omitted, 0.0.0.0 is assumed. Only
-one TCP connection at a time is accepted. You can use @code{telnet} to
-connect to the corresponding character device.
-@table @code
-@item Example to send tcp console to 192.168.0.2 port 4444
--serial tcp:192.168.0.2:4444
-@item Example to listen and wait on port 4444 for connection
--serial tcp::4444,server
-@item Example to not wait and listen on ip 192.168.0.100 port 4444
--serial tcp:192.168.0.100:4444,server,nowait
-@end table
-
-@item telnet:@var{host}:@var{port}[,server][,nowait][,nodelay]
-The telnet protocol is used instead of raw tcp sockets.  The options
-work the same as if you had specified @code{-serial tcp}.  The
-difference is that the port acts like a telnet server or client using
-telnet option negotiation.  This will also allow you to send the
-MAGIC_SYSRQ sequence if you use a telnet that supports sending the break
-sequence.  Typically in unix telnet you do it with Control-] and then
-type "send break" followed by pressing the enter key.
-
-@item websocket:@var{host}:@var{port},server[,nowait][,nodelay]
-The WebSocket protocol is used instead of raw tcp socket. The port acts as
-a WebSocket server. Client mode is not supported.
-
-@item unix:@var{path}[,server][,nowait][,reconnect=@var{seconds}]
-A unix domain socket is used instead of a tcp socket.  The option works the
-same as if you had specified @code{-serial tcp} except the unix domain socket
-@var{path} is used for connections.
-
-@item mon:@var{dev_string}
-This is a special option to allow the monitor to be multiplexed onto
-another serial port.  The monitor is accessed with key sequence of
-@key{Control-a} and then pressing @key{c}.
-@var{dev_string} should be any one of the serial devices specified
-above.  An example to multiplex the monitor onto a telnet server
-listening on port 4444 would be:
-@table @code
-@item -serial mon:telnet::4444,server,nowait
-@end table
-When the monitor is multiplexed to stdio in this way, Ctrl+C will not terminate
-QEMU any more but will be passed to the guest instead.
-
-@item braille
-Braille device.  This will use BrlAPI to display the braille output on a real
-or fake device.
-
-@item msmouse
-Three button serial mouse. Configure the guest to use Microsoft protocol.
-@end table
-ETEXI
+SRST
+``-serial dev``
+    Redirect the virtual serial port to host character device dev. The
+    default device is ``vc`` in graphical mode and ``stdio`` in non
+    graphical mode.
+
+    This option can be used several times to simulate up to 4 serial
+    ports.
+
+    Use ``-serial none`` to disable all serial ports.
+
+    Available character devices are:
+
+    ``vc[:WxH]``
+        Virtual console. Optionally, a width and height can be given in
+        pixel with
+
+        ::
+
+            vc:800x600
+
+        It is also possible to specify width or height in characters:
+
+        ::
+
+            vc:80Cx24C
+
+    ``pty``
+        [Linux only] Pseudo TTY (a new PTY is automatically allocated)
+
+    ``none``
+        No device is allocated.
+
+    ``null``
+        void device
+
+    ``chardev:id``
+        Use a named character device defined with the ``-chardev``
+        option.
+
+    ``/dev/XXX``
+        [Linux only] Use host tty, e.g. ``/dev/ttyS0``. The host serial
+        port parameters are set according to the emulated ones.
+
+    ``/dev/parportN``
+        [Linux only, parallel port only] Use host parallel port N.
+        Currently SPP and EPP parallel port features can be used.
+
+    ``file:filename``
+        Write output to filename. No character can be read.
+
+    ``stdio``
+        [Unix only] standard input/output
+
+    ``pipe:filename``
+        name pipe filename
+
+    ``COMn``
+        [Windows only] Use host serial port n
+
+    ``udp:[remote_host]:remote_port[@[src_ip]:src_port]``
+        This implements UDP Net Console. When remote\_host or src\_ip
+        are not specified they default to ``0.0.0.0``. When not using a
+        specified src\_port a random port is automatically chosen.
+
+        If you just want a simple readonly console you can use
+        ``netcat`` or ``nc``, by starting QEMU with:
+        ``-serial udp::4555`` and nc as: ``nc -u -l -p 4555``. Any time
+        QEMU writes something to that port it will appear in the
+        netconsole session.
+
+        If you plan to send characters back via netconsole or you want
+        to stop and start QEMU a lot of times, you should have QEMU use
+        the same source port each time by using something like ``-serial
+        udp::4555@:4556`` to QEMU. Another approach is to use a patched
+        version of netcat which can listen to a TCP port and send and
+        receive characters via udp. If you have a patched version of
+        netcat which activates telnet remote echo and single char
+        transfer, then you can use the following options to set up a
+        netcat redirector to allow telnet on port 5555 to access the
+        QEMU port.
+
+        ``QEMU Options:``
+            -serial udp::4555@:4556
+
+        ``netcat options:``
+            -u -P 4555 -L 0.0.0.0:4556 -t -p 5555 -I -T
+
+        ``telnet options:``
+            localhost 5555
+
+    ``tcp:[host]:port[,server][,nowait][,nodelay][,reconnect=seconds]``
+        The TCP Net Console has two modes of operation. It can send the
+        serial I/O to a location or wait for a connection from a
+        location. By default the TCP Net Console is sent to host at the
+        port. If you use the server option QEMU will wait for a client
+        socket application to connect to the port before continuing,
+        unless the ``nowait`` option was specified. The ``nodelay``
+        option disables the Nagle buffering algorithm. The ``reconnect``
+        option only applies if noserver is set, if the connection goes
+        down it will attempt to reconnect at the given interval. If host
+        is omitted, 0.0.0.0 is assumed. Only one TCP connection at a
+        time is accepted. You can use ``telnet`` to connect to the
+        corresponding character device.
+
+        ``Example to send tcp console to 192.168.0.2 port 4444``
+            -serial tcp:192.168.0.2:4444
+
+        ``Example to listen and wait on port 4444 for connection``
+            -serial tcp::4444,server
+
+        ``Example to not wait and listen on ip 192.168.0.100 port 4444``
+            -serial tcp:192.168.0.100:4444,server,nowait
+
+    ``telnet:host:port[,server][,nowait][,nodelay]``
+        The telnet protocol is used instead of raw tcp sockets. The
+        options work the same as if you had specified ``-serial tcp``.
+        The difference is that the port acts like a telnet server or
+        client using telnet option negotiation. This will also allow you
+        to send the MAGIC\_SYSRQ sequence if you use a telnet that
+        supports sending the break sequence. Typically in unix telnet
+        you do it with Control-] and then type "send break" followed by
+        pressing the enter key.
+
+    ``websocket:host:port,server[,nowait][,nodelay]``
+        The WebSocket protocol is used instead of raw tcp socket. The
+        port acts as a WebSocket server. Client mode is not supported.
+
+    ``unix:path[,server][,nowait][,reconnect=seconds]``
+        A unix domain socket is used instead of a tcp socket. The option
+        works the same as if you had specified ``-serial tcp`` except
+        the unix domain socket path is used for connections.
+
+    ``mon:dev_string``
+        This is a special option to allow the monitor to be multiplexed
+        onto another serial port. The monitor is accessed with key
+        sequence of Control-a and then pressing c. dev\_string should be
+        any one of the serial devices specified above. An example to
+        multiplex the monitor onto a telnet server listening on port
+        4444 would be:
+
+        ``-serial mon:telnet::4444,server,nowait``
+
+        When the monitor is multiplexed to stdio in this way, Ctrl+C
+        will not terminate QEMU any more but will be passed to the guest
+        instead.
+
+    ``braille``
+        Braille device. This will use BrlAPI to display the braille
+        output on a real or fake device.
+
+    ``msmouse``
+        Three button serial mouse. Configure the guest to use Microsoft
+        protocol.
+ERST
 
 DEF("parallel", HAS_ARG, QEMU_OPTION_parallel, \
     "-parallel dev   redirect the parallel port to char device 'dev'\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -parallel @var{dev}
-@findex -parallel
-Redirect the virtual parallel port to host device @var{dev} (same
-devices as the serial port). On Linux hosts, @file{/dev/parportN} can
-be used to use hardware devices connected on the corresponding host
-parallel port.
+SRST
+``-parallel dev``
+    Redirect the virtual parallel port to host device dev (same devices
+    as the serial port). On Linux hosts, ``/dev/parportN`` can be used
+    to use hardware devices connected on the corresponding host parallel
+    port.
 
-This option can be used several times to simulate up to 3 parallel
-ports.
+    This option can be used several times to simulate up to 3 parallel
+    ports.
 
-Use @code{-parallel none} to disable all parallel ports.
-ETEXI
+    Use ``-parallel none`` to disable all parallel ports.
+ERST
 
 DEF("monitor", HAS_ARG, QEMU_OPTION_monitor, \
     "-monitor dev    redirect the monitor to char device 'dev'\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -monitor @var{dev}
-@findex -monitor
-Redirect the monitor to host device @var{dev} (same devices as the
-serial port).
-The default device is @code{vc} in graphical mode and @code{stdio} in
-non graphical mode.
-Use @code{-monitor none} to disable the default monitor.
-ETEXI
+SRST
+``-monitor dev``
+    Redirect the monitor to host device dev (same devices as the serial
+    port). The default device is ``vc`` in graphical mode and ``stdio``
+    in non graphical mode. Use ``-monitor none`` to disable the default
+    monitor.
+ERST
 DEF("qmp", HAS_ARG, QEMU_OPTION_qmp, \
     "-qmp dev        like -monitor but opens in 'control' mode\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -qmp @var{dev}
-@findex -qmp
-Like -monitor but opens in 'control' mode.
-ETEXI
+SRST
+``-qmp dev``
+    Like -monitor but opens in 'control' mode.
+ERST
 DEF("qmp-pretty", HAS_ARG, QEMU_OPTION_qmp_pretty, \
     "-qmp-pretty dev like -qmp but uses pretty JSON formatting\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -qmp-pretty @var{dev}
-@findex -qmp-pretty
-Like -qmp but uses pretty JSON formatting.
-ETEXI
+SRST
+``-qmp-pretty dev``
+    Like -qmp but uses pretty JSON formatting.
+ERST
 
 DEF("mon", HAS_ARG, QEMU_OPTION_mon, \
     "-mon [chardev=]name[,mode=readline|control][,pretty[=on|off]]\n", QEMU_ARCH_ALL)
-STEXI
-@item -mon [chardev=]name[,mode=readline|control][,pretty[=on|off]]
-@findex -mon
-Setup monitor on chardev @var{name}. @code{pretty} turns on JSON pretty printing
-easing human reading and debugging.
-ETEXI
+SRST
+``-mon [chardev=]name[,mode=readline|control][,pretty[=on|off]]``
+    Setup monitor on chardev name. ``pretty`` turns on JSON pretty
+    printing easing human reading and debugging.
+ERST
 
 DEF("debugcon", HAS_ARG, QEMU_OPTION_debugcon, \
     "-debugcon dev   redirect the debug console to char device 'dev'\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -debugcon @var{dev}
-@findex -debugcon
-Redirect the debug console to host device @var{dev} (same devices as the
-serial port).  The debug console is an I/O port which is typically port
-0xe9; writing to that I/O port sends output to this device.
-The default device is @code{vc} in graphical mode and @code{stdio} in
-non graphical mode.
-ETEXI
+SRST
+``-debugcon dev``
+    Redirect the debug console to host device dev (same devices as the
+    serial port). The debug console is an I/O port which is typically
+    port 0xe9; writing to that I/O port sends output to this device. The
+    default device is ``vc`` in graphical mode and ``stdio`` in non
+    graphical mode.
+ERST
 
 DEF("pidfile", HAS_ARG, QEMU_OPTION_pidfile, \
     "-pidfile file   write PID to 'file'\n", QEMU_ARCH_ALL)
-STEXI
-@item -pidfile @var{file}
-@findex -pidfile
-Store the QEMU process PID in @var{file}. It is useful if you launch QEMU
-from a script.
-ETEXI
+SRST
+``-pidfile file``
+    Store the QEMU process PID in file. It is useful if you launch QEMU
+    from a script.
+ERST
 
 DEF("singlestep", 0, QEMU_OPTION_singlestep, \
     "-singlestep     always run in singlestep mode\n", QEMU_ARCH_ALL)
-STEXI
-@item -singlestep
-@findex -singlestep
-Run the emulation in single step mode.
-ETEXI
+SRST
+``-singlestep``
+    Run the emulation in single step mode.
+ERST
 
 DEF("preconfig", 0, QEMU_OPTION_preconfig, \
     "--preconfig     pause QEMU before machine is initialized (experimental)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item --preconfig
-@findex --preconfig
-Pause QEMU for interactive configuration before the machine is created,
-which allows querying and configuring properties that will affect
-machine initialization.  Use QMP command 'x-exit-preconfig' to exit
-the preconfig state and move to the next state (i.e. run guest if -S
-isn't used or pause the second time if -S is used).  This option is
-experimental.
-ETEXI
+SRST
+``--preconfig``
+    Pause QEMU for interactive configuration before the machine is
+    created, which allows querying and configuring properties that will
+    affect machine initialization. Use QMP command 'x-exit-preconfig' to
+    exit the preconfig state and move to the next state (i.e. run guest
+    if -S isn't used or pause the second time if -S is used). This
+    option is experimental.
+ERST
 
 DEF("S", 0, QEMU_OPTION_S, \
     "-S              freeze CPU at startup (use 'c' to start execution)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -S
-@findex -S
-Do not start CPU at startup (you must type 'c' in the monitor).
-ETEXI
+SRST
+``-S``
+    Do not start CPU at startup (you must type 'c' in the monitor).
+ERST
 
 DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,
     "-realtime [mlock=on|off]\n"
     "                run qemu with realtime features\n"
     "                mlock=on|off controls mlock support (default: on)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -realtime mlock=on|off
-@findex -realtime
-Run qemu with realtime features.
-mlocking qemu and guest memory can be enabled via @option{mlock=on}
-(enabled by default).
-ETEXI
+SRST
+``-realtime mlock=on|off``
+    Run qemu with realtime features. mlocking qemu and guest memory can
+    be enabled via ``mlock=on`` (enabled by default).
+ERST
 
 DEF("overcommit", HAS_ARG, QEMU_OPTION_overcommit,
     "-overcommit [mem-lock=on|off][cpu-pm=on|off]\n"
@@ -3655,121 +3659,120 @@ DEF("overcommit", HAS_ARG, QEMU_OPTION_overcommit,
     "                mem-lock=on|off controls memory lock support (default: off)\n"
     "                cpu-pm=on|off controls cpu power management (default: off)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -overcommit mem-lock=on|off
-@item -overcommit cpu-pm=on|off
-@findex -overcommit
-Run qemu with hints about host resource overcommit. The default is
-to assume that host overcommits all resources.
-
-Locking qemu and guest memory can be enabled via @option{mem-lock=on} (disabled
-by default).  This works when host memory is not overcommitted and reduces the
-worst-case latency for guest.  This is equivalent to @option{realtime}.
-
-Guest ability to manage power state of host cpus (increasing latency for other
-processes on the same host cpu, but decreasing latency for guest) can be
-enabled via @option{cpu-pm=on} (disabled by default).  This works best when
-host CPU is not overcommitted. When used, host estimates of CPU cycle and power
-utilization will be incorrect, not taking into account guest idle time.
-ETEXI
+SRST
+``-overcommit mem-lock=on|off``
+  \ 
+``-overcommit cpu-pm=on|off``
+    Run qemu with hints about host resource overcommit. The default is
+    to assume that host overcommits all resources.
+
+    Locking qemu and guest memory can be enabled via ``mem-lock=on``
+    (disabled by default). This works when host memory is not
+    overcommitted and reduces the worst-case latency for guest. This is
+    equivalent to ``realtime``.
+
+    Guest ability to manage power state of host cpus (increasing latency
+    for other processes on the same host cpu, but decreasing latency for
+    guest) can be enabled via ``cpu-pm=on`` (disabled by default). This
+    works best when host CPU is not overcommitted. When used, host
+    estimates of CPU cycle and power utilization will be incorrect, not
+    taking into account guest idle time.
+ERST
 
 DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
     "-gdb dev        wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
-STEXI
-@item -gdb @var{dev}
-@findex -gdb
-Wait for gdb connection on device @var{dev} (@pxref{gdb_usage}). Typical
-connections will likely be TCP-based, but also UDP, pseudo TTY, or even
-stdio are reasonable use case. The latter is allowing to start QEMU from
-within gdb and establish the connection via a pipe:
-@example
-(gdb) target remote | exec @value{qemu_system} -gdb stdio ...
-@end example
-ETEXI
+SRST
+``-gdb dev``
+    Wait for gdb connection on device dev (see
+    :ref:`gdb_005fusage`). Typical connections will likely be
+    TCP-based, but also UDP, pseudo TTY, or even stdio are reasonable
+    use case. The latter is allowing to start QEMU from within gdb and
+    establish the connection via a pipe:
+
+    .. parsed-literal::
+
+        (gdb) target remote | exec |qemu_system| -gdb stdio ...
+ERST
 
 DEF("s", 0, QEMU_OPTION_s, \
     "-s              shorthand for -gdb tcp::" DEFAULT_GDBSTUB_PORT "\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -s
-@findex -s
-Shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port 1234
-(@pxref{gdb_usage}).
-ETEXI
+SRST
+``-s``
+    Shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port 1234
+    (see :ref:`gdb_005fusage`).
+ERST
 
 DEF("d", HAS_ARG, QEMU_OPTION_d, \
     "-d item1,...    enable logging of specified items (use '-d help' for a list of log items)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -d @var{item1}[,...]
-@findex -d
-Enable logging of specified items. Use '-d help' for a list of log items.
-ETEXI
+SRST
+``-d item1[,...]``
+    Enable logging of specified items. Use '-d help' for a list of log
+    items.
+ERST
 
 DEF("D", HAS_ARG, QEMU_OPTION_D, \
     "-D logfile      output log to logfile (default stderr)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -D @var{logfile}
-@findex -D
-Output log in @var{logfile} instead of to stderr
-ETEXI
+SRST
+``-D logfile``
+    Output log in logfile instead of to stderr
+ERST
 
 DEF("dfilter", HAS_ARG, QEMU_OPTION_DFILTER, \
     "-dfilter range,..  filter debug output to range of addresses (useful for -d cpu,exec,etc..)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -dfilter @var{range1}[,...]
-@findex -dfilter
-Filter debug output to that relevant to a range of target addresses. The filter
-spec can be either @var{start}+@var{size}, @var{start}-@var{size} or
-@var{start}..@var{end} where @var{start} @var{end} and @var{size} are the
-addresses and sizes required. For example:
-@example
-    -dfilter 0x8000..0x8fff,0xffffffc000080000+0x200,0xffffffc000060000-0x1000
-@end example
-Will dump output for any code in the 0x1000 sized block starting at 0x8000 and
-the 0x200 sized block starting at 0xffffffc000080000 and another 0x1000 sized
-block starting at 0xffffffc00005f000.
-ETEXI
+SRST
+``-dfilter range1[,...]``
+    Filter debug output to that relevant to a range of target addresses.
+    The filter spec can be either start+size, start-size or start..end
+    where start end and size are the addresses and sizes required. For
+    example:
+
+    ::
+
+            -dfilter 0x8000..0x8fff,0xffffffc000080000+0x200,0xffffffc000060000-0x1000
+
+    Will dump output for any code in the 0x1000 sized block starting at
+    0x8000 and the 0x200 sized block starting at 0xffffffc000080000 and
+    another 0x1000 sized block starting at 0xffffffc00005f000.
+ERST
 
 DEF("seed", HAS_ARG, QEMU_OPTION_seed, \
     "-seed number       seed the pseudo-random number generator\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -seed @var{number}
-@findex -seed
-Force the guest to use a deterministic pseudo-random number generator, seeded
-with @var{number}.  This does not affect crypto routines within the host.
-ETEXI
+SRST
+``-seed number``
+    Force the guest to use a deterministic pseudo-random number
+    generator, seeded with number. This does not affect crypto routines
+    within the host.
+ERST
 
 DEF("L", HAS_ARG, QEMU_OPTION_L, \
     "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -L  @var{path}
-@findex -L
-Set the directory for the BIOS, VGA BIOS and keymaps.
+SRST
+``-L  path``
+    Set the directory for the BIOS, VGA BIOS and keymaps.
 
-To list all the data directories, use @code{-L help}.
-ETEXI
+    To list all the data directories, use ``-L help``.
+ERST
 
 DEF("bios", HAS_ARG, QEMU_OPTION_bios, \
     "-bios file      set the filename for the BIOS\n", QEMU_ARCH_ALL)
-STEXI
-@item -bios @var{file}
-@findex -bios
-Set the filename for the BIOS.
-ETEXI
+SRST
+``-bios file``
+    Set the filename for the BIOS.
+ERST
 
 DEF("enable-kvm", 0, QEMU_OPTION_enable_kvm, \
     "-enable-kvm     enable KVM full virtualization support\n", QEMU_ARCH_ALL)
-STEXI
-@item -enable-kvm
-@findex -enable-kvm
-Enable KVM full virtualization support. This option is only available
-if KVM support is enabled when compiling.
-ETEXI
+SRST
+``-enable-kvm``
+    Enable KVM full virtualization support. This option is only
+    available if KVM support is enabled when compiling.
+ERST
 
 DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid,
     "-xen-domid id   specify xen guest domain id\n", QEMU_ARCH_ALL)
@@ -3782,243 +3785,225 @@ DEF("xen-domid-restrict", 0, QEMU_OPTION_xen_domid_restrict,
     "                        to specified domain id. (Does not affect\n"
     "                        xenpv machine type).\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -xen-domid @var{id}
-@findex -xen-domid
-Specify xen guest domain @var{id} (XEN only).
-@item -xen-attach
-@findex -xen-attach
-Attach to existing xen domain.
-libxl will use this when starting QEMU (XEN only).
-@findex -xen-domid-restrict
-Restrict set of available xen operations to specified domain id (XEN only).
-ETEXI
+SRST
+``-xen-domid id``
+    Specify xen guest domain id (XEN only).
+
+``-xen-attach``
+    Attach to existing xen domain. libxl will use this when starting
+    QEMU (XEN only). Restrict set of available xen operations to
+    specified domain id (XEN only).
+ERST
 
 DEF("no-reboot", 0, QEMU_OPTION_no_reboot, \
     "-no-reboot      exit instead of rebooting\n", QEMU_ARCH_ALL)
-STEXI
-@item -no-reboot
-@findex -no-reboot
-Exit instead of rebooting.
-ETEXI
+SRST
+``-no-reboot``
+    Exit instead of rebooting.
+ERST
 
 DEF("no-shutdown", 0, QEMU_OPTION_no_shutdown, \
     "-no-shutdown    stop before shutdown\n", QEMU_ARCH_ALL)
-STEXI
-@item -no-shutdown
-@findex -no-shutdown
-Don't exit QEMU on guest shutdown, but instead only stop the emulation.
-This allows for instance switching to monitor to commit changes to the
-disk image.
-ETEXI
+SRST
+``-no-shutdown``
+    Don't exit QEMU on guest shutdown, but instead only stop the
+    emulation. This allows for instance switching to monitor to commit
+    changes to the disk image.
+ERST
 
 DEF("loadvm", HAS_ARG, QEMU_OPTION_loadvm, \
     "-loadvm [tag|id]\n" \
     "                start right away with a saved state (loadvm in monitor)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -loadvm @var{file}
-@findex -loadvm
-Start right away with a saved state (@code{loadvm} in monitor)
-ETEXI
+SRST
+``-loadvm file``
+    Start right away with a saved state (``loadvm`` in monitor)
+ERST
 
 #ifndef _WIN32
 DEF("daemonize", 0, QEMU_OPTION_daemonize, \
     "-daemonize      daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
 #endif
-STEXI
-@item -daemonize
-@findex -daemonize
-Daemonize the QEMU process after initialization.  QEMU will not detach from
-standard IO until it is ready to receive connections on any of its devices.
-This option is a useful way for external programs to launch QEMU without having
-to cope with initialization race conditions.
-ETEXI
+SRST
+``-daemonize``
+    Daemonize the QEMU process after initialization. QEMU will not
+    detach from standard IO until it is ready to receive connections on
+    any of its devices. This option is a useful way for external
+    programs to launch QEMU without having to cope with initialization
+    race conditions.
+ERST
 
 DEF("option-rom", HAS_ARG, QEMU_OPTION_option_rom, \
     "-option-rom rom load a file, rom, into the option ROM space\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -option-rom @var{file}
-@findex -option-rom
-Load the contents of @var{file} as an option ROM.
-This option is useful to load things like EtherBoot.
-ETEXI
+SRST
+``-option-rom file``
+    Load the contents of file as an option ROM. This option is useful to
+    load things like EtherBoot.
+ERST
 
 DEF("rtc", HAS_ARG, QEMU_OPTION_rtc, \
     "-rtc [base=utc|localtime|<datetime>][,clock=host|rt|vm][,driftfix=none|slew]\n" \
     "                set the RTC base and clock, enable drift fix for clock ticks (x86 only)\n",
     QEMU_ARCH_ALL)
 
-STEXI
-
-@item -rtc [base=utc|localtime|@var{datetime}][,clock=host|rt|vm][,driftfix=none|slew]
-@findex -rtc
-Specify @option{base} as @code{utc} or @code{localtime} to let the RTC start at the current
-UTC or local time, respectively. @code{localtime} is required for correct date in
-MS-DOS or Windows. To start at a specific point in time, provide @var{datetime} in the
-format @code{2006-06-17T16:01:21} or @code{2006-06-17}. The default base is UTC.
-
-By default the RTC is driven by the host system time. This allows using of the
-RTC as accurate reference clock inside the guest, specifically if the host
-time is smoothly following an accurate external reference clock, e.g. via NTP.
-If you want to isolate the guest time from the host, you can set @option{clock}
-to @code{rt} instead, which provides a host monotonic clock if host support it.
-To even prevent the RTC from progressing during suspension, you can set @option{clock}
-to @code{vm} (virtual clock). @samp{clock=vm} is recommended especially in
-icount mode in order to preserve determinism; however, note that in icount mode
-the speed of the virtual clock is variable and can in general differ from the
-host clock.
-
-Enable @option{driftfix} (i386 targets only) if you experience time drift problems,
-specifically with Windows' ACPI HAL. This option will try to figure out how
-many timer interrupts were not processed by the Windows guest and will
-re-inject them.
-ETEXI
+SRST
+``-rtc [base=utc|localtime|datetime][,clock=host|rt|vm][,driftfix=none|slew]``
+    Specify ``base`` as ``utc`` or ``localtime`` to let the RTC start at
+    the current UTC or local time, respectively. ``localtime`` is
+    required for correct date in MS-DOS or Windows. To start at a
+    specific point in time, provide datetime in the format
+    ``2006-06-17T16:01:21`` or ``2006-06-17``. The default base is UTC.
+
+    By default the RTC is driven by the host system time. This allows
+    using of the RTC as accurate reference clock inside the guest,
+    specifically if the host time is smoothly following an accurate
+    external reference clock, e.g. via NTP. If you want to isolate the
+    guest time from the host, you can set ``clock`` to ``rt`` instead,
+    which provides a host monotonic clock if host support it. To even
+    prevent the RTC from progressing during suspension, you can set
+    ``clock`` to ``vm`` (virtual clock). '\ ``clock=vm``\ ' is
+    recommended especially in icount mode in order to preserve
+    determinism; however, note that in icount mode the speed of the
+    virtual clock is variable and can in general differ from the host
+    clock.
+
+    Enable ``driftfix`` (i386 targets only) if you experience time drift
+    problems, specifically with Windows' ACPI HAL. This option will try
+    to figure out how many timer interrupts were not processed by the
+    Windows guest and will re-inject them.
+ERST
 
 DEF("icount", HAS_ARG, QEMU_OPTION_icount, \
     "-icount [shift=N|auto][,align=on|off][,sleep=on|off,rr=record|replay,rrfile=<filename>,rrsnapshot=<snapshot>]\n" \
     "                enable virtual instruction counter with 2^N clock ticks per\n" \
     "                instruction, enable aligning the host and virtual clocks\n" \
     "                or disable real time cpu sleeping\n", QEMU_ARCH_ALL)
-STEXI
-@item -icount [shift=@var{N}|auto][,rr=record|replay,rrfile=@var{filename},rrsnapshot=@var{snapshot}]
-@findex -icount
-Enable virtual instruction counter.  The virtual cpu will execute one
-instruction every 2^@var{N} ns of virtual time.  If @code{auto} is specified
-then the virtual cpu speed will be automatically adjusted to keep virtual
-time within a few seconds of real time.
-
-When the virtual cpu is sleeping, the virtual time will advance at default
-speed unless @option{sleep=on|off} is specified.
-With @option{sleep=on|off}, the virtual time will jump to the next timer deadline
-instantly whenever the virtual cpu goes to sleep mode and will not advance
-if no timer is enabled. This behavior give deterministic execution times from
-the guest point of view.
-
-Note that while this option can give deterministic behavior, it does not
-provide cycle accurate emulation.  Modern CPUs contain superscalar out of
-order cores with complex cache hierarchies.  The number of instructions
-executed often has little or no correlation with actual performance.
-
-@option{align=on} will activate the delay algorithm which will try
-to synchronise the host clock and the virtual clock. The goal is to
-have a guest running at the real frequency imposed by the shift option.
-Whenever the guest clock is behind the host clock and if
-@option{align=on} is specified then we print a message to the user
-to inform about the delay.
-Currently this option does not work when @option{shift} is @code{auto}.
-Note: The sync algorithm will work for those shift values for which
-the guest clock runs ahead of the host clock. Typically this happens
-when the shift value is high (how high depends on the host machine).
-
-When @option{rr} option is specified deterministic record/replay is enabled.
-Replay log is written into @var{filename} file in record mode and
-read from this file in replay mode.
-
-Option rrsnapshot is used to create new vm snapshot named @var{snapshot}
-at the start of execution recording. In replay mode this option is used
-to load the initial VM state.
-ETEXI
+SRST
+``-icount [shift=N|auto][,rr=record|replay,rrfile=filename,rrsnapshot=snapshot]``
+    Enable virtual instruction counter. The virtual cpu will execute one
+    instruction every 2^N ns of virtual time. If ``auto`` is specified
+    then the virtual cpu speed will be automatically adjusted to keep
+    virtual time within a few seconds of real time.
+
+    When the virtual cpu is sleeping, the virtual time will advance at
+    default speed unless ``sleep=on|off`` is specified. With
+    ``sleep=on|off``, the virtual time will jump to the next timer
+    deadline instantly whenever the virtual cpu goes to sleep mode and
+    will not advance if no timer is enabled. This behavior give
+    deterministic execution times from the guest point of view.
+
+    Note that while this option can give deterministic behavior, it does
+    not provide cycle accurate emulation. Modern CPUs contain
+    superscalar out of order cores with complex cache hierarchies. The
+    number of instructions executed often has little or no correlation
+    with actual performance.
+
+    ``align=on`` will activate the delay algorithm which will try to
+    synchronise the host clock and the virtual clock. The goal is to
+    have a guest running at the real frequency imposed by the shift
+    option. Whenever the guest clock is behind the host clock and if
+    ``align=on`` is specified then we print a message to the user to
+    inform about the delay. Currently this option does not work when
+    ``shift`` is ``auto``. Note: The sync algorithm will work for those
+    shift values for which the guest clock runs ahead of the host clock.
+    Typically this happens when the shift value is high (how high
+    depends on the host machine).
+
+    When ``rr`` option is specified deterministic record/replay is
+    enabled. Replay log is written into filename file in record mode and
+    read from this file in replay mode.
+
+    Option rrsnapshot is used to create new vm snapshot named snapshot
+    at the start of execution recording. In replay mode this option is
+    used to load the initial VM state.
+ERST
 
 DEF("watchdog", HAS_ARG, QEMU_OPTION_watchdog, \
     "-watchdog model\n" \
     "                enable virtual hardware watchdog [default=none]\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -watchdog @var{model}
-@findex -watchdog
-Create a virtual hardware watchdog device.  Once enabled (by a guest
-action), the watchdog must be periodically polled by an agent inside
-the guest or else the guest will be restarted. Choose a model for
-which your guest has drivers.
-
-The @var{model} is the model of hardware watchdog to emulate. Use
-@code{-watchdog help} to list available hardware models. Only one
-watchdog can be enabled for a guest.
-
-The following models may be available:
-@table @option
-@item ib700
-iBASE 700 is a very simple ISA watchdog with a single timer.
-@item i6300esb
-Intel 6300ESB I/O controller hub is a much more featureful PCI-based
-dual-timer watchdog.
-@item diag288
-A virtual watchdog for s390x backed by the diagnose 288 hypercall
-(currently KVM only).
-@end table
-ETEXI
+SRST
+``-watchdog model``
+    Create a virtual hardware watchdog device. Once enabled (by a guest
+    action), the watchdog must be periodically polled by an agent inside
+    the guest or else the guest will be restarted. Choose a model for
+    which your guest has drivers.
+
+    The model is the model of hardware watchdog to emulate. Use
+    ``-watchdog help`` to list available hardware models. Only one
+    watchdog can be enabled for a guest.
+
+    The following models may be available:
+
+    ``ib700``
+        iBASE 700 is a very simple ISA watchdog with a single timer.
+
+    ``i6300esb``
+        Intel 6300ESB I/O controller hub is a much more featureful
+        PCI-based dual-timer watchdog.
+
+    ``diag288``
+        A virtual watchdog for s390x backed by the diagnose 288
+        hypercall (currently KVM only).
+ERST
 
 DEF("watchdog-action", HAS_ARG, QEMU_OPTION_watchdog_action, \
     "-watchdog-action reset|shutdown|poweroff|inject-nmi|pause|debug|none\n" \
     "                action when watchdog fires [default=reset]\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -watchdog-action @var{action}
-@findex -watchdog-action
-
-The @var{action} controls what QEMU will do when the watchdog timer
-expires.
-The default is
-@code{reset} (forcefully reset the guest).
-Other possible actions are:
-@code{shutdown} (attempt to gracefully shutdown the guest),
-@code{poweroff} (forcefully poweroff the guest),
-@code{inject-nmi} (inject a NMI into the guest),
-@code{pause} (pause the guest),
-@code{debug} (print a debug message and continue), or
-@code{none} (do nothing).
-
-Note that the @code{shutdown} action requires that the guest responds
-to ACPI signals, which it may not be able to do in the sort of
-situations where the watchdog would have expired, and thus
-@code{-watchdog-action shutdown} is not recommended for production use.
-
-Examples:
-
-@table @code
-@item -watchdog i6300esb -watchdog-action pause
-@itemx -watchdog ib700
-@end table
-ETEXI
+SRST
+``-watchdog-action action``
+    The action controls what QEMU will do when the watchdog timer
+    expires. The default is ``reset`` (forcefully reset the guest).
+    Other possible actions are: ``shutdown`` (attempt to gracefully
+    shutdown the guest), ``poweroff`` (forcefully poweroff the guest),
+    ``inject-nmi`` (inject a NMI into the guest), ``pause`` (pause the
+    guest), ``debug`` (print a debug message and continue), or ``none``
+    (do nothing).
+
+    Note that the ``shutdown`` action requires that the guest responds
+    to ACPI signals, which it may not be able to do in the sort of
+    situations where the watchdog would have expired, and thus
+    ``-watchdog-action shutdown`` is not recommended for production use.
+
+    Examples:
+
+    ``-watchdog i6300esb -watchdog-action pause``; \ ``-watchdog ib700``
+
+ERST
 
 DEF("echr", HAS_ARG, QEMU_OPTION_echr, \
     "-echr chr       set terminal escape character instead of ctrl-a\n",
     QEMU_ARCH_ALL)
-STEXI
-
-@item -echr @var{numeric_ascii_value}
-@findex -echr
-Change the escape character used for switching to the monitor when using
-monitor and serial sharing.  The default is @code{0x01} when using the
-@code{-nographic} option.  @code{0x01} is equal to pressing
-@code{Control-a}.  You can select a different character from the ascii
-control keys where 1 through 26 map to Control-a through Control-z.  For
-instance you could use the either of the following to change the escape
-character to Control-t.
-@table @code
-@item -echr 0x14
-@itemx -echr 20
-@end table
-ETEXI
+SRST
+``-echr numeric_ascii_value``
+    Change the escape character used for switching to the monitor when
+    using monitor and serial sharing. The default is ``0x01`` when using
+    the ``-nographic`` option. ``0x01`` is equal to pressing
+    ``Control-a``. You can select a different character from the ascii
+    control keys where 1 through 26 map to Control-a through Control-z.
+    For instance you could use the either of the following to change the
+    escape character to Control-t.
+
+    ``-echr 0x14``; \ ``-echr 20``
+
+ERST
 
 DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \
     "-show-cursor    show cursor\n", QEMU_ARCH_ALL)
-STEXI
-@item -show-cursor
-@findex -show-cursor
-Show cursor.
-ETEXI
+SRST
+``-show-cursor``
+    Show cursor.
+ERST
 
 DEF("tb-size", HAS_ARG, QEMU_OPTION_tb_size, \
     "-tb-size n      set TB size\n", QEMU_ARCH_ALL)
-STEXI
-@item -tb-size @var{n}
-@findex -tb-size
-Set TCG translation block cache size.  Deprecated, use @samp{-accel tcg,tb-size=@var{n}}
-instead.
-ETEXI
+SRST
+``-tb-size n``
+    Set TCG translation block cache size. Deprecated, use
+    '\ ``-accel tcg,tb-size=n``\ ' instead.
+ERST
 
 DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
     "-incoming tcp:[host]:port[,to=maxport][,ipv4][,ipv6]\n" \
@@ -4033,58 +4018,56 @@ DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
     "-incoming defer\n" \
     "                wait for the URI to be specified via migrate_incoming\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -incoming tcp:[@var{host}]:@var{port}[,to=@var{maxport}][,ipv4][,ipv6]
-@itemx -incoming rdma:@var{host}:@var{port}[,ipv4][,ipv6]
-@findex -incoming
-Prepare for incoming migration, listen on a given tcp port.
+SRST
+``-incoming tcp:[host]:port[,to=maxport][,ipv4][,ipv6]``
+  \ 
+``-incoming rdma:host:port[,ipv4][,ipv6]``
+    Prepare for incoming migration, listen on a given tcp port.
 
-@item -incoming unix:@var{socketpath}
-Prepare for incoming migration, listen on a given unix socket.
+``-incoming unix:socketpath``
+    Prepare for incoming migration, listen on a given unix socket.
 
-@item -incoming fd:@var{fd}
-Accept incoming migration from a given filedescriptor.
+``-incoming fd:fd``
+    Accept incoming migration from a given filedescriptor.
 
-@item -incoming exec:@var{cmdline}
-Accept incoming migration as an output from specified external command.
+``-incoming exec:cmdline``
+    Accept incoming migration as an output from specified external
+    command.
 
-@item -incoming defer
-Wait for the URI to be specified via migrate_incoming.  The monitor can
-be used to change settings (such as migration parameters) prior to issuing
-the migrate_incoming to allow the migration to begin.
-ETEXI
+``-incoming defer``
+    Wait for the URI to be specified via migrate\_incoming. The monitor
+    can be used to change settings (such as migration parameters) prior
+    to issuing the migrate\_incoming to allow the migration to begin.
+ERST
 
 DEF("only-migratable", 0, QEMU_OPTION_only_migratable, \
     "-only-migratable     allow only migratable devices\n", QEMU_ARCH_ALL)
-STEXI
-@item -only-migratable
-@findex -only-migratable
-Only allow migratable devices. Devices will not be allowed to enter an
-unmigratable state.
-ETEXI
+SRST
+``-only-migratable``
+    Only allow migratable devices. Devices will not be allowed to enter
+    an unmigratable state.
+ERST
 
 DEF("nodefaults", 0, QEMU_OPTION_nodefaults, \
     "-nodefaults     don't create default devices\n", QEMU_ARCH_ALL)
-STEXI
-@item -nodefaults
-@findex -nodefaults
-Don't create default devices. Normally, QEMU sets the default devices like serial
-port, parallel port, virtual console, monitor device, VGA adapter, floppy and
-CD-ROM drive and others. The @code{-nodefaults} option will disable all those
-default devices.
-ETEXI
+SRST
+``-nodefaults``
+    Don't create default devices. Normally, QEMU sets the default
+    devices like serial port, parallel port, virtual console, monitor
+    device, VGA adapter, floppy and CD-ROM drive and others. The
+    ``-nodefaults`` option will disable all those default devices.
+ERST
 
 #ifndef _WIN32
 DEF("chroot", HAS_ARG, QEMU_OPTION_chroot, \
     "-chroot dir     chroot to dir just before starting the VM\n",
     QEMU_ARCH_ALL)
 #endif
-STEXI
-@item -chroot @var{dir}
-@findex -chroot
-Immediately before starting guest execution, chroot to the specified
-directory.  Especially useful in combination with -runas.
-ETEXI
+SRST
+``-chroot dir``
+    Immediately before starting guest execution, chroot to the specified
+    directory. Especially useful in combination with -runas.
+ERST
 
 #ifndef _WIN32
 DEF("runas", HAS_ARG, QEMU_OPTION_runas, \
@@ -4092,62 +4075,91 @@ DEF("runas", HAS_ARG, QEMU_OPTION_runas, \
     "                user can be numeric uid:gid instead\n",
     QEMU_ARCH_ALL)
 #endif
-STEXI
-@item -runas @var{user}
-@findex -runas
-Immediately before starting guest execution, drop root privileges, switching
-to the specified user.
-ETEXI
+SRST
+``-runas user``
+    Immediately before starting guest execution, drop root privileges,
+    switching to the specified user.
+ERST
 
 DEF("prom-env", HAS_ARG, QEMU_OPTION_prom_env,
     "-prom-env variable=value\n"
     "                set OpenBIOS nvram variables\n",
     QEMU_ARCH_PPC | QEMU_ARCH_SPARC)
-STEXI
-@item -prom-env @var{variable}=@var{value}
-@findex -prom-env
-Set OpenBIOS nvram @var{variable} to given @var{value} (PPC, SPARC only).
-ETEXI
+SRST
+``-prom-env variable=value``
+    Set OpenBIOS nvram variable to given value (PPC, SPARC only).
+
+    ::
+
+        qemu-system-sparc -prom-env 'auto-boot?=false' \
+         -prom-env 'boot-device=sd(0,2,0):d' -prom-env 'boot-args=linux single'
+
+    ::
+
+        qemu-system-ppc -prom-env 'auto-boot?=false' \
+         -prom-env 'boot-device=hd:2,\yaboot' \
+         -prom-env 'boot-args=conf=hd:2,\yaboot.conf'
+ERST
 DEF("semihosting", 0, QEMU_OPTION_semihosting,
     "-semihosting    semihosting mode\n",
     QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
     QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2)
-STEXI
-@item -semihosting
-@findex -semihosting
-Enable semihosting mode (ARM, M68K, Xtensa, MIPS, Nios II only).
-ETEXI
+SRST
+``-semihosting``
+    Enable semihosting mode (ARM, M68K, Xtensa, MIPS, Nios II only).
+
+    Note that this allows guest direct access to the host filesystem, so
+    should only be used with a trusted guest OS.
+
+    See the -semihosting-config option documentation for further
+    information about the facilities this enables.
+ERST
 DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
     "-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]\n" \
     "                semihosting configuration\n",
 QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
 QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2)
-STEXI
-@item -semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]
-@findex -semihosting-config
-Enable and configure semihosting (ARM, M68K, Xtensa, MIPS, Nios II only).
-@table @option
-@item target=@code{native|gdb|auto}
-Defines where the semihosting calls will be addressed, to QEMU (@code{native})
-or to GDB (@code{gdb}). The default is @code{auto}, which means @code{gdb}
-during debug sessions and @code{native} otherwise.
-@item chardev=@var{str1}
-Send the output to a chardev backend output for native or auto output when not in gdb
-@item arg=@var{str1},arg=@var{str2},...
-Allows the user to pass input arguments, and can be used multiple times to build
-up a list. The old-style @code{-kernel}/@code{-append} method of passing a
-command line is still supported for backward compatibility. If both the
-@code{--semihosting-config arg} and the @code{-kernel}/@code{-append} are
-specified, the former is passed to semihosting as it always takes precedence.
-@end table
-ETEXI
+SRST
+``-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]``
+    Enable and configure semihosting (ARM, M68K, Xtensa, MIPS, Nios II
+    only).
+
+    Note that this allows guest direct access to the host filesystem, so
+    should only be used with a trusted guest OS.
+
+    On Arm this implements the standard semihosting API, version 2.0.
+
+    On M68K this implements the "ColdFire GDB" interface used by
+    libgloss.
+
+    Xtensa semihosting provides basic file IO calls, such as
+    open/read/write/seek/select. Tensilica baremetal libc for ISS and
+    linux platform "sim" use this interface.
+
+    ``target=native|gdb|auto``
+        Defines where the semihosting calls will be addressed, to QEMU
+        (``native``) or to GDB (``gdb``). The default is ``auto``, which
+        means ``gdb`` during debug sessions and ``native`` otherwise.
+
+    ``chardev=str1``
+        Send the output to a chardev backend output for native or auto
+        output when not in gdb
+
+    ``arg=str1,arg=str2,...``
+        Allows the user to pass input arguments, and can be used
+        multiple times to build up a list. The old-style
+        ``-kernel``/``-append`` method of passing a command line is
+        still supported for backward compatibility. If both the
+        ``--semihosting-config arg`` and the ``-kernel``/``-append`` are
+        specified, the former is passed to semihosting as it always
+        takes precedence.
+ERST
 DEF("old-param", 0, QEMU_OPTION_old_param,
     "-old-param      old param mode\n", QEMU_ARCH_ARM)
-STEXI
-@item -old-param
-@findex -old-param (ARM)
-Old param mode (ARM only).
-ETEXI
+SRST
+``-old-param``
+    Old param mode (ARM only).
+ERST
 
 DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \
     "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \
@@ -4164,82 +4176,77 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \
     "                     blacklisting *fork and execve\n" \
     "                use 'resourcecontrol' to disable process affinity and schedular priority\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -sandbox @var{arg}[,obsolete=@var{string}][,elevateprivileges=@var{string}][,spawn=@var{string}][,resourcecontrol=@var{string}]
-@findex -sandbox
-Enable Seccomp mode 2 system call filter. 'on' will enable syscall filtering and 'off' will
-disable it.  The default is 'off'.
-@table @option
-@item obsolete=@var{string}
-Enable Obsolete system calls
-@item elevateprivileges=@var{string}
-Disable set*uid|gid system calls
-@item spawn=@var{string}
-Disable *fork and execve
-@item resourcecontrol=@var{string}
-Disable process affinity and schedular priority
-@end table
-ETEXI
+SRST
+``-sandbox arg[,obsolete=string][,elevateprivileges=string][,spawn=string][,resourcecontrol=string]``
+    Enable Seccomp mode 2 system call filter. 'on' will enable syscall
+    filtering and 'off' will disable it. The default is 'off'.
+
+    ``obsolete=string``
+        Enable Obsolete system calls
+
+    ``elevateprivileges=string``
+        Disable set\*uid\|gid system calls
+
+    ``spawn=string``
+        Disable \*fork and execve
+
+    ``resourcecontrol=string``
+        Disable process affinity and schedular priority
+ERST
 
 DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig,
     "-readconfig <file>\n", QEMU_ARCH_ALL)
-STEXI
-@item -readconfig @var{file}
-@findex -readconfig
-Read device configuration from @var{file}. This approach is useful when you want to spawn
-QEMU process with many command line options but you don't want to exceed the command line
-character limit.
-ETEXI
+SRST
+``-readconfig file``
+    Read device configuration from file. This approach is useful when
+    you want to spawn QEMU process with many command line options but
+    you don't want to exceed the command line character limit.
+ERST
 DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig,
     "-writeconfig <file>\n"
     "                read/write config file\n", QEMU_ARCH_ALL)
-STEXI
-@item -writeconfig @var{file}
-@findex -writeconfig
-Write device configuration to @var{file}. The @var{file} can be either filename to save
-command line and device configuration into file or dash @code{-}) character to print the
-output to stdout. This can be later used as input file for @code{-readconfig} option.
-ETEXI
+SRST
+``-writeconfig file``
+    Write device configuration to file. The file can be either filename
+    to save command line and device configuration into file or dash
+    ``-``) character to print the output to stdout. This can be later
+    used as input file for ``-readconfig`` option.
+ERST
 
 DEF("no-user-config", 0, QEMU_OPTION_nouserconfig,
     "-no-user-config\n"
     "                do not load default user-provided config files at startup\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -no-user-config
-@findex -no-user-config
-The @code{-no-user-config} option makes QEMU not load any of the user-provided
-config files on @var{sysconfdir}.
-ETEXI
+SRST
+``-no-user-config``
+    The ``-no-user-config`` option makes QEMU not load any of the
+    user-provided config files on sysconfdir.
+ERST
 
 DEF("trace", HAS_ARG, QEMU_OPTION_trace,
     "-trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
     "                specify tracing options\n",
     QEMU_ARCH_ALL)
-STEXI
-HXCOMM This line is not accurate, as some sub-options are backend-specific but
-HXCOMM HX does not support conditional compilation of text.
-@item -trace [[enable=]@var{pattern}][,events=@var{file}][,file=@var{file}]
-@findex -trace
-@include qemu-option-trace.texi
-ETEXI
+SRST
+``-trace [[enable=]pattern][,events=file][,file=file]``
+  .. include:: ../qemu-option-trace.rst.inc
+
+ERST
 DEF("plugin", HAS_ARG, QEMU_OPTION_plugin,
     "-plugin [file=]<file>[,arg=<string>]\n"
     "                load a plugin\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -plugin file=@var{file}[,arg=@var{string}]
-@findex -plugin
+SRST
+``-plugin file=file[,arg=string]``
+    Load a plugin.
 
-Load a plugin.
+    ``file=file``
+        Load the given plugin from a shared library file.
 
-@table @option
-@item file=@var{file}
-Load the given plugin from a shared library file.
-@item arg=@var{string}
-Argument string passed to the plugin. (Can be given multiple times.)
-@end table
-ETEXI
+    ``arg=string``
+        Argument string passed to the plugin. (Can be given multiple
+        times.)
+ERST
 
 HXCOMM Internal use
 DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL)
@@ -4250,11 +4257,10 @@ DEF("enable-fips", 0, QEMU_OPTION_enablefips,
     "-enable-fips    enable FIPS 140-2 compliance\n",
     QEMU_ARCH_ALL)
 #endif
-STEXI
-@item -enable-fips
-@findex -enable-fips
-Enable FIPS 140-2 compliance mode.
-ETEXI
+SRST
+``-enable-fips``
+    Enable FIPS 140-2 compliance mode.
+ERST
 
 HXCOMM Deprecated by -accel tcg
 DEF("no-kvm", 0, QEMU_OPTION_no_kvm, "", QEMU_ARCH_I386)
@@ -4264,15 +4270,13 @@ DEF("msg", HAS_ARG, QEMU_OPTION_msg,
     "                control error message format\n"
     "                timestamp=on enables timestamps (default: off)\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -msg timestamp[=on|off]
-@findex -msg
-Control error message format.
-@table @option
-@item timestamp=on|off
-Prefix messages with a timestamp.  Default is off.
-@end table
-ETEXI
+SRST
+``-msg timestamp[=on|off]``
+    Control error message format.
+
+    ``timestamp=on|off``
+        Prefix messages with a timestamp. Default is off.
+ERST
 
 DEF("dump-vmstate", HAS_ARG, QEMU_OPTION_dump_vmstate,
     "-dump-vmstate <file>\n"
@@ -4281,32 +4285,24 @@ DEF("dump-vmstate", HAS_ARG, QEMU_OPTION_dump_vmstate,
     "                check for possible regressions in migration code\n"
     "                by comparing two such vmstate dumps.\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -dump-vmstate @var{file}
-@findex -dump-vmstate
-Dump json-encoded vmstate information for current machine type to file
-in @var{file}
-ETEXI
+SRST
+``-dump-vmstate file``
+    Dump json-encoded vmstate information for current machine type to
+    file in file
+ERST
 
 DEF("enable-sync-profile", 0, QEMU_OPTION_enable_sync_profile,
     "-enable-sync-profile\n"
     "                enable synchronization profiling\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -enable-sync-profile
-@findex -enable-sync-profile
-Enable synchronization profiling.
-ETEXI
-
-STEXI
-@end table
-ETEXI
+SRST
+``-enable-sync-profile``
+    Enable synchronization profiling.
+ERST
+
 DEFHEADING()
 
 DEFHEADING(Generic object creation:)
-STEXI
-@table @option
-ETEXI
 
 DEF("object", HAS_ARG, QEMU_OPTION_object,
     "-object TYPENAME[,PROP1=VALUE1,...]\n"
@@ -4315,692 +4311,697 @@ DEF("object", HAS_ARG, QEMU_OPTION_object,
     "                property must be set.  These objects are placed in the\n"
     "                '/objects' path.\n",
     QEMU_ARCH_ALL)
-STEXI
-@item -object @var{typename}[,@var{prop1}=@var{value1},...]
-@findex -object
-Create a new object of type @var{typename} setting properties
-in the order they are specified.  Note that the 'id'
-property must be set.  These objects are placed in the
-'/objects' path.
-
-@table @option
-
-@item -object memory-backend-file,id=@var{id},size=@var{size},mem-path=@var{dir},share=@var{on|off},discard-data=@var{on|off},merge=@var{on|off},dump=@var{on|off},prealloc=@var{on|off},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave},align=@var{align}
-
-Creates a memory file backend object, which can be used to back
-the guest RAM with huge pages.
-
-The @option{id} parameter is a unique ID that will be used to reference this
-memory region when configuring the @option{-numa} argument.
+SRST
+``-object typename[,prop1=value1,...]``
+    Create a new object of type typename setting properties in the order
+    they are specified. Note that the 'id' property must be set. These
+    objects are placed in the '/objects' path.
+
+    ``-object memory-backend-file,id=id,size=size,mem-path=dir,share=on|off,discard-data=on|off,merge=on|off,dump=on|off,prealloc=on|off,host-nodes=host-nodes,policy=default|preferred|bind|interleave,align=align``
+        Creates a memory file backend object, which can be used to back
+        the guest RAM with huge pages.
+
+        The ``id`` parameter is a unique ID that will be used to
+        reference this memory region when configuring the ``-numa``
+        argument.
+
+        The ``size`` option provides the size of the memory region, and
+        accepts common suffixes, eg ``500M``.
+
+        The ``mem-path`` provides the path to either a shared memory or
+        huge page filesystem mount.
+
+        The ``share`` boolean option determines whether the memory
+        region is marked as private to QEMU, or shared. The latter
+        allows a co-operating external process to access the QEMU memory
+        region.
+
+        The ``share`` is also required for pvrdma devices due to
+        limitations in the RDMA API provided by Linux.
+
+        Setting share=on might affect the ability to configure NUMA
+        bindings for the memory backend under some circumstances, see
+        Documentation/vm/numa\_memory\_policy.txt on the Linux kernel
+        source tree for additional details.
+
+        Setting the ``discard-data`` boolean option to on indicates that
+        file contents can be destroyed when QEMU exits, to avoid
+        unnecessarily flushing data to the backing file. Note that
+        ``discard-data`` is only an optimization, and QEMU might not
+        discard file contents if it aborts unexpectedly or is terminated
+        using SIGKILL.
+
+        The ``merge`` boolean option enables memory merge, also known as
+        MADV\_MERGEABLE, so that Kernel Samepage Merging will consider
+        the pages for memory deduplication.
+
+        Setting the ``dump`` boolean option to off excludes the memory
+        from core dumps. This feature is also known as MADV\_DONTDUMP.
+
+        The ``prealloc`` boolean option enables memory preallocation.
+
+        The ``host-nodes`` option binds the memory range to a list of
+        NUMA host nodes.
+
+        The ``policy`` option sets the NUMA policy to one of the
+        following values:
+
+        ``default``
+            default host policy
+
+        ``preferred``
+            prefer the given host node list for allocation
+
+        ``bind``
+            restrict memory allocation to the given host node list
+
+        ``interleave``
+            interleave memory allocations across the given host node
+            list
+
+        The ``align`` option specifies the base address alignment when
+        QEMU mmap(2) ``mem-path``, and accepts common suffixes, eg
+        ``2M``. Some backend store specified by ``mem-path`` requires an
+        alignment different than the default one used by QEMU, eg the
+        device DAX /dev/dax0.0 requires 2M alignment rather than 4K. In
+        such cases, users can specify the required alignment via this
+        option.
+
+        The ``pmem`` option specifies whether the backing file specified
+        by ``mem-path`` is in host persistent memory that can be
+        accessed using the SNIA NVM programming model (e.g. Intel
+        NVDIMM). If ``pmem`` is set to 'on', QEMU will take necessary
+        operations to guarantee the persistence of its own writes to
+        ``mem-path`` (e.g. in vNVDIMM label emulation and live
+        migration). Also, we will map the backend-file with MAP\_SYNC
+        flag, which ensures the file metadata is in sync for
+        ``mem-path`` in case of host crash or a power failure. MAP\_SYNC
+        requires support from both the host kernel (since Linux kernel
+        4.15) and the filesystem of ``mem-path`` mounted with DAX
+        option.
+
+    ``-object memory-backend-ram,id=id,merge=on|off,dump=on|off,share=on|off,prealloc=on|off,size=size,host-nodes=host-nodes,policy=default|preferred|bind|interleave``
+        Creates a memory backend object, which can be used to back the
+        guest RAM. Memory backend objects offer more control than the
+        ``-m`` option that is traditionally used to define guest RAM.
+        Please refer to ``memory-backend-file`` for a description of the
+        options.
+
+    ``-object memory-backend-memfd,id=id,merge=on|off,dump=on|off,share=on|off,prealloc=on|off,size=size,host-nodes=host-nodes,policy=default|preferred|bind|interleave,seal=on|off,hugetlb=on|off,hugetlbsize=size``
+        Creates an anonymous memory file backend object, which allows
+        QEMU to share the memory with an external process (e.g. when
+        using vhost-user). The memory is allocated with memfd and
+        optional sealing. (Linux only)
+
+        The ``seal`` option creates a sealed-file, that will block
+        further resizing the memory ('on' by default).
+
+        The ``hugetlb`` option specify the file to be created resides in
+        the hugetlbfs filesystem (since Linux 4.14). Used in conjunction
+        with the ``hugetlb`` option, the ``hugetlbsize`` option specify
+        the hugetlb page size on systems that support multiple hugetlb
+        page sizes (it must be a power of 2 value supported by the
+        system).
+
+        In some versions of Linux, the ``hugetlb`` option is
+        incompatible with the ``seal`` option (requires at least Linux
+        4.16).
+
+        Please refer to ``memory-backend-file`` for a description of the
+        other options.
+
+        The ``share`` boolean option is on by default with memfd.
+
+    ``-object rng-builtin,id=id``
+        Creates a random number generator backend which obtains entropy
+        from QEMU builtin functions. The ``id`` parameter is a unique ID
+        that will be used to reference this entropy backend from the
+        ``virtio-rng`` device. By default, the ``virtio-rng`` device
+        uses this RNG backend.
+
+    ``-object rng-random,id=id,filename=/dev/random``
+        Creates a random number generator backend which obtains entropy
+        from a device on the host. The ``id`` parameter is a unique ID
+        that will be used to reference this entropy backend from the
+        ``virtio-rng`` device. The ``filename`` parameter specifies
+        which file to obtain entropy from and if omitted defaults to
+        ``/dev/urandom``.
+
+    ``-object rng-egd,id=id,chardev=chardevid``
+        Creates a random number generator backend which obtains entropy
+        from an external daemon running on the host. The ``id``
+        parameter is a unique ID that will be used to reference this
+        entropy backend from the ``virtio-rng`` device. The ``chardev``
+        parameter is the unique ID of a character device backend that
+        provides the connection to the RNG daemon.
+
+    ``-object tls-creds-anon,id=id,endpoint=endpoint,dir=/path/to/cred/dir,verify-peer=on|off``
+        Creates a TLS anonymous credentials object, which can be used to
+        provide TLS support on network backends. The ``id`` parameter is
+        a unique ID which network backends will use to access the
+        credentials. The ``endpoint`` is either ``server`` or ``client``
+        depending on whether the QEMU network backend that uses the
+        credentials will be acting as a client or as a server. If
+        ``verify-peer`` is enabled (the default) then once the handshake
+        is completed, the peer credentials will be verified, though this
+        is a no-op for anonymous credentials.
+
+        The dir parameter tells QEMU where to find the credential files.
+        For server endpoints, this directory may contain a file
+        dh-params.pem providing diffie-hellman parameters to use for the
+        TLS server. If the file is missing, QEMU will generate a set of
+        DH parameters at startup. This is a computationally expensive
+        operation that consumes random pool entropy, so it is
+        recommended that a persistent set of parameters be generated
+        upfront and saved.
+
+    ``-object tls-creds-psk,id=id,endpoint=endpoint,dir=/path/to/keys/dir[,username=username]``
+        Creates a TLS Pre-Shared Keys (PSK) credentials object, which
+        can be used to provide TLS support on network backends. The
+        ``id`` parameter is a unique ID which network backends will use
+        to access the credentials. The ``endpoint`` is either ``server``
+        or ``client`` depending on whether the QEMU network backend that
+        uses the credentials will be acting as a client or as a server.
+        For clients only, ``username`` is the username which will be
+        sent to the server. If omitted it defaults to "qemu".
+
+        The dir parameter tells QEMU where to find the keys file. It is
+        called "dir/keys.psk" and contains "username:key" pairs. This
+        file can most easily be created using the GnuTLS ``psktool``
+        program.
+
+        For server endpoints, dir may also contain a file dh-params.pem
+        providing diffie-hellman parameters to use for the TLS server.
+        If the file is missing, QEMU will generate a set of DH
+        parameters at startup. This is a computationally expensive
+        operation that consumes random pool entropy, so it is
+        recommended that a persistent set of parameters be generated up
+        front and saved.
+
+    ``-object tls-creds-x509,id=id,endpoint=endpoint,dir=/path/to/cred/dir,priority=priority,verify-peer=on|off,passwordid=id``
+        Creates a TLS anonymous credentials object, which can be used to
+        provide TLS support on network backends. The ``id`` parameter is
+        a unique ID which network backends will use to access the
+        credentials. The ``endpoint`` is either ``server`` or ``client``
+        depending on whether the QEMU network backend that uses the
+        credentials will be acting as a client or as a server. If
+        ``verify-peer`` is enabled (the default) then once the handshake
+        is completed, the peer credentials will be verified. With x509
+        certificates, this implies that the clients must be provided
+        with valid client certificates too.
+
+        The dir parameter tells QEMU where to find the credential files.
+        For server endpoints, this directory may contain a file
+        dh-params.pem providing diffie-hellman parameters to use for the
+        TLS server. If the file is missing, QEMU will generate a set of
+        DH parameters at startup. This is a computationally expensive
+        operation that consumes random pool entropy, so it is
+        recommended that a persistent set of parameters be generated
+        upfront and saved.
+
+        For x509 certificate credentials the directory will contain
+        further files providing the x509 certificates. The certificates
+        must be stored in PEM format, in filenames ca-cert.pem,
+        ca-crl.pem (optional), server-cert.pem (only servers),
+        server-key.pem (only servers), client-cert.pem (only clients),
+        and client-key.pem (only clients).
+
+        For the server-key.pem and client-key.pem files which contain
+        sensitive private keys, it is possible to use an encrypted
+        version by providing the passwordid parameter. This provides the
+        ID of a previously created ``secret`` object containing the
+        password for decryption.
+
+        The priority parameter allows to override the global default
+        priority used by gnutls. This can be useful if the system
+        administrator needs to use a weaker set of crypto priorities for
+        QEMU without potentially forcing the weakness onto all
+        applications. Or conversely if one wants wants a stronger
+        default for QEMU than for all other applications, they can do
+        this through this parameter. Its format is a gnutls priority
+        string as described at
+        https://gnutls.org/manual/html_node/Priority-Strings.html.
+
+    ``-object filter-buffer,id=id,netdev=netdevid,interval=t[,queue=all|rx|tx][,status=on|off][,position=head|tail|id=<id>][,insert=behind|before]``
+        Interval t can't be 0, this filter batches the packet delivery:
+        all packets arriving in a given interval on netdev netdevid are
+        delayed until the end of the interval. Interval is in
+        microseconds. ``status`` is optional that indicate whether the
+        netfilter is on (enabled) or off (disabled), the default status
+        for netfilter will be 'on'.
+
+        queue all\|rx\|tx is an option that can be applied to any
+        netfilter.
+
+        ``all``: the filter is attached both to the receive and the
+        transmit queue of the netdev (default).
+
+        ``rx``: the filter is attached to the receive queue of the
+        netdev, where it will receive packets sent to the netdev.
+
+        ``tx``: the filter is attached to the transmit queue of the
+        netdev, where it will receive packets sent by the netdev.
+
+        position head\|tail\|id=<id> is an option to specify where the
+        filter should be inserted in the filter list. It can be applied
+        to any netfilter.
+
+        ``head``: the filter is inserted at the head of the filter list,
+        before any existing filters.
+
+        ``tail``: the filter is inserted at the tail of the filter list,
+        behind any existing filters (default).
+
+        ``id=<id>``: the filter is inserted before or behind the filter
+        specified by <id>, see the insert option below.
+
+        insert behind\|before is an option to specify where to insert
+        the new filter relative to the one specified with
+        position=id=<id>. It can be applied to any netfilter.
+
+        ``before``: insert before the specified filter.
+
+        ``behind``: insert behind the specified filter (default).
+
+    ``-object filter-mirror,id=id,netdev=netdevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=<id>][,insert=behind|before]``
+        filter-mirror on netdev netdevid,mirror net packet to
+        chardevchardevid, if it has the vnet\_hdr\_support flag,
+        filter-mirror will mirror packet with vnet\_hdr\_len.
+
+    ``-object filter-redirector,id=id,netdev=netdevid,indev=chardevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=<id>][,insert=behind|before]``
+        filter-redirector on netdev netdevid,redirect filter's net
+        packet to chardev chardevid,and redirect indev's packet to
+        filter.if it has the vnet\_hdr\_support flag, filter-redirector
+        will redirect packet with vnet\_hdr\_len. Create a
+        filter-redirector we need to differ outdev id from indev id, id
+        can not be the same. we can just use indev or outdev, but at
+        least one of indev or outdev need to be specified.
+
+    ``-object filter-rewriter,id=id,netdev=netdevid,queue=all|rx|tx,[vnet_hdr_support][,position=head|tail|id=<id>][,insert=behind|before]``
+        Filter-rewriter is a part of COLO project.It will rewrite tcp
+        packet to secondary from primary to keep secondary tcp
+        connection,and rewrite tcp packet to primary from secondary make
+        tcp packet can be handled by client.if it has the
+        vnet\_hdr\_support flag, we can parse packet with vnet header.
+
+        usage: colo secondary: -object
+        filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0 -object
+        filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1 -object
+        filter-rewriter,id=rew0,netdev=hn0,queue=all
+
+    ``-object filter-dump,id=id,netdev=dev[,file=filename][,maxlen=len][,position=head|tail|id=<id>][,insert=behind|before]``
+        Dump the network traffic on netdev dev to the file specified by
+        filename. At most len bytes (64k by default) per packet are
+        stored. The file format is libpcap, so it can be analyzed with
+        tools such as tcpdump or Wireshark.
+
+    ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id]``
+        Colo-compare gets packet from primary\_inchardevid and
+        secondary\_inchardevid, than compare primary packet with
+        secondary packet. If the packets are same, we will output
+        primary packet to outdevchardevid, else we will notify
+        colo-frame do checkpoint and send primary packet to
+        outdevchardevid. In order to improve efficiency, we need to put
+        the task of comparison in another thread. If it has the
+        vnet\_hdr\_support flag, colo compare will send/recv packet with
+        vnet\_hdr\_len. If you want to use Xen COLO, will need the
+        notify\_dev to notify Xen colo-frame to do checkpoint.
+
+        we must use it with the help of filter-mirror and
+        filter-redirector.
+
+        ::
+
+            KVM COLO
+
+            primary:
+            -netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
+            -device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
+            -chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
+            -chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
+            -chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
+            -chardev socket,id=compare0-0,host=3.3.3.3,port=9001
+            -chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
+            -chardev socket,id=compare_out0,host=3.3.3.3,port=9005
+            -object iothread,id=iothread1
+            -object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
+            -object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
+            -object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
+            -object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,iothread=iothread1
+
+            secondary:
+            -netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
+            -device e1000,netdev=hn0,mac=52:a4:00:12:78:66
+            -chardev socket,id=red0,host=3.3.3.3,port=9003
+            -chardev socket,id=red1,host=3.3.3.3,port=9004
+            -object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
+            -object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
+
+
+            Xen COLO
+
+            primary:
+            -netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
+            -device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
+            -chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
+            -chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
+            -chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
+            -chardev socket,id=compare0-0,host=3.3.3.3,port=9001
+            -chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
+            -chardev socket,id=compare_out0,host=3.3.3.3,port=9005
+            -chardev socket,id=notify_way,host=3.3.3.3,port=9009,server,nowait
+            -object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
+            -object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
+            -object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
+            -object iothread,id=iothread1
+            -object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,notify_dev=nofity_way,iothread=iothread1
+
+            secondary:
+            -netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
+            -device e1000,netdev=hn0,mac=52:a4:00:12:78:66
+            -chardev socket,id=red0,host=3.3.3.3,port=9003
+            -chardev socket,id=red1,host=3.3.3.3,port=9004
+            -object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
+            -object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
+
+        If you want to know the detail of above command line, you can
+        read the colo-compare git log.
+
+    ``-object cryptodev-backend-builtin,id=id[,queues=queues]``
+        Creates a cryptodev backend which executes crypto opreation from
+        the QEMU cipher APIS. The id parameter is a unique ID that will
+        be used to reference this cryptodev backend from the
+        ``virtio-crypto`` device. The queues parameter is optional,
+        which specify the queue number of cryptodev backend, the default
+        of queues is 1.
+
+        .. parsed-literal::
+
+             # |qemu_system| \
+               [...] \
+                   -object cryptodev-backend-builtin,id=cryptodev0 \
+                   -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
+               [...]
+
+    ``-object cryptodev-vhost-user,id=id,chardev=chardevid[,queues=queues]``
+        Creates a vhost-user cryptodev backend, backed by a chardev
+        chardevid. The id parameter is a unique ID that will be used to
+        reference this cryptodev backend from the ``virtio-crypto``
+        device. The chardev should be a unix domain socket backed one.
+        The vhost-user uses a specifically defined protocol to pass
+        vhost ioctl replacement messages to an application on the other
+        end of the socket. The queues parameter is optional, which
+        specify the queue number of cryptodev backend for multiqueue
+        vhost-user, the default of queues is 1.
+
+        .. parsed-literal::
+
+             # |qemu_system| \
+               [...] \
+                   -chardev socket,id=chardev0,path=/path/to/socket \
+                   -object cryptodev-vhost-user,id=cryptodev0,chardev=chardev0 \
+                   -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
+               [...]
+
+    ``-object secret,id=id,data=string,format=raw|base64[,keyid=secretid,iv=string]``
+      \ 
+    ``-object secret,id=id,file=filename,format=raw|base64[,keyid=secretid,iv=string]``
+        Defines a secret to store a password, encryption key, or some
+        other sensitive data. The sensitive data can either be passed
+        directly via the data parameter, or indirectly via the file
+        parameter. Using the data parameter is insecure unless the
+        sensitive data is encrypted.
+
+        The sensitive data can be provided in raw format (the default),
+        or base64. When encoded as JSON, the raw format only supports
+        valid UTF-8 characters, so base64 is recommended for sending
+        binary data. QEMU will convert from which ever format is
+        provided to the format it needs internally. eg, an RBD password
+        can be provided in raw format, even though it will be base64
+        encoded when passed onto the RBD sever.
+
+        For added protection, it is possible to encrypt the data
+        associated with a secret using the AES-256-CBC cipher. Use of
+        encryption is indicated by providing the keyid and iv
+        parameters. The keyid parameter provides the ID of a previously
+        defined secret that contains the AES-256 decryption key. This
+        key should be 32-bytes long and be base64 encoded. The iv
+        parameter provides the random initialization vector used for
+        encryption of this particular secret and should be a base64
+        encrypted string of the 16-byte IV.
+
+        The simplest (insecure) usage is to provide the secret inline
+
+        .. parsed-literal::
+
+             # |qemu_system| -object secret,id=sec0,data=letmein,format=raw
+
+        The simplest secure usage is to provide the secret via a file
+
+        # printf "letmein" > mypasswd.txt # QEMU\_SYSTEM\_MACRO -object
+        secret,id=sec0,file=mypasswd.txt,format=raw
+
+        For greater security, AES-256-CBC should be used. To illustrate
+        usage, consider the openssl command line tool which can encrypt
+        the data. Note that when encrypting, the plaintext must be
+        padded to the cipher block size (32 bytes) using the standard
+        PKCS#5/6 compatible padding algorithm.
+
+        First a master key needs to be created in base64 encoding:
+
+        ::
+
+             # openssl rand -base64 32 > key.b64
+             # KEY=$(base64 -d key.b64 | hexdump  -v -e '/1 "%02X"')
+
+        Each secret to be encrypted needs to have a random
+        initialization vector generated. These do not need to be kept
+        secret
+
+        ::
+
+             # openssl rand -base64 16 > iv.b64
+             # IV=$(base64 -d iv.b64 | hexdump  -v -e '/1 "%02X"')
+
+        The secret to be defined can now be encrypted, in this case
+        we're telling openssl to base64 encode the result, but it could
+        be left as raw bytes if desired.
+
+        ::
+
+             # SECRET=$(printf "letmein" |
+                        openssl enc -aes-256-cbc -a -K $KEY -iv $IV)
+
+        When launching QEMU, create a master secret pointing to
+        ``key.b64`` and specify that to be used to decrypt the user
+        password. Pass the contents of ``iv.b64`` to the second secret
+
+        .. parsed-literal::
+
+             # |qemu_system| \
+                 -object secret,id=secmaster0,format=base64,file=key.b64 \
+                 -object secret,id=sec0,keyid=secmaster0,format=base64,\
+                     data=$SECRET,iv=$(<iv.b64)
+
+    ``-object sev-guest,id=id,cbitpos=cbitpos,reduced-phys-bits=val,[sev-device=string,policy=policy,handle=handle,dh-cert-file=file,session-file=file]``
+        Create a Secure Encrypted Virtualization (SEV) guest object,
+        which can be used to provide the guest memory encryption support
+        on AMD processors.
+
+        When memory encryption is enabled, one of the physical address
+        bit (aka the C-bit) is utilized to mark if a memory page is
+        protected. The ``cbitpos`` is used to provide the C-bit
+        position. The C-bit position is Host family dependent hence user
+        must provide this value. On EPYC, the value should be 47.
+
+        When memory encryption is enabled, we loose certain bits in
+        physical address space. The ``reduced-phys-bits`` is used to
+        provide the number of bits we loose in physical address space.
+        Similar to C-bit, the value is Host family dependent. On EPYC,
+        the value should be 5.
+
+        The ``sev-device`` provides the device file to use for
+        communicating with the SEV firmware running inside AMD Secure
+        Processor. The default device is '/dev/sev'. If hardware
+        supports memory encryption then /dev/sev devices are created by
+        CCP driver.
+
+        The ``policy`` provides the guest policy to be enforced by the
+        SEV firmware and restrict what configuration and operational
+        commands can be performed on this guest by the hypervisor. The
+        policy should be provided by the guest owner and is bound to the
+        guest and cannot be changed throughout the lifetime of the
+        guest. The default is 0.
 
-The @option{size} option provides the size of the memory region, and accepts
-common suffixes, eg @option{500M}.
+        If guest ``policy`` allows sharing the key with another SEV
+        guest then ``handle`` can be use to provide handle of the guest
+        from which to share the key.
 
-The @option{mem-path} provides the path to either a shared memory or huge page
-filesystem mount.
+        The ``dh-cert-file`` and ``session-file`` provides the guest
+        owner's Public Diffie-Hillman key defined in SEV spec. The PDH
+        and session parameters are used for establishing a cryptographic
+        session with the guest owner to negotiate keys used for
+        attestation. The file must be encoded in base64.
 
-The @option{share} boolean option determines whether the memory
-region is marked as private to QEMU, or shared. The latter allows
-a co-operating external process to access the QEMU memory region.
+        e.g to launch a SEV guest
 
-The @option{share} is also required for pvrdma devices due to
-limitations in the RDMA API provided by Linux.
+        .. parsed-literal::
 
-Setting share=on might affect the ability to configure NUMA
-bindings for the memory backend under some circumstances, see
-Documentation/vm/numa_memory_policy.txt on the Linux kernel
-source tree for additional details.
+             # |qemu_system_x86| \
+                 ......
+                 -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5 \
+                 -machine ...,memory-encryption=sev0
+                 .....
 
-Setting the @option{discard-data} boolean option to @var{on}
-indicates that file contents can be destroyed when QEMU exits,
-to avoid unnecessarily flushing data to the backing file.  Note
-that @option{discard-data} is only an optimization, and QEMU
-might not discard file contents if it aborts unexpectedly or is
-terminated using SIGKILL.
+    ``-object authz-simple,id=id,identity=string``
+        Create an authorization object that will control access to
+        network services.
 
-The @option{merge} boolean option enables memory merge, also known as
-MADV_MERGEABLE, so that Kernel Samepage Merging will consider the pages for
-memory deduplication.
+        The ``identity`` parameter is identifies the user and its format
+        depends on the network service that authorization object is
+        associated with. For authorizing based on TLS x509 certificates,
+        the identity must be the x509 distinguished name. Note that care
+        must be taken to escape any commas in the distinguished name.
 
-Setting the @option{dump} boolean option to @var{off} excludes the memory from
-core dumps. This feature is also known as MADV_DONTDUMP.
+        An example authorization object to validate a x509 distinguished
+        name would look like:
 
-The @option{prealloc} boolean option enables memory preallocation.
+        .. parsed-literal::
 
-The @option{host-nodes} option binds the memory range to a list of NUMA host
-nodes.
+             # |qemu_system| \
+                 ...
+                 -object 'authz-simple,id=auth0,identity=CN=laptop.example.com,,O=Example Org,,L=London,,ST=London,,C=GB' \
+                 ...
 
-The @option{policy} option sets the NUMA policy to one of the following values:
+        Note the use of quotes due to the x509 distinguished name
+        containing whitespace, and escaping of ','.
 
-@table @option
-@item @var{default}
-default host policy
-
-@item @var{preferred}
-prefer the given host node list for allocation
-
-@item @var{bind}
-restrict memory allocation to the given host node list
+    ``-object authz-listfile,id=id,filename=path,refresh=yes|no``
+        Create an authorization object that will control access to
+        network services.
 
-@item @var{interleave}
-interleave memory allocations across the given host node list
-@end table
-
-The @option{align} option specifies the base address alignment when
-QEMU mmap(2) @option{mem-path}, and accepts common suffixes, eg
-@option{2M}. Some backend store specified by @option{mem-path}
-requires an alignment different than the default one used by QEMU, eg
-the device DAX /dev/dax0.0 requires 2M alignment rather than 4K. In
-such cases, users can specify the required alignment via this option.
-
-The @option{pmem} option specifies whether the backing file specified
-by @option{mem-path} is in host persistent memory that can be accessed
-using the SNIA NVM programming model (e.g. Intel NVDIMM).
-If @option{pmem} is set to 'on', QEMU will take necessary operations to
-guarantee the persistence of its own writes to @option{mem-path}
-(e.g. in vNVDIMM label emulation and live migration).
-Also, we will map the backend-file with MAP_SYNC flag, which ensures the
-file metadata is in sync for @option{mem-path} in case of host crash
-or a power failure. MAP_SYNC requires support from both the host kernel
-(since Linux kernel 4.15) and the filesystem of @option{mem-path} mounted
-with DAX option.
-
-@item -object memory-backend-ram,id=@var{id},merge=@var{on|off},dump=@var{on|off},share=@var{on|off},prealloc=@var{on|off},size=@var{size},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave}
-
-Creates a memory backend object, which can be used to back the guest RAM.
-Memory backend objects offer more control than the @option{-m} option that is
-traditionally used to define guest RAM. Please refer to
-@option{memory-backend-file} for a description of the options.
-
-@item -object memory-backend-memfd,id=@var{id},merge=@var{on|off},dump=@var{on|off},share=@var{on|off},prealloc=@var{on|off},size=@var{size},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave},seal=@var{on|off},hugetlb=@var{on|off},hugetlbsize=@var{size}
-
-Creates an anonymous memory file backend object, which allows QEMU to
-share the memory with an external process (e.g. when using
-vhost-user). The memory is allocated with memfd and optional
-sealing. (Linux only)
-
-The @option{seal} option creates a sealed-file, that will block
-further resizing the memory ('on' by default).
-
-The @option{hugetlb} option specify the file to be created resides in
-the hugetlbfs filesystem (since Linux 4.14).  Used in conjunction with
-the @option{hugetlb} option, the @option{hugetlbsize} option specify
-the hugetlb page size on systems that support multiple hugetlb page
-sizes (it must be a power of 2 value supported by the system).
-
-In some versions of Linux, the @option{hugetlb} option is incompatible
-with the @option{seal} option (requires at least Linux 4.16).
-
-Please refer to @option{memory-backend-file} for a description of the
-other options.
-
-The @option{share} boolean option is @var{on} by default with memfd.
-
-@item -object rng-builtin,id=@var{id}
-
-Creates a random number generator backend which obtains entropy from
-QEMU builtin functions. The @option{id} parameter is a unique ID that
-will be used to reference this entropy backend from the @option{virtio-rng}
-device. By default, the @option{virtio-rng} device uses this RNG backend.
-
-@item -object rng-random,id=@var{id},filename=@var{/dev/random}
-
-Creates a random number generator backend which obtains entropy from
-a device on the host. The @option{id} parameter is a unique ID that
-will be used to reference this entropy backend from the @option{virtio-rng}
-device. The @option{filename} parameter specifies which file to obtain
-entropy from and if omitted defaults to @option{/dev/urandom}.
-
-@item -object rng-egd,id=@var{id},chardev=@var{chardevid}
-
-Creates a random number generator backend which obtains entropy from
-an external daemon running on the host. The @option{id} parameter is
-a unique ID that will be used to reference this entropy backend from
-the @option{virtio-rng} device. The @option{chardev} parameter is
-the unique ID of a character device backend that provides the connection
-to the RNG daemon.
-
-@item -object tls-creds-anon,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/cred/dir},verify-peer=@var{on|off}
-
-Creates a TLS anonymous credentials object, which can be used to provide
-TLS support on network backends. The @option{id} parameter is a unique
-ID which network backends will use to access the credentials. The
-@option{endpoint} is either @option{server} or @option{client} depending
-on whether the QEMU network backend that uses the credentials will be
-acting as a client or as a server. If @option{verify-peer} is enabled
-(the default) then once the handshake is completed, the peer credentials
-will be verified, though this is a no-op for anonymous credentials.
-
-The @var{dir} parameter tells QEMU where to find the credential
-files. For server endpoints, this directory may contain a file
-@var{dh-params.pem} providing diffie-hellman parameters to use
-for the TLS server. If the file is missing, QEMU will generate
-a set of DH parameters at startup. This is a computationally
-expensive operation that consumes random pool entropy, so it is
-recommended that a persistent set of parameters be generated
-upfront and saved.
-
-@item -object tls-creds-psk,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/keys/dir}[,username=@var{username}]
-
-Creates a TLS Pre-Shared Keys (PSK) credentials object, which can be used to provide
-TLS support on network backends. The @option{id} parameter is a unique
-ID which network backends will use to access the credentials. The
-@option{endpoint} is either @option{server} or @option{client} depending
-on whether the QEMU network backend that uses the credentials will be
-acting as a client or as a server. For clients only, @option{username}
-is the username which will be sent to the server.  If omitted
-it defaults to ``qemu''.
-
-The @var{dir} parameter tells QEMU where to find the keys file.
-It is called ``@var{dir}/keys.psk'' and contains ``username:key''
-pairs.  This file can most easily be created using the GnuTLS
-@code{psktool} program.
-
-For server endpoints, @var{dir} may also contain a file
-@var{dh-params.pem} providing diffie-hellman parameters to use
-for the TLS server. If the file is missing, QEMU will generate
-a set of DH parameters at startup. This is a computationally
-expensive operation that consumes random pool entropy, so it is
-recommended that a persistent set of parameters be generated
-up front and saved.
-
-@item -object tls-creds-x509,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/cred/dir},priority=@var{priority},verify-peer=@var{on|off},passwordid=@var{id}
-
-Creates a TLS anonymous credentials object, which can be used to provide
-TLS support on network backends. The @option{id} parameter is a unique
-ID which network backends will use to access the credentials. The
-@option{endpoint} is either @option{server} or @option{client} depending
-on whether the QEMU network backend that uses the credentials will be
-acting as a client or as a server. If @option{verify-peer} is enabled
-(the default) then once the handshake is completed, the peer credentials
-will be verified. With x509 certificates, this implies that the clients
-must be provided with valid client certificates too.
-
-The @var{dir} parameter tells QEMU where to find the credential
-files. For server endpoints, this directory may contain a file
-@var{dh-params.pem} providing diffie-hellman parameters to use
-for the TLS server. If the file is missing, QEMU will generate
-a set of DH parameters at startup. This is a computationally
-expensive operation that consumes random pool entropy, so it is
-recommended that a persistent set of parameters be generated
-upfront and saved.
-
-For x509 certificate credentials the directory will contain further files
-providing the x509 certificates. The certificates must be stored
-in PEM format, in filenames @var{ca-cert.pem}, @var{ca-crl.pem} (optional),
-@var{server-cert.pem} (only servers), @var{server-key.pem} (only servers),
-@var{client-cert.pem} (only clients), and @var{client-key.pem} (only clients).
-
-For the @var{server-key.pem} and @var{client-key.pem} files which
-contain sensitive private keys, it is possible to use an encrypted
-version by providing the @var{passwordid} parameter. This provides
-the ID of a previously created @code{secret} object containing the
-password for decryption.
-
-The @var{priority} parameter allows to override the global default
-priority used by gnutls. This can be useful if the system administrator
-needs to use a weaker set of crypto priorities for QEMU without
-potentially forcing the weakness onto all applications. Or conversely
-if one wants wants a stronger default for QEMU than for all other
-applications, they can do this through this parameter. Its format is
-a gnutls priority string as described at
-@url{https://gnutls.org/manual/html_node/Priority-Strings.html}.
-
-@item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}][,position=@var{head|tail|id=<id>}][,insert=@var{behind|before}]
-
-Interval @var{t} can't be 0, this filter batches the packet delivery: all
-packets arriving in a given interval on netdev @var{netdevid} are delayed
-until the end of the interval. Interval is in microseconds.
-@option{status} is optional that indicate whether the netfilter is
-on (enabled) or off (disabled), the default status for netfilter will be 'on'.
-
-queue @var{all|rx|tx} is an option that can be applied to any netfilter.
-
-@option{all}: the filter is attached both to the receive and the transmit
-              queue of the netdev (default).
-
-@option{rx}: the filter is attached to the receive queue of the netdev,
-             where it will receive packets sent to the netdev.
-
-@option{tx}: the filter is attached to the transmit queue of the netdev,
-             where it will receive packets sent by the netdev.
-
-position @var{head|tail|id=<id>} is an option to specify where the
-filter should be inserted in the filter list. It can be applied to any
-netfilter.
-
-@option{head}: the filter is inserted at the head of the filter
-               list, before any existing filters.
-
-@option{tail}: the filter is inserted at the tail of the filter
-               list, behind any existing filters (default).
-
-@option{id=<id>}: the filter is inserted before or behind the filter
-                  specified by <id>, see the insert option below.
-
-insert @var{behind|before} is an option to specify where to insert the
-new filter relative to the one specified with position=id=<id>. It can
-be applied to any netfilter.
-
-@option{before}: insert before the specified filter.
-
-@option{behind}: insert behind the specified filter (default).
-
-@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support][,position=@var{head|tail|id=<id>}][,insert=@var{behind|before}]
-
-filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len.
-
-@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support][,position=@var{head|tail|id=<id>}][,insert=@var{behind|before}]
-
-filter-redirector on netdev @var{netdevid},redirect filter's net packet to chardev
-@var{chardevid},and redirect indev's packet to filter.if it has the vnet_hdr_support flag,
-filter-redirector will redirect packet with vnet_hdr_len.
-Create a filter-redirector we need to differ outdev id from indev id, id can not
-be the same. we can just use indev or outdev, but at least one of indev or outdev
-need to be specified.
-
-@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support][,position=@var{head|tail|id=<id>}][,insert=@var{behind|before}]
-
-Filter-rewriter is a part of COLO project.It will rewrite tcp packet to
-secondary from primary to keep secondary tcp connection,and rewrite
-tcp packet to primary from secondary make tcp packet can be handled by
-client.if it has the vnet_hdr_support flag, we can parse packet with vnet header.
-
-usage:
-colo secondary:
--object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
--object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
--object filter-rewriter,id=rew0,netdev=hn0,queue=all
-
-@item -object filter-dump,id=@var{id},netdev=@var{dev}[,file=@var{filename}][,maxlen=@var{len}][,position=@var{head|tail|id=<id>}][,insert=@var{behind|before}]
-
-Dump the network traffic on netdev @var{dev} to the file specified by
-@var{filename}. At most @var{len} bytes (64k by default) per packet are stored.
-The file format is libpcap, so it can be analyzed with tools such as tcpdump
-or Wireshark.
-
-@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid},iothread=@var{id}[,vnet_hdr_support][,notify_dev=@var{id}]
-
-Colo-compare gets packet from primary_in@var{chardevid} and secondary_in@var{chardevid}, than compare primary packet with
-secondary packet. If the packets are same, we will output primary
-packet to outdev@var{chardevid}, else we will notify colo-frame
-do checkpoint and send primary packet to outdev@var{chardevid}.
-In order to improve efficiency, we need to put the task of comparison
-in another thread. If it has the vnet_hdr_support flag, colo compare
-will send/recv packet with vnet_hdr_len.
-If you want to use Xen COLO, will need the notify_dev to notify Xen
-colo-frame to do checkpoint.
-
-we must use it with the help of filter-mirror and filter-redirector.
-
-@example
-
-KVM COLO
-
-primary:
--netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
--device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
--chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
--chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
--chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
--chardev socket,id=compare0-0,host=3.3.3.3,port=9001
--chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
--chardev socket,id=compare_out0,host=3.3.3.3,port=9005
--object iothread,id=iothread1
--object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
--object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
--object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
--object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,iothread=iothread1
-
-secondary:
--netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
--device e1000,netdev=hn0,mac=52:a4:00:12:78:66
--chardev socket,id=red0,host=3.3.3.3,port=9003
--chardev socket,id=red1,host=3.3.3.3,port=9004
--object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
--object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
-
-
-Xen COLO
-
-primary:
--netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
--device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
--chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
--chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
--chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
--chardev socket,id=compare0-0,host=3.3.3.3,port=9001
--chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
--chardev socket,id=compare_out0,host=3.3.3.3,port=9005
--chardev socket,id=notify_way,host=3.3.3.3,port=9009,server,nowait
--object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
--object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
--object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
--object iothread,id=iothread1
--object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,notify_dev=nofity_way,iothread=iothread1
-
-secondary:
--netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
--device e1000,netdev=hn0,mac=52:a4:00:12:78:66
--chardev socket,id=red0,host=3.3.3.3,port=9003
--chardev socket,id=red1,host=3.3.3.3,port=9004
--object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
--object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
-
-@end example
-
-If you want to know the detail of above command line, you can read
-the colo-compare git log.
-
-@item -object cryptodev-backend-builtin,id=@var{id}[,queues=@var{queues}]
-
-Creates a cryptodev backend which executes crypto opreation from
-the QEMU cipher APIS. The @var{id} parameter is
-a unique ID that will be used to reference this cryptodev backend from
-the @option{virtio-crypto} device. The @var{queues} parameter is optional,
-which specify the queue number of cryptodev backend, the default of
-@var{queues} is 1.
-
-@example
-
- # @value{qemu_system} \
-   [...] \
-       -object cryptodev-backend-builtin,id=cryptodev0 \
-       -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
-   [...]
-@end example
-
-@item -object cryptodev-vhost-user,id=@var{id},chardev=@var{chardevid}[,queues=@var{queues}]
-
-Creates a vhost-user cryptodev backend, backed by a chardev @var{chardevid}.
-The @var{id} parameter is a unique ID that will be used to reference this
-cryptodev backend from the @option{virtio-crypto} device.
-The chardev should be a unix domain socket backed one. The vhost-user uses
-a specifically defined protocol to pass vhost ioctl replacement messages
-to an application on the other end of the socket.
-The @var{queues} parameter is optional, which specify the queue number
-of cryptodev backend for multiqueue vhost-user, the default of @var{queues} is 1.
-
-@example
-
- # @value{qemu_system} \
-   [...] \
-       -chardev socket,id=chardev0,path=/path/to/socket \
-       -object cryptodev-vhost-user,id=cryptodev0,chardev=chardev0 \
-       -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
-   [...]
-@end example
-
-@item -object secret,id=@var{id},data=@var{string},format=@var{raw|base64}[,keyid=@var{secretid},iv=@var{string}]
-@item -object secret,id=@var{id},file=@var{filename},format=@var{raw|base64}[,keyid=@var{secretid},iv=@var{string}]
-
-Defines a secret to store a password, encryption key, or some other sensitive
-data. The sensitive data can either be passed directly via the @var{data}
-parameter, or indirectly via the @var{file} parameter. Using the @var{data}
-parameter is insecure unless the sensitive data is encrypted.
-
-The sensitive data can be provided in raw format (the default), or base64.
-When encoded as JSON, the raw format only supports valid UTF-8 characters,
-so base64 is recommended for sending binary data. QEMU will convert from
-which ever format is provided to the format it needs internally. eg, an
-RBD password can be provided in raw format, even though it will be base64
-encoded when passed onto the RBD sever.
-
-For added protection, it is possible to encrypt the data associated with
-a secret using the AES-256-CBC cipher. Use of encryption is indicated
-by providing the @var{keyid} and @var{iv} parameters. The @var{keyid}
-parameter provides the ID of a previously defined secret that contains
-the AES-256 decryption key. This key should be 32-bytes long and be
-base64 encoded. The @var{iv} parameter provides the random initialization
-vector used for encryption of this particular secret and should be a
-base64 encrypted string of the 16-byte IV.
-
-The simplest (insecure) usage is to provide the secret inline
-
-@example
-
- # @value{qemu_system} -object secret,id=sec0,data=letmein,format=raw
-
-@end example
-
-The simplest secure usage is to provide the secret via a file
-
- # printf "letmein" > mypasswd.txt
- # @value{qemu_system} -object secret,id=sec0,file=mypasswd.txt,format=raw
-
-For greater security, AES-256-CBC should be used. To illustrate usage,
-consider the openssl command line tool which can encrypt the data. Note
-that when encrypting, the plaintext must be padded to the cipher block
-size (32 bytes) using the standard PKCS#5/6 compatible padding algorithm.
-
-First a master key needs to be created in base64 encoding:
-
-@example
- # openssl rand -base64 32 > key.b64
- # KEY=$(base64 -d key.b64 | hexdump  -v -e '/1 "%02X"')
-@end example
-
-Each secret to be encrypted needs to have a random initialization vector
-generated. These do not need to be kept secret
-
-@example
- # openssl rand -base64 16 > iv.b64
- # IV=$(base64 -d iv.b64 | hexdump  -v -e '/1 "%02X"')
-@end example
-
-The secret to be defined can now be encrypted, in this case we're
-telling openssl to base64 encode the result, but it could be left
-as raw bytes if desired.
-
-@example
- # SECRET=$(printf "letmein" |
-            openssl enc -aes-256-cbc -a -K $KEY -iv $IV)
-@end example
-
-When launching QEMU, create a master secret pointing to @code{key.b64}
-and specify that to be used to decrypt the user password. Pass the
-contents of @code{iv.b64} to the second secret
-
-@example
- # @value{qemu_system} \
-     -object secret,id=secmaster0,format=base64,file=key.b64 \
-     -object secret,id=sec0,keyid=secmaster0,format=base64,\
-         data=$SECRET,iv=$(<iv.b64)
-@end example
-
-@item -object sev-guest,id=@var{id},cbitpos=@var{cbitpos},reduced-phys-bits=@var{val},[sev-device=@var{string},policy=@var{policy},handle=@var{handle},dh-cert-file=@var{file},session-file=@var{file}]
-
-Create a Secure Encrypted Virtualization (SEV) guest object, which can be used
-to provide the guest memory encryption support on AMD processors.
-
-When memory encryption is enabled, one of the physical address bit (aka the
-C-bit) is utilized to mark if a memory page is protected. The @option{cbitpos}
-is used to provide the C-bit position. The C-bit position is Host family dependent
-hence user must provide this value. On EPYC, the value should be 47.
-
-When memory encryption is enabled, we loose certain bits in physical address space.
-The @option{reduced-phys-bits} is used to provide the number of bits we loose in
-physical address space. Similar to C-bit, the value is Host family dependent.
-On EPYC, the value should be 5.
-
-The @option{sev-device} provides the device file to use for communicating with
-the SEV firmware running inside AMD Secure Processor. The default device is
-'/dev/sev'. If hardware supports memory encryption then /dev/sev devices are
-created by CCP driver.
-
-The @option{policy} provides the guest policy to be enforced by the SEV firmware
-and restrict what configuration and operational commands can be performed on this
-guest by the hypervisor. The policy should be provided by the guest owner and is
-bound to the guest and cannot be changed throughout the lifetime of the guest.
-The default is 0.
-
-If guest @option{policy} allows sharing the key with another SEV guest then
-@option{handle} can be use to provide handle of the guest from which to share
-the key.
-
-The @option{dh-cert-file} and @option{session-file} provides the guest owner's
-Public Diffie-Hillman key defined in SEV spec. The PDH and session parameters
-are used for establishing a cryptographic session with the guest owner to
-negotiate keys used for attestation. The file must be encoded in base64.
-
-e.g to launch a SEV guest
-@example
- # @value{qemu_system_x86} \
-     ......
-     -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5 \
-     -machine ...,memory-encryption=sev0
-     .....
-
-@end example
+        The ``filename`` parameter is the fully qualified path to a file
+        containing the access control list rules in JSON format.
 
+        An example set of rules that match against SASL usernames might
+        look like:
 
-@item -object authz-simple,id=@var{id},identity=@var{string}
+        ::
+
+              {
+                "rules": [
+                   { "match": "fred", "policy": "allow", "format": "exact" },
+                   { "match": "bob", "policy": "allow", "format": "exact" },
+                   { "match": "danb", "policy": "deny", "format": "glob" },
+                   { "match": "dan*", "policy": "allow", "format": "exact" },
+                ],
+                "policy": "deny"
+              }
+
+        When checking access the object will iterate over all the rules
+        and the first rule to match will have its ``policy`` value
+        returned as the result. If no rules match, then the default
+        ``policy`` value is returned.
 
-Create an authorization object that will control access to network services.
+        The rules can either be an exact string match, or they can use
+        the simple UNIX glob pattern matching to allow wildcards to be
+        used.
 
-The @option{identity} parameter is identifies the user and its format
-depends on the network service that authorization object is associated
-with. For authorizing based on TLS x509 certificates, the identity must
-be the x509 distinguished name. Note that care must be taken to escape
-any commas in the distinguished name.
-
-An example authorization object to validate a x509 distinguished name
-would look like:
-@example
- # @value{qemu_system} \
-     ...
-     -object 'authz-simple,id=auth0,identity=CN=laptop.example.com,,O=Example Org,,L=London,,ST=London,,C=GB' \
-     ...
-@end example
-
-Note the use of quotes due to the x509 distinguished name containing
-whitespace, and escaping of ','.
-
-@item -object authz-listfile,id=@var{id},filename=@var{path},refresh=@var{yes|no}
-
-Create an authorization object that will control access to network services.
-
-The @option{filename} parameter is the fully qualified path to a file
-containing the access control list rules in JSON format.
-
-An example set of rules that match against SASL usernames might look
-like:
-
-@example
-  @{
-    "rules": [
-       @{ "match": "fred", "policy": "allow", "format": "exact" @},
-       @{ "match": "bob", "policy": "allow", "format": "exact" @},
-       @{ "match": "danb", "policy": "deny", "format": "glob" @},
-       @{ "match": "dan*", "policy": "allow", "format": "exact" @},
-    ],
-    "policy": "deny"
-  @}
-@end example
-
-When checking access the object will iterate over all the rules and
-the first rule to match will have its @option{policy} value returned
-as the result. If no rules match, then the default @option{policy}
-value is returned.
+        If ``refresh`` is set to true the file will be monitored and
+        automatically reloaded whenever its content changes.
 
-The rules can either be an exact string match, or they can use the
-simple UNIX glob pattern matching to allow wildcards to be used.
+        As with the ``authz-simple`` object, the format of the identity
+        strings being matched depends on the network service, but is
+        usually a TLS x509 distinguished name, or a SASL username.
 
-If @option{refresh} is set to true the file will be monitored
-and automatically reloaded whenever its content changes.
+        An example authorization object to validate a SASL username
+        would look like:
 
-As with the @code{authz-simple} object, the format of the identity
-strings being matched depends on the network service, but is usually
-a TLS x509 distinguished name, or a SASL username.
+        .. parsed-literal::
 
-An example authorization object to validate a SASL username
-would look like:
-@example
- # @value{qemu_system} \
-     ...
-     -object authz-simple,id=auth0,filename=/etc/qemu/vnc-sasl.acl,refresh=yes
-     ...
-@end example
+             # |qemu_system| \
+                 ...
+                 -object authz-simple,id=auth0,filename=/etc/qemu/vnc-sasl.acl,refresh=yes
+                 ...
 
-@item -object authz-pam,id=@var{id},service=@var{string}
+    ``-object authz-pam,id=id,service=string``
+        Create an authorization object that will control access to
+        network services.
 
-Create an authorization object that will control access to network services.
+        The ``service`` parameter provides the name of a PAM service to
+        use for authorization. It requires that a file
+        ``/etc/pam.d/service`` exist to provide the configuration for
+        the ``account`` subsystem.
 
-The @option{service} parameter provides the name of a PAM service to use
-for authorization. It requires that a file @code{/etc/pam.d/@var{service}}
-exist to provide the configuration for the @code{account} subsystem.
+        An example authorization object to validate a TLS x509
+        distinguished name would look like:
 
-An example authorization object to validate a TLS x509 distinguished
-name would look like:
+        .. parsed-literal::
 
-@example
- # @value{qemu_system} \
-     ...
-     -object authz-pam,id=auth0,service=qemu-vnc
-     ...
-@end example
+             # |qemu_system| \
+                 ...
+                 -object authz-pam,id=auth0,service=qemu-vnc
+                 ...
 
-There would then be a corresponding config file for PAM at
-@code{/etc/pam.d/qemu-vnc} that contains:
+        There would then be a corresponding config file for PAM at
+        ``/etc/pam.d/qemu-vnc`` that contains:
 
-@example
-account requisite  pam_listfile.so item=user sense=allow \
-           file=/etc/qemu/vnc.allow
-@end example
+        ::
 
-Finally the @code{/etc/qemu/vnc.allow} file would contain
-the list of x509 distingished names that are permitted
-access
+            account requisite  pam_listfile.so item=user sense=allow \
+                       file=/etc/qemu/vnc.allow
 
-@example
-CN=laptop.example.com,O=Example Home,L=London,ST=London,C=GB
-@end example
+        Finally the ``/etc/qemu/vnc.allow`` file would contain the list
+        of x509 distingished names that are permitted access
 
-@item -object iothread,id=@var{id},poll-max-ns=@var{poll-max-ns},poll-grow=@var{poll-grow},poll-shrink=@var{poll-shrink}
+        ::
 
-Creates a dedicated event loop thread that devices can be assigned to.  This is
-known as an IOThread.  By default device emulation happens in vCPU threads or
-the main event loop thread.  This can become a scalability bottleneck.
-IOThreads allow device emulation and I/O to run on other host CPUs.
+            CN=laptop.example.com,O=Example Home,L=London,ST=London,C=GB
 
-The @option{id} parameter is a unique ID that will be used to reference this
-IOThread from @option{-device ...,iothread=@var{id}}.  Multiple devices can be
-assigned to an IOThread.  Note that not all devices support an
-@option{iothread} parameter.
+    ``-object iothread,id=id,poll-max-ns=poll-max-ns,poll-grow=poll-grow,poll-shrink=poll-shrink``
+        Creates a dedicated event loop thread that devices can be
+        assigned to. This is known as an IOThread. By default device
+        emulation happens in vCPU threads or the main event loop thread.
+        This can become a scalability bottleneck. IOThreads allow device
+        emulation and I/O to run on other host CPUs.
 
-The @code{query-iothreads} QMP command lists IOThreads and reports their thread
-IDs so that the user can configure host CPU pinning/affinity.
+        The ``id`` parameter is a unique ID that will be used to
+        reference this IOThread from ``-device ...,iothread=id``.
+        Multiple devices can be assigned to an IOThread. Note that not
+        all devices support an ``iothread`` parameter.
 
-IOThreads use an adaptive polling algorithm to reduce event loop latency.
-Instead of entering a blocking system call to monitor file descriptors and then
-pay the cost of being woken up when an event occurs, the polling algorithm
-spins waiting for events for a short time.  The algorithm's default parameters
-are suitable for many cases but can be adjusted based on knowledge of the
-workload and/or host device latency.
+        The ``query-iothreads`` QMP command lists IOThreads and reports
+        their thread IDs so that the user can configure host CPU
+        pinning/affinity.
 
-The @option{poll-max-ns} parameter is the maximum number of nanoseconds to busy
-wait for events.  Polling can be disabled by setting this value to 0.
+        IOThreads use an adaptive polling algorithm to reduce event loop
+        latency. Instead of entering a blocking system call to monitor
+        file descriptors and then pay the cost of being woken up when an
+        event occurs, the polling algorithm spins waiting for events for
+        a short time. The algorithm's default parameters are suitable
+        for many cases but can be adjusted based on knowledge of the
+        workload and/or host device latency.
 
-The @option{poll-grow} parameter is the multiplier used to increase the polling
-time when the algorithm detects it is missing events due to not polling long
-enough.
+        The ``poll-max-ns`` parameter is the maximum number of
+        nanoseconds to busy wait for events. Polling can be disabled by
+        setting this value to 0.
 
-The @option{poll-shrink} parameter is the divisor used to decrease the polling
-time when the algorithm detects it is spending too long polling without
-encountering events.
+        The ``poll-grow`` parameter is the multiplier used to increase
+        the polling time when the algorithm detects it is missing events
+        due to not polling long enough.
 
-The polling parameters can be modified at run-time using the @code{qom-set} command (where @code{iothread1} is the IOThread's @code{id}):
+        The ``poll-shrink`` parameter is the divisor used to decrease
+        the polling time when the algorithm detects it is spending too
+        long polling without encountering events.
 
-@example
-(qemu) qom-set /objects/iothread1 poll-max-ns 100000
-@end example
+        The polling parameters can be modified at run-time using the
+        ``qom-set`` command (where ``iothread1`` is the IOThread's
+        ``id``):
 
-@end table
+        ::
 
-ETEXI
+            (qemu) qom-set /objects/iothread1 poll-max-ns 100000
+ERST
 
 
 HXCOMM This is the last statement. Insert new options before this line!
-STEXI
-@end table
-ETEXI
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
new file mode 100644 (file)
index 0000000..dd12897
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * QEMU storage daemon
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2019 Kevin Wolf <kwolf@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+
+#include <getopt.h>
+
+#include "block/block.h"
+#include "block/nbd.h"
+#include "chardev/char.h"
+#include "crypto/init.h"
+#include "monitor/monitor.h"
+#include "monitor/monitor-internal.h"
+
+#include "qapi/error.h"
+#include "qapi/qapi-visit-block.h"
+#include "qapi/qapi-visit-block-core.h"
+#include "qapi/qapi-visit-control.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qstring.h"
+#include "qapi/qobject-input-visitor.h"
+
+#include "qemu-common.h"
+#include "qemu-version.h"
+#include "qemu/config-file.h"
+#include "qemu/error-report.h"
+#include "qemu/help_option.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
+#include "qom/object_interfaces.h"
+
+#include "storage-daemon/qapi/qapi-commands.h"
+#include "storage-daemon/qapi/qapi-init-commands.h"
+
+#include "sysemu/runstate.h"
+#include "trace/control.h"
+
+static volatile bool exit_requested = false;
+
+void qemu_system_killed(int signal, pid_t pid)
+{
+    exit_requested = true;
+}
+
+void qmp_quit(Error **errp)
+{
+    exit_requested = true;
+}
+
+static void help(void)
+{
+    printf(
+"Usage: %s [options]\n"
+"QEMU storage daemon\n"
+"\n"
+"  -h, --help             display this help and exit\n"
+"  -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
+"                         specify tracing options\n"
+"  -V, --version          output version information and exit\n"
+"\n"
+"  --blockdev [driver=]<driver>[,node-name=<N>][,discard=ignore|unmap]\n"
+"             [,cache.direct=on|off][,cache.no-flush=on|off]\n"
+"             [,read-only=on|off][,auto-read-only=on|off]\n"
+"             [,force-share=on|off][,detect-zeroes=on|off|unmap]\n"
+"             [,driver specific parameters...]\n"
+"                         configure a block backend\n"
+"\n"
+"  --chardev <options>    configure a character device backend\n"
+"                         (see the qemu(1) man page for possible options)\n"
+"\n"
+"  --export [type=]nbd,device=<node-name>[,name=<export-name>]\n"
+"           [,writable=on|off][,bitmap=<name>]\n"
+"                         export the specified block node over NBD\n"
+"                         (requires --nbd-server)\n"
+"\n"
+"  --monitor [chardev=]name[,mode=control][,pretty[=on|off]]\n"
+"                         configure a QMP monitor\n"
+"\n"
+"  --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
+"               [,tls-creds=<id>][,tls-authz=<id>]\n"
+"  --nbd-server addr.type=unix,addr.path=<path>\n"
+"               [,tls-creds=<id>][,tls-authz=<id>]\n"
+"                         start an NBD server for exporting block nodes\n"
+"\n"
+"  --object help          list object types that can be added\n"
+"  --object <type>,help   list properties for the given object type\n"
+"  --object <type>[,<property>=<value>...]\n"
+"                         create a new object of type <type>, setting\n"
+"                         properties in the order they are specified. Note\n"
+"                         that the 'id' property must be set.\n"
+"                         See the qemu(1) man page for documentation of the\n"
+"                         objects that can be added.\n"
+"\n"
+QEMU_HELP_BOTTOM "\n",
+    error_get_progname());
+}
+
+enum {
+    OPTION_BLOCKDEV = 256,
+    OPTION_CHARDEV,
+    OPTION_EXPORT,
+    OPTION_MONITOR,
+    OPTION_NBD_SERVER,
+    OPTION_OBJECT,
+};
+
+extern QemuOptsList qemu_chardev_opts;
+
+static QemuOptsList qemu_object_opts = {
+    .name = "object",
+    .implied_opt_name = "qom-type",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
+    .desc = {
+        { }
+    },
+};
+
+static void init_qmp_commands(void)
+{
+    qmp_init_marshal(&qmp_commands);
+    qmp_register_command(&qmp_commands, "query-qmp-schema",
+                         qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
+
+    QTAILQ_INIT(&qmp_cap_negotiation_commands);
+    qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
+                         qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);
+}
+
+static void init_export(BlockExport *export, Error **errp)
+{
+    switch (export->type) {
+    case BLOCK_EXPORT_TYPE_NBD:
+        qmp_nbd_server_add(&export->u.nbd, errp);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
+static void process_options(int argc, char *argv[])
+{
+    int c;
+
+    static const struct option long_options[] = {
+        {"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
+        {"chardev", required_argument, NULL, OPTION_CHARDEV},
+        {"export", required_argument, NULL, OPTION_EXPORT},
+        {"help", no_argument, NULL, 'h'},
+        {"monitor", required_argument, NULL, OPTION_MONITOR},
+        {"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
+        {"object", required_argument, NULL, OPTION_OBJECT},
+        {"trace", required_argument, NULL, 'T'},
+        {"version", no_argument, NULL, 'V'},
+        {0, 0, 0, 0}
+    };
+
+    /*
+     * In contrast to the system emulator, options are processed in the order
+     * they are given on the command lines. This means that things must be
+     * defined first before they can be referenced in another option.
+     */
+    while ((c = getopt_long(argc, argv, "hT:V", long_options, NULL)) != -1) {
+        switch (c) {
+        case '?':
+            exit(EXIT_FAILURE);
+        case 'h':
+            help();
+            exit(EXIT_SUCCESS);
+        case 'T':
+            {
+                char *trace_file = trace_opt_parse(optarg);
+                trace_init_file(trace_file);
+                g_free(trace_file);
+                break;
+            }
+        case 'V':
+            printf("qemu-storage-daemon version "
+                   QEMU_FULL_VERSION "\n" QEMU_COPYRIGHT "\n");
+            exit(EXIT_SUCCESS);
+        case OPTION_BLOCKDEV:
+            {
+                Visitor *v;
+                BlockdevOptions *options;
+
+                v = qobject_input_visitor_new_str(optarg, "driver",
+                                                  &error_fatal);
+
+                visit_type_BlockdevOptions(v, NULL, &options, &error_fatal);
+                visit_free(v);
+
+                qmp_blockdev_add(options, &error_fatal);
+                qapi_free_BlockdevOptions(options);
+                break;
+            }
+        case OPTION_CHARDEV:
+            {
+                /* TODO This interface is not stable until we QAPIfy it */
+                QemuOpts *opts = qemu_opts_parse_noisily(&qemu_chardev_opts,
+                                                         optarg, true);
+                if (opts == NULL) {
+                    exit(EXIT_FAILURE);
+                }
+
+                if (!qemu_chr_new_from_opts(opts, NULL, &error_fatal)) {
+                    /* No error, but NULL returned means help was printed */
+                    exit(EXIT_SUCCESS);
+                }
+                qemu_opts_del(opts);
+                break;
+            }
+        case OPTION_EXPORT:
+            {
+                Visitor *v;
+                BlockExport *export;
+
+                v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
+                visit_type_BlockExport(v, NULL, &export, &error_fatal);
+                visit_free(v);
+
+                init_export(export, &error_fatal);
+                qapi_free_BlockExport(export);
+                break;
+            }
+        case OPTION_MONITOR:
+            {
+                Visitor *v;
+                MonitorOptions *monitor;
+
+                v = qobject_input_visitor_new_str(optarg, "chardev",
+                                                  &error_fatal);
+                visit_type_MonitorOptions(v, NULL, &monitor, &error_fatal);
+                visit_free(v);
+
+                /* TODO Catch duplicate monitor IDs */
+                monitor_init(monitor, false, &error_fatal);
+                qapi_free_MonitorOptions(monitor);
+                break;
+            }
+        case OPTION_NBD_SERVER:
+            {
+                Visitor *v;
+                NbdServerOptions *options;
+
+                v = qobject_input_visitor_new_str(optarg, NULL, &error_fatal);
+                visit_type_NbdServerOptions(v, NULL, &options, &error_fatal);
+                visit_free(v);
+
+                nbd_server_start_options(options, &error_fatal);
+                qapi_free_NbdServerOptions(options);
+                break;
+            }
+        case OPTION_OBJECT:
+            {
+                QemuOpts *opts;
+                const char *type;
+                QDict *args;
+                QObject *ret_data = NULL;
+
+                /* FIXME The keyval parser rejects 'help' arguments, so we must
+                 * unconditionall try QemuOpts first. */
+                opts = qemu_opts_parse(&qemu_object_opts,
+                                       optarg, true, &error_fatal);
+                type = qemu_opt_get(opts, "qom-type");
+                if (type && user_creatable_print_help(type, opts)) {
+                    exit(EXIT_SUCCESS);
+                }
+                qemu_opts_del(opts);
+
+                args = keyval_parse(optarg, "qom-type", &error_fatal);
+                qmp_object_add(args, &ret_data, &error_fatal);
+                qobject_unref(args);
+                qobject_unref(ret_data);
+                break;
+            }
+        default:
+            g_assert_not_reached();
+        }
+    }
+    if (optind != argc) {
+        error_report("Unexpected argument: %s", argv[optind]);
+        exit(EXIT_FAILURE);
+    }
+}
+
+int main(int argc, char *argv[])
+{
+#ifdef CONFIG_POSIX
+    signal(SIGPIPE, SIG_IGN);
+#endif
+
+    error_init(argv[0]);
+    qemu_init_exec_dir(argv[0]);
+    os_setup_signal_handling();
+
+    module_call_init(MODULE_INIT_QOM);
+    module_call_init(MODULE_INIT_TRACE);
+    qemu_add_opts(&qemu_trace_opts);
+    qcrypto_init(&error_fatal);
+    bdrv_init();
+    monitor_init_globals_core();
+    init_qmp_commands();
+
+    if (!trace_init_backends()) {
+        return EXIT_FAILURE;
+    }
+    qemu_set_log(LOG_TRACE);
+
+    qemu_init_main_loop(&error_fatal);
+    process_options(argc, argv);
+
+    while (!exit_requested) {
+        main_loop_wait(false);
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/qemu-tech.texi b/qemu-tech.texi
deleted file mode 100644 (file)
index 0380de7..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-@node Implementation notes
-@appendix Implementation notes
-
-@menu
-* CPU emulation::
-* Managed start up options::
-@end menu
-
-@node CPU emulation
-@section CPU emulation
-
-@menu
-* x86::     x86 and x86-64 emulation
-* ARM::     ARM emulation
-* MIPS::    MIPS emulation
-* PPC::     PowerPC emulation
-* SPARC::   Sparc32 and Sparc64 emulation
-* Xtensa::  Xtensa emulation
-@end menu
-
-@node x86
-@subsection x86 and x86-64 emulation
-
-QEMU x86 target features:
-
-@itemize
-
-@item The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation.
-LDT/GDT and IDT are emulated. VM86 mode is also supported to run
-DOSEMU. There is some support for MMX/3DNow!, SSE, SSE2, SSE3, SSSE3,
-and SSE4 as well as x86-64 SVM.
-
-@item Support of host page sizes bigger than 4KB in user mode emulation.
-
-@item QEMU can emulate itself on x86.
-
-@item An extensive Linux x86 CPU test program is included @file{tests/test-i386}.
-It can be used to test other x86 virtual CPUs.
-
-@end itemize
-
-Current QEMU limitations:
-
-@itemize
-
-@item Limited x86-64 support.
-
-@item IPC syscalls are missing.
-
-@item The x86 segment limits and access rights are not tested at every
-memory access (yet). Hopefully, very few OSes seem to rely on that for
-normal use.
-
-@end itemize
-
-@node ARM
-@subsection ARM emulation
-
-@itemize
-
-@item Full ARM 7 user emulation.
-
-@item NWFPE FPU support included in user Linux emulation.
-
-@item Can run most ARM Linux binaries.
-
-@end itemize
-
-@node MIPS
-@subsection MIPS emulation
-
-@itemize
-
-@item The system emulation allows full MIPS32/MIPS64 Release 2 emulation,
-including privileged instructions, FPU and MMU, in both little and big
-endian modes.
-
-@item The Linux userland emulation can run many 32 bit MIPS Linux binaries.
-
-@end itemize
-
-Current QEMU limitations:
-
-@itemize
-
-@item Self-modifying code is not always handled correctly.
-
-@item 64 bit userland emulation is not implemented.
-
-@item The system emulation is not complete enough to run real firmware.
-
-@item The watchpoint debug facility is not implemented.
-
-@end itemize
-
-@node PPC
-@subsection PowerPC emulation
-
-@itemize
-
-@item Full PowerPC 32 bit emulation, including privileged instructions,
-FPU and MMU.
-
-@item Can run most PowerPC Linux binaries.
-
-@end itemize
-
-@node SPARC
-@subsection Sparc32 and Sparc64 emulation
-
-@itemize
-
-@item Full SPARC V8 emulation, including privileged
-instructions, FPU and MMU. SPARC V9 emulation includes most privileged
-and VIS instructions, FPU and I/D MMU. Alignment is fully enforced.
-
-@item Can run most 32-bit SPARC Linux binaries, SPARC32PLUS Linux binaries and
-some 64-bit SPARC Linux binaries.
-
-@end itemize
-
-Current QEMU limitations:
-
-@itemize
-
-@item IPC syscalls are missing.
-
-@item Floating point exception support is buggy.
-
-@item Atomic instructions are not correctly implemented.
-
-@item There are still some problems with Sparc64 emulators.
-
-@end itemize
-
-@node Xtensa
-@subsection Xtensa emulation
-
-@itemize
-
-@item Core Xtensa ISA emulation, including most options: code density,
-loop, extended L32R, 16- and 32-bit multiplication, 32-bit division,
-MAC16, miscellaneous operations, boolean, FP coprocessor, coprocessor
-context, debug, multiprocessor synchronization,
-conditional store, exceptions, relocatable vectors, unaligned exception,
-interrupts (including high priority and timer), hardware alignment,
-region protection, region translation, MMU, windowed registers, thread
-pointer, processor ID.
-
-@item Not implemented options: data/instruction cache (including cache
-prefetch and locking), XLMI, processor interface. Also options not
-covered by the core ISA (e.g. FLIX, wide branches) are not implemented.
-
-@item Can run most Xtensa Linux binaries.
-
-@item New core configuration that requires no additional instructions
-may be created from overlay with minimal amount of hand-written code.
-
-@end itemize
-
-@node Managed start up options
-@section Managed start up options
-
-In system mode emulation, it's possible to create a VM in a paused state using
-the -S command line option. In this state the machine is completely initialized
-according to command line options and ready to execute VM code but VCPU threads
-are not executing any code. The VM state in this paused state depends on the way
-QEMU was started. It could be in:
-@table @asis
-@item initial state (after reset/power on state)
-@item with direct kernel loading, the initial state could be amended to execute
-code loaded by QEMU in the VM's RAM and with incoming migration
-@item with incoming migration, initial state will by amended with the migrated
-machine state after migration completes.
-@end table
-
-This paused state is typically used by users to query machine state and/or
-additionally configure the machine (by hotplugging devices) in runtime before
-allowing VM code to run.
-
-However, at the -S pause point, it's impossible to configure options that affect
-initial VM creation (like: -smp/-m/-numa ...) or cold plug devices. The
-experimental --preconfig command line option  allows pausing QEMU
-before the initial VM creation, in a ``preconfig'' state, where additional
-queries and configuration can be performed via QMP before moving on to
-the resulting configuration startup. In the preconfig state, QEMU only allows
-a limited set of commands over the QMP monitor, where the commands do not
-depend on an initialized machine, including but not limited to:
-@table @asis
-@item qmp_capabilities
-@item query-qmp-schema
-@item query-commands
-@item query-status
-@item x-exit-preconfig
-@end table
index 0c29ba359cd6ccf5edead774e71f3134421f36e1..1a0112265b073d1be03d2b00529975a33129dd0f 100644 (file)
--- a/qemu.nsi
+++ b/qemu.nsi
@@ -177,9 +177,20 @@ SectionEnd
 !ifdef CONFIG_DOCUMENTATION
 Section "Documentation" SectionDoc
     SetOutPath "$INSTDIR"
-    File "${BINDIR}\qemu-doc.html"
+    File "${BINDIR}\index.html"
+    SetOutPath "$INSTDIR\interop"
+    FILE /r "${BINDIR}\interop\*.*"
+    SetOutPath "$INSTDIR\specs"
+    FILE /r "${BINDIR}\specs\*.*"
+    SetOutPath "$INSTDIR\system"
+    FILE /r "${BINDIR}\system\*.*"
+    SetOutPath "$INSTDIR\tools"
+    FILE /r "${BINDIR}\tools\*.*"
+    SetOutPath "$INSTDIR\user"
+    FILE /r "${BINDIR}\user\*.*"
+    SetOutPath "$INSTDIR"
     CreateDirectory "$SMPROGRAMS\${PRODUCT}"
-    CreateShortCut "$SMPROGRAMS\${PRODUCT}\User Documentation.lnk" "$INSTDIR\qemu-doc.html" "" "$INSTDIR\qemu-doc.html" 0
+    CreateShortCut "$SMPROGRAMS\${PRODUCT}\User Documentation.lnk" "$INSTDIR\index.html" "" "$INSTDIR\index.html" 0
 SectionEnd
 !endif
 
@@ -227,7 +238,12 @@ Section "Uninstall"
     Delete "$INSTDIR\qemu-io.exe"
     Delete "$INSTDIR\qemu.exe"
     Delete "$INSTDIR\qemu-system-*.exe"
-    Delete "$INSTDIR\qemu-doc.html"
+    Delete "$INSTDIR\index.html"
+    RMDir /r "$INSTDIR\interop"
+    RMDir /r "$INSTDIR\specs"
+    RMDir /r "$INSTDIR\system"
+    RMDir /r "$INSTDIR\tools"
+    RMDir /r "$INSTDIR\user"
     RMDir /r "$INSTDIR\keymaps"
     RMDir /r "$INSTDIR\share"
     ; Remove generated files
index c86f4388dbc3a1a33727be76e3f566984ec982a5..4f04868a763472c2bee532995aa44e871a741ea9 100644 (file)
@@ -302,13 +302,14 @@ static gboolean ga_channel_open(GAChannel *c, GAChannelMethod method,
                            OPEN_EXISTING,
                            FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL);
     if (c->handle == INVALID_HANDLE_VALUE) {
-        g_critical("error opening path %s: %s", newpath,
-                   g_win32_error_message(GetLastError()));
+        g_autofree gchar *emsg = g_win32_error_message(GetLastError());
+        g_critical("error opening path %s: %s", newpath, emsg);
         return false;
     }
 
     if (method == GA_CHANNEL_ISA_SERIAL && !SetCommTimeouts(c->handle,&comTimeOut)) {
-        g_critical("error setting timeout for com port: %lu",GetLastError());
+        g_autofree gchar *emsg = g_win32_error_message(GetLastError());
+        g_critical("error setting timeout for com port: %s", emsg);
         CloseHandle(c->handle);
         return false;
     }
index 2461fd19bf738e48dcb57ff0e52d126cf7adcf82..9c744d6405bb8a012092dda660ffd117aef701b3 100644 (file)
@@ -315,8 +315,9 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp)
     }
 
     if (!ExitWindowsEx(shutdown_flag, SHTDN_REASON_FLAG_PLANNED)) {
-        slog("guest-shutdown failed: %lu", GetLastError());
-        error_setg(errp, QERR_UNDEFINED_ERROR);
+        g_autofree gchar *emsg = g_win32_error_message(GetLastError());
+        slog("guest-shutdown failed: %s", emsg);
+        error_setg_win32(errp, GetLastError(), "guest-shutdown failed");
     }
 }
 
@@ -1319,7 +1320,8 @@ static DWORD WINAPI do_suspend(LPVOID opaque)
     DWORD ret = 0;
 
     if (!SetSuspendState(*mode == GUEST_SUSPEND_MODE_DISK, TRUE, TRUE)) {
-        slog("failed to suspend guest, %lu", GetLastError());
+        g_autofree gchar *emsg = g_win32_error_message(GetLastError());
+        slog("failed to suspend guest: %s", emsg);
         ret = -1;
     }
     g_free(mode);
index f9d77350ace9ce18656320451ff4f8593fe4b3ef..1b45d104ba64971f1f2e5d1441693344849f866c 100644 (file)
@@ -2,3 +2,4 @@ qom-obj-y = object.o container.o qom-qobject.o
 qom-obj-y += object_interfaces.o
 
 common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o
+storage-daemon-obj-y += qom-qmp-cmds.o
index 6136efec16f85381c1cbc001ac84f2f2ba3c11bf..49db926fcc41ce70caf3e4c5f7eaa343d149a400 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "block/qdict.h"
 #include "hw/qdev-core.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-qdev.h"
@@ -240,13 +241,34 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
     return prop_list;
 }
 
-void qmp_object_add(const char *type, const char *id,
-                    bool has_props, QObject *props, Error **errp)
+void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
 {
+    QObject *props;
     QDict *pdict;
     Visitor *v;
     Object *obj;
+    const char *type;
+    const char *id;
 
+    type = qdict_get_try_str(qdict, "qom-type");
+    if (!type) {
+        error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
+        return;
+    } else {
+        type = g_strdup(type);
+        qdict_del(qdict, "qom-type");
+    }
+
+    id = qdict_get_try_str(qdict, "id");
+    if (!id) {
+        error_setg(errp, QERR_MISSING_PARAMETER, "id");
+        return;
+    } else {
+        id = g_strdup(id);
+        qdict_del(qdict, "id");
+    }
+
+    props = qdict_get(qdict, "props");
     if (props) {
         pdict = qobject_to(QDict, props);
         if (!pdict) {
@@ -254,17 +276,23 @@ void qmp_object_add(const char *type, const char *id,
             return;
         }
         qobject_ref(pdict);
-    } else {
-        pdict = qdict_new();
+        qdict_del(qdict, "props");
+        qdict_join(qdict, pdict, false);
+        if (qdict_size(pdict) != 0) {
+            error_setg(errp, "Option in 'props' conflicts with top level");
+            qobject_unref(pdict);
+            return;
+        }
+        qobject_unref(pdict);
     }
 
-    v = qobject_input_visitor_new(QOBJECT(pdict));
-    obj = user_creatable_add_type(type, id, pdict, v, errp);
+    v = qobject_input_visitor_new(QOBJECT(qdict));
+    obj = user_creatable_add_type(type, id, qdict, v, errp);
     visit_free(v);
     if (obj) {
         object_unref(obj);
     }
-    qobject_unref(pdict);
+    *ret_data = QOBJECT(qdict_new());
 }
 
 void qmp_object_del(const char *id, Error **errp)
diff --git a/qtest.c b/qtest.c
index 1af4e1b08ddf5715948ac7adda46929264871c34..5672b75c354b6cdae5df0b0d49e0ba9da0b13faf 100644 (file)
--- a/qtest.c
+++ b/qtest.c
@@ -794,7 +794,8 @@ void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **
     }
 }
 
-void qtest_server_set_send_handler(void (*send)(void*, const char*), void *opaque)
+void qtest_server_set_send_handler(void (*send)(void*, const char*),
+                                   void *opaque)
 {
     qtest_server_send = send;
     qtest_server_send_opaque = opaque;
index e39b073d4648a230c5749d3d53eadc09d6755c8f..694865b63ee84f8b3e28f9b3bb233abb4015cd00 100644 (file)
--- a/rules.mak
+++ b/rules.mak
@@ -435,3 +435,6 @@ sentinel = .$(subst $(SPACE),_,$(subst /,_,$1)).sentinel.
 atomic = $(eval $1: $(call sentinel,$1) ; @:) \
          $(call sentinel,$1) : $2 ; @touch $$@ \
          $(foreach t,$1,$(if $(wildcard $t),,$(shell rm -f $(call sentinel,$1))))
+
+print-%:
+       @echo '$*=$($*)'
index 7cf22e0bf546dc679b748e239bd64b7abd8ec165..73fd818d7f3ee19a7a79c93221fcd4ddf026dbfd 100644 (file)
@@ -11,6 +11,7 @@
 
 # Documentation
 docs/*
+*.rst
 *.texi
 
 # build system
index 0003e7b673db0da36e82d4f6b46511ae07f67065..7b1452f3cf1588cc8fd4053f53dc733adb99b52b 100644 (file)
@@ -7,7 +7,7 @@ hxtoh()
         case $str in
             HXCOMM*)
             ;;
-            STEXI*|ETEXI*|SRST*|ERST*) flag=$(($flag^1))
+            SRST*|ERST*) flag=$(($flag^1))
             ;;
             *)
             test $flag -eq 1 && printf "%s\n" "$str"
@@ -16,84 +16,8 @@ hxtoh()
     done
 }
 
-print_texi_heading()
-{
-    if test "$*" != ""; then
-        title="$*"
-        printf "@subsection %s\n" "${title%:}"
-    fi
-}
-
-hxtotexi()
-{
-    flag=0
-    rstflag=0
-    line=1
-    while read -r str; do
-        case "$str" in
-            HXCOMM*)
-            ;;
-            STEXI*)
-            if test $rstflag -eq 1 ; then
-                printf "line %d: syntax error: expected ERST, found '%s'\n" "$line" "$str" >&2
-                exit 1
-            fi
-            if test $flag -eq 1 ; then
-                printf "line %d: syntax error: expected ETEXI, found '%s'\n" "$line" "$str" >&2
-                exit 1
-            fi
-            flag=1
-            ;;
-            ETEXI*)
-            if test $rstflag -eq 1 ; then
-                printf "line %d: syntax error: expected ERST, found '%s'\n" "$line" "$str" >&2
-                exit 1
-            fi
-            if test $flag -ne 1 ; then
-                printf "line %d: syntax error: expected STEXI, found '%s'\n" "$line" "$str" >&2
-                exit 1
-            fi
-            flag=0
-            ;;
-            SRST*)
-            if test $rstflag -eq 1 ; then
-                printf "line %d: syntax error: expected ERST, found '%s'\n" "$line" "$str" >&2
-                exit 1
-            fi
-            if test $flag -eq 1 ; then
-                printf "line %d: syntax error: expected ETEXI, found '%s'\n" "$line" "$str" >&2
-                exit 1
-            fi
-            rstflag=1
-            ;;
-            ERST*)
-            if test $flag -eq 1 ; then
-                printf "line %d: syntax error: expected ETEXI, found '%s'\n" "$line" "$str" >&2
-                exit 1
-            fi
-            if test $rstflag -ne 1 ; then
-                printf "line %d: syntax error: expected SRST, found '%s'\n" "$line" "$str" >&2
-                exit 1
-            fi
-            rstflag=0
-            ;;
-            DEFHEADING*)
-            print_texi_heading "$(expr "$str" : "DEFHEADING(\(.*\))")"
-            ;;
-            ARCHHEADING*)
-            print_texi_heading "$(expr "$str" : "ARCHHEADING(\(.*\),.*)")"
-            ;;
-            *)
-            test $flag -eq 1 && printf '%s\n' "$str"
-            ;;
-        esac
-        line=$((line+1))
-    done
-}
-
 case "$1" in
 "-h") hxtoh ;;
-"-t") hxtotexi ;;
 *) exit 1 ;;
 esac
 
diff --git a/scripts/hxtool-conv.pl b/scripts/hxtool-conv.pl
new file mode 100755 (executable)
index 0000000..eede40b
--- /dev/null
@@ -0,0 +1,137 @@
+#!/usr/bin/perl -w
+#
+# Script to convert .hx file STEXI/ETEXI blocks to SRST/ERST
+#
+# Copyright (C) 2020 Linaro
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# (at your option) any later version. See the COPYING file in the
+# top-level directory.
+
+# This script was only ever intended as a one-off conversion operation.
+# Please excuse the places where it is a bit hacky.
+# Some manual intervention after the conversion is expected, as are
+# some warnings from makeinfo.
+# Warning: this script is not idempotent: don't try to run it on
+# a .hx file that already has SRST/ERST sections.
+
+# Expected usage:
+# scripts/hxtool-conv.pl file.hx > file.hx.new
+
+use utf8;
+
+my $reading_texi = 0;
+my $texiblock = '';
+my @tables = ();
+
+sub update_tables($) {
+    my ($texi) = @_;
+    # Update our list of open table directives: every @table
+    # line in the texi fragment is added to the list, and every
+    # @end table line means we remove an entry from the list.
+    # If this fragment had a completely self contained table with
+    # both the @table and @end table lines, this will be a no-op.
+    foreach (split(/\n/, $texi)) {
+        push @tables, $_ if /^\@table/;
+        pop @tables if /^\@end table/;
+    }
+}
+
+sub only_table_directives($) {
+    # Return true if every line in the fragment is a start or end table directive
+    my ($texi) = @_;
+    foreach (split(/\n/, $texi)) {
+        return 0 unless /^\@table/ or /^\@end table/;
+    }
+    return 1;
+}
+
+sub output_rstblock($) {
+    # Write the output to /tmp/frag.texi, wrapped in whatever current @table
+    # lines we need.
+    my ($texi) = @_;
+
+    # As a special case, if this fragment is only table directives and
+    # nothing else, update our set of open table directives but otherwise
+    # ignore it. This avoids emitting an empty SRST/ERST block.
+    if (only_table_directives($texi)) {
+        update_tables($texi);
+        return;
+    }
+
+    open(my $fragfh, '>', '/tmp/frag.texi');
+    # First output the currently active set of open table directives
+    print $fragfh join("\n", @tables);
+    # Next, update our list of open table directives.
+    # We need to do this before we emit the closing table directives
+    # so that we emit the right number if this fragment had an
+    # unbalanced set of directives.
+    update_tables($texi);
+    # Then emit the texi fragment itself.
+    print $fragfh "\n$texi\n";
+    # Finally, add the necessary closing table directives.
+    print $fragfh "\@end table\n" x scalar @tables;
+    close $fragfh;
+
+    # Now invoke makeinfo/pandoc on it and slurp the results into a string
+    open(my $fh, '-|', "makeinfo --force -o - --docbook "
+         . "-D 'qemu_system_x86 QEMU_SYSTEM_X86_MACRO' "
+         . "-D 'qemu_system     QEMU_SYSTEM_MACRO'  /tmp/frag.texi "
+         . " | pandoc  -f docbook -t rst")
+        or die "can't start makeinfo/pandoc: $!";
+
+    binmode $fh, ':encoding(utf8)';
+
+    print "SRST\n";
+
+    # Slurp the whole thing into a string so we can do multiline
+    # string matches on it.
+    my $rst = do {
+        local $/ = undef;
+        <$fh>;
+    };
+    $rst =~ s/^-  − /-  /gm;
+    $rst =~ s/“/"/gm;
+    $rst =~ s/”/"/gm;
+    $rst =~ s/‘/'/gm;
+    $rst =~ s/’/'/gm;
+    $rst =~ s/QEMU_SYSTEM_MACRO/|qemu_system|/g;
+    $rst =~ s/QEMU_SYSTEM_X86_MACRO/|qemu_system_x86|/g;
+    $rst =~ s/(?=::\n\n +\|qemu)/.. parsed-literal/g;
+    $rst =~ s/:\n\n::$/::/gm;
+
+    # Fix up the invalid reference format makeinfo/pandoc emit:
+    # `Some string here <#anchorname>`__
+    # should be:
+    # :ref:`anchorname`
+    $rst =~ s/\`[^<`]+\<\#([^>]+)\>\`__/:ref:`$1`/gm;
+    print $rst;
+
+    close $fh or die "error on close: $!";
+    print "ERST\n";
+}
+
+# Read the whole .hx input file.
+while (<>) {
+    # Always print the current line
+    print;
+    if (/STEXI/) {
+        $reading_texi = 1;
+        $texiblock = '';
+        next;
+    }
+    if (/ETEXI/) {
+        $reading_texi = 0;
+        # dump RST version of block
+        output_rstblock($texiblock);
+        next;
+    }
+    if ($reading_texi) {
+        # Accumulate the texi into a string
+        # but drop findex entries as they will confuse makeinfo
+        next if /^\@findex/;
+        $texiblock .= $_;
+    }
+}
+
+die "Unexpectedly still in texi block at EOF" if $reading_texi;
index afa55b055c9c724d7b076ac7c512dc280469dd3c..0e13e82989964fbd3289e79d98e033f36613b590 100644 (file)
@@ -237,8 +237,8 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
 class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
 
     def __init__(self, prefix):
-        QAPISchemaModularCVisitor.__init__(
-            self, prefix, 'qapi-commands',
+        super().__init__(
+            prefix, 'qapi-commands',
             ' * Schema-defined QAPI/QMP commands', None, __doc__)
         self._regy = QAPIGenCCode(None)
         self._visited_ret_types = {}
@@ -274,7 +274,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
 
 void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
 ''',
-                       c_prefix=c_name(self._prefix, protect=False)))
+                             c_prefix=c_name(self._prefix, protect=False)))
         self._genc.preamble_add(mcgen('''
 #include "qemu/osdep.h"
 #include "%(prefix)sqapi-commands.h"
index e00dcafce7705cc81e5e22d1269245a8df3ef120..ba35abea478e1647da077a2699bbf7455cead2f9 100644 (file)
@@ -12,7 +12,6 @@
 # See the COPYING file in the top-level directory.
 
 import re
-import string
 
 
 # ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
@@ -43,10 +42,7 @@ def c_enum_const(type_name, const_name, prefix=None):
     return camel_to_upper(type_name) + '_' + c_name(const_name, False).upper()
 
 
-if hasattr(str, 'maketrans'):
-    c_name_trans = str.maketrans('.-', '__')
-else:
-    c_name_trans = string.maketrans('.-', '__')
+c_name_trans = str.maketrans('.-', '__')
 
 
 # Map @name to a valid C identifier.
index b9f3751bea47f61a0b1c43d0450d64a15134e450..ae60d9e2fe8166f82e4601da3d70e599529b5ba0 100644 (file)
@@ -35,9 +35,9 @@ class QAPIParseError(QAPIError):
                 col = (col + 7) % 8 + 1
             else:
                 col += 1
-        QAPIError.__init__(self, parser.info, col, msg)
+        super().__init__(parser.info, col, msg)
 
 
 class QAPISemError(QAPIError):
     def __init__(self, info, msg):
-        QAPIError.__init__(self, info, None, msg)
+        super().__init__(info, None, msg)
index 2bde3e61288006d9bbbdb83b3f418c367258ce0f..a98b9f5099b0e007dc88c825c88fa21977147f62 100644 (file)
@@ -138,8 +138,8 @@ def gen_event_send(name, arg_type, boxed, event_enum_name, event_emit):
 class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
 
     def __init__(self, prefix):
-        QAPISchemaModularCVisitor.__init__(
-            self, prefix, 'qapi-events',
+        super().__init__(
+            prefix, 'qapi-events',
             ' * Schema-defined QAPI/QMP events', None, __doc__)
         self._event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
         self._event_enum_members = []
index d7a289eded62ec7eb67626152823ecd9b98c131e..fecf466fa7c61c4c1340f42c03625deb41f484bd 100644 (file)
@@ -35,7 +35,6 @@ def check_name_is_str(name, info, source):
 def check_name_str(name, info, source,
                    allow_optional=False, enum_member=False,
                    permit_upper=False):
-    global valid_name
     membername = name
 
     if allow_optional and name.startswith('*'):
@@ -249,7 +248,7 @@ def check_union(expr, info):
 def check_alternate(expr, info):
     members = expr['data']
 
-    if len(members) == 0:
+    if not members:
         raise QAPISemError(info, "'data' must not be empty")
     for (key, value) in members.items():
         source = "'data' member '%s'" % key
index 95afae0615af1d23f0a50fa3d730bf135b74cff7..bf5552a4e7f279c46924120fd157271b24d1c98b 100644 (file)
 import errno
 import os
 import re
-import sys
 from contextlib import contextmanager
 
 from qapi.common import *
 from qapi.schema import QAPISchemaVisitor
 
 
-class QAPIGen(object):
+class QAPIGen:
 
     def __init__(self, fname):
         self.fname = fname
@@ -45,19 +44,21 @@ class QAPIGen(object):
         return ''
 
     def write(self, output_dir):
+        # Include paths starting with ../ are used to reuse modules of the main
+        # schema in specialised schemas. Don't overwrite the files that are
+        # already generated for the main schema.
+        if self.fname.startswith('../'):
+            return
         pathname = os.path.join(output_dir, self.fname)
-        dir = os.path.dirname(pathname)
-        if dir:
+        odir = os.path.dirname(pathname)
+        if odir:
             try:
-                os.makedirs(dir)
+                os.makedirs(odir)
             except os.error as e:
                 if e.errno != errno.EEXIST:
                     raise
         fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0o666)
-        if sys.version_info[0] >= 3:
-            f = open(fd, 'r+', encoding='utf-8')
-        else:
-            f = os.fdopen(fd, 'r+')
+        f = open(fd, 'r+', encoding='utf-8')
         text = self.get_content()
         oldtext = f.read(len(text) + 1)
         if text != oldtext:
@@ -86,7 +87,7 @@ def _wrap_ifcond(ifcond, before, after):
 class QAPIGenCCode(QAPIGen):
 
     def __init__(self, fname):
-        QAPIGen.__init__(self, fname)
+        super().__init__(fname)
         self._start_if = None
 
     def start_if(self, ifcond):
@@ -106,13 +107,13 @@ class QAPIGenCCode(QAPIGen):
 
     def get_content(self):
         assert self._start_if is None
-        return QAPIGen.get_content(self)
+        return super().get_content()
 
 
 class QAPIGenC(QAPIGenCCode):
 
     def __init__(self, fname, blurb, pydoc):
-        QAPIGenCCode.__init__(self, fname)
+        super().__init__(fname)
         self._blurb = blurb
         self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
                                                   re.MULTILINE))
@@ -145,7 +146,7 @@ char qapi_dummy_%(name)s;
 class QAPIGenH(QAPIGenC):
 
     def _top(self):
-        return QAPIGenC._top(self) + guardstart(self.fname)
+        return super()._top() + guardstart(self.fname)
 
     def _bottom(self):
         return guardend(self.fname)
@@ -180,7 +181,7 @@ def ifcontext(ifcond, *args):
 class QAPIGenDoc(QAPIGen):
 
     def _top(self):
-        return (QAPIGen._top(self)
+        return (super()._top()
                 + '@c AUTOMATICALLY GENERATED, DO NOT MODIFY\n\n')
 
 
@@ -265,6 +266,9 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor):
             genc.write(output_dir)
             genh.write(output_dir)
 
+    def _begin_system_module(self, name):
+        pass
+
     def _begin_user_module(self, name):
         pass
 
index b3a463dd8b8423bdf16dd81587350cec0e159701..b5537eddc0d989bf1d34dbe79207ea9854d37b17 100644 (file)
@@ -10,8 +10,6 @@ This work is licensed under the terms of the GNU GPL, version 2.
 See the COPYING file in the top-level directory.
 """
 
-import string
-
 from qapi.common import *
 from qapi.gen import QAPISchemaMonolithicCVisitor
 from qapi.schema import (QAPISchemaArrayType, QAPISchemaBuiltinType,
@@ -76,8 +74,8 @@ def to_c_string(string):
 class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
 
     def __init__(self, prefix, unmask):
-        QAPISchemaMonolithicCVisitor.__init__(
-            self, prefix, 'qapi-introspect',
+        super().__init__(
+            prefix, 'qapi-introspect',
             ' * QAPI/QMP schema introspection', __doc__)
         self._unmask = unmask
         self._schema = None
index 342792e4103c351268b10fbb0624d0db7ade5834..abadacbb0e8b43f06e9c5d3e949e1796f0b00751 100644 (file)
 
 import os
 import re
-import sys
 from collections import OrderedDict
 
 from qapi.error import QAPIParseError, QAPISemError
 from qapi.source import QAPISourceInfo
 
 
-class QAPISchemaParser(object):
+class QAPISchemaParser:
 
     def __init__(self, fname, previously_included=None, incl_info=None):
         previously_included = previously_included or set()
         previously_included.add(os.path.abspath(fname))
 
         try:
-            if sys.version_info[0] >= 3:
-                fp = open(fname, 'r', encoding='utf-8')
-            else:
-                fp = open(fname, 'r')
+            fp = open(fname, 'r', encoding='utf-8')
             self.src = fp.read()
         except IOError as e:
             raise QAPISemError(incl_info or QAPISourceInfo(None, None, None),
@@ -286,14 +282,13 @@ class QAPISchemaParser(object):
                 doc.end_comment()
                 self.accept()
                 return doc
-            else:
-                doc.append(self.val)
+            doc.append(self.val)
             self.accept(False)
 
         raise QAPIParseError(self, "documentation comment must end with '##'")
 
 
-class QAPIDoc(object):
+class QAPIDoc:
     """
     A documentation comment block, either definition or free-form
 
@@ -312,7 +307,7 @@ class QAPIDoc(object):
     Free-form documentation blocks consist only of a body section.
     """
 
-    class Section(object):
+    class Section:
         def __init__(self, name=None):
             # optional section name (argument/member or section name)
             self.name = name
@@ -324,7 +319,7 @@ class QAPIDoc(object):
 
     class ArgSection(Section):
         def __init__(self, name):
-            QAPIDoc.Section.__init__(self, name)
+            super().__init__(name)
             self.member = None
 
         def connect(self, member):
@@ -496,7 +491,7 @@ class QAPIDoc(object):
             raise QAPIParseError(self._parser,
                                  "'%s' can't follow '%s' section"
                                  % (name, self.sections[0].name))
-        elif self._is_section_tag(name):
+        if self._is_section_tag(name):
             line = line[len(name)+1:]
             self._start_section(name[:-1])
 
@@ -560,7 +555,6 @@ class QAPIDoc(object):
             raise QAPISemError(feature.info,
                                "feature '%s' lacks documentation"
                                % feature.name)
-            self.features[feature.name] = QAPIDoc.ArgSection(feature.name)
         self.features[feature.name].connect(feature)
 
     def check_expr(self, expr):
index 5100110fa2dee17f1777cb6ae795c6ac621003d2..d759308b4e7d4220893ffe5069f88f31f7a86073 100644 (file)
@@ -19,12 +19,12 @@ import re
 from collections import OrderedDict
 
 from qapi.common import c_name, pointer_suffix
-from qapi.error import QAPIError, QAPIParseError, QAPISemError
+from qapi.error import QAPIError, QAPISemError
 from qapi.expr import check_exprs
 from qapi.parser import QAPISchemaParser
 
 
-class QAPISchemaEntity(object):
+class QAPISchemaEntity:
     meta = None
 
     def __init__(self, name, info, doc, ifcond=None, features=None):
@@ -89,21 +89,21 @@ class QAPISchemaEntity(object):
         return "%s '%s'" % (self.meta, self.name)
 
 
-class QAPISchemaVisitor(object):
+class QAPISchemaVisitor:
     def visit_begin(self, schema):
         pass
 
     def visit_end(self):
         pass
 
-    def visit_module(self, fname):
+    def visit_module(self, name):
         pass
 
     def visit_needed(self, entity):
         # Default to visiting everything
         return True
 
-    def visit_include(self, fname, info):
+    def visit_include(self, name, info):
         pass
 
     def visit_builtin_type(self, name, info, json_type):
@@ -135,7 +135,7 @@ class QAPISchemaVisitor(object):
         pass
 
 
-class QAPISchemaModule(object):
+class QAPISchemaModule:
     def __init__(self, name):
         self.name = name
         self._entity_list = []
@@ -152,11 +152,11 @@ class QAPISchemaModule(object):
 
 class QAPISchemaInclude(QAPISchemaEntity):
     def __init__(self, sub_module, info):
-        QAPISchemaEntity.__init__(self, None, info, None)
+        super().__init__(None, info, None)
         self._sub_module = sub_module
 
     def visit(self, visitor):
-        QAPISchemaEntity.visit(self, visitor)
+        super().visit(visitor)
         visitor.visit_include(self._sub_module.name, self.info)
 
 
@@ -202,7 +202,7 @@ class QAPISchemaBuiltinType(QAPISchemaType):
     meta = 'built-in'
 
     def __init__(self, name, json_type, c_type):
-        QAPISchemaType.__init__(self, name, None, None)
+        super().__init__(name, None, None)
         assert not c_type or isinstance(c_type, str)
         assert json_type in ('string', 'number', 'int', 'boolean', 'null',
                              'value')
@@ -227,7 +227,7 @@ class QAPISchemaBuiltinType(QAPISchemaType):
         return self.json_type()
 
     def visit(self, visitor):
-        QAPISchemaType.visit(self, visitor)
+        super().visit(visitor)
         visitor.visit_builtin_type(self.name, self.info, self.json_type())
 
 
@@ -235,7 +235,7 @@ class QAPISchemaEnumType(QAPISchemaType):
     meta = 'enum'
 
     def __init__(self, name, info, doc, ifcond, members, prefix):
-        QAPISchemaType.__init__(self, name, info, doc, ifcond)
+        super().__init__(name, info, doc, ifcond)
         for m in members:
             assert isinstance(m, QAPISchemaEnumMember)
             m.set_defined_in(name)
@@ -244,7 +244,7 @@ class QAPISchemaEnumType(QAPISchemaType):
         self.prefix = prefix
 
     def check(self, schema):
-        QAPISchemaType.check(self, schema)
+        super().check(schema)
         seen = {}
         for m in self.members:
             m.check_clash(self.info, seen)
@@ -269,7 +269,7 @@ class QAPISchemaEnumType(QAPISchemaType):
         return 'string'
 
     def visit(self, visitor):
-        QAPISchemaType.visit(self, visitor)
+        super().visit(visitor)
         visitor.visit_enum_type(self.name, self.info, self.ifcond,
                                 self.members, self.prefix)
 
@@ -278,13 +278,13 @@ class QAPISchemaArrayType(QAPISchemaType):
     meta = 'array'
 
     def __init__(self, name, info, element_type):
-        QAPISchemaType.__init__(self, name, info, None, None)
+        super().__init__(name, info, None, None)
         assert isinstance(element_type, str)
         self._element_type_name = element_type
         self.element_type = None
 
     def check(self, schema):
-        QAPISchemaType.check(self, schema)
+        super().check(schema)
         self.element_type = schema.resolve_type(
             self._element_type_name, self.info,
             self.info and self.info.defn_meta)
@@ -314,7 +314,7 @@ class QAPISchemaArrayType(QAPISchemaType):
         return 'array of ' + elt_doc_type
 
     def visit(self, visitor):
-        QAPISchemaType.visit(self, visitor)
+        super().visit(visitor)
         visitor.visit_array_type(self.name, self.info, self.ifcond,
                                  self.element_type)
 
@@ -329,7 +329,7 @@ class QAPISchemaObjectType(QAPISchemaType):
         # struct has local_members, optional base, and no variants
         # flat union has base, variants, and no local_members
         # simple union has local_members, variants, and no base
-        QAPISchemaType.__init__(self, name, info, doc, ifcond, features)
+        super().__init__(name, info, doc, ifcond, features)
         self.meta = 'union' if variants else 'struct'
         assert base is None or isinstance(base, str)
         for m in local_members:
@@ -356,7 +356,7 @@ class QAPISchemaObjectType(QAPISchemaType):
             raise QAPISemError(self.info,
                                "object %s contains itself" % self.name)
 
-        QAPISchemaType.check(self, schema)
+        super().check(schema)
         assert self._checked and self.members is None
 
         seen = OrderedDict()
@@ -419,7 +419,7 @@ class QAPISchemaObjectType(QAPISchemaType):
 
     def c_name(self):
         assert self.name != 'q_empty'
-        return QAPISchemaType.c_name(self)
+        return super().c_name()
 
     def c_type(self):
         assert not self.is_implicit()
@@ -432,7 +432,7 @@ class QAPISchemaObjectType(QAPISchemaType):
         return 'object'
 
     def visit(self, visitor):
-        QAPISchemaType.visit(self, visitor)
+        super().visit(visitor)
         visitor.visit_object_type(self.name, self.info, self.ifcond,
                                   self.base, self.local_members, self.variants,
                                   self.features)
@@ -441,7 +441,7 @@ class QAPISchemaObjectType(QAPISchemaType):
                                        self.features)
 
 
-class QAPISchemaMember(object):
+class QAPISchemaMember:
     """ Represents object members, enum members and features """
     role = 'member'
 
@@ -506,7 +506,7 @@ class QAPISchemaFeature(QAPISchemaMember):
 
 class QAPISchemaObjectTypeMember(QAPISchemaMember):
     def __init__(self, name, info, typ, optional, ifcond=None):
-        QAPISchemaMember.__init__(self, name, info, ifcond)
+        super().__init__(name, info, ifcond)
         assert isinstance(typ, str)
         assert isinstance(optional, bool)
         self._type_name = typ
@@ -519,7 +519,7 @@ class QAPISchemaObjectTypeMember(QAPISchemaMember):
                                         self.describe)
 
 
-class QAPISchemaObjectTypeVariants(object):
+class QAPISchemaObjectTypeVariants:
     def __init__(self, tag_name, info, tag_member, variants):
         # Flat unions pass tag_name but not tag_member.
         # Simple unions and alternates pass tag_member but not tag_name.
@@ -576,7 +576,7 @@ class QAPISchemaObjectTypeVariants(object):
             assert self.tag_member.ifcond == []
         if self._tag_name:    # flat union
             # branches that are not explicitly covered get an empty type
-            cases = set([v.name for v in self.variants])
+            cases = {v.name for v in self.variants}
             for m in self.tag_member.type.members:
                 if m.name not in cases:
                     v = QAPISchemaObjectTypeVariant(m.name, self.info,
@@ -614,15 +614,14 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
     role = 'branch'
 
     def __init__(self, name, info, typ, ifcond=None):
-        QAPISchemaObjectTypeMember.__init__(self, name, info, typ,
-                                            False, ifcond)
+        super().__init__(name, info, typ, False, ifcond)
 
 
 class QAPISchemaAlternateType(QAPISchemaType):
     meta = 'alternate'
 
     def __init__(self, name, info, doc, ifcond, variants):
-        QAPISchemaType.__init__(self, name, info, doc, ifcond)
+        super().__init__(name, info, doc, ifcond)
         assert isinstance(variants, QAPISchemaObjectTypeVariants)
         assert variants.tag_member
         variants.set_defined_in(name)
@@ -630,7 +629,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
         self.variants = variants
 
     def check(self, schema):
-        QAPISchemaType.check(self, schema)
+        super().check(schema)
         self.variants.tag_member.check(schema)
         # Not calling self.variants.check_clash(), because there's nothing
         # to clash with
@@ -680,7 +679,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
         return 'value'
 
     def visit(self, visitor):
-        QAPISchemaType.visit(self, visitor)
+        super().visit(visitor)
         visitor.visit_alternate_type(self.name, self.info, self.ifcond,
                                      self.variants)
 
@@ -691,7 +690,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
     def __init__(self, name, info, doc, ifcond, arg_type, ret_type,
                  gen, success_response, boxed, allow_oob, allow_preconfig,
                  features):
-        QAPISchemaEntity.__init__(self, name, info, doc, ifcond, features)
+        super().__init__(name, info, doc, ifcond, features)
         assert not arg_type or isinstance(arg_type, str)
         assert not ret_type or isinstance(ret_type, str)
         self._arg_type_name = arg_type
@@ -705,7 +704,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
         self.allow_preconfig = allow_preconfig
 
     def check(self, schema):
-        QAPISchemaEntity.check(self, schema)
+        super().check(schema)
         if self._arg_type_name:
             self.arg_type = schema.resolve_type(
                 self._arg_type_name, self.info, "command's 'data'")
@@ -740,7 +739,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
                 self.arg_type.connect_doc(doc)
 
     def visit(self, visitor):
-        QAPISchemaEntity.visit(self, visitor)
+        super().visit(visitor)
         visitor.visit_command(self.name, self.info, self.ifcond,
                               self.arg_type, self.ret_type,
                               self.gen, self.success_response,
@@ -753,14 +752,14 @@ class QAPISchemaEvent(QAPISchemaEntity):
     meta = 'event'
 
     def __init__(self, name, info, doc, ifcond, arg_type, boxed):
-        QAPISchemaEntity.__init__(self, name, info, doc, ifcond)
+        super().__init__(name, info, doc, ifcond)
         assert not arg_type or isinstance(arg_type, str)
         self._arg_type_name = arg_type
         self.arg_type = None
         self.boxed = boxed
 
     def check(self, schema):
-        QAPISchemaEntity.check(self, schema)
+        super().check(schema)
         if self._arg_type_name:
             self.arg_type = schema.resolve_type(
                 self._arg_type_name, self.info, "event's 'data'")
@@ -782,12 +781,12 @@ class QAPISchemaEvent(QAPISchemaEntity):
                 self.arg_type.connect_doc(doc)
 
     def visit(self, visitor):
-        QAPISchemaEntity.visit(self, visitor)
+        super().visit(visitor)
         visitor.visit_event(self.name, self.info, self.ifcond,
                             self.arg_type, self.boxed)
 
 
-class QAPISchema(object):
+class QAPISchema:
     def __init__(self, fname):
         self.fname = fname
         parser = QAPISchemaParser(fname)
@@ -849,7 +848,7 @@ class QAPISchema(object):
 
     def _make_module(self, fname):
         name = self._module_name(fname)
-        if not name in self._module_dict:
+        if name not in self._module_dict:
             self._module_dict[name] = QAPISchemaModule(name)
         return self._module_dict[name]
 
@@ -1098,7 +1097,6 @@ class QAPISchema(object):
 
     def visit(self, visitor):
         visitor.visit_begin(self)
-        module = None
         for mod in self._module_dict.values():
             mod.visit(visitor)
         visitor.visit_end()
index 8956885033ae7340cfb5c4e462d2199ea6461387..e97b9a8e15ef8892923d4545c62a521cfb86bfb7 100644 (file)
@@ -13,7 +13,7 @@ import copy
 import sys
 
 
-class QAPISchemaPragma(object):
+class QAPISchemaPragma:
     def __init__(self):
         # Are documentation comments required?
         self.doc_required = False
@@ -23,7 +23,7 @@ class QAPISchemaPragma(object):
         self.name_case_whitelist = []
 
 
-class QAPISourceInfo(object):
+class QAPISourceInfo:
     def __init__(self, fname, line, parent):
         self.fname = fname
         self.line = line
index 99dcaf70747cec8151ac08a820fb00a13bcca743..3c83b6e4befa238159191c6c7f2fea11278aa694 100644 (file)
@@ -241,8 +241,8 @@ void qapi_free_%(c_name)s(%(c_name)s *obj)
 class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
 
     def __init__(self, prefix):
-        QAPISchemaModularCVisitor.__init__(
-            self, prefix, 'qapi-types', ' * Schema-defined QAPI types',
+        super().__init__(
+            prefix, 'qapi-types', ' * Schema-defined QAPI types',
             ' * Built-in QAPI types', __doc__)
 
     def _begin_system_module(self, name):
index 4efce62b0c3d89602f3195ffd412ccb270079dd2..421e5bd8cd417d97acd5e3ade9c8bc0598400777 100644 (file)
@@ -283,8 +283,8 @@ out:
 class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
 
     def __init__(self, prefix):
-        QAPISchemaModularCVisitor.__init__(
-            self, prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
+        super().__init__(
+            prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
             ' * Built-in QAPI visitors', __doc__)
 
     def _begin_system_module(self, name):
index 839b7917cf7f8efff3260eb933bd4b423776a51a..8bfc6f6f4c47194889aec0cfe0ab0d76340ca33d 100755 (executable)
@@ -143,6 +143,24 @@ while(<$inf>) {
        next;
     };
 
+    # Single line command handlers.
+
+    /^\@include\s+(.+)$/ and do {
+       push @instack, $inf;
+       $inf = gensym();
+       $file = postprocess($1);
+
+       # Try cwd and $ibase, then explicit -I paths.
+       $done = 0;
+       foreach $path ("", $ibase, @ipath) {
+           $mypath = $file;
+           $mypath = $path . "/" . $mypath if ($path ne "");
+           open($inf, "<" . $mypath) and ($done = 1, last);
+       }
+       die "cannot find $file" if !$done;
+       next;
+    };
+
     next unless $output;
 
     # Discard comments.  (Can't do it above, because then we'd never see
@@ -242,24 +260,6 @@ while(<$inf>) {
        s/>/&GT;/g;
     }
 
-    # Single line command handlers.
-
-    /^\@include\s+(.+)$/ and do {
-       push @instack, $inf;
-       $inf = gensym();
-       $file = postprocess($1);
-
-       # Try cwd and $ibase, then explicit -I paths.
-       $done = 0;
-       foreach $path ("", $ibase, @ipath) {
-           $mypath = $file;
-           $mypath = $path . "/" . $mypath if ($path ne "");
-           open($inf, "<" . $mypath) and ($done = 1, last);
-       }
-       die "cannot find $file" if !$done;
-       next;
-    };
-
     /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/
        and $_ = "\n=head2 $1\n";
     /^\@subsection\s+(.+)$/
index 5549f4b619861f2e275537f26f52bad9bc0be04b..ff2685dff8450b0100ec1b6a5cd2fa7682f2d2c9 100644 (file)
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/units.h"
+#include "hw/boards.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu-version.h"
diff --git a/storage-daemon/Makefile.objs b/storage-daemon/Makefile.objs
new file mode 100644 (file)
index 0000000..cfe6bee
--- /dev/null
@@ -0,0 +1 @@
+storage-daemon-obj-y += qapi/
diff --git a/storage-daemon/qapi/Makefile.objs b/storage-daemon/qapi/Makefile.objs
new file mode 100644 (file)
index 0000000..8a4b220
--- /dev/null
@@ -0,0 +1 @@
+storage-daemon-obj-y += qapi-commands.o qapi-init-commands.o qapi-introspect.o
diff --git a/storage-daemon/qapi/qapi-schema.json b/storage-daemon/qapi/qapi-schema.json
new file mode 100644 (file)
index 0000000..14f4f8f
--- /dev/null
@@ -0,0 +1,26 @@
+# -*- Mode: Python -*-
+
+# Note that modules are shared with the QEMU main schema under the assumption
+# that the storage daemon schema is a subset of the main schema. For the shared
+# modules, no code is generated here, but we reuse the code files generated
+# from the main schema.
+#
+# If you wish to extend the storage daemon schema to contain things that are
+# not in the main schema, be aware that array types of types defined in shared
+# modules are only generated if an array of the respective type is already used
+# in the main schema. Therefore, if you use such arrays, you may need to define
+# the array type in the main schema, even if it is unused outside of the
+# storage daemon.
+
+{ 'include': '../../qapi/pragma.json' }
+
+{ 'include': '../../qapi/block-core.json' }
+{ 'include': '../../qapi/char.json' }
+{ 'include': '../../qapi/common.json' }
+{ 'include': '../../qapi/control.json' }
+{ 'include': '../../qapi/crypto.json' }
+{ 'include': '../../qapi/introspect.json' }
+{ 'include': '../../qapi/job.json' }
+{ 'include': '../../qapi/qom.json' }
+{ 'include': '../../qapi/sockets.json' }
+{ 'include': '../../qapi/transaction.json' }
index 7afbe5fb61d31dd2c84859d77fa52a2c6db3a5cc..45be5dc0ed78e4778e48e1146cdc860ab16128a9 100644 (file)
@@ -1,3 +1,4 @@
+stub-obj-y += arch_type.o
 stub-obj-y += bdrv-next-monitor-owned.o
 stub-obj-y += blk-commit-all.o
 stub-obj-y += blockdev-close-all-bdrv-states.o
@@ -18,6 +19,7 @@ stub-obj-y += machine-init-done.o
 stub-obj-y += migr-blocker.o
 stub-obj-y += change-state-handler.o
 stub-obj-y += monitor.o
+stub-obj-y += monitor-core.o
 stub-obj-y += notify-event.o
 stub-obj-y += qtest.o
 stub-obj-y += replay.o
diff --git a/stubs/arch_type.c b/stubs/arch_type.c
new file mode 100644 (file)
index 0000000..fc5423b
--- /dev/null
@@ -0,0 +1,4 @@
+#include "qemu/osdep.h"
+#include "sysemu/arch_init.h"
+
+const uint32_t arch_type = QEMU_ARCH_NONE;
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
new file mode 100644 (file)
index 0000000..6cff1c4
--- /dev/null
@@ -0,0 +1,21 @@
+#include "qemu/osdep.h"
+#include "monitor/monitor.h"
+#include "qemu-common.h"
+#include "qapi/qapi-emit-events.h"
+
+__thread Monitor *cur_mon;
+
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
+{
+}
+
+void qapi_event_emit(QAPIEvent event, QDict *qdict)
+{
+}
+
+int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+{
+    abort();
+}
+
+
index c3e9a2e4dc713472bb9d9f80cb12b395678cf0db..20786ac4ffb95efd9837d59a9cfb66c58ac9e1b5 100644 (file)
@@ -1,14 +1,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qapi/qapi-emit-events.h"
 #include "monitor/monitor.h"
-
-__thread Monitor *cur_mon;
-
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
-{
-    abort();
-}
+#include "../monitor/monitor-internal.h"
 
 int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
 {
@@ -16,14 +9,10 @@ int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
     return -1;
 }
 
-void monitor_init_qmp(Chardev *chr, bool pretty)
-{
-}
-
-void monitor_init_hmp(Chardev *chr, bool use_readline)
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp)
 {
 }
 
-void qapi_event_emit(QAPIEvent event, QDict *qdict)
+void monitor_fdsets_cleanup(void)
 {
 }
index e6016e33cece905aed3e59d7c10f7077cf362a28..3623ecefbd9c2bb2755b759e4c40389a6e2f295b 100644 (file)
@@ -191,19 +191,13 @@ static void arm_cpu_reset(CPUState *s)
         /* Enable all PAC keys.  */
         env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
                                   SCTLR_EnDA | SCTLR_EnDB);
-        /* Enable all PAC instructions */
-        env->cp15.hcr_el2 |= HCR_API;
-        env->cp15.scr_el3 |= SCR_API;
         /* and to the FP/Neon instructions */
         env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
         /* and to the SVE instructions */
         env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
-        env->cp15.cptr_el[3] |= CPTR_EZ;
         /* with maximum vector length */
         env->vfp.zcr_el[1] = cpu_isar_feature(aa64_sve, cpu) ?
                              cpu->sve_max_vq - 1 : 0;
-        env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
-        env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
         /*
          * Enable TBI0 and TBI1.  While the real kernel only enables TBI0,
          * turning on both here will produce smaller code and otherwise
@@ -1103,11 +1097,13 @@ static Property arm_cpu_reset_hivecs_property =
 static Property arm_cpu_rvbar_property =
             DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0);
 
+#ifndef CONFIG_USER_ONLY
 static Property arm_cpu_has_el2_property =
             DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true);
 
 static Property arm_cpu_has_el3_property =
             DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true);
+#endif
 
 static Property arm_cpu_cfgend_property =
             DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false);
@@ -1222,25 +1218,25 @@ void arm_cpu_post_init(Object *obj)
         qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property);
     }
 
+#ifndef CONFIG_USER_ONLY
     if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
         /* Add the has_el3 state CPU property only if EL3 is allowed.  This will
          * prevent "has_el3" from existing on CPUs which cannot support EL3.
          */
         qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el3_property);
 
-#ifndef CONFIG_USER_ONLY
         object_property_add_link(obj, "secure-memory",
                                  TYPE_MEMORY_REGION,
                                  (Object **)&cpu->secure_memory,
                                  qdev_prop_allow_set_link_before_realize,
                                  OBJ_PROP_LINK_STRONG,
                                  &error_abort);
-#endif
     }
 
     if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
         qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el2_property);
     }
+#endif
 
     if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
         cpu->has_pmu = true;
@@ -2702,6 +2698,7 @@ static void arm_max_initfn(Object *obj)
             t = cpu->isar.id_mmfr4;
             t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
             t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
+            t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
             cpu->isar.id_mmfr4 = t;
         }
 #endif
index 0b84742b66ab6aca437252893ec3f5cf450e7e4b..4ffd991b6fcb5830844a668b1ca51148b279dce6 100644 (file)
@@ -1410,6 +1410,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define HCR_TERR      (1ULL << 36)
 #define HCR_TEA       (1ULL << 37)
 #define HCR_MIOCNCE   (1ULL << 38)
+/* RES0 bit 39 */
 #define HCR_APK       (1ULL << 40)
 #define HCR_API       (1ULL << 41)
 #define HCR_NV        (1ULL << 42)
@@ -1418,13 +1419,19 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define HCR_NV2       (1ULL << 45)
 #define HCR_FWB       (1ULL << 46)
 #define HCR_FIEN      (1ULL << 47)
+/* RES0 bit 48 */
 #define HCR_TID4      (1ULL << 49)
 #define HCR_TICAB     (1ULL << 50)
+#define HCR_AMVOFFEN  (1ULL << 51)
 #define HCR_TOCU      (1ULL << 52)
+#define HCR_ENSCXT    (1ULL << 53)
 #define HCR_TTLBIS    (1ULL << 54)
 #define HCR_TTLBOS    (1ULL << 55)
 #define HCR_ATA       (1ULL << 56)
 #define HCR_DCT       (1ULL << 57)
+#define HCR_TID5      (1ULL << 58)
+#define HCR_TWEDEN    (1ULL << 59)
+#define HCR_TWEDEL    MAKE_64BIT_MASK(60, 4)
 
 #define SCR_NS                (1U << 0)
 #define SCR_IRQ               (1U << 1)
@@ -2936,16 +2943,6 @@ typedef enum ARMMMUIdxBit {
 
 #define MMU_USER_IDX 0
 
-/**
- * cpu_mmu_index:
- * @env: The cpu environment
- * @ifetch: True for code access, false for data access.
- *
- * Return the core mmu index for the current translation regime.
- * This function is used by generic TCG code paths.
- */
-int cpu_mmu_index(CPUARMState *env, bool ifetch);
-
 /* Indexes used when registering address spaces with cpu_address_space_init */
 typedef enum ARMASIdx {
     ARMASIdx_NS = 0,
@@ -3225,6 +3222,19 @@ FIELD(TBFLAG_A64, BTYPE, 10, 2)         /* Not cached. */
 FIELD(TBFLAG_A64, TBID, 12, 2)
 FIELD(TBFLAG_A64, UNPRIV, 14, 1)
 
+/**
+ * cpu_mmu_index:
+ * @env: The cpu environment
+ * @ifetch: True for code access, false for data access.
+ *
+ * Return the core mmu index for the current translation regime.
+ * This function is used by generic TCG code paths.
+ */
+static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
+{
+    return FIELD_EX32(env->hflags, TBFLAG_ANY, MMUIDX);
+}
+
 static inline bool bswap_code(bool sctlr_b)
 {
 #ifdef CONFIG_USER_ONLY
index b842e2b664a624c1b14faf07b5b90e9dc5d671ea..62d36f9e8d3638cfe38909a96f61b96508b20c8f 100644 (file)
@@ -677,6 +677,7 @@ static void aarch64_max_initfn(Object *obj)
 
         t = cpu->isar.id_aa64mmfr2;
         t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
+        t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
         cpu->isar.id_aa64mmfr2 = t;
 
         /* Replicate the same data to the 32-bit id registers.  */
@@ -704,6 +705,7 @@ static void aarch64_max_initfn(Object *obj)
         u = cpu->isar.id_mmfr4;
         u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
         u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
+        u = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
         cpu->isar.id_mmfr4 = u;
 
         u = cpu->isar.id_aa64dfr0;
index 509ae93069811bdd1c298ff1b1bb119b6d215831..bc0649a44aac17c44f695f848d21901e79901ee1 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/units.h"
 #include "cpu.h"
 #include "exec/gdbstub.h"
 #include "exec/helper-proto.h"
@@ -1031,6 +1032,8 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
                       "AArch32 EL%d PC 0x%" PRIx32 "\n",
                       cur_el, new_el, env->regs[15]);
     } else {
+        int tbii;
+
         env->aarch64 = 1;
         spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar);
         pstate_write(env, spsr);
@@ -1038,8 +1041,27 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
             env->pstate &= ~PSTATE_SS;
         }
         aarch64_restore_sp(env, new_el);
-        env->pc = new_pc;
         helper_rebuild_hflags_a64(env, new_el);
+
+        /*
+         * Apply TBI to the exception return address.  We had to delay this
+         * until after we selected the new EL, so that we could select the
+         * correct TBI+TBID bits.  This is made easier by waiting until after
+         * the hflags rebuild, since we can pull the composite TBII field
+         * from there.
+         */
+        tbii = FIELD_EX32(env->hflags, TBFLAG_A64, TBII);
+        if ((tbii >> extract64(new_pc, 55, 1)) & 1) {
+            /* TBI is enabled. */
+            int core_mmu_idx = cpu_mmu_index(env, false);
+            if (regime_has_2_ranges(core_to_aa64_mmu_idx(core_mmu_idx))) {
+                new_pc = sextract64(new_pc, 0, 56);
+            } else {
+                new_pc = extract64(new_pc, 0, 56);
+            }
+        }
+        env->pc = new_pc;
+
         qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
                       "AArch64 EL%d PC 0x%" PRIx64 "\n",
                       cur_el, new_el, env->pc);
@@ -1088,4 +1110,94 @@ uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
     return float16_sqrt(a, s);
 }
 
+void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
+{
+    /*
+     * Implement DC ZVA, which zeroes a fixed-length block of memory.
+     * Note that we do not implement the (architecturally mandated)
+     * alignment fault for attempts to use this on Device memory
+     * (which matches the usual QEMU behaviour of not implementing either
+     * alignment faults or any memory attribute handling).
+     */
+
+    ARMCPU *cpu = env_archcpu(env);
+    uint64_t blocklen = 4 << cpu->dcz_blocksize;
+    uint64_t vaddr = vaddr_in & ~(blocklen - 1);
+
+#ifndef CONFIG_USER_ONLY
+    {
+        /*
+         * Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than
+         * the block size so we might have to do more than one TLB lookup.
+         * We know that in fact for any v8 CPU the page size is at least 4K
+         * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
+         * 1K as an artefact of legacy v5 subpage support being present in the
+         * same QEMU executable. So in practice the hostaddr[] array has
+         * two entries, given the current setting of TARGET_PAGE_BITS_MIN.
+         */
+        int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
+        void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
+        int try, i;
+        unsigned mmu_idx = cpu_mmu_index(env, false);
+        TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
+
+        assert(maxidx <= ARRAY_SIZE(hostaddr));
+
+        for (try = 0; try < 2; try++) {
+
+            for (i = 0; i < maxidx; i++) {
+                hostaddr[i] = tlb_vaddr_to_host(env,
+                                                vaddr + TARGET_PAGE_SIZE * i,
+                                                1, mmu_idx);
+                if (!hostaddr[i]) {
+                    break;
+                }
+            }
+            if (i == maxidx) {
+                /*
+                 * If it's all in the TLB it's fair game for just writing to;
+                 * we know we don't need to update dirty status, etc.
+                 */
+                for (i = 0; i < maxidx - 1; i++) {
+                    memset(hostaddr[i], 0, TARGET_PAGE_SIZE);
+                }
+                memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE));
+                return;
+            }
+            /*
+             * OK, try a store and see if we can populate the tlb. This
+             * might cause an exception if the memory isn't writable,
+             * in which case we will longjmp out of here. We must for
+             * this purpose use the actual register value passed to us
+             * so that we get the fault address right.
+             */
+            helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
+            /* Now we can populate the other TLB entries, if any */
+            for (i = 0; i < maxidx; i++) {
+                uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
+                if (va != (vaddr_in & TARGET_PAGE_MASK)) {
+                    helper_ret_stb_mmu(env, va, 0, oi, GETPC());
+                }
+            }
+        }
 
+        /*
+         * Slow path (probably attempt to do this to an I/O device or
+         * similar, or clearing of a block of code we have translations
+         * cached for). Just do a series of byte writes as the architecture
+         * demands. It's not worth trying to use a cpu_physical_memory_map(),
+         * memset(), unmap() sequence here because:
+         *  + we'd need to account for the blocksize being larger than a page
+         *  + the direct-RAM access case is almost always going to be dealt
+         *    with in the fastpath code above, so there's no speed benefit
+         *  + we would have to deal with the map returning NULL because the
+         *    bounce buffer was in use
+         */
+        for (i = 0; i < blocklen; i++) {
+            helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC());
+        }
+    }
+#else
+    memset(g2h(vaddr), 0, blocklen);
+#endif
+}
index a915c1247fe29f9fa7a7bf3d1ce24aa49e4ec8d5..3df7c185aa1df67fe087d8dc34d752bd01902c5f 100644 (file)
@@ -90,6 +90,7 @@ DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
 DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
 
 DEF_HELPER_2(exception_return, void, env, i64)
+DEF_HELPER_FLAGS_2(dc_zva, TCG_CALL_NO_WG, void, env, i64)
 
 DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
index 6be9ffa09ef21478917e33cd88f9f039313802f0..f91e5d5345f5c968d9712b8652d504b1e5ab5db1 100644 (file)
@@ -530,6 +530,49 @@ static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
     return CP_ACCESS_OK;
 }
 
+/* Check for traps from EL1 due to HCR_EL2.TVM and HCR_EL2.TRVM.  */
+static CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
+                                      bool isread)
+{
+    if (arm_current_el(env) == 1) {
+        uint64_t trap = isread ? HCR_TRVM : HCR_TVM;
+        if (arm_hcr_el2_eff(env) & trap) {
+            return CP_ACCESS_TRAP_EL2;
+        }
+    }
+    return CP_ACCESS_OK;
+}
+
+/* Check for traps from EL1 due to HCR_EL2.TSW.  */
+static CPAccessResult access_tsw(CPUARMState *env, const ARMCPRegInfo *ri,
+                                 bool isread)
+{
+    if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TSW)) {
+        return CP_ACCESS_TRAP_EL2;
+    }
+    return CP_ACCESS_OK;
+}
+
+/* Check for traps from EL1 due to HCR_EL2.TACR.  */
+static CPAccessResult access_tacr(CPUARMState *env, const ARMCPRegInfo *ri,
+                                  bool isread)
+{
+    if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TACR)) {
+        return CP_ACCESS_TRAP_EL2;
+    }
+    return CP_ACCESS_OK;
+}
+
+/* Check for traps from EL1 due to HCR_EL2.TTLB. */
+static CPAccessResult access_ttlb(CPUARMState *env, const ARMCPRegInfo *ri,
+                                  bool isread)
+{
+    if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TTLB)) {
+        return CP_ACCESS_TRAP_EL2;
+    }
+    return CP_ACCESS_OK;
+}
+
 static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     ARMCPU *cpu = env_archcpu(env);
@@ -785,12 +828,14 @@ static const ARMCPRegInfo cp_reginfo[] = {
      */
     { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
-      .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .secure = ARM_CP_SECSTATE_NS,
       .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
       .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
     { .name = "CONTEXTIDR_S", .state = ARM_CP_STATE_AA32,
       .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
-      .access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .secure = ARM_CP_SECSTATE_S,
       .fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
       .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
     REGINFO_SENTINEL
@@ -803,7 +848,7 @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
     /* MMU Domain access control / MPU write buffer control */
     { .name = "DACR",
       .cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY,
-      .access = PL1_RW, .resetvalue = 0,
+      .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
       .writefn = dacr_write, .raw_writefn = raw_write,
       .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
                              offsetoflow32(CPUARMState, cp15.dacr_ns) } },
@@ -996,7 +1041,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
     { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5,
       .access = PL0_W, .type = ARM_CP_NOP },
     { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL1_RW,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
                              offsetof(CPUARMState, cp15.ifar_ns) },
       .resetvalue = 0, },
@@ -2208,16 +2253,19 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
      */
     { .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
-      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .type = ARM_CP_CONST, .resetvalue = 0 },
     { .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
-      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .type = ARM_CP_CONST, .resetvalue = 0 },
     /* MAIR can just read-as-written because we don't implement caches
      * and so don't need to care about memory attributes.
      */
     { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
       .resetvalue = 0 },
     { .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0,
@@ -2231,12 +2279,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       * handled in the field definitions.
       */
     { .name = "MAIR0", .state = ARM_CP_STATE_AA32,
-      .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
+      .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s),
                              offsetof(CPUARMState, cp15.mair0_ns) },
       .resetfn = arm_cp_reset_ignore },
     { .name = "MAIR1", .state = ARM_CP_STATE_AA32,
-      .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
+      .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s),
                              offsetof(CPUARMState, cp15.mair1_ns) },
       .resetfn = arm_cp_reset_ignore },
@@ -2245,41 +2295,53 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read },
     /* 32 bit ITLB invalidates */
     { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbiall_write },
     { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbimva_write },
     { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbiasid_write },
     /* 32 bit DTLB invalidates */
     { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbiall_write },
     { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbimva_write },
     { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbiasid_write },
     /* 32 bit TLB invalidates */
     { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbiall_write },
     { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbimva_write },
     { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbiasid_write },
     { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbimvaa_write },
     REGINFO_SENTINEL
 };
 
 static const ARMCPRegInfo v7mp_cp_reginfo[] = {
     /* 32 bit TLB invalidates, Inner Shareable */
     { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_is_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbiall_is_write },
     { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbimva_is_write },
     { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
-      .type = ARM_CP_NO_RAW, .access = PL1_W,
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
       .writefn = tlbiasid_is_write },
     { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
-      .type = ARM_CP_NO_RAW, .access = PL1_W,
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
       .writefn = tlbimvaa_is_write },
     REGINFO_SENTINEL
 };
@@ -3886,20 +3948,21 @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 
 static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .type = ARM_CP_ALIAS,
+      .access = PL1_RW, .accessfn = access_tvm_trvm, .type = ARM_CP_ALIAS,
       .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s),
                              offsetoflow32(CPUARMState, cp15.dfsr_ns) }, },
     { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
-      .access = PL1_RW, .resetvalue = 0,
+      .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
       .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s),
                              offsetoflow32(CPUARMState, cp15.ifsr_ns) } },
     { .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0,
-      .access = PL1_RW, .resetvalue = 0,
+      .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s),
                              offsetof(CPUARMState, cp15.dfar_ns) } },
     { .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
       .resetvalue = 0, },
     REGINFO_SENTINEL
 };
@@ -3907,25 +3970,29 @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
 static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
       .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
     { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
-      .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .writefn = vmsa_ttbr_write, .resetvalue = 0,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
                              offsetof(CPUARMState, cp15.ttbr0_ns) } },
     { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
-      .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .writefn = vmsa_ttbr_write, .resetvalue = 0,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
                              offsetof(CPUARMState, cp15.ttbr1_ns) } },
     { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL1_RW, .writefn = vmsa_tcr_el12_write,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .writefn = vmsa_tcr_el12_write,
       .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
       .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) },
     { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write,
       .raw_writefn = vmsa_ttbcr_raw_write,
       .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]),
                              offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
@@ -3937,7 +4004,8 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
  */
 static const ARMCPRegInfo ttbcr2_reginfo = {
     .name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
-    .access = PL1_RW, .type = ARM_CP_ALIAS,
+    .access = PL1_RW, .accessfn = access_tvm_trvm,
+    .type = ARM_CP_ALIAS,
     .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]),
                            offsetofhigh32(CPUARMState, cp15.tcr_el[1]) },
 };
@@ -4157,23 +4225,25 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
     /* NOP AMAIR0/1 */
     { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .type = ARM_CP_CONST,
-      .resetvalue = 0 },
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .type = ARM_CP_CONST, .resetvalue = 0 },
     /* AMAIR1 is mapped to AMAIR_EL1[63:32] */
     { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
-      .access = PL1_RW, .type = ARM_CP_CONST,
-      .resetvalue = 0 },
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .type = ARM_CP_CONST, .resetvalue = 0 },
     { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
       .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
                              offsetof(CPUARMState, cp15.par_ns)} },
     { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
-      .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .type = ARM_CP_64BIT | ARM_CP_ALIAS,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
                              offsetof(CPUARMState, cp15.ttbr0_ns) },
       .writefn = vmsa_ttbr_write, },
     { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
-      .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
+      .access = PL1_RW, .accessfn = access_tvm_trvm,
+      .type = ARM_CP_64BIT | ARM_CP_ALIAS,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
                              offsetof(CPUARMState, cp15.ttbr1_ns) },
       .writefn = vmsa_ttbr_write, },
@@ -4253,15 +4323,46 @@ static const ARMCPRegInfo uao_reginfo = {
     .readfn = aa64_uao_read, .writefn = aa64_uao_write
 };
 
-static CPAccessResult aa64_cacheop_access(CPUARMState *env,
-                                          const ARMCPRegInfo *ri,
-                                          bool isread)
+static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
+                                              const ARMCPRegInfo *ri,
+                                              bool isread)
 {
-    /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
-     * SCTLR_EL1.UCI is set.
-     */
-    if (arm_current_el(env) == 0 && !(arm_sctlr(env, 0) & SCTLR_UCI)) {
-        return CP_ACCESS_TRAP;
+    /* Cache invalidate/clean to Point of Coherency or Persistence...  */
+    switch (arm_current_el(env)) {
+    case 0:
+        /* ... EL0 must UNDEF unless SCTLR_EL1.UCI is set.  */
+        if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
+            return CP_ACCESS_TRAP;
+        }
+        /* fall through */
+    case 1:
+        /* ... EL1 must trap to EL2 if HCR_EL2.TPCP is set.  */
+        if (arm_hcr_el2_eff(env) & HCR_TPCP) {
+            return CP_ACCESS_TRAP_EL2;
+        }
+        break;
+    }
+    return CP_ACCESS_OK;
+}
+
+static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env,
+                                              const ARMCPRegInfo *ri,
+                                              bool isread)
+{
+    /* Cache invalidate/clean to Point of Unification... */
+    switch (arm_current_el(env)) {
+    case 0:
+        /* ... EL0 must UNDEF unless SCTLR_EL1.UCI is set.  */
+        if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
+            return CP_ACCESS_TRAP;
+        }
+        /* fall through */
+    case 1:
+        /* ... EL1 must trap to EL2 if HCR_EL2.TPU is set.  */
+        if (arm_hcr_el2_eff(env) & HCR_TPU) {
+            return CP_ACCESS_TRAP_EL2;
+        }
+        break;
     }
     return CP_ACCESS_OK;
 }
@@ -4663,86 +4764,89 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     /* Cache ops: all NOPs since we don't emulate caches */
     { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
-      .access = PL1_W, .type = ARM_CP_NOP },
+      .access = PL1_W, .type = ARM_CP_NOP,
+      .accessfn = aa64_cacheop_pou_access },
     { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
-      .access = PL1_W, .type = ARM_CP_NOP },
+      .access = PL1_W, .type = ARM_CP_NOP,
+      .accessfn = aa64_cacheop_pou_access },
     { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
       .access = PL0_W, .type = ARM_CP_NOP,
-      .accessfn = aa64_cacheop_access },
+      .accessfn = aa64_cacheop_pou_access },
     { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
-      .access = PL1_W, .type = ARM_CP_NOP },
+      .access = PL1_W, .accessfn = aa64_cacheop_poc_access,
+      .type = ARM_CP_NOP },
     { .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
-      .access = PL1_W, .type = ARM_CP_NOP },
+      .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
     { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
       .access = PL0_W, .type = ARM_CP_NOP,
-      .accessfn = aa64_cacheop_access },
+      .accessfn = aa64_cacheop_poc_access },
     { .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
-      .access = PL1_W, .type = ARM_CP_NOP },
+      .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
     { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
       .access = PL0_W, .type = ARM_CP_NOP,
-      .accessfn = aa64_cacheop_access },
+      .accessfn = aa64_cacheop_pou_access },
     { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
       .access = PL0_W, .type = ARM_CP_NOP,
-      .accessfn = aa64_cacheop_access },
+      .accessfn = aa64_cacheop_poc_access },
     { .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
-      .access = PL1_W, .type = ARM_CP_NOP },
+      .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
     /* TLBI operations */
     { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vmalle1is_write },
     { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vae1is_write },
     { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vmalle1is_write },
     { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vae1is_write },
     { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vae1is_write },
     { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vae1is_write },
     { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vmalle1_write },
     { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vae1_write },
     { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vmalle1_write },
     { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vae1_write },
     { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vae1_write },
     { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
-      .access = PL1_W, .type = ARM_CP_NO_RAW,
+      .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
       .writefn = tlbi_aa64_vae1_write },
     { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
@@ -4828,14 +4932,17 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
 #endif
     /* TLB invalidate last level of translation table walk */
     { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbimva_is_write },
     { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
-      .type = ARM_CP_NO_RAW, .access = PL1_W,
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
       .writefn = tlbimvaa_is_write },
     { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbimva_write },
     { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
-      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
+      .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
+      .writefn = tlbimvaa_write },
     { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
       .type = ARM_CP_NO_RAW, .access = PL2_W,
       .writefn = tlbimva_hyp_write },
@@ -4861,34 +4968,34 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
       .writefn = tlbiipas2_is_write },
     /* 32 bit cache operations */
     { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
     { .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6,
       .type = ARM_CP_NOP, .access = PL1_W },
     { .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
     { .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
     { .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6,
       .type = ARM_CP_NOP, .access = PL1_W },
     { .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7,
       .type = ARM_CP_NOP, .access = PL1_W },
     { .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
     { .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
     { .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
     { .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
     { .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
     { .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
     { .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
-      .type = ARM_CP_NOP, .access = PL1_W },
+      .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
     /* MMU Domain access control / MPU write buffer control */
     { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
-      .access = PL1_RW, .resetvalue = 0,
+      .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
       .writefn = dacr_write, .raw_writefn = raw_write,
       .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
                              offsetoflow32(CPUARMState, cp15.dacr_ns) } },
@@ -5086,11 +5193,15 @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
 {
     ARMCPU *cpu = env_archcpu(env);
-    /* Begin with bits defined in base ARMv8.0.  */
-    uint64_t valid_mask = MAKE_64BIT_MASK(0, 34);
+
+    if (arm_feature(env, ARM_FEATURE_V8)) {
+        valid_mask |= MAKE_64BIT_MASK(0, 34);  /* ARMv8.0 */
+    } else {
+        valid_mask |= MAKE_64BIT_MASK(0, 28);  /* ARMv7VE */
+    }
 
     if (arm_feature(env, ARM_FEATURE_EL3)) {
         valid_mask &= ~HCR_HCD;
@@ -5104,14 +5215,17 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
          */
         valid_mask &= ~HCR_TSC;
     }
-    if (cpu_isar_feature(aa64_vh, cpu)) {
-        valid_mask |= HCR_E2H;
-    }
-    if (cpu_isar_feature(aa64_lor, cpu)) {
-        valid_mask |= HCR_TLOR;
-    }
-    if (cpu_isar_feature(aa64_pauth, cpu)) {
-        valid_mask |= HCR_API | HCR_APK;
+
+    if (arm_feature(env, ARM_FEATURE_AARCH64)) {
+        if (cpu_isar_feature(aa64_vh, cpu)) {
+            valid_mask |= HCR_E2H;
+        }
+        if (cpu_isar_feature(aa64_lor, cpu)) {
+            valid_mask |= HCR_TLOR;
+        }
+        if (cpu_isar_feature(aa64_pauth, cpu)) {
+            valid_mask |= HCR_API | HCR_APK;
+        }
     }
 
     /* Clear RES0 bits.  */
@@ -5143,12 +5257,17 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
     arm_cpu_update_vfiq(cpu);
 }
 
+static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+{
+    do_hcr_write(env, value, 0);
+}
+
 static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
                           uint64_t value)
 {
     /* Handle HCR2 write, i.e. write to high half of HCR_EL2 */
     value = deposit64(env->cp15.hcr_el2, 32, 32, value);
-    hcr_write(env, NULL, value);
+    do_hcr_write(env, value, MAKE_64BIT_MASK(0, 32));
 }
 
 static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -5156,7 +5275,7 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
 {
     /* Handle HCR write, i.e. write to low half of HCR_EL2 */
     value = deposit64(env->cp15.hcr_el2, 0, 32, value);
-    hcr_write(env, NULL, value);
+    do_hcr_write(env, value, MAKE_64BIT_MASK(32, 32));
 }
 
 /*
@@ -5184,14 +5303,37 @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
          * Since the v8.4 language applies to the entire register, and
          * appears to be backward compatible, use that.
          */
-        ret = 0;
-    } else if (ret & HCR_TGE) {
-        /* These bits are up-to-date as of ARMv8.4.  */
+        return 0;
+    }
+
+    /*
+     * For a cpu that supports both aarch64 and aarch32, we can set bits
+     * in HCR_EL2 (e.g. via EL3) that are RES0 when we enter EL2 as aa32.
+     * Ignore all of the bits in HCR+HCR2 that are not valid for aarch32.
+     */
+    if (!arm_el_is_aa64(env, 2)) {
+        uint64_t aa32_valid;
+
+        /*
+         * These bits are up-to-date as of ARMv8.6.
+         * For HCR, it's easiest to list just the 2 bits that are invalid.
+         * For HCR2, list those that are valid.
+         */
+        aa32_valid = MAKE_64BIT_MASK(0, 32) & ~(HCR_RW | HCR_TDZ);
+        aa32_valid |= (HCR_CD | HCR_ID | HCR_TERR | HCR_TEA | HCR_MIOCNCE |
+                       HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_TTLBIS);
+        ret &= aa32_valid;
+    }
+
+    if (ret & HCR_TGE) {
+        /* These bits are up-to-date as of ARMv8.6.  */
         if (ret & HCR_E2H) {
             ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
                      HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
                      HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
-                     HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE);
+                     HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE |
+                     HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_ENSCXT |
+                     HCR_TTLBIS | HCR_TTLBOS | HCR_TID5);
         } else {
             ret |= HCR_FMO | HCR_IMO | HCR_AMO;
         }
@@ -6667,7 +6809,7 @@ static const ARMCPRegInfo dcpop_reg[] = {
     { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
       .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
-      .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
+      .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
     REGINFO_SENTINEL
 };
 
@@ -6675,7 +6817,7 @@ static const ARMCPRegInfo dcpodp_reg[] = {
     { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
       .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
-      .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
+      .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
     REGINFO_SENTINEL
 };
 #endif /*CONFIG_USER_ONLY*/
@@ -6888,8 +7030,8 @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
 static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
     { .name = "ACTLR2", .state = ARM_CP_STATE_AA32,
       .cp = 15, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 3,
-      .access = PL1_RW, .type = ARM_CP_CONST,
-      .resetvalue = 0 },
+      .access = PL1_RW, .accessfn = access_tacr,
+      .type = ARM_CP_CONST, .resetvalue = 0 },
     { .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
       .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
       .access = PL2_RW, .type = ARM_CP_CONST,
@@ -7645,8 +7787,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         ARMCPRegInfo auxcr_reginfo[] = {
             { .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,
               .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,
-              .access = PL1_RW, .type = ARM_CP_CONST,
-              .resetvalue = cpu->reset_auxcr },
+              .access = PL1_RW, .accessfn = access_tacr,
+              .type = ARM_CP_CONST, .resetvalue = cpu->reset_auxcr },
             { .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,
               .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,
               .access = PL2_RW, .type = ARM_CP_CONST,
@@ -7730,7 +7872,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         ARMCPRegInfo sctlr = {
             .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
             .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
-            .access = PL1_RW,
+            .access = PL1_RW, .accessfn = access_tvm_trvm,
             .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
                                    offsetof(CPUARMState, cp15.sctlr_ns) },
             .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
@@ -10316,7 +10458,8 @@ static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
     } else if (mmu_idx == ARMMMUIdx_Stage2) {
         return 0; /* VTCR_EL2 */
     } else {
-        return extract32(tcr, 20, 1);
+        /* Replicate the single TBI bit so we always have 2 bits.  */
+        return extract32(tcr, 20, 1) * 3;
     }
 }
 
@@ -10327,7 +10470,8 @@ static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
     } else if (mmu_idx == ARMMMUIdx_Stage2) {
         return 0; /* VTCR_EL2 */
     } else {
-        return extract32(tcr, 29, 1);
+        /* Replicate the single TBID bit so we always have 2 bits.  */
+        return extract32(tcr, 29, 1) * 3;
     }
 }
 
@@ -10591,6 +10735,10 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
 
     /* Now we can extract the actual base address from the TTBR */
     descaddr = extract64(ttbr, 0, 48);
+    /*
+     * We rely on this masking to clear the RES0 bits at the bottom of the TTBR
+     * and also to mask out CnP (bit 0) which could validly be non-zero.
+     */
     descaddr &= ~indexmask;
 
     /* The address field in the descriptor goes up to bit 39 for ARMv7
@@ -12126,11 +12274,6 @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
     return arm_mmu_idx_el(env, arm_current_el(env));
 }
 
-int cpu_mmu_index(CPUARMState *env, bool ifetch)
-{
-    return arm_to_core_mmu_idx(arm_mmu_idx(env));
-}
-
 #ifndef CONFIG_USER_ONLY
 ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
 {
index fcbf5041213745d23c2609091cbef9b3e5658a0d..72eb9e6a1a5844bfaca2e1964cc86587d43bc197 100644 (file)
@@ -559,7 +559,6 @@ DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
 
 DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
-DEF_HELPER_2(dc_zva, void, env, i64)
 
 DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG,
                    void, ptr, ptr, ptr, ptr, i32)
index 9f96a2359f3dcafe543be477289ea746c276cec5..e633aff36ef014ee6fe8f60fb1f29b13b3fc9791 100644 (file)
@@ -783,6 +783,12 @@ static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
     }
 }
 
+static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
+{
+    /* AArch64 is always a-profile. */
+    return mmu_idx | ARM_MMU_IDX_A;
+}
+
 int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
 
 /*
index af3020b78f86bfa07a382ba790a021eff419c080..eb0de080f11192e0c2ddc92c1c681993ad444de8 100644 (file)
@@ -17,7 +17,6 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
-#include "qemu/units.h"
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
 #include "cpu.h"
@@ -936,95 +935,3 @@ uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
         return ((uint32_t)x >> shift) | (x << (32 - shift));
     }
 }
-
-void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
-{
-    /*
-     * Implement DC ZVA, which zeroes a fixed-length block of memory.
-     * Note that we do not implement the (architecturally mandated)
-     * alignment fault for attempts to use this on Device memory
-     * (which matches the usual QEMU behaviour of not implementing either
-     * alignment faults or any memory attribute handling).
-     */
-
-    ARMCPU *cpu = env_archcpu(env);
-    uint64_t blocklen = 4 << cpu->dcz_blocksize;
-    uint64_t vaddr = vaddr_in & ~(blocklen - 1);
-
-#ifndef CONFIG_USER_ONLY
-    {
-        /*
-         * Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than
-         * the block size so we might have to do more than one TLB lookup.
-         * We know that in fact for any v8 CPU the page size is at least 4K
-         * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
-         * 1K as an artefact of legacy v5 subpage support being present in the
-         * same QEMU executable. So in practice the hostaddr[] array has
-         * two entries, given the current setting of TARGET_PAGE_BITS_MIN.
-         */
-        int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
-        void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
-        int try, i;
-        unsigned mmu_idx = cpu_mmu_index(env, false);
-        TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
-
-        assert(maxidx <= ARRAY_SIZE(hostaddr));
-
-        for (try = 0; try < 2; try++) {
-
-            for (i = 0; i < maxidx; i++) {
-                hostaddr[i] = tlb_vaddr_to_host(env,
-                                                vaddr + TARGET_PAGE_SIZE * i,
-                                                1, mmu_idx);
-                if (!hostaddr[i]) {
-                    break;
-                }
-            }
-            if (i == maxidx) {
-                /*
-                 * If it's all in the TLB it's fair game for just writing to;
-                 * we know we don't need to update dirty status, etc.
-                 */
-                for (i = 0; i < maxidx - 1; i++) {
-                    memset(hostaddr[i], 0, TARGET_PAGE_SIZE);
-                }
-                memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE));
-                return;
-            }
-            /*
-             * OK, try a store and see if we can populate the tlb. This
-             * might cause an exception if the memory isn't writable,
-             * in which case we will longjmp out of here. We must for
-             * this purpose use the actual register value passed to us
-             * so that we get the fault address right.
-             */
-            helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
-            /* Now we can populate the other TLB entries, if any */
-            for (i = 0; i < maxidx; i++) {
-                uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
-                if (va != (vaddr_in & TARGET_PAGE_MASK)) {
-                    helper_ret_stb_mmu(env, va, 0, oi, GETPC());
-                }
-            }
-        }
-
-        /*
-         * Slow path (probably attempt to do this to an I/O device or
-         * similar, or clearing of a block of code we have translations
-         * cached for). Just do a series of byte writes as the architecture
-         * demands. It's not worth trying to use a cpu_physical_memory_map(),
-         * memset(), unmap() sequence here because:
-         *  + we'd need to account for the blocksize being larger than a page
-         *  + the direct-RAM access case is almost always going to be dealt
-         *    with in the fastpath code above, so there's no speed benefit
-         *  + we would have to deal with the map returning NULL because the
-         *    bounce buffer was in use
-         */
-        for (i = 0; i < blocklen; i++) {
-            helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC());
-        }
-    }
-#else
-    memset(g2h(vaddr), 0, blocklen);
-#endif
-}
index 579180af0a9d419a42196c1d4c2eb31e315734ec..fefe8af7f529822904a066398fe68712c9ce4b21 100644 (file)
@@ -1784,7 +1784,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
         return;
     case ARM_CP_DC_ZVA:
         /* Writes clear the aligned block of memory which rt points into. */
-        tcg_rt = cpu_reg(s, rt);
+        tcg_rt = clean_data_tbi(s, cpu_reg(s, rt));
         gen_helper_dc_zva(cpu_env, tcg_rt);
         return;
     default:
@@ -14300,7 +14300,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
     dc->condexec_mask = 0;
     dc->condexec_cond = 0;
     core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
-    dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
+    dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
     dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
     dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
     dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
index c47d10b739b3056ce0bdb84a4c15f594977aa7ed..c0b70231004cae0915df71f48e180dd7c28ed691 100644 (file)
@@ -66,7 +66,7 @@ const char * const riscv_excp_names[] = {
     "exec_page_fault",
     "load_page_fault",
     "reserved",
-    "store_page_fault"
+    "store_page_fault",
     "reserved",
     "reserved",
     "reserved",
@@ -74,7 +74,7 @@ const char * const riscv_excp_names[] = {
     "guest_exec_page_fault",
     "guest_load_page_fault",
     "reserved",
-    "guest_store_page_fault"
+    "guest_store_page_fault",
 };
 
 const char * const riscv_intr_names[] = {
index b5aec06d6bef0d1f5c39a312ecd5385354a4535d..54e5670b3fd6d960bd3fb4baca8b4e1438ac4f8f 100644 (file)
@@ -117,7 +117,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
 
         cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
 
-        if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {
+        if (!iplb_valid(iplb)) {
             env->regs[r1 + 1] = DIAG_308_RC_INVALID;
             goto out;
         }
index 41232c11a3901abcdf12110dd2b7cb01d1dbe471..bee18ee34452a30b5acb2257880a0b406c002dd5 100755 (executable)
@@ -16,15 +16,11 @@ import argparse
 import difflib
 import os
 import sys
+from io import StringIO
 
 from qapi.error import QAPIError
 from qapi.schema import QAPISchema, QAPISchemaVisitor
 
-if sys.version_info[0] < 3:
-    from cStringIO import StringIO
-else:
-    from io import StringIO
-
 
 class QAPISchemaTestVisitor(QAPISchemaVisitor):
 
index a4aa74764f8c21da65085bf278eb81a7152fd22a..b05a4692cf5b8282f27e838d6994a9b58a59af89 100755 (executable)
@@ -30,6 +30,7 @@ _cleanup()
 {
        _cleanup_test_img
     rm "$TEST_DIR/blkdebug.conf"
+    rm -f "$TEST_IMG.data_file"
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
@@ -218,6 +219,58 @@ _make_test_img 64M
 $QEMU_IO -c "write 0 1M" -c "write 0 1M" "$BLKDBG_TEST_IMG" | _filter_qemu_io
 _check_test_img
 
+echo
+echo === Avoid freeing preallocated zero clusters on failure ===
+echo
+
+cat > "$TEST_DIR/blkdebug.conf" <<EOF
+[inject-error]
+event = "write_aio"
+errno = "5"
+once = "on"
+EOF
+
+_make_test_img $CLUSTER_SIZE
+# Create a preallocated zero cluster
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" -c "write -z 0 $CLUSTER_SIZE" "$TEST_IMG" \
+    | _filter_qemu_io
+# Try to overwrite it (prompting an I/O error from blkdebug), thus
+# triggering the alloc abort code
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" "$BLKDBG_TEST_IMG" | _filter_qemu_io
+
+_check_test_img
+
+echo
+echo === Avoid freeing external data clusters on failure ===
+echo
+
+# Similar test as the last one, except we test what happens when there
+# is an error when writing to an external data file instead of when
+# writing to a preallocated zero cluster
+_make_test_img -o "data_file=$TEST_IMG.data_file" $CLUSTER_SIZE
+
+# Put blkdebug above the data-file, and a raw node on top of that so
+# that blkdebug will see a write_aio event and emit an error
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" \
+    "json:{
+         'driver': 'qcow2',
+         'file': { 'driver': 'file', 'filename': '$TEST_IMG' },
+         'data-file': {
+             'driver': 'raw',
+             'file': {
+                 'driver': 'blkdebug',
+                 'config': '$TEST_DIR/blkdebug.conf',
+                 'image': {
+                     'driver': 'file',
+                     'filename': '$TEST_IMG.data_file'
+                 }
+             }
+         }
+     }" \
+    | _filter_qemu_io
+
+_check_test_img
+
 # success, all done
 echo "*** done"
 rm -f $seq.full
index ff0817b6f282e566ae8fc8d2d376a611f5074e42..c1b3b584822ccc97910f4cc0db72d653014c7251 100644 (file)
@@ -643,4 +643,20 @@ write failed: Input/output error
 wrote 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 No errors were found on the image.
+
+=== Avoid freeing preallocated zero clusters on failure ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+write failed: Input/output error
+No errors were found on the image.
+
+=== Avoid freeing external data clusters on failure ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024 data_file=TEST_DIR/t.IMGFMT.data_file
+write failed: Input/output error
+No errors were found on the image.
 *** done
index 495d013007cd3c4e11ed88e61b22efb53adb865f..8d5001648a2265d5b9b8ab67ca07c13126d4f056 100644 (file)
@@ -651,4 +651,20 @@ write failed: Input/output error
 wrote 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 No errors were found on the image.
+
+=== Avoid freeing preallocated zero clusters on failure ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+write failed: Input/output error
+No errors were found on the image.
+
+=== Avoid freeing external data clusters on failure ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024 data_file=TEST_DIR/t.IMGFMT.data_file
+write failed: Input/output error
+No errors were found on the image.
 *** done
index 51a70fe669689d62d20d00c69f796415020980ad..7cf0e27154d0eee81cf29a1e4382ac301129b3f1 100755 (executable)
@@ -50,7 +50,7 @@ _make_test_img 1G
 $QEMU_IMG measure # missing arguments
 $QEMU_IMG measure --size 2G "$TEST_IMG" # only one allowed
 $QEMU_IMG measure "$TEST_IMG" a # only one filename allowed
-$QEMU_IMG measure --object secret,id=sec0,data=MTIzNDU2,format=base64 # missing filename
+$QEMU_IMG measure --object secret,id=sec0,data=MTIzNDU2,format=base64 # size or filename needed
 $QEMU_IMG measure --image-opts # missing filename
 $QEMU_IMG measure -f qcow2 # missing filename
 $QEMU_IMG measure -l snap1 # missing filename
index 9e7d8c44df641582f05cc34d52a93c5ddb2933da..f59bf4b2fbc4b5d843a8bd6b29a51a546a7a2210 100644 (file)
@@ -5,10 +5,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 qemu-img: Either --size N or one filename must be specified.
 qemu-img: --size N cannot be used together with a filename.
 qemu-img: At most one filename argument is allowed.
-qemu-img: --object, --image-opts, -f, and -l require a filename argument.
-qemu-img: --object, --image-opts, -f, and -l require a filename argument.
-qemu-img: --object, --image-opts, -f, and -l require a filename argument.
-qemu-img: --object, --image-opts, -f, and -l require a filename argument.
+qemu-img: Either --size N or one filename must be specified.
+qemu-img: --image-opts, -f, and -l require a filename argument.
+qemu-img: --image-opts, -f, and -l require a filename argument.
+qemu-img: --image-opts, -f, and -l require a filename argument.
 qemu-img: Invalid option list: ,
 qemu-img: Invalid parameter 'snapshot.foo'
 qemu-img: Failed in parsing snapshot param 'snapshot.foo'
index 6478365905a0e67b0c8ba6c389ca1c58aa4873f7..404ca908d8c2686d2be220d57db6ee6954a72915 100644 (file)
@@ -5,10 +5,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 qemu-img: Either --size N or one filename must be specified.
 qemu-img: --size N cannot be used together with a filename.
 qemu-img: At most one filename argument is allowed.
-qemu-img: --object, --image-opts, -f, and -l require a filename argument.
-qemu-img: --object, --image-opts, -f, and -l require a filename argument.
-qemu-img: --object, --image-opts, -f, and -l require a filename argument.
-qemu-img: --object, --image-opts, -f, and -l require a filename argument.
+qemu-img: Either --size N or one filename must be specified.
+qemu-img: --image-opts, -f, and -l require a filename argument.
+qemu-img: --image-opts, -f, and -l require a filename argument.
+qemu-img: --image-opts, -f, and -l require a filename argument.
 qemu-img: Invalid option list: ,
 qemu-img: Invalid parameter 'snapshot.foo'
 qemu-img: Failed in parsing snapshot param 'snapshot.foo'
index 489bf78bd08a440dd3d1fdeaf5692c3860e89a82..1001275a4451e92f4a4505cc2cb31280f78b5f6d 100755 (executable)
@@ -970,8 +970,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
         self.assertEqual(self.get_node('hd1'), None)
         self.assert_qmp(self.get_node('hd2'), 'ro', True)
 
-    # We don't allow setting a backing file that uses a different AioContext
-    def test_iothreads(self):
+    def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None):
         opts = hd_opts(0)
         result = self.vm.qmp('blockdev-add', conv_keys = False, **opts)
         self.assert_qmp(result, 'return', {})
@@ -986,20 +985,46 @@ class TestBlockdevReopen(iotests.QMPTestCase):
         result = self.vm.qmp('object-add', qom_type='iothread', id='iothread1')
         self.assert_qmp(result, 'return', {})
 
-        result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd0', iothread='iothread0')
+        result = self.vm.qmp('device_add', driver='virtio-scsi', id='scsi0',
+                             iothread=iothread_a)
         self.assert_qmp(result, 'return', {})
 
-        self.reopen(opts, {'backing': 'hd2'}, "Cannot use a new backing file with a different AioContext")
-
-        result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd2', iothread='iothread1')
+        result = self.vm.qmp('device_add', driver='virtio-scsi', id='scsi1',
+                             iothread=iothread_b)
         self.assert_qmp(result, 'return', {})
 
-        self.reopen(opts, {'backing': 'hd2'}, "Cannot use a new backing file with a different AioContext")
+        if iothread_a:
+            result = self.vm.qmp('device_add', driver='scsi-hd', drive='hd0',
+                                 share_rw=True, bus="scsi0.0")
+            self.assert_qmp(result, 'return', {})
 
-        result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd2', iothread='iothread0')
-        self.assert_qmp(result, 'return', {})
+        if iothread_b:
+            result = self.vm.qmp('device_add', driver='scsi-hd', drive='hd2',
+                                 share_rw=True, bus="scsi1.0")
+            self.assert_qmp(result, 'return', {})
 
-        self.reopen(opts, {'backing': 'hd2'})
+        # Attaching the backing file may or may not work
+        self.reopen(opts, {'backing': 'hd2'}, errmsg)
+
+        # But removing the backing file should always work
+        self.reopen(opts, {'backing': None})
+
+        self.vm.shutdown()
+
+    # We don't allow setting a backing file that uses a different AioContext if
+    # neither of them can switch to the other AioContext
+    def test_iothreads_error(self):
+        self.run_test_iothreads('iothread0', 'iothread1',
+                                "Cannot change iothread of active block backend")
+
+    def test_iothreads_compatible_users(self):
+        self.run_test_iothreads('iothread0', 'iothread0')
+
+    def test_iothreads_switch_backing(self):
+        self.run_test_iothreads('iothread0', None)
+
+    def test_iothreads_switch_overlay(self):
+        self.run_test_iothreads(None, 'iothread0')
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=["qcow2"],
index a19de5214dae1da0617e2ccfc1707cb6fc04bd56..682b93394dfafefd9e91d8388ee2c99b25b0fd7c 100644 (file)
@@ -1,6 +1,6 @@
-..................
+.....................
 ----------------------------------------------------------------------
-Ran 18 tests
+Ran 21 tests
 
 OK
 {"execute": "job-finalize", "arguments": {"id": "commit0"}}
diff --git a/tests/qemu-iotests/288 b/tests/qemu-iotests/288
new file mode 100755 (executable)
index 0000000..6c62065
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+#
+# qemu-img measure tests for LUKS images
+#
+# Copyright (C) 2020 Red Hat, Inc.
+#
+# 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/>.
+#
+
+# creator
+owner=stefanha@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1    # failure is the default!
+
+_cleanup()
+{
+    _cleanup_test_img
+    rm -f "$TEST_IMG.converted"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+_supported_fmt luks
+_supported_proto file
+_supported_os Linux
+
+SECRET=secret,id=sec0,data=passphrase
+
+echo "== measure 1G image file =="
+echo
+
+$QEMU_IMG measure --object "$SECRET" \
+                 -O "$IMGFMT" \
+                 -o key-secret=sec0,iter-time=10 \
+                 --size 1G
+
+echo
+echo "== create 1G image file (size should be no greater than measured) =="
+echo
+
+_make_test_img 1G
+stat -c "image file size in bytes: %s" "$TEST_IMG_FILE"
+
+echo
+echo "== modified 1G image file (size should be no greater than measured) =="
+echo
+
+$QEMU_IO --object "$SECRET" --image-opts "$TEST_IMG" -c "write -P 0x51 0x10000 0x400" | _filter_qemu_io | _filter_testdir
+stat -c "image file size in bytes: %s" "$TEST_IMG_FILE"
+
+echo
+echo "== measure preallocation=falloc 1G image file =="
+echo
+
+$QEMU_IMG measure --object "$SECRET" \
+                 -O "$IMGFMT" \
+                 -o key-secret=sec0,iter-time=10,preallocation=falloc \
+                 --size 1G
+
+echo
+echo "== measure with input image file =="
+echo
+
+IMGFMT=raw IMGKEYSECRET= IMGOPTS= _make_test_img 1G | _filter_imgfmt
+QEMU_IO_OPTIONS= IMGOPTSSYNTAX= $QEMU_IO -f raw -c "write -P 0x51 0x10000 0x400" "$TEST_IMG_FILE" | _filter_qemu_io | _filter_testdir
+$QEMU_IMG measure --object "$SECRET" \
+                 -O "$IMGFMT" \
+                 -o key-secret=sec0,iter-time=10 \
+                 -f raw \
+                 "$TEST_IMG_FILE"
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/288.out b/tests/qemu-iotests/288.out
new file mode 100644 (file)
index 0000000..4bc593d
--- /dev/null
@@ -0,0 +1,30 @@
+QA output created by 288
+== measure 1G image file ==
+
+required size: 1075810304
+fully allocated size: 1075810304
+
+== create 1G image file (size should be no greater than measured) ==
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+image file size in bytes: 1075810304
+
+== modified 1G image file (size should be no greater than measured) ==
+
+wrote 1024/1024 bytes at offset 65536
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+image file size in bytes: 1075810304
+
+== measure preallocation=falloc 1G image file ==
+
+required size: 1075810304
+fully allocated size: 1075810304
+
+== measure with input image file ==
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+wrote 1024/1024 bytes at offset 65536
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+required size: 1075810304
+fully allocated size: 1075810304
+*** done
index 8a6366c09dafa353d0624d12b64fed8af3a98024..4c246c0450e47c0c94359c67094414820efdc36e 100644 (file)
@@ -56,18 +56,30 @@ poke_file()
 # peek_file_le 'test.img' 512 2 => 65534
 peek_file_le()
 {
-    # Wrap in echo $() to strip spaces
-    echo $(od -j"$2" -N"$3" --endian=little -An -vtu"$3" "$1")
+    local val=0 shift=0 byte
+
+    # coreutils' od --endian is not portable, so manually assemble bytes.
+    for byte in $(od -j"$2" -N"$3" -An -v -tu1 "$1"); do
+        val=$(( val | (byte << shift) ))
+        shift=$((shift + 8))
+    done
+    printf %llu $val
 }
 
 # peek_file_be 'test.img' 512 2 => 65279
 peek_file_be()
 {
-    # Wrap in echo $() to strip spaces
-    echo $(od -j"$2" -N"$3" --endian=big -An -vtu"$3" "$1")
+    local val=0 byte
+
+    # coreutils' od --endian is not portable, so manually assemble bytes.
+    for byte in $(od -j"$2" -N"$3" -An -v -tu1 "$1"); do
+        val=$(( (val << 8) | byte ))
+    done
+    printf %llu $val
 }
 
-# peek_file_raw 'test.img' 512 2 => '\xff\xfe'
+# peek_file_raw 'test.img' 512 2 => '\xff\xfe'. Do not use if the raw data
+# is likely to contain \0 or trailing \n.
 peek_file_raw()
 {
     dd if="$1" bs=1 skip="$2" count="$3" status=none
index 03176676957138cb6e8ac102d63c7f8dd097603d..559edc139ade12badce0646dba1479fa3fa0441f 100644 (file)
 283 auto quick
 284 rw
 286 rw quick
+288 quick
index e769c1ad70b1f0721cd9ecb952290df2831d8a03..5115f7897db700e20bb6f6162c75799c512a790e 100644 (file)
@@ -18,7 +18,8 @@ check-qtest-pci-$(CONFIG_IVSHMEM_DEVICE) += ivshmem-test
 DBUS_DAEMON := $(shell which dbus-daemon 2>/dev/null)
 ifneq ($(GDBUS_CODEGEN),)
 ifneq ($(DBUS_DAEMON),)
-check-qtest-pci-$(CONFIG_GIO) += dbus-vmstate-test
+# Temporarily disabled due to Patchew failures:
+#check-qtest-pci-$(CONFIG_GIO) += dbus-vmstate-test
 endif
 endif
 
@@ -54,8 +55,8 @@ check-qtest-i386-y += q35-test
 check-qtest-i386-y += vmgenid-test
 check-qtest-i386-$(CONFIG_TPM_CRB) += tpm-crb-swtpm-test
 check-qtest-i386-$(CONFIG_TPM_CRB) += tpm-crb-test
-check-qtest-i386-$(CONFIG_TPM_TIS) += tpm-tis-swtpm-test
-check-qtest-i386-$(CONFIG_TPM_TIS) += tpm-tis-test
+check-qtest-i386-$(CONFIG_TPM_TIS_ISA) += tpm-tis-swtpm-test
+check-qtest-i386-$(CONFIG_TPM_TIS_ISA) += tpm-tis-test
 check-qtest-i386-$(CONFIG_SLIRP) += test-netfilter
 check-qtest-i386-$(CONFIG_POSIX) += test-filter-mirror
 check-qtest-i386-$(CONFIG_RTL8139_PCI) += test-filter-redirector
@@ -130,6 +131,8 @@ check-qtest-arm-y += hexloader-test
 check-qtest-arm-$(CONFIG_PFLASH_CFI02) += pflash-cfi02-test
 
 check-qtest-aarch64-y += arm-cpu-features
+check-qtest-aarch64-$(CONFIG_TPM_TIS_SYSBUS) += tpm-tis-device-test
+check-qtest-aarch64-$(CONFIG_TPM_TIS_SYSBUS) += tpm-tis-device-swtpm-test
 check-qtest-aarch64-y += numa-test
 check-qtest-aarch64-y += boot-serial-test
 check-qtest-aarch64-y += migration-test
@@ -302,7 +305,10 @@ tests/qtest/tpm-crb-swtpm-test$(EXESUF): tests/qtest/tpm-crb-swtpm-test.o tests/
 tests/qtest/tpm-crb-test$(EXESUF): tests/qtest/tpm-crb-test.o tests/qtest/tpm-emu.o $(test-io-obj-y)
 tests/qtest/tpm-tis-swtpm-test$(EXESUF): tests/qtest/tpm-tis-swtpm-test.o tests/qtest/tpm-emu.o \
        tests/qtest/tpm-util.o tests/qtest/tpm-tests.o $(test-io-obj-y)
-tests/qtest/tpm-tis-test$(EXESUF): tests/qtest/tpm-tis-test.o tests/qtest/tpm-emu.o $(test-io-obj-y)
+tests/qtest/tpm-tis-device-swtpm-test$(EXESUF): tests/qtest/tpm-tis-device-swtpm-test.o tests/qtest/tpm-emu.o \
+       tests/qtest/tpm-util.o tests/qtest/tpm-tests.o $(test-io-obj-y)
+tests/qtest/tpm-tis-test$(EXESUF): tests/qtest/tpm-tis-test.o tests/qtest/tpm-tis-util.o tests/qtest/tpm-emu.o $(test-io-obj-y)
+tests/qtest/tpm-tis-device-test$(EXESUF): tests/qtest/tpm-tis-device-test.o tests/qtest/tpm-tis-util.o tests/qtest/tpm-emu.o $(test-io-obj-y)
 
 # QTest rules
 
index b23a59f194138885e19f8817e6ddfb60f1b2f322..e086bba873d869fece6fd8a4225c4ee3559e3153 100644 (file)
@@ -1,7 +1,8 @@
-/* We adjust linker script modification to place all of the stuff that needs to
- * persist across fuzzing runs into a contiguous seciton of memory. Then, it is
+/*
+ * We adjust linker script modification to place all of the stuff that needs to
+ * persist across fuzzing runs into a contiguous section of memory. Then, it is
  * easy to re-map the counter-related memory as shared.
-*/
+ */
 
 SECTIONS
 {
@@ -17,7 +18,8 @@ SECTIONS
   }
   .data.fuzz_ordered :
   {
-      /* Coverage counters. They're not necessary for fuzzing, but are useful
+      /*
+       * Coverage counters. They're not necessary for fuzzing, but are useful
        * for analyzing the fuzzing performance
        */
       __start___llvm_prf_cnts = .;
@@ -32,6 +34,8 @@ SECTIONS
       __FUZZ_COUNTERS_END = .;
   }
 }
-/* Dont overwrite the SECTIONS in the default linker script. Instead insert the
- * above into the default script */
+/*
+ * Don't overwrite the SECTIONS in the default linker script. Instead insert the
+ * above into the default script
+ */
 INSERT AFTER .data;
index bbb17470ffdbc7cf767ae710aca599f2838d6a51..1a99277d60f1718468327b198519dc37889fa236 100644 (file)
@@ -120,7 +120,10 @@ static void walk_path(QOSGraphNode *orig_path, int len)
     QOSGraphNode *path;
     QOSGraphEdge *edge;
 
-    /* etype set to QEDGE_CONSUMED_BY so that machine can add to the command line */
+    /*
+     * etype set to QEDGE_CONSUMED_BY so that machine can add to the command
+     * line
+     */
     QOSEdgeType etype = QEDGE_CONSUMED_BY;
 
     /* twice QOS_PATH_MAX_ELEMENT_SIZE since each edge can have its arg */
index 2c4fb8ae292bafb2aa8f940c9c6834d59d7e7db8..55fdb5657d910ca3feaad9b5b762d2471778f6ba 100644 (file)
 #include "libqtest.h"
 #include "qemu/module.h"
 #include "tpm-tests.h"
+#include "hw/acpi/tpm.h"
+
+/* Not used but needed for linking */
+uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
 
 typedef struct TestState {
     char *src_tpm_path;
@@ -29,7 +33,8 @@ static void tpm_crb_swtpm_test(const void *data)
 {
     const TestState *ts = data;
 
-    tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_crb_transfer, "tpm-crb");
+    tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_crb_transfer,
+                        "tpm-crb", NULL);
 }
 
 static void tpm_crb_swtpm_migration_test(const void *data)
@@ -37,7 +42,7 @@ static void tpm_crb_swtpm_migration_test(const void *data)
     const TestState *ts = data;
 
     tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
-                                  tpm_util_crb_transfer, "tpm-crb");
+                                  tpm_util_crb_transfer, "tpm-crb", NULL);
 }
 
 int main(int argc, char **argv)
index 632fb7fbd86fa1dd9a078d913ee12199656da701..ed533900d18d53916afebe981e3c84834d5a0a3a 100644 (file)
@@ -19,6 +19,9 @@
 #include "qemu/module.h"
 #include "tpm-emu.h"
 
+/* Not used but needed for linking */
+uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
+
 #define TPM_CMD "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
 
 static void tpm_crb_test(const void *data)
index 6e45a0ba852552fa269b69f57cb00873bd1f7407..a2f2838e15b9b49b892b3c755e1d45e8bb2a2fa1 100644 (file)
@@ -30,7 +30,7 @@ tpm_test_swtpm_skip(void)
 }
 
 void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
-                         const char *ifmodel)
+                         const char *ifmodel, const char *machine_options)
 {
     char *args = NULL;
     QTestState *s;
@@ -47,10 +47,11 @@ void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
     g_assert_true(succ);
 
     args = g_strdup_printf(
+        "%s "
         "-chardev socket,id=chr,path=%s "
         "-tpmdev emulator,id=dev,chardev=chr "
         "-device %s,tpmdev=dev",
-        addr->u.q_unix.path, ifmodel);
+        machine_options ? : "", addr->u.q_unix.path, ifmodel);
 
     s = qtest_start(args);
     g_free(args);
@@ -78,7 +79,8 @@ void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
 void tpm_test_swtpm_migration_test(const char *src_tpm_path,
                                    const char *dst_tpm_path,
                                    const char *uri, tx_func *tx,
-                                   const char *ifmodel)
+                                   const char *ifmodel,
+                                   const char *machine_options)
 {
     gboolean succ;
     GPid src_tpm_pid, dst_tpm_pid;
@@ -100,7 +102,7 @@ void tpm_test_swtpm_migration_test(const char *src_tpm_path,
 
     tpm_util_migration_start_qemu(&src_qemu, &dst_qemu,
                                   src_tpm_addr, dst_tpm_addr, uri,
-                                  ifmodel);
+                                  ifmodel, machine_options);
 
     tpm_util_startup(src_qemu, tx);
     tpm_util_pcrextend(src_qemu, tx);
index b97688fe75337d840b41863cf5864ff9b1187777..a5df35ab5ba7685587400dbad7dec2bbcbffae1d 100644 (file)
 #include "tpm-util.h"
 
 void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
-                         const char *ifmodel);
+                         const char *ifmodel, const char *machine_options);
 
 void tpm_test_swtpm_migration_test(const char *src_tpm_path,
                                    const char *dst_tpm_path,
                                    const char *uri, tx_func *tx,
-                                   const char *ifmodel);
+                                   const char *ifmodel,
+                                   const char *machine_options);
 
 #endif /* TESTS_TPM_TESTS_H */
diff --git a/tests/qtest/tpm-tis-device-swtpm-test.c b/tests/qtest/tpm-tis-device-swtpm-test.c
new file mode 100644 (file)
index 0000000..7b20035
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * QTest testcase for Sysbus TPM TIS talking to external swtpm and swtpm
+ * migration
+ *
+ * Copyright (c) 2018 IBM Corporation
+ *  with parts borrowed from migration-test.c that is:
+ *     Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *   Stefan Berger <stefanb@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <glib/gstdio.h>
+
+#include "libqtest.h"
+#include "qemu/module.h"
+#include "tpm-tests.h"
+#include "hw/acpi/tpm.h"
+
+uint64_t tpm_tis_base_addr = 0xc000000;
+#define MACHINE_OPTIONS "-machine virt,gic-version=max -accel tcg"
+
+typedef struct TestState {
+    char *src_tpm_path;
+    char *dst_tpm_path;
+    char *uri;
+} TestState;
+
+static void tpm_tis_swtpm_test(const void *data)
+{
+    const TestState *ts = data;
+
+    tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
+                        "tpm-tis-device", MACHINE_OPTIONS);
+}
+
+static void tpm_tis_swtpm_migration_test(const void *data)
+{
+    const TestState *ts = data;
+
+    tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
+                                  tpm_util_tis_transfer, "tpm-tis-device",
+                                  MACHINE_OPTIONS);
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+    TestState ts = { 0 };
+
+    ts.src_tpm_path = g_dir_make_tmp("qemu-tpm-tis-device-swtpm-test.XXXXXX",
+                                     NULL);
+    ts.dst_tpm_path = g_dir_make_tmp("qemu-tpm-tis-device-swtpm-test.XXXXXX",
+                                     NULL);
+    ts.uri = g_strdup_printf("unix:%s/migsocket", ts.src_tpm_path);
+
+    module_call_init(MODULE_INIT_QOM);
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_data_func("/tpm/tis-swtpm/test", &ts, tpm_tis_swtpm_test);
+    qtest_add_data_func("/tpm/tis-swtpm-migration/test", &ts,
+                        tpm_tis_swtpm_migration_test);
+    ret = g_test_run();
+
+    g_rmdir(ts.dst_tpm_path);
+    g_free(ts.dst_tpm_path);
+    g_rmdir(ts.src_tpm_path);
+    g_free(ts.src_tpm_path);
+    g_free(ts.uri);
+
+    return ret;
+}
diff --git a/tests/qtest/tpm-tis-device-test.c b/tests/qtest/tpm-tis-device-test.c
new file mode 100644 (file)
index 0000000..63ed364
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * QTest testcase for SYSBUS TPM TIS
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ * Copyright (c) 2018 IBM Corporation
+ *
+ * Authors:
+ *   Marc-André Lureau <marcandre.lureau@redhat.com>
+ *   Stefan Berger <stefanb@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <glib/gstdio.h>
+
+#include "io/channel-socket.h"
+#include "libqtest-single.h"
+#include "qemu/module.h"
+#include "tpm-emu.h"
+#include "tpm-util.h"
+#include "tpm-tis-util.h"
+
+/*
+ * As the Sysbus tpm-tis-device is instantiated on the ARM virt
+ * platform bus and it is the only sysbus device dynamically
+ * instantiated, it gets plugged at its base address
+ */
+uint64_t tpm_tis_base_addr = 0xc000000;
+
+int main(int argc, char **argv)
+{
+    char *tmp_path = g_dir_make_tmp("qemu-tpm-tis-device-test.XXXXXX", NULL);
+    GThread *thread;
+    TestState test;
+    char *args;
+    int ret;
+
+    module_call_init(MODULE_INIT_QOM);
+    g_test_init(&argc, &argv, NULL);
+
+    test.addr = g_new0(SocketAddress, 1);
+    test.addr->type = SOCKET_ADDRESS_TYPE_UNIX;
+    test.addr->u.q_unix.path = g_build_filename(tmp_path, "sock", NULL);
+    g_mutex_init(&test.data_mutex);
+    g_cond_init(&test.data_cond);
+    test.data_cond_signal = false;
+
+    thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
+    tpm_emu_test_wait_cond(&test);
+
+    args = g_strdup_printf(
+        "-machine virt,gic-version=max -accel tcg "
+        "-chardev socket,id=chr,path=%s "
+        "-tpmdev emulator,id=dev,chardev=chr "
+        "-device tpm-tis-device,tpmdev=dev",
+        test.addr->u.q_unix.path);
+    qtest_start(args);
+
+    qtest_add_data_func("/tpm-tis/test_check_localities", &test,
+                        tpm_tis_test_check_localities);
+
+    qtest_add_data_func("/tpm-tis/test_check_access_reg", &test,
+                        tpm_tis_test_check_access_reg);
+
+    qtest_add_data_func("/tpm-tis/test_check_access_reg_seize", &test,
+                        tpm_tis_test_check_access_reg_seize);
+
+    qtest_add_data_func("/tpm-tis/test_check_access_reg_release", &test,
+                        tpm_tis_test_check_access_reg_release);
+
+    qtest_add_data_func("/tpm-tis/test_check_transmit", &test,
+                        tpm_tis_test_check_transmit);
+
+    ret = g_test_run();
+
+    qtest_end();
+
+    g_thread_join(thread);
+    g_unlink(test.addr->u.q_unix.path);
+    qapi_free_SocketAddress(test.addr);
+    g_rmdir(tmp_path);
+    g_free(tmp_path);
+    g_free(args);
+    return ret;
+}
index 9f58a3a92b2fde019f5d89a94fffac2157e5b1fa..90131cb3c487515f1a3f1124c8b9785296e1a11e 100644 (file)
@@ -18,6 +18,9 @@
 #include "libqtest.h"
 #include "qemu/module.h"
 #include "tpm-tests.h"
+#include "hw/acpi/tpm.h"
+
+uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
 
 typedef struct TestState {
     char *src_tpm_path;
@@ -29,7 +32,8 @@ static void tpm_tis_swtpm_test(const void *data)
 {
     const TestState *ts = data;
 
-    tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer, "tpm-tis");
+    tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
+                        "tpm-tis", NULL);
 }
 
 static void tpm_tis_swtpm_migration_test(const void *data)
@@ -37,7 +41,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
     const TestState *ts = data;
 
     tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
-                                  tpm_util_tis_transfer, "tpm-tis");
+                                  tpm_util_tis_transfer, "tpm-tis", NULL);
 }
 
 int main(int argc, char **argv)
index dcf30e05b74325e74be94e4a70bbe72171d370ac..79ffbc943e5246a66488ca249c494b62474ba0f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * QTest testcase for TPM TIS
+ * QTest testcase for ISA TPM TIS
  *
  * Copyright (c) 2018 Red Hat, Inc.
  * Copyright (c) 2018 IBM Corporation
 #include "libqtest-single.h"
 #include "qemu/module.h"
 #include "tpm-emu.h"
+#include "tpm-tis-util.h"
 
-#define TIS_REG(LOCTY, REG) \
-    (TPM_TIS_ADDR_BASE + ((LOCTY) << 12) + REG)
-
-#define DEBUG_TIS_TEST 0
-
-#define DPRINTF(fmt, ...) do { \
-    if (DEBUG_TIS_TEST) { \
-        printf(fmt, ## __VA_ARGS__); \
-    } \
-} while (0)
-
-#define DPRINTF_ACCESS \
-    DPRINTF("%s: %d: locty=%d l=%d access=0x%02x pending_request_flag=0x%x\n", \
-            __func__, __LINE__, locty, l, access, pending_request_flag)
-
-#define DPRINTF_STS \
-    DPRINTF("%s: %d: sts = 0x%08x\n", __func__, __LINE__, sts)
-
-static const uint8_t TPM_CMD[12] =
-    "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00";
-
-static void tpm_tis_test_check_localities(const void *data)
-{
-    uint8_t locty;
-    uint8_t access;
-    uint32_t ifaceid;
-    uint32_t capability;
-    uint32_t didvid;
-    uint32_t rid;
-
-    for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES; locty++) {
-        access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-        capability = readl(TIS_REG(locty, TPM_TIS_REG_INTF_CAPABILITY));
-        g_assert_cmpint(capability, ==, TPM_TIS_CAPABILITIES_SUPPORTED2_0);
-
-        ifaceid = readl(TIS_REG(locty, TPM_TIS_REG_INTERFACE_ID));
-        g_assert_cmpint(ifaceid, ==, TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0);
-
-        didvid = readl(TIS_REG(locty, TPM_TIS_REG_DID_VID));
-        g_assert_cmpint(didvid, !=, 0);
-        g_assert_cmpint(didvid, !=, 0xffffffff);
-
-        rid = readl(TIS_REG(locty, TPM_TIS_REG_RID));
-        g_assert_cmpint(rid, !=, 0);
-        g_assert_cmpint(rid, !=, 0xffffffff);
-    }
-}
-
-static void tpm_tis_test_check_access_reg(const void *data)
-{
-    uint8_t locty;
-    uint8_t access;
-
-    /* do not test locality 4 (hw only) */
-    for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES - 1; locty++) {
-        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-        /* request use of locality */
-        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
-
-        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-        /* release access */
-        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS),
-               TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-    }
-}
-
-/*
- * Test case for seizing access by a higher number locality
- */
-static void tpm_tis_test_check_access_reg_seize(const void *data)
-{
-    int locty, l;
-    uint8_t access;
-    uint8_t pending_request_flag;
-
-    /* do not test locality 4 (hw only) */
-    for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES - 1; locty++) {
-        pending_request_flag = 0;
-
-        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-        /* request use of locality */
-        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
-        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-        /* lower localities cannot seize access */
-        for (l = 0; l < locty; l++) {
-            /* lower locality is not active */
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* try to request use from 'l' */
-            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
-
-            /* requesting use from 'l' was not possible;
-               we must see REQUEST_USE and possibly PENDING_REQUEST */
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_REQUEST_USE |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* locality 'locty' must be unchanged;
-               we must see PENDING_REQUEST */
-            access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                        TPM_TIS_ACCESS_PENDING_REQUEST |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* try to seize from 'l' */
-            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_SEIZE);
-            /* seize from 'l' was not possible */
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_REQUEST_USE |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* locality 'locty' must be unchanged */
-            access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                        TPM_TIS_ACCESS_PENDING_REQUEST |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* on the next loop we will have a PENDING_REQUEST flag
-               set for locality 'l' */
-            pending_request_flag = TPM_TIS_ACCESS_PENDING_REQUEST;
-        }
-
-        /* higher localities can 'seize' access but not 'request use';
-           note: this will activate first l+1, then l+2 etc. */
-        for (l = locty + 1; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
-            /* try to 'request use' from 'l' */
-            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
-
-            /* requesting use from 'l' was not possible; we should see
-               REQUEST_USE and may see PENDING_REQUEST */
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_REQUEST_USE |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* locality 'l-1' must be unchanged; we should always
-               see PENDING_REQUEST from 'l' requesting access */
-            access = readb(TIS_REG(l - 1, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                        TPM_TIS_ACCESS_PENDING_REQUEST |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* try to seize from 'l' */
-            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_SEIZE);
-
-            /* seize from 'l' was possible */
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* l - 1 should show that it has BEEN_SEIZED */
-            access = readb(TIS_REG(l - 1, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_BEEN_SEIZED |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* clear the BEEN_SEIZED flag and make sure it's gone */
-            writeb(TIS_REG(l - 1, TPM_TIS_REG_ACCESS),
-                   TPM_TIS_ACCESS_BEEN_SEIZED);
-
-            access = readb(TIS_REG(l - 1, TPM_TIS_REG_ACCESS));
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-        }
-
-        /* PENDING_REQUEST will not be set if locty = 0 since all localities
-           were active; in case of locty = 1, locality 0 will be active
-           but no PENDING_REQUEST anywhere */
-        if (locty <= 1) {
-            pending_request_flag = 0;
-        }
-
-        /* release access from l - 1; this activates locty - 1 */
-        l--;
-
-        access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-        DPRINTF_ACCESS;
-
-        DPRINTF("%s: %d: relinquishing control on l = %d\n",
-                __func__, __LINE__, l);
-        writeb(TIS_REG(l, TPM_TIS_REG_ACCESS),
-               TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-
-        access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-        DPRINTF_ACCESS;
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    pending_request_flag |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-        for (l = locty - 1; l >= 0; l--) {
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-            /* release this locality */
-            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS),
-                   TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-
-            if (l == 1) {
-                pending_request_flag = 0;
-            }
-        }
-
-        /* no locality may be active now */
-        for (l = 0; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-        }
-    }
-}
-
-/*
- * Test case for getting access when higher number locality relinquishes access
- */
-static void tpm_tis_test_check_access_reg_release(const void *data)
-{
-    int locty, l;
-    uint8_t access;
-    uint8_t pending_request_flag;
-
-    /* do not test locality 4 (hw only) */
-    for (locty = TPM_TIS_NUM_LOCALITIES - 2; locty >= 0; locty--) {
-        pending_request_flag = 0;
-
-        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-        /* request use of locality */
-        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
-        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
-        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                    TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-        /* request use of all other localities */
-        for (l = 0; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
-            if (l == locty) {
-                continue;
-            }
-            /* request use of locality 'l' -- we MUST see REQUEST USE and
-               may see PENDING_REQUEST */
-            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_REQUEST_USE |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-            pending_request_flag = TPM_TIS_ACCESS_PENDING_REQUEST;
-        }
-        /* release locality 'locty' */
-        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS),
-               TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-        /* highest locality should now be active; release it and make sure the
-           next higest locality is active afterwards */
-        for (l = TPM_TIS_NUM_LOCALITIES - 2; l >= 0; l--) {
-            if (l == locty) {
-                continue;
-            }
-            /* 'l' should be active now */
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-            /* 'l' relinquishes access */
-            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS),
-                   TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
-            DPRINTF_ACCESS;
-            if (l == 1 || (locty <= 1 && l == 2)) {
-                pending_request_flag = 0;
-            }
-            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                        pending_request_flag |
-                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-        }
-    }
-}
-
-/*
- * Test case for transmitting packets
- */
-static void tpm_tis_test_check_transmit(const void *data)
-{
-    const TestState *s = data;
-    uint8_t access;
-    uint32_t sts;
-    uint16_t bcount;
-    size_t i;
-
-    /* request use of locality 0 */
-    writeb(TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
-    access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
-    g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-                                TPM_TIS_ACCESS_ACTIVE_LOCALITY |
-                                TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-    sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
-    DPRINTF_STS;
-
-    g_assert_cmpint(sts & 0xff, ==, 0);
-    g_assert_cmpint(sts & TPM_TIS_STS_TPM_FAMILY_MASK, ==,
-                    TPM_TIS_STS_TPM_FAMILY2_0);
-
-    bcount = (sts >> 8) & 0xffff;
-    g_assert_cmpint(bcount, >=, 128);
-
-    writel(TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_COMMAND_READY);
-    sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
-    DPRINTF_STS;
-    g_assert_cmpint(sts & 0xff, ==, TPM_TIS_STS_COMMAND_READY);
-
-    /* transmit command */
-    for (i = 0; i < sizeof(TPM_CMD); i++) {
-        writeb(TIS_REG(0, TPM_TIS_REG_DATA_FIFO), TPM_CMD[i]);
-        sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
-        DPRINTF_STS;
-        if (i < sizeof(TPM_CMD) - 1) {
-            g_assert_cmpint(sts & 0xff, ==,
-                            TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
-        } else {
-            g_assert_cmpint(sts & 0xff, ==, TPM_TIS_STS_VALID);
-        }
-        g_assert_cmpint((sts >> 8) & 0xffff, ==, --bcount);
-    }
-    /* start processing */
-    writeb(TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_TPM_GO);
-
-    uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
-    do {
-        sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
-        if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
-            break;
-        }
-    } while (g_get_monotonic_time() < end_time);
-
-    sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
-    DPRINTF_STS;
-    g_assert_cmpint(sts & 0xff, == ,
-                    TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
-    bcount = (sts >> 8) & 0xffff;
-
-    /* read response */
-    uint8_t tpm_msg[sizeof(struct tpm_hdr)];
-    g_assert_cmpint(sizeof(tpm_msg), ==, bcount);
-
-    for (i = 0; i < sizeof(tpm_msg); i++) {
-        tpm_msg[i] = readb(TIS_REG(0, TPM_TIS_REG_DATA_FIFO));
-        sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
-        DPRINTF_STS;
-        if (sts & TPM_TIS_STS_DATA_AVAILABLE) {
-            g_assert_cmpint((sts >> 8) & 0xffff, ==, --bcount);
-        }
-    }
-    g_assert_cmpmem(tpm_msg, sizeof(tpm_msg), s->tpm_msg, sizeof(*s->tpm_msg));
-
-    /* relinquish use of locality 0 */
-    writeb(TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-    access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
-}
+uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
 
 int main(int argc, char **argv)
 {
diff --git a/tests/qtest/tpm-tis-util.c b/tests/qtest/tpm-tis-util.c
new file mode 100644 (file)
index 0000000..9aff503
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * QTest testcase for TPM TIS: common test functions used for both
+ * the ISA and SYSBUS devices
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ * Copyright (c) 2018 IBM Corporation
+ *
+ * Authors:
+ *   Marc-André Lureau <marcandre.lureau@redhat.com>
+ *   Stefan Berger <stefanb@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <glib/gstdio.h>
+
+#include "hw/acpi/tpm.h"
+#include "io/channel-socket.h"
+#include "libqtest-single.h"
+#include "qemu/module.h"
+#include "tpm-emu.h"
+#include "tpm-util.h"
+#include "tpm-tis-util.h"
+
+#define DEBUG_TIS_TEST 0
+
+#define DPRINTF(fmt, ...) do { \
+    if (DEBUG_TIS_TEST) { \
+        printf(fmt, ## __VA_ARGS__); \
+    } \
+} while (0)
+
+#define DPRINTF_ACCESS \
+    DPRINTF("%s: %d: locty=%d l=%d access=0x%02x pending_request_flag=0x%x\n", \
+            __func__, __LINE__, locty, l, access, pending_request_flag)
+
+#define DPRINTF_STS \
+    DPRINTF("%s: %d: sts = 0x%08x\n", __func__, __LINE__, sts)
+
+static const uint8_t TPM_CMD[12] =
+    "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00";
+
+void tpm_tis_test_check_localities(const void *data)
+{
+    uint8_t locty;
+    uint8_t access;
+    uint32_t ifaceid;
+    uint32_t capability;
+    uint32_t didvid;
+    uint32_t rid;
+
+    for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES; locty++) {
+        access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+        capability = readl(TIS_REG(locty, TPM_TIS_REG_INTF_CAPABILITY));
+        g_assert_cmpint(capability, ==, TPM_TIS_CAPABILITIES_SUPPORTED2_0);
+
+        ifaceid = readl(TIS_REG(locty, TPM_TIS_REG_INTERFACE_ID));
+        g_assert_cmpint(ifaceid, ==, TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0);
+
+        didvid = readl(TIS_REG(locty, TPM_TIS_REG_DID_VID));
+        g_assert_cmpint(didvid, !=, 0);
+        g_assert_cmpint(didvid, !=, 0xffffffff);
+
+        rid = readl(TIS_REG(locty, TPM_TIS_REG_RID));
+        g_assert_cmpint(rid, !=, 0);
+        g_assert_cmpint(rid, !=, 0xffffffff);
+    }
+}
+
+void tpm_tis_test_check_access_reg(const void *data)
+{
+    uint8_t locty;
+    uint8_t access;
+
+    /* do not test locality 4 (hw only) */
+    for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES - 1; locty++) {
+        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+        /* request use of locality */
+        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
+
+        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+        /* release access */
+        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS),
+               TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+    }
+}
+
+/*
+ * Test case for seizing access by a higher number locality
+ */
+void tpm_tis_test_check_access_reg_seize(const void *data)
+{
+    int locty, l;
+    uint8_t access;
+    uint8_t pending_request_flag;
+
+    /* do not test locality 4 (hw only) */
+    for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES - 1; locty++) {
+        pending_request_flag = 0;
+
+        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+        /* request use of locality */
+        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
+        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+        /* lower localities cannot seize access */
+        for (l = 0; l < locty; l++) {
+            /* lower locality is not active */
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /* try to request use from 'l' */
+            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
+
+            /*
+             * requesting use from 'l' was not possible;
+             * we must see REQUEST_USE and possibly PENDING_REQUEST
+             */
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_REQUEST_USE |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /*
+             * locality 'locty' must be unchanged;
+             * we must see PENDING_REQUEST
+             */
+            access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                        TPM_TIS_ACCESS_PENDING_REQUEST |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /* try to seize from 'l' */
+            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_SEIZE);
+            /* seize from 'l' was not possible */
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_REQUEST_USE |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /* locality 'locty' must be unchanged */
+            access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                        TPM_TIS_ACCESS_PENDING_REQUEST |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /*
+             * on the next loop we will have a PENDING_REQUEST flag
+             * set for locality 'l'
+             */
+            pending_request_flag = TPM_TIS_ACCESS_PENDING_REQUEST;
+        }
+
+        /*
+         * higher localities can 'seize' access but not 'request use';
+         * note: this will activate first l+1, then l+2 etc.
+         */
+        for (l = locty + 1; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
+            /* try to 'request use' from 'l' */
+            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
+
+            /*
+             * requesting use from 'l' was not possible; we should see
+             * REQUEST_USE and may see PENDING_REQUEST
+             */
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_REQUEST_USE |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /*
+             * locality 'l-1' must be unchanged; we should always
+             * see PENDING_REQUEST from 'l' requesting access
+             */
+            access = readb(TIS_REG(l - 1, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                        TPM_TIS_ACCESS_PENDING_REQUEST |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /* try to seize from 'l' */
+            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_SEIZE);
+
+            /* seize from 'l' was possible */
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /* l - 1 should show that it has BEEN_SEIZED */
+            access = readb(TIS_REG(l - 1, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_BEEN_SEIZED |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /* clear the BEEN_SEIZED flag and make sure it's gone */
+            writeb(TIS_REG(l - 1, TPM_TIS_REG_ACCESS),
+                   TPM_TIS_ACCESS_BEEN_SEIZED);
+
+            access = readb(TIS_REG(l - 1, TPM_TIS_REG_ACCESS));
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+        }
+
+        /*
+         * PENDING_REQUEST will not be set if locty = 0 since all localities
+         * were active; in case of locty = 1, locality 0 will be active
+         * but no PENDING_REQUEST anywhere
+         */
+        if (locty <= 1) {
+            pending_request_flag = 0;
+        }
+
+        /* release access from l - 1; this activates locty - 1 */
+        l--;
+
+        access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+        DPRINTF_ACCESS;
+
+        DPRINTF("%s: %d: relinquishing control on l = %d\n",
+                __func__, __LINE__, l);
+        writeb(TIS_REG(l, TPM_TIS_REG_ACCESS),
+               TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+
+        access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+        DPRINTF_ACCESS;
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    pending_request_flag |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+        for (l = locty - 1; l >= 0; l--) {
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+            /* release this locality */
+            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS),
+                   TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+
+            if (l == 1) {
+                pending_request_flag = 0;
+            }
+        }
+
+        /* no locality may be active now */
+        for (l = 0; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+        }
+    }
+}
+
+/*
+ * Test case for getting access when higher number locality relinquishes access
+ */
+void tpm_tis_test_check_access_reg_release(const void *data)
+{
+    int locty, l;
+    uint8_t access;
+    uint8_t pending_request_flag;
+
+    /* do not test locality 4 (hw only) */
+    for (locty = TPM_TIS_NUM_LOCALITIES - 2; locty >= 0; locty--) {
+        pending_request_flag = 0;
+
+        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+        /* request use of locality */
+        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
+        access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
+        g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                    TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                    TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+        /* request use of all other localities */
+        for (l = 0; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
+            if (l == locty) {
+                continue;
+            }
+            /*
+             * request use of locality 'l' -- we MUST see REQUEST USE and
+             * may see PENDING_REQUEST
+             */
+            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_REQUEST_USE |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+            pending_request_flag = TPM_TIS_ACCESS_PENDING_REQUEST;
+        }
+        /* release locality 'locty' */
+        writeb(TIS_REG(locty, TPM_TIS_REG_ACCESS),
+               TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+        /*
+         * highest locality should now be active; release it and make sure the
+         * next higest locality is active afterwards
+         */
+        for (l = TPM_TIS_NUM_LOCALITIES - 2; l >= 0; l--) {
+            if (l == locty) {
+                continue;
+            }
+            /* 'l' should be active now */
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+            /* 'l' relinquishes access */
+            writeb(TIS_REG(l, TPM_TIS_REG_ACCESS),
+                   TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+            access = readb(TIS_REG(l, TPM_TIS_REG_ACCESS));
+            DPRINTF_ACCESS;
+            if (l == 1 || (locty <= 1 && l == 2)) {
+                pending_request_flag = 0;
+            }
+            g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                        pending_request_flag |
+                                        TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+        }
+    }
+}
+
+/*
+ * Test case for transmitting packets
+ */
+void tpm_tis_test_check_transmit(const void *data)
+{
+    const TestState *s = data;
+    uint8_t access;
+    uint32_t sts;
+    uint16_t bcount;
+    size_t i;
+
+    /* request use of locality 0 */
+    writeb(TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
+    access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
+    g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
+                                TPM_TIS_ACCESS_ACTIVE_LOCALITY |
+                                TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
+
+    sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
+    DPRINTF_STS;
+
+    g_assert_cmpint(sts & 0xff, ==, 0);
+    g_assert_cmpint(sts & TPM_TIS_STS_TPM_FAMILY_MASK, ==,
+                    TPM_TIS_STS_TPM_FAMILY2_0);
+
+    bcount = (sts >> 8) & 0xffff;
+    g_assert_cmpint(bcount, >=, 128);
+
+    writel(TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_COMMAND_READY);
+    sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
+    DPRINTF_STS;
+    g_assert_cmpint(sts & 0xff, ==, TPM_TIS_STS_COMMAND_READY);
+
+    /* transmit command */
+    for (i = 0; i < sizeof(TPM_CMD); i++) {
+        writeb(TIS_REG(0, TPM_TIS_REG_DATA_FIFO), TPM_CMD[i]);
+        sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
+        DPRINTF_STS;
+        if (i < sizeof(TPM_CMD) - 1) {
+            g_assert_cmpint(sts & 0xff, ==,
+                            TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
+        } else {
+            g_assert_cmpint(sts & 0xff, ==, TPM_TIS_STS_VALID);
+        }
+        g_assert_cmpint((sts >> 8) & 0xffff, ==, --bcount);
+    }
+    /* start processing */
+    writeb(TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_TPM_GO);
+
+    uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
+    do {
+        sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
+        if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
+            break;
+        }
+    } while (g_get_monotonic_time() < end_time);
+
+    sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
+    DPRINTF_STS;
+    g_assert_cmpint(sts & 0xff, == ,
+                    TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
+    bcount = (sts >> 8) & 0xffff;
+
+    /* read response */
+    uint8_t tpm_msg[sizeof(struct tpm_hdr)];
+    g_assert_cmpint(sizeof(tpm_msg), ==, bcount);
+
+    for (i = 0; i < sizeof(tpm_msg); i++) {
+        tpm_msg[i] = readb(TIS_REG(0, TPM_TIS_REG_DATA_FIFO));
+        sts = readl(TIS_REG(0, TPM_TIS_REG_STS));
+        DPRINTF_STS;
+        if (sts & TPM_TIS_STS_DATA_AVAILABLE) {
+            g_assert_cmpint((sts >> 8) & 0xffff, ==, --bcount);
+        }
+    }
+    g_assert_cmpmem(tpm_msg, sizeof(tpm_msg), s->tpm_msg, sizeof(*s->tpm_msg));
+
+    /* relinquish use of locality 0 */
+    writeb(TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+    access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
+}
diff --git a/tests/qtest/tpm-tis-util.h b/tests/qtest/tpm-tis-util.h
new file mode 100644 (file)
index 0000000..d10efe8
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * QTest TPM TIS: Common test functions used for both the
+ * ISA and SYSBUS devices
+ *
+ * Copyright (c) 2018 IBM Corporation
+ *
+ * Authors:
+ *   Stefan Berger <stefanb@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef TESTS_TPM_TIS_UTIL_H
+#define TESTS_TPM_TIS_UTIL_H
+
+void tpm_tis_test_check_localities(const void *data);
+void tpm_tis_test_check_access_reg(const void *data);
+void tpm_tis_test_check_access_reg_seize(const void *data);
+void tpm_tis_test_check_access_reg_release(const void *data);
+void tpm_tis_test_check_transmit(const void *data);
+
+#endif /* TESTS_TPM_TIS_UTIL_H */
index e08b13765148f3c44e8a97564a0396424a19700e..34efae8f181d83bc34a62367ebc184a6702863de 100644 (file)
@@ -19,9 +19,6 @@
 #include "tpm-util.h"
 #include "qapi/qmp/qdict.h"
 
-#define TIS_REG(LOCTY, REG) \
-    (TPM_TIS_ADDR_BASE + ((LOCTY) << 12) + REG)
-
 void tpm_util_crb_transfer(QTestState *s,
                            const unsigned char *req, size_t req_size,
                            unsigned char *rsp, size_t rsp_size)
@@ -258,23 +255,27 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu,
                                    SocketAddress *src_tpm_addr,
                                    SocketAddress *dst_tpm_addr,
                                    const char *miguri,
-                                   const char *ifmodel)
+                                   const char *ifmodel,
+                                   const char *machine_options)
 {
     char *src_qemu_args, *dst_qemu_args;
 
     src_qemu_args = g_strdup_printf(
+        "%s "
         "-chardev socket,id=chr,path=%s "
         "-tpmdev emulator,id=dev,chardev=chr "
         "-device %s,tpmdev=dev ",
-        src_tpm_addr->u.q_unix.path, ifmodel);
+        machine_options ? : "", src_tpm_addr->u.q_unix.path, ifmodel);
 
     *src_qemu = qtest_init(src_qemu_args);
 
     dst_qemu_args = g_strdup_printf(
+        "%s "
         "-chardev socket,id=chr,path=%s "
         "-tpmdev emulator,id=dev,chardev=chr "
         "-device %s,tpmdev=dev "
         "-incoming %s",
+        machine_options ? : "",
         dst_tpm_addr->u.q_unix.path,
         ifmodel, miguri);
 
index 5755698ad2a465846f18ed85e10cc69c9822f4a6..3b97d690170c6a32a03c18e68d43426f16097780 100644 (file)
 
 #include "io/channel-socket.h"
 
+extern uint64_t tpm_tis_base_addr;
+
+#define TIS_REG(LOCTY, REG) \
+    (tpm_tis_base_addr + ((LOCTY) << 12) + REG)
+
 typedef void (tx_func)(QTestState *s,
                        const unsigned char *req, size_t req_size,
                        unsigned char *rsp, size_t rsp_size);
@@ -44,7 +49,8 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu,
                                    SocketAddress *src_tpm_addr,
                                    SocketAddress *dst_tpm_addr,
                                    const char *miguri,
-                                   const char *ifmodel);
+                                   const char *ifmodel,
+                                   const char *machine_options);
 
 void tpm_util_wait_for_migration_complete(QTestState *who);
 
index a2a587223a9c0fb6f99c2170f518a45ad5b45eb0..f4f1736a086e0387a7e20da931c05170e8da541d 100644 (file)
@@ -1,4 +1,4 @@
 # Add Python module requirements, one per line, to be installed
 # in the tests/venv Python virtual environment. For more info,
 # refer to: https://pip.pypa.io/en/stable/user_guide/#id1
-avocado-framework==72.0
+avocado-framework==76.0
index ea0984ea823de31a19627a331f2360ab2966147f..d3878cbeb6e50057ffca5c5e539ae8b6825d8774 100644 (file)
@@ -29,7 +29,7 @@ int main()
     }
 
     perc = (float) count / (float) (TESTS * 2);
-    printf("Ptr Check: %0.2f%%", perc * 100.0);
+    printf("Ptr Check: %0.2f%%\n", perc * 100.0);
     assert(perc > 0.95);
     return 0;
 }
index 1442c0c98269104846b730c4981e168302842490..92be51ec505b2b231fd1d331f87cc3168539bd48 100644 (file)
@@ -235,7 +235,7 @@ static void *rcu_q_updater(void *arg)
             j++;
             if (target_el == j) {
                 struct list_element *new_el = g_new(struct list_element, 1);
-                n_nodes += n_nodes_local;
+                n_nodes_local++;
                 TEST_LIST_INSERT_AFTER_RCU(el, new_el, entry);
                 break;
             }
index 8ce55efe703c5df49127fabecced07ca1c36cba5..5fd947c7bf6d054a59a0928f32915618915d16f6 100644 (file)
@@ -71,8 +71,8 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
  */
 __thread Monitor *cur_mon;
 int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
-void monitor_init_qmp(Chardev *chr, bool pretty) {}
-void monitor_init_hmp(Chardev *chr, bool use_readline) {}
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) {}
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp) {}
 
 
 static void test_socket_fd_pass_name_good(void)
index 9e7c46a4735b7b6aa587ae044498f88ab541f52d..1bf9693d195b8a057ce1a5e57b8c92a1efc9a7fc 100644 (file)
@@ -2,7 +2,11 @@
 
 .PHONY: vm-build-all vm-clean-all
 
-IMAGES := ubuntu.i386 freebsd netbsd openbsd centos fedora
+IMAGES := freebsd netbsd openbsd centos fedora
+ifneq ($(GENISOIMAGE),)
+IMAGES += ubuntu.i386 centos
+endif
+
 IMAGES_DIR := $(HOME)/.cache/qemu-vm/images
 IMAGE_FILES := $(patsubst %, $(IMAGES_DIR)/%.img, $(IMAGES))
 
@@ -12,12 +16,16 @@ IMAGE_FILES := $(patsubst %, $(IMAGES_DIR)/%.img, $(IMAGES))
 vm-help vm-test:
        @echo "vm-help: Test QEMU in preconfigured virtual machines"
        @echo
-       @echo "  vm-build-ubuntu.i386            - Build QEMU in ubuntu i386 VM"
        @echo "  vm-build-freebsd                - Build QEMU in FreeBSD VM"
        @echo "  vm-build-netbsd                 - Build QEMU in NetBSD VM"
        @echo "  vm-build-openbsd                - Build QEMU in OpenBSD VM"
-       @echo "  vm-build-centos                 - Build QEMU in CentOS VM, with Docker"
        @echo "  vm-build-fedora                 - Build QEMU in Fedora VM"
+ifneq ($(GENISOIMAGE),)
+       @echo "  vm-build-centos                 - Build QEMU in CentOS VM, with Docker"
+       @echo "  vm-build-ubuntu.i386            - Build QEMU in ubuntu i386 VM"
+else
+       @echo "  (install genisoimage to build centos/ubuntu images)"
+endif
        @echo ""
        @echo "  vm-build-all                    - Build QEMU in all VMs"
        @echo "  vm-clean-all                    - Clean up VM images"
@@ -80,7 +88,7 @@ vm-boot-serial-%: $(IMAGES_DIR)/%.img
 
 vm-boot-ssh-%: $(IMAGES_DIR)/%.img
        $(call quiet-command, \
-               $(SRC_PATH)/tests/vm/$* \
+               $(PYTHON) $(SRC_PATH)/tests/vm/$* \
                $(if $(J),--jobs $(J)) \
                --image "$<" \
                --interactive \
index 4dee6647e6e67f77a7d7f9de5b70fe414be2ba0f..8400b0e07f65785ed2cc5df1fb53687b7eb70f43 100644 (file)
@@ -57,6 +57,10 @@ class BaseVM(object):
     poweroff = "poweroff"
     # enable IPv6 networking
     ipv6 = True
+    # Scale up some timeouts under TCG.
+    # 4 is arbitrary, but greater than 2,
+    # since we found we need to wait more than twice as long.
+    tcg_ssh_timeout_multiplier = 4
     def __init__(self, debug=False, vcpus=None):
         self._guest = None
         self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
@@ -120,11 +124,16 @@ class BaseVM(object):
         return fname
 
     def _ssh_do(self, user, cmd, check):
-        ssh_cmd = ["ssh", "-q", "-t",
+        ssh_cmd = ["ssh",
+                   "-t",
                    "-o", "StrictHostKeyChecking=no",
                    "-o", "UserKnownHostsFile=" + os.devnull,
                    "-o", "ConnectTimeout=1",
                    "-p", self.ssh_port, "-i", self._ssh_key_file]
+        # If not in debug mode, set ssh to quiet mode to
+        # avoid printing the results of commands.
+        if not self.debug:
+            ssh_cmd.append("-q")
         for var in self.envvars:
             ssh_cmd += ['-o', "SendEnv=%s" % var ]
         assert not isinstance(cmd, str)
@@ -303,12 +312,18 @@ class BaseVM(object):
     def print_step(self, text):
         sys.stderr.write("### %s ...\n" % text)
 
-    def wait_ssh(self, seconds=300):
+    def wait_ssh(self, wait_root=False, seconds=300):
+        # Allow more time for VM to boot under TCG.
+        if not kvm_available(self.arch):
+            seconds *= self.tcg_ssh_timeout_multiplier
         starttime = datetime.datetime.now()
         endtime = starttime + datetime.timedelta(seconds=seconds)
         guest_up = False
         while datetime.datetime.now() < endtime:
-            if self.ssh("exit 0") == 0:
+            if wait_root and self.ssh_root("exit 0") == 0:
+                guest_up = True
+                break
+            elif self.ssh("exit 0") == 0:
                 guest_up = True
                 break
             seconds = (endtime - datetime.datetime.now()).total_seconds()
@@ -330,6 +345,46 @@ class BaseVM(object):
     def qmp(self, *args, **kwargs):
         return self._guest.qmp(*args, **kwargs)
 
+    def gen_cloud_init_iso(self):
+        cidir = self._tmpdir
+        mdata = open(os.path.join(cidir, "meta-data"), "w")
+        name = self.name.replace(".","-")
+        mdata.writelines(["instance-id: {}-vm-0\n".format(name),
+                          "local-hostname: {}-guest\n".format(name)])
+        mdata.close()
+        udata = open(os.path.join(cidir, "user-data"), "w")
+        print("guest user:pw {}:{}".format(self._config['guest_user'],
+                                           self._config['guest_pass']))
+        udata.writelines(["#cloud-config\n",
+                          "chpasswd:\n",
+                          "  list: |\n",
+                          "    root:%s\n" % self._config['root_pass'],
+                          "    %s:%s\n" % (self._config['guest_user'],
+                                           self._config['guest_pass']),
+                          "  expire: False\n",
+                          "users:\n",
+                          "  - name: %s\n" % self._config['guest_user'],
+                          "    sudo: ALL=(ALL) NOPASSWD:ALL\n",
+                          "    ssh-authorized-keys:\n",
+                          "    - %s\n" % self._config['ssh_pub_key'],
+                          "  - name: root\n",
+                          "    ssh-authorized-keys:\n",
+                          "    - %s\n" % self._config['ssh_pub_key'],
+                          "locale: en_US.UTF-8\n"])
+        proxy = os.environ.get("http_proxy")
+        if not proxy is None:
+            udata.writelines(["apt:\n",
+                              "  proxy: %s" % proxy])
+        udata.close()
+        subprocess.check_call(["genisoimage", "-output", "cloud-init.iso",
+                               "-volid", "cidata", "-joliet", "-rock",
+                               "user-data", "meta-data"],
+                               cwd=cidir,
+                               stdin=self._devnull, stdout=self._stdout,
+                               stderr=self._stdout)
+
+        return os.path.join(cidir, "cloud-init.iso")
+
 def parse_args(vmcls):
 
     def get_default_jobs():
index a41ff109eb5174be61444ca258cf4771cacc34a6..0ad4ecf4190e130cebdf804454ee07e8d65208e6 100755 (executable)
@@ -31,37 +31,6 @@ class CentosVM(basevm.BaseVM):
         make docker-test-mingw@fedora  {verbose} J={jobs} NETWORK=1;
     """
 
-    def _gen_cloud_init_iso(self):
-        cidir = self._tmpdir
-        mdata = open(os.path.join(cidir, "meta-data"), "w")
-        mdata.writelines(["instance-id: centos-vm-0\n",
-                          "local-hostname: centos-guest\n"])
-        mdata.close()
-        udata = open(os.path.join(cidir, "user-data"), "w")
-        udata.writelines(["#cloud-config\n",
-                          "chpasswd:\n",
-                          "  list: |\n",
-                          "    root:%s\n" % self.ROOT_PASS,
-                          "    %s:%s\n" % (self.GUEST_USER, self.GUEST_PASS),
-                          "  expire: False\n",
-                          "users:\n",
-                          "  - name: %s\n" % self.GUEST_USER,
-                          "    sudo: ALL=(ALL) NOPASSWD:ALL\n",
-                          "    ssh-authorized-keys:\n",
-                          "    - %s\n" % basevm.SSH_PUB_KEY,
-                          "  - name: root\n",
-                          "    ssh-authorized-keys:\n",
-                          "    - %s\n" % basevm.SSH_PUB_KEY,
-                          "locale: en_US.UTF-8\n"])
-        udata.close()
-        subprocess.check_call(["genisoimage", "-output", "cloud-init.iso",
-                               "-volid", "cidata", "-joliet", "-rock",
-                               "user-data", "meta-data"],
-                               cwd=cidir,
-                               stdin=self._devnull, stdout=self._stdout,
-                               stderr=self._stdout)
-        return os.path.join(cidir, "cloud-init.iso")
-
     def build_image(self, img):
         cimg = self._download_with_cache("https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1802.qcow2.xz")
         img_tmp = img + ".tmp"
@@ -69,7 +38,7 @@ class CentosVM(basevm.BaseVM):
         subprocess.check_call(["ln", "-f", cimg, img_tmp + ".xz"])
         subprocess.check_call(["xz", "--keep", "-dvf", img_tmp + ".xz"])
         self.exec_qemu_img("resize", img_tmp, "50G")
-        self.boot(img_tmp, extra_args = ["-cdrom", self._gen_cloud_init_iso()])
+        self.boot(img_tmp, extra_args = ["-cdrom", self.gen_cloud_init_iso()])
         self.wait_ssh()
         self.ssh_root_check("touch /etc/cloud/cloud-init.disabled")
         self.ssh_root_check("yum update -y")
index 48e9cb1ad3da5d77884fd114f3f395cc747018d3..3266038fbde503a2c40d6857278d024d778e67d1 100755 (executable)
@@ -29,41 +29,6 @@ class UbuntuX86VM(basevm.BaseVM):
         make --output-sync {target} -j{jobs} {verbose};
     """
 
-    def _gen_cloud_init_iso(self):
-        cidir = self._tmpdir
-        mdata = open(os.path.join(cidir, "meta-data"), "w")
-        mdata.writelines(["instance-id: ubuntu-vm-0\n",
-                          "local-hostname: ubuntu-guest\n"])
-        mdata.close()
-        udata = open(os.path.join(cidir, "user-data"), "w")
-        udata.writelines(["#cloud-config\n",
-                          "chpasswd:\n",
-                          "  list: |\n",
-                          "    root:%s\n" % self.ROOT_PASS,
-                          "    %s:%s\n" % (self.GUEST_USER, self.GUEST_PASS),
-                          "  expire: False\n",
-                          "users:\n",
-                          "  - name: %s\n" % self.GUEST_USER,
-                          "    sudo: ALL=(ALL) NOPASSWD:ALL\n",
-                          "    ssh-authorized-keys:\n",
-                          "    - %s\n" % basevm.SSH_PUB_KEY,
-                          "  - name: root\n",
-                          "    ssh-authorized-keys:\n",
-                          "    - %s\n" % basevm.SSH_PUB_KEY,
-                          "locale: en_US.UTF-8\n"])
-        proxy = os.environ.get("http_proxy")
-        if not proxy is None:
-            udata.writelines(["apt:\n",
-                              "  proxy: %s" % proxy])
-        udata.close()
-        subprocess.check_call(["genisoimage", "-output", "cloud-init.iso",
-                               "-volid", "cidata", "-joliet", "-rock",
-                               "user-data", "meta-data"],
-                               cwd=cidir,
-                               stdin=self._devnull, stdout=self._stdout,
-                               stderr=self._stdout)
-        return os.path.join(cidir, "cloud-init.iso")
-
     def build_image(self, img):
         cimg = self._download_with_cache(
             "https://cloud-images.ubuntu.com/releases/bionic/release-20191114/ubuntu-18.04-server-cloudimg-i386.img",
@@ -71,7 +36,7 @@ class UbuntuX86VM(basevm.BaseVM):
         img_tmp = img + ".tmp"
         subprocess.check_call(["cp", "-f", cimg, img_tmp])
         self.exec_qemu_img("resize", img_tmp, "50G")
-        self.boot(img_tmp, extra_args = ["-cdrom", self._gen_cloud_init_iso()])
+        self.boot(img_tmp, extra_args = ["-cdrom", self.gen_cloud_init_iso()])
         self.wait_ssh()
         self.ssh_root_check("touch /etc/cloud/cloud-init.disabled")
         self.ssh_root_check("apt-get update")
index dd1c605dbf63510f2bb335dd1ba2c91d877c53bd..3b6d16a0417ae560ee46dfec9254039487251007 100644 (file)
@@ -426,6 +426,8 @@ err:
     return ret;
 }
 
+static __thread bool clone_fs_called;
+
 /* Process one FVRequest in a thread pool */
 static void fv_queue_worker(gpointer data, gpointer user_data)
 {
@@ -441,6 +443,17 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
 
     assert(se->bufsize > sizeof(struct fuse_in_header));
 
+    if (!clone_fs_called) {
+        int ret;
+
+        /* unshare FS for xattr operation */
+        ret = unshare(CLONE_FS);
+        /* should not fail */
+        assert(ret == 0);
+
+        clone_fs_called = true;
+    }
+
     /*
      * An element contains one request and the space to send our response
      * They're spread over multiple descriptors in a scatter/gather set
index 02ff01fad092f7af2064519a69347e4809d3a177..4f259aac70ddb1b76bc4178ab8cbe8f7c364bdb4 100644 (file)
@@ -123,7 +123,7 @@ struct lo_inode {
     pthread_mutex_t plock_mutex;
     GHashTable *posix_locks; /* protected by lo_inode->plock_mutex */
 
-    bool is_symlink;
+    mode_t filetype;
 };
 
 struct lo_cred {
@@ -695,7 +695,7 @@ static int utimensat_empty(struct lo_data *lo, struct lo_inode *inode,
     struct lo_inode *parent;
     char path[PATH_MAX];
 
-    if (inode->is_symlink) {
+    if (S_ISLNK(inode->filetype)) {
         res = utimensat(inode->fd, "", tv, AT_EMPTY_PATH);
         if (res == -1 && errno == EINVAL) {
             /* Sorry, no race free way to set times on symlink. */
@@ -928,7 +928,8 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name,
             goto out_err;
         }
 
-        inode->is_symlink = S_ISLNK(e->attr.st_mode);
+        /* cache only filetype */
+        inode->filetype = (e->attr.st_mode & S_IFMT);
 
         /*
          * One for the caller and one for nlookup (released in
@@ -1135,7 +1136,7 @@ static int linkat_empty_nofollow(struct lo_data *lo, struct lo_inode *inode,
     struct lo_inode *parent;
     char path[PATH_MAX];
 
-    if (inode->is_symlink) {
+    if (S_ISLNK(inode->filetype)) {
         res = linkat(inode->fd, "", dfd, name, AT_EMPTY_PATH);
         if (res == -1 && (errno == ENOENT || errno == EINVAL)) {
             /* Sorry, no race free way to hard-link a symlink. */
@@ -2189,40 +2190,43 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
     fuse_log(FUSE_LOG_DEBUG, "lo_getxattr(ino=%" PRIu64 ", name=%s size=%zd)\n",
              ino, name, size);
 
-    if (inode->is_symlink) {
-        /* Sorry, no race free way to getxattr on symlink. */
-        saverr = EPERM;
-        goto out;
-    }
-
-    sprintf(procname, "%i", inode->fd);
-    fd = openat(lo->proc_self_fd, procname, O_RDONLY);
-    if (fd < 0) {
-        goto out_err;
-    }
-
     if (size) {
         value = malloc(size);
         if (!value) {
             goto out_err;
         }
+    }
 
-        ret = fgetxattr(fd, name, value, size);
-        if (ret == -1) {
+    sprintf(procname, "%i", inode->fd);
+    /*
+     * It is not safe to open() non-regular/non-dir files in file server
+     * unless O_PATH is used, so use that method for regular files/dir
+     * only (as it seems giving less performance overhead).
+     * Otherwise, call fchdir() to avoid open().
+     */
+    if (S_ISREG(inode->filetype) || S_ISDIR(inode->filetype)) {
+        fd = openat(lo->proc_self_fd, procname, O_RDONLY);
+        if (fd < 0) {
             goto out_err;
         }
+        ret = fgetxattr(fd, name, value, size);
+    } else {
+        /* fchdir should not fail here */
+        assert(fchdir(lo->proc_self_fd) == 0);
+        ret = getxattr(procname, name, value, size);
+        assert(fchdir(lo->root.fd) == 0);
+    }
+
+    if (ret == -1) {
+        goto out_err;
+    }
+    if (size) {
         saverr = 0;
         if (ret == 0) {
             goto out;
         }
-
         fuse_reply_buf(req, value, ret);
     } else {
-        ret = fgetxattr(fd, name, NULL, 0);
-        if (ret == -1) {
-            goto out_err;
-        }
-
         fuse_reply_xattr(req, ret);
     }
 out_free:
@@ -2238,7 +2242,6 @@ out_free:
 out_err:
     saverr = errno;
 out:
-    lo_inode_put(lo, &inode);
     fuse_reply_err(req, saverr);
     goto out_free;
 }
@@ -2267,40 +2270,37 @@ static void lo_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
     fuse_log(FUSE_LOG_DEBUG, "lo_listxattr(ino=%" PRIu64 ", size=%zd)\n", ino,
              size);
 
-    if (inode->is_symlink) {
-        /* Sorry, no race free way to listxattr on symlink. */
-        saverr = EPERM;
-        goto out;
-    }
-
-    sprintf(procname, "%i", inode->fd);
-    fd = openat(lo->proc_self_fd, procname, O_RDONLY);
-    if (fd < 0) {
-        goto out_err;
-    }
-
     if (size) {
         value = malloc(size);
         if (!value) {
             goto out_err;
         }
+    }
 
-        ret = flistxattr(fd, value, size);
-        if (ret == -1) {
+    sprintf(procname, "%i", inode->fd);
+    if (S_ISREG(inode->filetype) || S_ISDIR(inode->filetype)) {
+        fd = openat(lo->proc_self_fd, procname, O_RDONLY);
+        if (fd < 0) {
             goto out_err;
         }
+        ret = flistxattr(fd, value, size);
+    } else {
+        /* fchdir should not fail here */
+        assert(fchdir(lo->proc_self_fd) == 0);
+        ret = listxattr(procname, value, size);
+        assert(fchdir(lo->root.fd) == 0);
+    }
+
+    if (ret == -1) {
+        goto out_err;
+    }
+    if (size) {
         saverr = 0;
         if (ret == 0) {
             goto out;
         }
-
         fuse_reply_buf(req, value, ret);
     } else {
-        ret = flistxattr(fd, NULL, 0);
-        if (ret == -1) {
-            goto out_err;
-        }
-
         fuse_reply_xattr(req, ret);
     }
 out_free:
@@ -2316,7 +2316,6 @@ out_free:
 out_err:
     saverr = errno;
 out:
-    lo_inode_put(lo, &inode);
     fuse_reply_err(req, saverr);
     goto out_free;
 }
@@ -2345,20 +2344,21 @@ static void lo_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
     fuse_log(FUSE_LOG_DEBUG, "lo_setxattr(ino=%" PRIu64
              ", name=%s value=%s size=%zd)\n", ino, name, value, size);
 
-    if (inode->is_symlink) {
-        /* Sorry, no race free way to setxattr on symlink. */
-        saverr = EPERM;
-        goto out;
-    }
-
     sprintf(procname, "%i", inode->fd);
-    fd = openat(lo->proc_self_fd, procname, O_RDWR);
-    if (fd < 0) {
-        saverr = errno;
-        goto out;
+    if (S_ISREG(inode->filetype) || S_ISDIR(inode->filetype)) {
+        fd = openat(lo->proc_self_fd, procname, O_RDONLY);
+        if (fd < 0) {
+            saverr = errno;
+            goto out;
+        }
+        ret = fsetxattr(fd, name, value, size, flags);
+    } else {
+        /* fchdir should not fail here */
+        assert(fchdir(lo->proc_self_fd) == 0);
+        ret = setxattr(procname, name, value, size, flags);
+        assert(fchdir(lo->root.fd) == 0);
     }
 
-    ret = fsetxattr(fd, name, value, size, flags);
     saverr = ret == -1 ? errno : 0;
 
 out:
@@ -2393,20 +2393,21 @@ static void lo_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name)
     fuse_log(FUSE_LOG_DEBUG, "lo_removexattr(ino=%" PRIu64 ", name=%s)\n", ino,
              name);
 
-    if (inode->is_symlink) {
-        /* Sorry, no race free way to setxattr on symlink. */
-        saverr = EPERM;
-        goto out;
-    }
-
     sprintf(procname, "%i", inode->fd);
-    fd = openat(lo->proc_self_fd, procname, O_RDWR);
-    if (fd < 0) {
-        saverr = errno;
-        goto out;
+    if (S_ISREG(inode->filetype) || S_ISDIR(inode->filetype)) {
+        fd = openat(lo->proc_self_fd, procname, O_RDONLY);
+        if (fd < 0) {
+            saverr = errno;
+            goto out;
+        }
+        ret = fremovexattr(fd, name);
+    } else {
+        /* fchdir should not fail here */
+        assert(fchdir(lo->proc_self_fd) == 0);
+        ret = removexattr(procname, name);
+        assert(fchdir(lo->root.fd) == 0);
     }
 
-    ret = fremovexattr(fd, name);
     saverr = ret == -1 ? errno : 0;
 
 out:
@@ -2806,7 +2807,7 @@ static void setup_root(struct lo_data *lo, struct lo_inode *root)
         exit(1);
     }
 
-    root->is_symlink = false;
+    root->filetype = S_IFDIR;
     root->fd = fd;
     root->key.ino = stat.st_ino;
     root->key.dev = stat.st_dev;
index 2d9d4a7ec0167f42eec07ef65fca1f88c83a0d51..bd9e7b083c98e1a79cc2417db91ff97ef25352d3 100644 (file)
@@ -41,6 +41,7 @@ static const int syscall_whitelist[] = {
     SCMP_SYS(exit),
     SCMP_SYS(exit_group),
     SCMP_SYS(fallocate),
+    SCMP_SYS(fchdir),
     SCMP_SYS(fchmodat),
     SCMP_SYS(fchownat),
     SCMP_SYS(fcntl),
@@ -62,7 +63,9 @@ static const int syscall_whitelist[] = {
     SCMP_SYS(getpid),
     SCMP_SYS(gettid),
     SCMP_SYS(gettimeofday),
+    SCMP_SYS(getxattr),
     SCMP_SYS(linkat),
+    SCMP_SYS(listxattr),
     SCMP_SYS(lseek),
     SCMP_SYS(madvise),
     SCMP_SYS(mkdirat),
@@ -85,6 +88,7 @@ static const int syscall_whitelist[] = {
     SCMP_SYS(recvmsg),
     SCMP_SYS(renameat),
     SCMP_SYS(renameat2),
+    SCMP_SYS(removexattr),
     SCMP_SYS(rt_sigaction),
     SCMP_SYS(rt_sigprocmask),
     SCMP_SYS(rt_sigreturn),
@@ -98,10 +102,12 @@ static const int syscall_whitelist[] = {
     SCMP_SYS(setresuid32),
 #endif
     SCMP_SYS(set_robust_list),
+    SCMP_SYS(setxattr),
     SCMP_SYS(symlinkat),
     SCMP_SYS(time), /* Rarely needed, except on static builds */
     SCMP_SYS(tgkill),
     SCMP_SYS(unlinkat),
+    SCMP_SYS(unshare),
     SCMP_SYS(utimensat),
     SCMP_SYS(write),
     SCMP_SYS(writev),
index 747a70839af8f19477b134543b0a18e85897ebd9..cb556e4e6689df83f28457905eb805fec6e567ad 100644 (file)
@@ -1174,7 +1174,7 @@ QemuCocoaView *cocoaView;
 - (void) openDocumentation: (NSString *) filename
 {
     /* Where to look for local files */
-    NSString *path_array[] = {@"../share/doc/qemu/", @"../doc/qemu/", @"../"};
+    NSString *path_array[] = {@"../share/doc/qemu/", @"../doc/qemu/", @"../docs/"};
     NSString *full_file_path;
 
     /* iterate thru the possible paths until the file is found */
@@ -1198,7 +1198,7 @@ QemuCocoaView *cocoaView;
 {
     COCOA_DEBUG("QemuCocoaAppController: showQEMUDoc\n");
 
-    [self openDocumentation: @"qemu-doc.html"];
+    [self openDocumentation: @"index.html"];
 }
 
 /* Stretches video to fit host monitor size */
index 6b38b67cf14cf6d925f8415ab9850341f510583d..6718a38b616d8bdba39241e942aa6dadaeb7b7ed 100644 (file)
@@ -5,6 +5,9 @@ util-obj-y += aiocb.o async.o aio-wait.o thread-pool.o qemu-timer.o
 util-obj-y += main-loop.o
 util-obj-$(call lnot,$(CONFIG_ATOMIC64)) += atomic64.o
 util-obj-$(CONFIG_POSIX) += aio-posix.o
+util-obj-$(CONFIG_POSIX) += fdmon-poll.o
+util-obj-$(CONFIG_EPOLL_CREATE1) += fdmon-epoll.o
+util-obj-$(CONFIG_LINUX_IO_URING) += fdmon-io_uring.o
 util-obj-$(CONFIG_POSIX) += compatfd.o
 util-obj-$(CONFIG_POSIX) += event_notifier-posix.o
 util-obj-$(CONFIG_POSIX) += mmap-alloc.o
index 9e1befc0c0fe599871dd42974e18c7e2ddc8ffaf..cd6cf0a4a97d97e3e8242f9ab59769034444803f 100644 (file)
 #include "qemu/sockets.h"
 #include "qemu/cutils.h"
 #include "trace.h"
-#ifdef CONFIG_EPOLL_CREATE1
-#include <sys/epoll.h>
-#endif
+#include "aio-posix.h"
 
-struct AioHandler
-{
-    GPollFD pfd;
-    IOHandler *io_read;
-    IOHandler *io_write;
-    AioPollFn *io_poll;
-    IOHandler *io_poll_begin;
-    IOHandler *io_poll_end;
-    void *opaque;
-    bool is_external;
-    QLIST_ENTRY(AioHandler) node;
-    QLIST_ENTRY(AioHandler) node_ready; /* only used during aio_poll() */
-    QLIST_ENTRY(AioHandler) node_deleted;
-};
-
-/* Add a handler to a ready list */
-static void add_ready_handler(AioHandlerList *ready_list,
-                              AioHandler *node,
-                              int revents)
-{
-    QLIST_SAFE_REMOVE(node, node_ready); /* remove from nested parent's list */
-    node->pfd.revents = revents;
-    QLIST_INSERT_HEAD(ready_list, node, node_ready);
-}
-
-#ifdef CONFIG_EPOLL_CREATE1
-
-/* The fd number threshold to switch to epoll */
-#define EPOLL_ENABLE_THRESHOLD 64
-
-static void aio_epoll_disable(AioContext *ctx)
-{
-    ctx->epoll_enabled = false;
-    if (!ctx->epoll_available) {
-        return;
-    }
-    ctx->epoll_available = false;
-    close(ctx->epollfd);
-}
-
-static inline int epoll_events_from_pfd(int pfd_events)
-{
-    return (pfd_events & G_IO_IN ? EPOLLIN : 0) |
-           (pfd_events & G_IO_OUT ? EPOLLOUT : 0) |
-           (pfd_events & G_IO_HUP ? EPOLLHUP : 0) |
-           (pfd_events & G_IO_ERR ? EPOLLERR : 0);
-}
-
-static bool aio_epoll_try_enable(AioContext *ctx)
-{
-    AioHandler *node;
-    struct epoll_event event;
-
-    QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
-        int r;
-        if (QLIST_IS_INSERTED(node, node_deleted) || !node->pfd.events) {
-            continue;
-        }
-        event.events = epoll_events_from_pfd(node->pfd.events);
-        event.data.ptr = node;
-        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_ADD, node->pfd.fd, &event);
-        if (r) {
-            return false;
-        }
-    }
-    ctx->epoll_enabled = true;
-    return true;
-}
-
-static void aio_epoll_update(AioContext *ctx, AioHandler *node, bool is_new)
-{
-    struct epoll_event event;
-    int r;
-    int ctl;
-
-    if (!ctx->epoll_enabled) {
-        return;
-    }
-    if (!node->pfd.events) {
-        ctl = EPOLL_CTL_DEL;
-    } else {
-        event.data.ptr = node;
-        event.events = epoll_events_from_pfd(node->pfd.events);
-        ctl = is_new ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
-    }
-
-    r = epoll_ctl(ctx->epollfd, ctl, node->pfd.fd, &event);
-    if (r) {
-        aio_epoll_disable(ctx);
-    }
-}
-
-static int aio_epoll(AioContext *ctx, AioHandlerList *ready_list,
-                     int64_t timeout)
-{
-    GPollFD pfd = {
-        .fd = ctx->epollfd,
-        .events = G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR,
-    };
-    AioHandler *node;
-    int i, ret = 0;
-    struct epoll_event events[128];
-
-    if (timeout > 0) {
-        ret = qemu_poll_ns(&pfd, 1, timeout);
-        if (ret > 0) {
-            timeout = 0;
-        }
-    }
-    if (timeout <= 0 || ret > 0) {
-        ret = epoll_wait(ctx->epollfd, events,
-                         ARRAY_SIZE(events),
-                         timeout);
-        if (ret <= 0) {
-            goto out;
-        }
-        for (i = 0; i < ret; i++) {
-            int ev = events[i].events;
-            int revents = (ev & EPOLLIN ? G_IO_IN : 0) |
-                          (ev & EPOLLOUT ? G_IO_OUT : 0) |
-                          (ev & EPOLLHUP ? G_IO_HUP : 0) |
-                          (ev & EPOLLERR ? G_IO_ERR : 0);
-
-            node = events[i].data.ptr;
-            add_ready_handler(ready_list, node, revents);
-        }
-    }
-out:
-    return ret;
-}
+/* Stop userspace polling on a handler if it isn't active for some time */
+#define POLL_IDLE_INTERVAL_NS (7 * NANOSECONDS_PER_SECOND)
 
-static bool aio_epoll_enabled(AioContext *ctx)
+bool aio_poll_disabled(AioContext *ctx)
 {
-    /* Fall back to ppoll when external clients are disabled. */
-    return !aio_external_disabled(ctx) && ctx->epoll_enabled;
+    return atomic_read(&ctx->poll_disable_cnt);
 }
 
-static bool aio_epoll_check_poll(AioContext *ctx, GPollFD *pfds,
-                                 unsigned npfd, int64_t timeout)
+void aio_add_ready_handler(AioHandlerList *ready_list,
+                           AioHandler *node,
+                           int revents)
 {
-    if (!ctx->epoll_available) {
-        return false;
-    }
-    if (aio_epoll_enabled(ctx)) {
-        return true;
-    }
-    if (npfd >= EPOLL_ENABLE_THRESHOLD) {
-        if (aio_epoll_try_enable(ctx)) {
-            return true;
-        } else {
-            aio_epoll_disable(ctx);
-        }
-    }
-    return false;
-}
-
-#else
-
-static void aio_epoll_update(AioContext *ctx, AioHandler *node, bool is_new)
-{
-}
-
-static int aio_epoll(AioContext *ctx, AioHandlerList *ready_list,
-                     int64_t timeout)
-{
-    assert(false);
-}
-
-static bool aio_epoll_enabled(AioContext *ctx)
-{
-    return false;
-}
-
-static bool aio_epoll_check_poll(AioContext *ctx, GPollFD *pfds,
-                          unsigned npfd, int64_t timeout)
-{
-    return false;
+    QLIST_SAFE_REMOVE(node, node_ready); /* remove from nested parent's list */
+    node->pfd.revents = revents;
+    QLIST_INSERT_HEAD(ready_list, node, node_ready);
 }
 
-#endif
-
 static AioHandler *find_aio_handler(AioContext *ctx, int fd)
 {
     AioHandler *node;
@@ -231,16 +65,23 @@ static bool aio_remove_fd_handler(AioContext *ctx, AioHandler *node)
         g_source_remove_poll(&ctx->source, &node->pfd);
     }
 
+    node->pfd.revents = 0;
+
+    /* If the fd monitor has already marked it deleted, leave it alone */
+    if (QLIST_IS_INSERTED(node, node_deleted)) {
+        return false;
+    }
+
     /* If a read is in progress, just mark the node as deleted */
     if (qemu_lockcnt_count(&ctx->list_lock)) {
         QLIST_INSERT_HEAD_RCU(&ctx->deleted_aio_handlers, node, node_deleted);
-        node->pfd.revents = 0;
         return false;
     }
     /* Otherwise, delete it for real.  We can't just mark it as
      * deleted because deleted nodes are only cleaned up while
      * no one is walking the handlers list.
      */
+    QLIST_SAFE_REMOVE(node, node_poll);
     QLIST_REMOVE(node, node);
     return true;
 }
@@ -300,9 +141,6 @@ void aio_set_fd_handler(AioContext *ctx,
 
         QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, new_node, node);
     }
-    if (node) {
-        deleted = aio_remove_fd_handler(ctx, node);
-    }
 
     /* No need to order poll_disable_cnt writes against other updates;
      * the counter is only used to avoid wasting time and latency on
@@ -313,11 +151,9 @@ void aio_set_fd_handler(AioContext *ctx,
     atomic_set(&ctx->poll_disable_cnt,
                atomic_read(&ctx->poll_disable_cnt) + poll_disable_change);
 
-    if (new_node) {
-        aio_epoll_update(ctx, new_node, is_new);
-    } else if (node) {
-        /* Unregister deleted fd_handler */
-        aio_epoll_update(ctx, node, false);
+    ctx->fdmon_ops->update(ctx, node, new_node);
+    if (node) {
+        deleted = aio_remove_fd_handler(ctx, node);
     }
     qemu_lockcnt_unlock(&ctx->list_lock);
     aio_notify(ctx);
@@ -361,18 +197,19 @@ void aio_set_event_notifier_poll(AioContext *ctx,
                     (IOHandler *)io_poll_end);
 }
 
-static void poll_set_started(AioContext *ctx, bool started)
+static bool poll_set_started(AioContext *ctx, bool started)
 {
     AioHandler *node;
+    bool progress = false;
 
     if (started == ctx->poll_started) {
-        return;
+        return false;
     }
 
     ctx->poll_started = started;
 
     qemu_lockcnt_inc(&ctx->list_lock);
-    QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
+    QLIST_FOREACH(node, &ctx->poll_aio_handlers, node_poll) {
         IOHandler *fn;
 
         if (QLIST_IS_INSERTED(node, node_deleted)) {
@@ -388,8 +225,15 @@ static void poll_set_started(AioContext *ctx, bool started)
         if (fn) {
             fn(node->opaque);
         }
+
+        /* Poll one last time in case ->io_poll_end() raced with the event */
+        if (!started) {
+            progress = node->io_poll(node->opaque) || progress;
+        }
     }
     qemu_lockcnt_dec(&ctx->list_lock);
+
+    return progress;
 }
 
 
@@ -446,6 +290,7 @@ static void aio_free_deleted_handlers(AioContext *ctx)
     while ((node = QLIST_FIRST_RCU(&ctx->deleted_aio_handlers))) {
         QLIST_REMOVE(node, node);
         QLIST_REMOVE(node, node_deleted);
+        QLIST_SAFE_REMOVE(node, node_poll);
         g_free(node);
     }
 
@@ -460,6 +305,22 @@ static bool aio_dispatch_handler(AioContext *ctx, AioHandler *node)
     revents = node->pfd.revents & node->pfd.events;
     node->pfd.revents = 0;
 
+    /*
+     * Start polling AioHandlers when they become ready because activity is
+     * likely to continue.  Note that starvation is theoretically possible when
+     * fdmon_supports_polling(), but only until the fd fires for the first
+     * time.
+     */
+    if (!QLIST_IS_INSERTED(node, node_deleted) &&
+        !QLIST_IS_INSERTED(node, node_poll) &&
+        node->io_poll) {
+        trace_poll_add(ctx, node, node->pfd.fd, revents);
+        if (ctx->poll_started && node->io_poll_begin) {
+            node->io_poll_begin(node->opaque);
+        }
+        QLIST_INSERT_HEAD(&ctx->poll_aio_handlers, node, node_poll);
+    }
+
     if (!QLIST_IS_INSERTED(node, node_deleted) &&
         (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&
         aio_node_check(ctx, node->is_external) &&
@@ -493,7 +354,7 @@ static bool aio_dispatch_ready_handlers(AioContext *ctx,
     AioHandler *node;
 
     while ((node = QLIST_FIRST(ready_list))) {
-        QLIST_SAFE_REMOVE(node, node_ready);
+        QLIST_REMOVE(node, node_ready);
         progress = aio_dispatch_handler(ctx, node) || progress;
     }
 
@@ -524,71 +385,19 @@ void aio_dispatch(AioContext *ctx)
     timerlistgroup_run_timers(&ctx->tlg);
 }
 
-/* These thread-local variables are used only in a small part of aio_poll
- * around the call to the poll() system call.  In particular they are not
- * used while aio_poll is performing callbacks, which makes it much easier
- * to think about reentrancy!
- *
- * Stack-allocated arrays would be perfect but they have size limitations;
- * heap allocation is expensive enough that we want to reuse arrays across
- * calls to aio_poll().  And because poll() has to be called without holding
- * any lock, the arrays cannot be stored in AioContext.  Thread-local data
- * has none of the disadvantages of these three options.
- */
-static __thread GPollFD *pollfds;
-static __thread AioHandler **nodes;
-static __thread unsigned npfd, nalloc;
-static __thread Notifier pollfds_cleanup_notifier;
-
-static void pollfds_cleanup(Notifier *n, void *unused)
-{
-    g_assert(npfd == 0);
-    g_free(pollfds);
-    g_free(nodes);
-    nalloc = 0;
-}
-
-static void add_pollfd(AioHandler *node)
-{
-    if (npfd == nalloc) {
-        if (nalloc == 0) {
-            pollfds_cleanup_notifier.notify = pollfds_cleanup;
-            qemu_thread_atexit_add(&pollfds_cleanup_notifier);
-            nalloc = 8;
-        } else {
-            g_assert(nalloc <= INT_MAX);
-            nalloc *= 2;
-        }
-        pollfds = g_renew(GPollFD, pollfds, nalloc);
-        nodes = g_renew(AioHandler *, nodes, nalloc);
-    }
-    nodes[npfd] = node;
-    pollfds[npfd] = (GPollFD) {
-        .fd = node->pfd.fd,
-        .events = node->pfd.events,
-    };
-    npfd++;
-}
-
-static bool run_poll_handlers_once(AioContext *ctx, int64_t *timeout)
+static bool run_poll_handlers_once(AioContext *ctx,
+                                   int64_t now,
+                                   int64_t *timeout)
 {
     bool progress = false;
     AioHandler *node;
+    AioHandler *tmp;
 
-    /*
-     * Optimization: ->io_poll() handlers often contain RCU read critical
-     * sections and we therefore see many rcu_read_lock() -> rcu_read_unlock()
-     * -> rcu_read_lock() -> ... sequences with expensive memory
-     * synchronization primitives.  Make the entire polling loop an RCU
-     * critical section because nested rcu_read_lock()/rcu_read_unlock() calls
-     * are cheap.
-     */
-    RCU_READ_LOCK_GUARD();
-
-    QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
-        if (!QLIST_IS_INSERTED(node, node_deleted) && node->io_poll &&
-            aio_node_check(ctx, node->is_external) &&
+    QLIST_FOREACH_SAFE(node, &ctx->poll_aio_handlers, node_poll, tmp) {
+        if (aio_node_check(ctx, node->is_external) &&
             node->io_poll(node->opaque)) {
+            node->poll_idle_timeout = now + POLL_IDLE_INTERVAL_NS;
+
             /*
              * Polling was successful, exit try_poll_mode immediately
              * to adjust the next polling time.
@@ -605,6 +414,50 @@ static bool run_poll_handlers_once(AioContext *ctx, int64_t *timeout)
     return progress;
 }
 
+static bool fdmon_supports_polling(AioContext *ctx)
+{
+    return ctx->fdmon_ops->need_wait != aio_poll_disabled;
+}
+
+static bool remove_idle_poll_handlers(AioContext *ctx, int64_t now)
+{
+    AioHandler *node;
+    AioHandler *tmp;
+    bool progress = false;
+
+    /*
+     * File descriptor monitoring implementations without userspace polling
+     * support suffer from starvation when a subset of handlers is polled
+     * because fds will not be processed in a timely fashion.  Don't remove
+     * idle poll handlers.
+     */
+    if (!fdmon_supports_polling(ctx)) {
+        return false;
+    }
+
+    QLIST_FOREACH_SAFE(node, &ctx->poll_aio_handlers, node_poll, tmp) {
+        if (node->poll_idle_timeout == 0LL) {
+            node->poll_idle_timeout = now + POLL_IDLE_INTERVAL_NS;
+        } else if (now >= node->poll_idle_timeout) {
+            trace_poll_remove(ctx, node, node->pfd.fd);
+            node->poll_idle_timeout = 0LL;
+            QLIST_SAFE_REMOVE(node, node_poll);
+            if (ctx->poll_started && node->io_poll_end) {
+                node->io_poll_end(node->opaque);
+
+                /*
+                 * Final poll in case ->io_poll_end() races with an event.
+                 * Nevermind about re-adding the handler in the rare case where
+                 * this causes progress.
+                 */
+                progress = node->io_poll(node->opaque) || progress;
+            }
+        }
+    }
+
+    return progress;
+}
+
 /* run_poll_handlers:
  * @ctx: the AioContext
  * @max_ns: maximum time to poll for, in nanoseconds
@@ -628,13 +481,28 @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns, int64_t *timeout)
 
     trace_run_poll_handlers_begin(ctx, max_ns, *timeout);
 
+    /*
+     * Optimization: ->io_poll() handlers often contain RCU read critical
+     * sections and we therefore see many rcu_read_lock() -> rcu_read_unlock()
+     * -> rcu_read_lock() -> ... sequences with expensive memory
+     * synchronization primitives.  Make the entire polling loop an RCU
+     * critical section because nested rcu_read_lock()/rcu_read_unlock() calls
+     * are cheap.
+     */
+    RCU_READ_LOCK_GUARD();
+
     start_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     do {
-        progress = run_poll_handlers_once(ctx, timeout);
+        progress = run_poll_handlers_once(ctx, start_time, timeout);
         elapsed_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start_time;
         max_ns = qemu_soonest_timeout(*timeout, max_ns);
         assert(!(max_ns && progress));
-    } while (elapsed_time < max_ns && !atomic_read(&ctx->poll_disable_cnt));
+    } while (elapsed_time < max_ns && !ctx->fdmon_ops->need_wait(ctx));
+
+    if (remove_idle_poll_handlers(ctx, start_time + elapsed_time)) {
+        *timeout = 0;
+        progress = true;
+    }
 
     /* If time has passed with no successful polling, adjust *timeout to
      * keep the same ending time.
@@ -660,9 +528,14 @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns, int64_t *timeout)
  */
 static bool try_poll_mode(AioContext *ctx, int64_t *timeout)
 {
-    int64_t max_ns = qemu_soonest_timeout(*timeout, ctx->poll_ns);
+    int64_t max_ns;
 
-    if (max_ns && !atomic_read(&ctx->poll_disable_cnt)) {
+    if (QLIST_EMPTY_RCU(&ctx->poll_aio_handlers)) {
+        return false;
+    }
+
+    max_ns = qemu_soonest_timeout(*timeout, ctx->poll_ns);
+    if (max_ns && !ctx->fdmon_ops->need_wait(ctx)) {
         poll_set_started(ctx, true);
 
         if (run_poll_handlers(ctx, max_ns, timeout)) {
@@ -670,19 +543,17 @@ static bool try_poll_mode(AioContext *ctx, int64_t *timeout)
         }
     }
 
-    poll_set_started(ctx, false);
+    if (poll_set_started(ctx, false)) {
+        *timeout = 0;
+        return true;
+    }
 
-    /* Even if we don't run busy polling, try polling once in case it can make
-     * progress and the caller will be able to avoid ppoll(2)/epoll_wait(2).
-     */
-    return run_poll_handlers_once(ctx, timeout);
+    return false;
 }
 
 bool aio_poll(AioContext *ctx, bool blocking)
 {
     AioHandlerList ready_list = QLIST_HEAD_INITIALIZER(ready_list);
-    AioHandler *node;
-    int i;
     int ret = 0;
     bool progress;
     int64_t timeout;
@@ -714,27 +585,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
     /* If polling is allowed, non-blocking aio_poll does not need the
      * system call---a single round of run_poll_handlers_once suffices.
      */
-    if (timeout || atomic_read(&ctx->poll_disable_cnt)) {
-        assert(npfd == 0);
-
-        /* fill pollfds */
-
-        if (!aio_epoll_enabled(ctx)) {
-            QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
-                if (!QLIST_IS_INSERTED(node, node_deleted) && node->pfd.events
-                    && aio_node_check(ctx, node->is_external)) {
-                    add_pollfd(node);
-                }
-            }
-        }
-
-        /* wait until next event */
-        if (aio_epoll_check_poll(ctx, pollfds, npfd, timeout)) {
-            npfd = 0; /* pollfds[] is not being used */
-            ret = aio_epoll(ctx, &ready_list, timeout);
-        } else  {
-            ret = qemu_poll_ns(pollfds, npfd, timeout);
-        }
+    if (timeout || ctx->fdmon_ops->need_wait(ctx)) {
+        ret = ctx->fdmon_ops->wait(ctx, &ready_list, timeout);
     }
 
     if (blocking) {
@@ -783,19 +635,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
         }
     }
 
-    /* if we have any readable fds, dispatch event */
-    if (ret > 0) {
-        for (i = 0; i < npfd; i++) {
-            int revents = pollfds[i].revents;
-
-            if (revents) {
-                add_ready_handler(&ready_list, nodes[i], revents);
-            }
-        }
-    }
-
-    npfd = 0;
-
     progress |= aio_bh_poll(ctx);
 
     if (ret > 0) {
@@ -813,23 +652,21 @@ bool aio_poll(AioContext *ctx, bool blocking)
 
 void aio_context_setup(AioContext *ctx)
 {
-#ifdef CONFIG_EPOLL_CREATE1
-    assert(!ctx->epollfd);
-    ctx->epollfd = epoll_create1(EPOLL_CLOEXEC);
-    if (ctx->epollfd == -1) {
-        fprintf(stderr, "Failed to create epoll instance: %s", strerror(errno));
-        ctx->epoll_available = false;
-    } else {
-        ctx->epoll_available = true;
+    ctx->fdmon_ops = &fdmon_poll_ops;
+    ctx->epollfd = -1;
+
+    /* Use the fastest fd monitoring implementation if available */
+    if (fdmon_io_uring_setup(ctx)) {
+        return;
     }
-#endif
+
+    fdmon_epoll_setup(ctx);
 }
 
 void aio_context_destroy(AioContext *ctx)
 {
-#ifdef CONFIG_EPOLL_CREATE1
-    aio_epoll_disable(ctx);
-#endif
+    fdmon_io_uring_destroy(ctx);
+    fdmon_epoll_disable(ctx);
 }
 
 void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
diff --git a/util/aio-posix.h b/util/aio-posix.h
new file mode 100644 (file)
index 0000000..c80c045
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * AioContext POSIX event loop implementation internal APIs
+ *
+ * Copyright IBM, Corp. 2008
+ * Copyright Red Hat, Inc. 2020
+ *
+ * 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.
+ */
+
+#ifndef AIO_POSIX_H
+#define AIO_POSIX_H
+
+#include "block/aio.h"
+
+struct AioHandler {
+    GPollFD pfd;
+    IOHandler *io_read;
+    IOHandler *io_write;
+    AioPollFn *io_poll;
+    IOHandler *io_poll_begin;
+    IOHandler *io_poll_end;
+    void *opaque;
+    QLIST_ENTRY(AioHandler) node;
+    QLIST_ENTRY(AioHandler) node_ready; /* only used during aio_poll() */
+    QLIST_ENTRY(AioHandler) node_deleted;
+    QLIST_ENTRY(AioHandler) node_poll;
+#ifdef CONFIG_LINUX_IO_URING
+    QSLIST_ENTRY(AioHandler) node_submitted;
+    unsigned flags; /* see fdmon-io_uring.c */
+#endif
+    int64_t poll_idle_timeout; /* when to stop userspace polling */
+    bool is_external;
+};
+
+/* Add a handler to a ready list */
+void aio_add_ready_handler(AioHandlerList *ready_list, AioHandler *node,
+                           int revents);
+
+extern const FDMonOps fdmon_poll_ops;
+
+#ifdef CONFIG_EPOLL_CREATE1
+bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd);
+void fdmon_epoll_setup(AioContext *ctx);
+void fdmon_epoll_disable(AioContext *ctx);
+#else
+static inline bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
+{
+    return false;
+}
+
+static inline void fdmon_epoll_setup(AioContext *ctx)
+{
+}
+
+static inline void fdmon_epoll_disable(AioContext *ctx)
+{
+}
+#endif /* !CONFIG_EPOLL_CREATE1 */
+
+#ifdef CONFIG_LINUX_IO_URING
+bool fdmon_io_uring_setup(AioContext *ctx);
+void fdmon_io_uring_destroy(AioContext *ctx);
+#else
+static inline bool fdmon_io_uring_setup(AioContext *ctx)
+{
+    return false;
+}
+
+static inline void fdmon_io_uring_destroy(AioContext *ctx)
+{
+}
+#endif /* !CONFIG_LINUX_IO_URING */
+
+#endif /* AIO_POSIX_H */
diff --git a/util/fdmon-epoll.c b/util/fdmon-epoll.c
new file mode 100644 (file)
index 0000000..fcd989d
--- /dev/null
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * epoll(7) file descriptor monitoring
+ */
+
+#include "qemu/osdep.h"
+#include <sys/epoll.h>
+#include "qemu/rcu_queue.h"
+#include "aio-posix.h"
+
+/* The fd number threshold to switch to epoll */
+#define EPOLL_ENABLE_THRESHOLD 64
+
+void fdmon_epoll_disable(AioContext *ctx)
+{
+    if (ctx->epollfd >= 0) {
+        close(ctx->epollfd);
+        ctx->epollfd = -1;
+    }
+
+    /* Switch back */
+    ctx->fdmon_ops = &fdmon_poll_ops;
+}
+
+static inline int epoll_events_from_pfd(int pfd_events)
+{
+    return (pfd_events & G_IO_IN ? EPOLLIN : 0) |
+           (pfd_events & G_IO_OUT ? EPOLLOUT : 0) |
+           (pfd_events & G_IO_HUP ? EPOLLHUP : 0) |
+           (pfd_events & G_IO_ERR ? EPOLLERR : 0);
+}
+
+static void fdmon_epoll_update(AioContext *ctx,
+                               AioHandler *old_node,
+                               AioHandler *new_node)
+{
+    struct epoll_event event = {
+        .data.ptr = new_node,
+        .events = new_node ? epoll_events_from_pfd(new_node->pfd.events) : 0,
+    };
+    int r;
+
+    if (!new_node) {
+        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_DEL, old_node->pfd.fd, &event);
+    } else if (!old_node) {
+        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_ADD, new_node->pfd.fd, &event);
+    } else {
+        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_MOD, new_node->pfd.fd, &event);
+    }
+
+    if (r) {
+        fdmon_epoll_disable(ctx);
+    }
+}
+
+static int fdmon_epoll_wait(AioContext *ctx, AioHandlerList *ready_list,
+                            int64_t timeout)
+{
+    GPollFD pfd = {
+        .fd = ctx->epollfd,
+        .events = G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR,
+    };
+    AioHandler *node;
+    int i, ret = 0;
+    struct epoll_event events[128];
+
+    /* Fall back while external clients are disabled */
+    if (atomic_read(&ctx->external_disable_cnt)) {
+        return fdmon_poll_ops.wait(ctx, ready_list, timeout);
+    }
+
+    if (timeout > 0) {
+        ret = qemu_poll_ns(&pfd, 1, timeout);
+        if (ret > 0) {
+            timeout = 0;
+        }
+    }
+    if (timeout <= 0 || ret > 0) {
+        ret = epoll_wait(ctx->epollfd, events,
+                         ARRAY_SIZE(events),
+                         timeout);
+        if (ret <= 0) {
+            goto out;
+        }
+        for (i = 0; i < ret; i++) {
+            int ev = events[i].events;
+            int revents = (ev & EPOLLIN ? G_IO_IN : 0) |
+                          (ev & EPOLLOUT ? G_IO_OUT : 0) |
+                          (ev & EPOLLHUP ? G_IO_HUP : 0) |
+                          (ev & EPOLLERR ? G_IO_ERR : 0);
+
+            node = events[i].data.ptr;
+            aio_add_ready_handler(ready_list, node, revents);
+        }
+    }
+out:
+    return ret;
+}
+
+static const FDMonOps fdmon_epoll_ops = {
+    .update = fdmon_epoll_update,
+    .wait = fdmon_epoll_wait,
+    .need_wait = aio_poll_disabled,
+};
+
+static bool fdmon_epoll_try_enable(AioContext *ctx)
+{
+    AioHandler *node;
+    struct epoll_event event;
+
+    QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
+        int r;
+        if (QLIST_IS_INSERTED(node, node_deleted) || !node->pfd.events) {
+            continue;
+        }
+        event.events = epoll_events_from_pfd(node->pfd.events);
+        event.data.ptr = node;
+        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_ADD, node->pfd.fd, &event);
+        if (r) {
+            return false;
+        }
+    }
+
+    ctx->fdmon_ops = &fdmon_epoll_ops;
+    return true;
+}
+
+bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
+{
+    if (ctx->epollfd < 0) {
+        return false;
+    }
+
+    /* Do not upgrade while external clients are disabled */
+    if (atomic_read(&ctx->external_disable_cnt)) {
+        return false;
+    }
+
+    if (npfd >= EPOLL_ENABLE_THRESHOLD) {
+        if (fdmon_epoll_try_enable(ctx)) {
+            return true;
+        } else {
+            fdmon_epoll_disable(ctx);
+        }
+    }
+    return false;
+}
+
+void fdmon_epoll_setup(AioContext *ctx)
+{
+    ctx->epollfd = epoll_create1(EPOLL_CLOEXEC);
+    if (ctx->epollfd == -1) {
+        fprintf(stderr, "Failed to create epoll instance: %s", strerror(errno));
+    }
+}
diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c
new file mode 100644 (file)
index 0000000..893b79b
--- /dev/null
@@ -0,0 +1,332 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Linux io_uring file descriptor monitoring
+ *
+ * The Linux io_uring API supports file descriptor monitoring with a few
+ * advantages over existing APIs like poll(2) and epoll(7):
+ *
+ * 1. Userspace polling of events is possible because the completion queue (cq
+ *    ring) is shared between the kernel and userspace.  This allows
+ *    applications that rely on userspace polling to also monitor file
+ *    descriptors in the same userspace polling loop.
+ *
+ * 2. Submission and completion is batched and done together in a single system
+ *    call.  This minimizes the number of system calls.
+ *
+ * 3. File descriptor monitoring is O(1) like epoll(7) so it scales better than
+ *    poll(2).
+ *
+ * 4. Nanosecond timeouts are supported so it requires fewer syscalls than
+ *    epoll(7).
+ *
+ * This code only monitors file descriptors and does not do asynchronous disk
+ * I/O.  Implementing disk I/O efficiently has other requirements and should
+ * use a separate io_uring so it does not make sense to unify the code.
+ *
+ * File descriptor monitoring is implemented using the following operations:
+ *
+ * 1. IORING_OP_POLL_ADD - adds a file descriptor to be monitored.
+ * 2. IORING_OP_POLL_REMOVE - removes a file descriptor being monitored.  When
+ *    the poll mask changes for a file descriptor it is first removed and then
+ *    re-added with the new poll mask, so this operation is also used as part
+ *    of modifying an existing monitored file descriptor.
+ * 3. IORING_OP_TIMEOUT - added every time a blocking syscall is made to wait
+ *    for events.  This operation self-cancels if another event completes
+ *    before the timeout.
+ *
+ * io_uring calls the submission queue the "sq ring" and the completion queue
+ * the "cq ring".  Ring entries are called "sqe" and "cqe", respectively.
+ *
+ * The code is structured so that sq/cq rings are only modified within
+ * fdmon_io_uring_wait().  Changes to AioHandlers are made by enqueuing them on
+ * ctx->submit_list so that fdmon_io_uring_wait() can submit IORING_OP_POLL_ADD
+ * and/or IORING_OP_POLL_REMOVE sqes for them.
+ */
+
+#include "qemu/osdep.h"
+#include <poll.h>
+#include "qemu/rcu_queue.h"
+#include "aio-posix.h"
+
+enum {
+    FDMON_IO_URING_ENTRIES  = 128, /* sq/cq ring size */
+
+    /* AioHandler::flags */
+    FDMON_IO_URING_PENDING  = (1 << 0),
+    FDMON_IO_URING_ADD      = (1 << 1),
+    FDMON_IO_URING_REMOVE   = (1 << 2),
+};
+
+static inline int poll_events_from_pfd(int pfd_events)
+{
+    return (pfd_events & G_IO_IN ? POLLIN : 0) |
+           (pfd_events & G_IO_OUT ? POLLOUT : 0) |
+           (pfd_events & G_IO_HUP ? POLLHUP : 0) |
+           (pfd_events & G_IO_ERR ? POLLERR : 0);
+}
+
+static inline int pfd_events_from_poll(int poll_events)
+{
+    return (poll_events & POLLIN ? G_IO_IN : 0) |
+           (poll_events & POLLOUT ? G_IO_OUT : 0) |
+           (poll_events & POLLHUP ? G_IO_HUP : 0) |
+           (poll_events & POLLERR ? G_IO_ERR : 0);
+}
+
+/*
+ * Returns an sqe for submitting a request.  Only be called within
+ * fdmon_io_uring_wait().
+ */
+static struct io_uring_sqe *get_sqe(AioContext *ctx)
+{
+    struct io_uring *ring = &ctx->fdmon_io_uring;
+    struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
+    int ret;
+
+    if (likely(sqe)) {
+        return sqe;
+    }
+
+    /* No free sqes left, submit pending sqes first */
+    ret = io_uring_submit(ring);
+    assert(ret > 1);
+    sqe = io_uring_get_sqe(ring);
+    assert(sqe);
+    return sqe;
+}
+
+/* Atomically enqueue an AioHandler for sq ring submission */
+static void enqueue(AioHandlerSList *head, AioHandler *node, unsigned flags)
+{
+    unsigned old_flags;
+
+    old_flags = atomic_fetch_or(&node->flags, FDMON_IO_URING_PENDING | flags);
+    if (!(old_flags & FDMON_IO_URING_PENDING)) {
+        QSLIST_INSERT_HEAD_ATOMIC(head, node, node_submitted);
+    }
+}
+
+/* Dequeue an AioHandler for sq ring submission.  Called by fill_sq_ring(). */
+static AioHandler *dequeue(AioHandlerSList *head, unsigned *flags)
+{
+    AioHandler *node = QSLIST_FIRST(head);
+
+    if (!node) {
+        return NULL;
+    }
+
+    /* Doesn't need to be atomic since fill_sq_ring() moves the list */
+    QSLIST_REMOVE_HEAD(head, node_submitted);
+
+    /*
+     * Don't clear FDMON_IO_URING_REMOVE.  It's sticky so it can serve two
+     * purposes: telling fill_sq_ring() to submit IORING_OP_POLL_REMOVE and
+     * telling process_cqe() to delete the AioHandler when its
+     * IORING_OP_POLL_ADD completes.
+     */
+    *flags = atomic_fetch_and(&node->flags, ~(FDMON_IO_URING_PENDING |
+                                              FDMON_IO_URING_ADD));
+    return node;
+}
+
+static void fdmon_io_uring_update(AioContext *ctx,
+                                  AioHandler *old_node,
+                                  AioHandler *new_node)
+{
+    if (new_node) {
+        enqueue(&ctx->submit_list, new_node, FDMON_IO_URING_ADD);
+    }
+
+    if (old_node) {
+        /*
+         * Deletion is tricky because IORING_OP_POLL_ADD and
+         * IORING_OP_POLL_REMOVE are async.  We need to wait for the original
+         * IORING_OP_POLL_ADD to complete before this handler can be freed
+         * safely.
+         *
+         * It's possible that the file descriptor becomes ready and the
+         * IORING_OP_POLL_ADD cqe is enqueued before IORING_OP_POLL_REMOVE is
+         * submitted, too.
+         *
+         * Mark this handler deleted right now but don't place it on
+         * ctx->deleted_aio_handlers yet.  Instead, manually fudge the list
+         * entry to make QLIST_IS_INSERTED() think this handler has been
+         * inserted and other code recognizes this AioHandler as deleted.
+         *
+         * Once the original IORING_OP_POLL_ADD completes we enqueue the
+         * handler on the real ctx->deleted_aio_handlers list to be freed.
+         */
+        assert(!QLIST_IS_INSERTED(old_node, node_deleted));
+        old_node->node_deleted.le_prev = &old_node->node_deleted.le_next;
+
+        enqueue(&ctx->submit_list, old_node, FDMON_IO_URING_REMOVE);
+    }
+}
+
+static void add_poll_add_sqe(AioContext *ctx, AioHandler *node)
+{
+    struct io_uring_sqe *sqe = get_sqe(ctx);
+    int events = poll_events_from_pfd(node->pfd.events);
+
+    io_uring_prep_poll_add(sqe, node->pfd.fd, events);
+    io_uring_sqe_set_data(sqe, node);
+}
+
+static void add_poll_remove_sqe(AioContext *ctx, AioHandler *node)
+{
+    struct io_uring_sqe *sqe = get_sqe(ctx);
+
+    io_uring_prep_poll_remove(sqe, node);
+}
+
+/* Add a timeout that self-cancels when another cqe becomes ready */
+static void add_timeout_sqe(AioContext *ctx, int64_t ns)
+{
+    struct io_uring_sqe *sqe;
+    struct __kernel_timespec ts = {
+        .tv_sec = ns / NANOSECONDS_PER_SECOND,
+        .tv_nsec = ns % NANOSECONDS_PER_SECOND,
+    };
+
+    sqe = get_sqe(ctx);
+    io_uring_prep_timeout(sqe, &ts, 1, 0);
+}
+
+/* Add sqes from ctx->submit_list for submission */
+static void fill_sq_ring(AioContext *ctx)
+{
+    AioHandlerSList submit_list;
+    AioHandler *node;
+    unsigned flags;
+
+    QSLIST_MOVE_ATOMIC(&submit_list, &ctx->submit_list);
+
+    while ((node = dequeue(&submit_list, &flags))) {
+        /* Order matters, just in case both flags were set */
+        if (flags & FDMON_IO_URING_ADD) {
+            add_poll_add_sqe(ctx, node);
+        }
+        if (flags & FDMON_IO_URING_REMOVE) {
+            add_poll_remove_sqe(ctx, node);
+        }
+    }
+}
+
+/* Returns true if a handler became ready */
+static bool process_cqe(AioContext *ctx,
+                        AioHandlerList *ready_list,
+                        struct io_uring_cqe *cqe)
+{
+    AioHandler *node = io_uring_cqe_get_data(cqe);
+    unsigned flags;
+
+    /* poll_timeout and poll_remove have a zero user_data field */
+    if (!node) {
+        return false;
+    }
+
+    /*
+     * Deletion can only happen when IORING_OP_POLL_ADD completes.  If we race
+     * with enqueue() here then we can safely clear the FDMON_IO_URING_REMOVE
+     * bit before IORING_OP_POLL_REMOVE is submitted.
+     */
+    flags = atomic_fetch_and(&node->flags, ~FDMON_IO_URING_REMOVE);
+    if (flags & FDMON_IO_URING_REMOVE) {
+        QLIST_INSERT_HEAD_RCU(&ctx->deleted_aio_handlers, node, node_deleted);
+        return false;
+    }
+
+    aio_add_ready_handler(ready_list, node, pfd_events_from_poll(cqe->res));
+
+    /* IORING_OP_POLL_ADD is one-shot so we must re-arm it */
+    add_poll_add_sqe(ctx, node);
+    return true;
+}
+
+static int process_cq_ring(AioContext *ctx, AioHandlerList *ready_list)
+{
+    struct io_uring *ring = &ctx->fdmon_io_uring;
+    struct io_uring_cqe *cqe;
+    unsigned num_cqes = 0;
+    unsigned num_ready = 0;
+    unsigned head;
+
+    io_uring_for_each_cqe(ring, head, cqe) {
+        if (process_cqe(ctx, ready_list, cqe)) {
+            num_ready++;
+        }
+
+        num_cqes++;
+    }
+
+    io_uring_cq_advance(ring, num_cqes);
+    return num_ready;
+}
+
+static int fdmon_io_uring_wait(AioContext *ctx, AioHandlerList *ready_list,
+                               int64_t timeout)
+{
+    unsigned wait_nr = 1; /* block until at least one cqe is ready */
+    int ret;
+
+    /* Fall back while external clients are disabled */
+    if (atomic_read(&ctx->external_disable_cnt)) {
+        return fdmon_poll_ops.wait(ctx, ready_list, timeout);
+    }
+
+    if (timeout == 0) {
+        wait_nr = 0; /* non-blocking */
+    } else if (timeout > 0) {
+        add_timeout_sqe(ctx, timeout);
+    }
+
+    fill_sq_ring(ctx);
+
+    ret = io_uring_submit_and_wait(&ctx->fdmon_io_uring, wait_nr);
+    assert(ret >= 0);
+
+    return process_cq_ring(ctx, ready_list);
+}
+
+static bool fdmon_io_uring_need_wait(AioContext *ctx)
+{
+    return io_uring_cq_ready(&ctx->fdmon_io_uring);
+}
+
+static const FDMonOps fdmon_io_uring_ops = {
+    .update = fdmon_io_uring_update,
+    .wait = fdmon_io_uring_wait,
+    .need_wait = fdmon_io_uring_need_wait,
+};
+
+bool fdmon_io_uring_setup(AioContext *ctx)
+{
+    int ret;
+
+    ret = io_uring_queue_init(FDMON_IO_URING_ENTRIES, &ctx->fdmon_io_uring, 0);
+    if (ret != 0) {
+        return false;
+    }
+
+    QSLIST_INIT(&ctx->submit_list);
+    ctx->fdmon_ops = &fdmon_io_uring_ops;
+    return true;
+}
+
+void fdmon_io_uring_destroy(AioContext *ctx)
+{
+    if (ctx->fdmon_ops == &fdmon_io_uring_ops) {
+        AioHandler *node;
+
+        io_uring_queue_exit(&ctx->fdmon_io_uring);
+
+        /* No need to submit these anymore, just free them. */
+        while ((node = QSLIST_FIRST_RCU(&ctx->submit_list))) {
+            QSLIST_REMOVE_HEAD_RCU(&ctx->submit_list, node_submitted);
+            QLIST_REMOVE(node, node);
+            g_free(node);
+        }
+
+        ctx->fdmon_ops = &fdmon_poll_ops;
+    }
+}
diff --git a/util/fdmon-poll.c b/util/fdmon-poll.c
new file mode 100644 (file)
index 0000000..488067b
--- /dev/null
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * poll(2) file descriptor monitoring
+ *
+ * Uses ppoll(2) when available, g_poll() otherwise.
+ */
+
+#include "qemu/osdep.h"
+#include "aio-posix.h"
+#include "qemu/rcu_queue.h"
+
+/*
+ * These thread-local variables are used only in fdmon_poll_wait() around the
+ * call to the poll() system call.  In particular they are not used while
+ * aio_poll is performing callbacks, which makes it much easier to think about
+ * reentrancy!
+ *
+ * Stack-allocated arrays would be perfect but they have size limitations;
+ * heap allocation is expensive enough that we want to reuse arrays across
+ * calls to aio_poll().  And because poll() has to be called without holding
+ * any lock, the arrays cannot be stored in AioContext.  Thread-local data
+ * has none of the disadvantages of these three options.
+ */
+static __thread GPollFD *pollfds;
+static __thread AioHandler **nodes;
+static __thread unsigned npfd, nalloc;
+static __thread Notifier pollfds_cleanup_notifier;
+
+static void pollfds_cleanup(Notifier *n, void *unused)
+{
+    g_assert(npfd == 0);
+    g_free(pollfds);
+    g_free(nodes);
+    nalloc = 0;
+}
+
+static void add_pollfd(AioHandler *node)
+{
+    if (npfd == nalloc) {
+        if (nalloc == 0) {
+            pollfds_cleanup_notifier.notify = pollfds_cleanup;
+            qemu_thread_atexit_add(&pollfds_cleanup_notifier);
+            nalloc = 8;
+        } else {
+            g_assert(nalloc <= INT_MAX);
+            nalloc *= 2;
+        }
+        pollfds = g_renew(GPollFD, pollfds, nalloc);
+        nodes = g_renew(AioHandler *, nodes, nalloc);
+    }
+    nodes[npfd] = node;
+    pollfds[npfd] = (GPollFD) {
+        .fd = node->pfd.fd,
+        .events = node->pfd.events,
+    };
+    npfd++;
+}
+
+static int fdmon_poll_wait(AioContext *ctx, AioHandlerList *ready_list,
+                            int64_t timeout)
+{
+    AioHandler *node;
+    int ret;
+
+    assert(npfd == 0);
+
+    QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
+        if (!QLIST_IS_INSERTED(node, node_deleted) && node->pfd.events
+                && aio_node_check(ctx, node->is_external)) {
+            add_pollfd(node);
+        }
+    }
+
+    /* epoll(7) is faster above a certain number of fds */
+    if (fdmon_epoll_try_upgrade(ctx, npfd)) {
+        return ctx->fdmon_ops->wait(ctx, ready_list, timeout);
+    }
+
+    ret = qemu_poll_ns(pollfds, npfd, timeout);
+    if (ret > 0) {
+        int i;
+
+        for (i = 0; i < npfd; i++) {
+            int revents = pollfds[i].revents;
+
+            if (revents) {
+                aio_add_ready_handler(ready_list, nodes[i], revents);
+            }
+        }
+    }
+
+    npfd = 0;
+    return ret;
+}
+
+static void fdmon_poll_update(AioContext *ctx,
+                              AioHandler *old_node,
+                              AioHandler *new_node)
+{
+    /* Do nothing, AioHandler already contains the state we'll need */
+}
+
+const FDMonOps fdmon_poll_ops = {
+    .update = fdmon_poll_update,
+    .wait = fdmon_poll_wait,
+    .need_wait = aio_poll_disabled,
+};
index f7d06050f712a154c12df07a25083611f924f63e..4829c07ff6edbb1508946ad789031f51b2cb6035 100644 (file)
@@ -82,8 +82,8 @@ static int qemu_mprotect__osdep(void *addr, size_t size, int prot)
     DWORD old_protect;
 
     if (!VirtualProtect(addr, size, prot, &old_protect)) {
-        error_report("%s: VirtualProtect failed with error code %ld",
-                     __func__, GetLastError());
+        g_autofree gchar *emsg = g_win32_error_message(GetLastError());
+        error_report("%s: VirtualProtect failed: %s", __func__, emsg);
         return -1;
     }
     return 0;
index 83b6639018a26288d6400a0920802d102ac22987..0ce42822eba9f160302cca3b3bf15a1e6c09e80b 100644 (file)
@@ -5,6 +5,8 @@ run_poll_handlers_begin(void *ctx, int64_t max_ns, int64_t timeout) "ctx %p max_
 run_poll_handlers_end(void *ctx, bool progress, int64_t timeout) "ctx %p progress %d new timeout %"PRId64
 poll_shrink(void *ctx, int64_t old, int64_t new) "ctx %p old %"PRId64" new %"PRId64
 poll_grow(void *ctx, int64_t old, int64_t new) "ctx %p old %"PRId64" new %"PRId64
+poll_add(void *ctx, void *node, int fd, unsigned revents) "ctx %p node %p fd %d revents 0x%x"
+poll_remove(void *ctx, void *node, int fd) "ctx %p node %p fd %d"
 
 # async.c
 aio_co_schedule(void *ctx, void *co) "ctx %p co %p"