/qapi-gen-timestamp
/qapi/qapi-builtin-types.[ch]
/qapi/qapi-builtin-visit.[ch]
-/qapi/qapi-commands-block-core.[ch]
-/qapi/qapi-commands-block.[ch]
-/qapi/qapi-commands-char.[ch]
-/qapi/qapi-commands-common.[ch]
-/qapi/qapi-commands-crypto.[ch]
-/qapi/qapi-commands-introspect.[ch]
-/qapi/qapi-commands-job.[ch]
-/qapi/qapi-commands-migration.[ch]
-/qapi/qapi-commands-misc.[ch]
-/qapi/qapi-commands-net.[ch]
-/qapi/qapi-commands-rocker.[ch]
-/qapi/qapi-commands-run-state.[ch]
-/qapi/qapi-commands-sockets.[ch]
-/qapi/qapi-commands-tpm.[ch]
-/qapi/qapi-commands-trace.[ch]
-/qapi/qapi-commands-transaction.[ch]
-/qapi/qapi-commands-ui.[ch]
+/qapi/qapi-commands-*.[ch]
/qapi/qapi-commands.[ch]
-/qapi/qapi-events-block-core.[ch]
-/qapi/qapi-events-block.[ch]
-/qapi/qapi-events-char.[ch]
-/qapi/qapi-events-common.[ch]
-/qapi/qapi-events-crypto.[ch]
-/qapi/qapi-events-introspect.[ch]
-/qapi/qapi-events-job.[ch]
-/qapi/qapi-events-migration.[ch]
-/qapi/qapi-events-misc.[ch]
-/qapi/qapi-events-net.[ch]
-/qapi/qapi-events-rocker.[ch]
-/qapi/qapi-events-run-state.[ch]
-/qapi/qapi-events-sockets.[ch]
-/qapi/qapi-events-tpm.[ch]
-/qapi/qapi-events-trace.[ch]
-/qapi/qapi-events-transaction.[ch]
-/qapi/qapi-events-ui.[ch]
+/qapi/qapi-events-*.[ch]
/qapi/qapi-events.[ch]
/qapi/qapi-introspect.[ch]
-/qapi/qapi-types-block-core.[ch]
-/qapi/qapi-types-block.[ch]
-/qapi/qapi-types-char.[ch]
-/qapi/qapi-types-common.[ch]
-/qapi/qapi-types-crypto.[ch]
-/qapi/qapi-types-introspect.[ch]
-/qapi/qapi-types-job.[ch]
-/qapi/qapi-types-migration.[ch]
-/qapi/qapi-types-misc.[ch]
-/qapi/qapi-types-net.[ch]
-/qapi/qapi-types-rocker.[ch]
-/qapi/qapi-types-run-state.[ch]
-/qapi/qapi-types-sockets.[ch]
-/qapi/qapi-types-tpm.[ch]
-/qapi/qapi-types-trace.[ch]
-/qapi/qapi-types-transaction.[ch]
-/qapi/qapi-types-ui.[ch]
+/qapi/qapi-types-*.[ch]
/qapi/qapi-types.[ch]
-/qapi/qapi-visit-block-core.[ch]
-/qapi/qapi-visit-block.[ch]
-/qapi/qapi-visit-char.[ch]
-/qapi/qapi-visit-common.[ch]
-/qapi/qapi-visit-crypto.[ch]
-/qapi/qapi-visit-introspect.[ch]
-/qapi/qapi-visit-job.[ch]
-/qapi/qapi-visit-migration.[ch]
-/qapi/qapi-visit-misc.[ch]
-/qapi/qapi-visit-net.[ch]
-/qapi/qapi-visit-rocker.[ch]
-/qapi/qapi-visit-run-state.[ch]
-/qapi/qapi-visit-sockets.[ch]
-/qapi/qapi-visit-tpm.[ch]
-/qapi/qapi-visit-trace.[ch]
-/qapi/qapi-visit-transaction.[ch]
-/qapi/qapi-visit-ui.[ch]
+/qapi/qapi-visit-*.[ch]
/qapi/qapi-visit.[ch]
/qapi/qapi-doc.texi
/qemu-doc.html
# Also list preferred name forms where people have changed their
-# git author config, or having utf8/latin1 encoding issues.
+# git author config, or had utf8/latin1 encoding issues.
Daniel P. Berrangé <berrange@redhat.com>
Reimar Döffinger <Reimar.Doeffinger@gmx.de>
S: Maintained
F: target/nios2/
F: hw/nios2/
+F: hw/intc/nios2_iic.c
F: disas/nios2.c
+F: default-configs/nios2-softmmu.mak
OpenRISC
M: Stafford Horne <shorne@gmail.com>
F: target/sparc/
F: hw/sparc/
F: hw/sparc64/
+F: include/hw/sparc/sparc64.h
F: disas/sparc.c
UniCore32
F: target/ppc/kvm.c
S390
-M: Christian Borntraeger <borntraeger@de.ibm.com>
+M: Halil Pasic <pasic@linux.ibm.com>
M: Cornelia Huck <cohuck@redhat.com>
+M: Christian Borntraeger <borntraeger@de.ibm.com>
S: Maintained
F: target/s390x/kvm.c
F: target/s390x/kvm_s390x.h
S: Odd Fixes
F: include/hw/arm/digic.h
F: hw/*/digic*
+F: include/hw/*/digic*
Gumstix
M: Peter Maydell <peter.maydell@linaro.org>
F: include/hw/misc/mps2-*.h
F: hw/arm/iotkit.c
F: include/hw/arm/iotkit.h
+F: hw/misc/iotkit-secctl.c
+F: include/hw/misc/iotkit-secctl.h
F: hw/misc/iotkit-sysctl.c
F: include/hw/misc/iotkit-sysctl.h
F: hw/misc/iotkit-sysinfo.c
S: Maintained
F: hw/*/xlnx*.c
F: include/hw/*/xlnx*.h
+F: include/hw/ssi/xilinx_spips.h
+F: hw/display/dpcd.c
+F: include/hw/display/dpcd.h
ARM ACPI Subsystem
M: Shannon Zhao <shannon.zhaosl@gmail.com>
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
F: hw/microblaze/petalogix_s3adsp1800_mmu.c
+F: include/hw/char/xilinx_uartlite.h
petalogix_ml605
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Maintained
F: hw/mips/mips_jazz.c
+F: hw/display/jazz_led.c
+F: hw/dma/rc4030.c
Malta
M: Aurelien Jarno <aurelien@aurel32.net>
S: Odd Fixes
F: hw/mips/mips_fulong2e.c
F: hw/isa/vt82c686.c
-
+F: hw/pci-host/bonito.c
F: include/hw/isa/vt82c686.h
Boston
F: hw/core/loader-fit.c
F: hw/mips/boston.c
F: hw/pci-host/xilinx-pcie.c
+F: include/hw/pci-host/xilinx-pcie.h
OpenRISC Machines
-----------------
F: include/hw/misc/macio/
F: include/hw/misc/mos6522.h
F: include/hw/ppc/mac_dbdma.h
+F: include/hw/pci-host/uninorth.h
Old World
M: David Gibson <david@gibson.dropbear.id.au>
F: hw/pci-host/grackle.c
F: hw/misc/macio/
F: hw/intc/heathrow_pic.c
+F: include/hw/intc/heathrow_pic.h
PReP
M: Hervé Poussineau <hpoussin@reactos.org>
F: hw/misc/slavio_misc.c
F: include/hw/sparc/sparc32_dma.h
F: pc-bios/openbios-sparc32
+F: include/hw/sparc/sun4m_iommu.h
Sun4u
M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
S: Maintained
F: hw/sparc64/sun4u.c
F: pc-bios/openbios-sparc64
+F: hw/pci-host/sabre.c
+F: include/hw/pci-host/sabre.h
Sun4v
M: Artyom Tarasenko <atar4qemu@gmail.com>
-------------
S390 Virtio-ccw
M: Cornelia Huck <cohuck@redhat.com>
+M: Halil Pasic <pasic@linux.ibm.com>
M: Christian Borntraeger <borntraeger@de.ibm.com>
S: Supported
F: hw/char/sclp*.[hc]
F: hw/timer/i8254*
F: hw/timer/mc146818rtc*
F: hw/watchdog/wdt_ib700.c
+F: hw/watchdog/wdt_i6300esb.c
F: include/hw/display/vga.h
F: include/hw/char/parallel.h
F: include/hw/dma/i8257.h
F: include/hw/i2c/pm_smbus.h
F: include/hw/input/i8042.h
+F: include/hw/isa/i8259_internal.h
F: include/hw/isa/superio.h
F: include/hw/timer/hpet.h
F: include/hw/timer/i8254*
F: hw/arm/virt-acpi-build.c
F: tests/bios-tables-test.c
F: tests/acpi-utils.[hc]
-F: tests/acpi-test-data/*
-F: tests/acpi-test-data/*/*
+F: tests/data/acpi/
ppc4xx
M: David Gibson <david@gibson.dropbear.id.au>
SCSI
M: Paolo Bonzini <pbonzini@redhat.com>
-R: Fam Zheng <famz@redhat.com>
+R: Fam Zheng <fam@euphon.net>
S: Supported
F: include/hw/scsi/*
F: hw/scsi/*
S: Supported
F: hw/*/*vhost*
F: docs/interop/vhost-user.txt
+F: contrib/vhost-user-*/
virtio
M: Michael S. Tsirkin <mst@redhat.com>
F: hw/acpi/nvdimm.c
F: hw/mem/nvdimm.c
F: include/hw/mem/nvdimm.h
+F: docs/nvdimm.txt
e1000x
M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
Block I/O path
M: Stefan Hajnoczi <stefanha@redhat.com>
-M: Fam Zheng <famz@redhat.com>
+M: Fam Zheng <fam@euphon.net>
L: qemu-block@nongnu.org
S: Supported
F: util/async.c
Block SCSI subsystem
M: Paolo Bonzini <pbonzini@redhat.com>
-R: Fam Zheng <famz@redhat.com>
+R: Fam Zheng <fam@euphon.net>
L: qemu-block@nongnu.org
S: Supported
F: include/scsi/*
T: git https://repo.or.cz/qemu/armbru.git block-next
Dirty Bitmaps
-M: Fam Zheng <famz@redhat.com>
+M: Fam Zheng <fam@euphon.net>
M: John Snow <jsnow@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: audio/spiceaudio.c
F: hw/display/qxl*
F: qapi/ui.json
+F: docs/spice-port-fqdn.txt
Graphics
M: Gerd Hoffmann <kraxel@redhat.com>
F: qmp.c
F: monitor.c
F: docs/devel/*qmp-*
+F: docs/interop/*qmp-*
F: scripts/qmp/
F: tests/qmp-test.c
F: tests/qmp-cmd-test.c
L: qemu-block@nongnu.org
UUID
-M: Fam Zheng <famz@redhat.com>
+M: Fam Zheng <fam@euphon.net>
S: Supported
F: util/uuid.c
F: include/qemu/uuid.h
Block drivers
-------------
VMDK
-M: Fam Zheng <famz@redhat.com>
+M: Fam Zheng <fam@euphon.net>
L: qemu-block@nongnu.org
S: Supported
F: block/vmdk.c
T: git https://github.com/codyprime/qemu-kvm-jtc.git block
Null Block Driver
-M: Fam Zheng <famz@redhat.com>
+M: Fam Zheng <fam@euphon.net>
L: qemu-block@nongnu.org
S: Supported
F: block/null.c
NVMe Block Driver
-M: Fam Zheng <famz@redhat.com>
+M: Fam Zheng <fam@euphon.net>
L: qemu-block@nongnu.org
S: Supported
F: block/nvme*
-------------------------
Build and test automation
M: Alex Bennée <alex.bennee@linaro.org>
-M: Fam Zheng <famz@redhat.com>
-R: Philippe Mathieu-Daudé <f4bug@amsat.org>
+M: Fam Zheng <fam@euphon.net>
+R: Philippe Mathieu-Daudé <philmd@redhat.com>
L: qemu-devel@nongnu.org
S: Maintained
F: .travis.yml
include $(SRC_PATH)/rules.mak
GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
-GENERATED_FILES += qapi/qapi-builtin-types.h qapi/qapi-builtin-types.c
-GENERATED_FILES += qapi/qapi-types.h qapi/qapi-types.c
-GENERATED_FILES += qapi/qapi-types-block-core.h qapi/qapi-types-block-core.c
-GENERATED_FILES += qapi/qapi-types-block.h qapi/qapi-types-block.c
-GENERATED_FILES += qapi/qapi-types-char.h qapi/qapi-types-char.c
-GENERATED_FILES += qapi/qapi-types-common.h qapi/qapi-types-common.c
-GENERATED_FILES += qapi/qapi-types-crypto.h qapi/qapi-types-crypto.c
-GENERATED_FILES += qapi/qapi-types-introspect.h qapi/qapi-types-introspect.c
-GENERATED_FILES += qapi/qapi-types-job.h qapi/qapi-types-job.c
-GENERATED_FILES += qapi/qapi-types-migration.h qapi/qapi-types-migration.c
-GENERATED_FILES += qapi/qapi-types-misc.h qapi/qapi-types-misc.c
-GENERATED_FILES += qapi/qapi-types-net.h qapi/qapi-types-net.c
-GENERATED_FILES += qapi/qapi-types-rocker.h qapi/qapi-types-rocker.c
-GENERATED_FILES += qapi/qapi-types-run-state.h qapi/qapi-types-run-state.c
-GENERATED_FILES += qapi/qapi-types-sockets.h qapi/qapi-types-sockets.c
-GENERATED_FILES += qapi/qapi-types-tpm.h qapi/qapi-types-tpm.c
-GENERATED_FILES += qapi/qapi-types-trace.h qapi/qapi-types-trace.c
-GENERATED_FILES += qapi/qapi-types-transaction.h qapi/qapi-types-transaction.c
-GENERATED_FILES += qapi/qapi-types-ui.h qapi/qapi-types-ui.c
-GENERATED_FILES += qapi/qapi-builtin-visit.h qapi/qapi-builtin-visit.c
-GENERATED_FILES += qapi/qapi-visit.h qapi/qapi-visit.c
-GENERATED_FILES += qapi/qapi-visit-block-core.h qapi/qapi-visit-block-core.c
-GENERATED_FILES += qapi/qapi-visit-block.h qapi/qapi-visit-block.c
-GENERATED_FILES += qapi/qapi-visit-char.h qapi/qapi-visit-char.c
-GENERATED_FILES += qapi/qapi-visit-common.h qapi/qapi-visit-common.c
-GENERATED_FILES += qapi/qapi-visit-crypto.h qapi/qapi-visit-crypto.c
-GENERATED_FILES += qapi/qapi-visit-introspect.h qapi/qapi-visit-introspect.c
-GENERATED_FILES += qapi/qapi-visit-job.h qapi/qapi-visit-job.c
-GENERATED_FILES += qapi/qapi-visit-migration.h qapi/qapi-visit-migration.c
-GENERATED_FILES += qapi/qapi-visit-misc.h qapi/qapi-visit-misc.c
-GENERATED_FILES += qapi/qapi-visit-net.h qapi/qapi-visit-net.c
-GENERATED_FILES += qapi/qapi-visit-rocker.h qapi/qapi-visit-rocker.c
-GENERATED_FILES += qapi/qapi-visit-run-state.h qapi/qapi-visit-run-state.c
-GENERATED_FILES += qapi/qapi-visit-sockets.h qapi/qapi-visit-sockets.c
-GENERATED_FILES += qapi/qapi-visit-tpm.h qapi/qapi-visit-tpm.c
-GENERATED_FILES += qapi/qapi-visit-trace.h qapi/qapi-visit-trace.c
-GENERATED_FILES += qapi/qapi-visit-transaction.h qapi/qapi-visit-transaction.c
-GENERATED_FILES += qapi/qapi-visit-ui.h qapi/qapi-visit-ui.c
-GENERATED_FILES += qapi/qapi-commands.h qapi/qapi-commands.c
-GENERATED_FILES += qapi/qapi-commands-block-core.h qapi/qapi-commands-block-core.c
-GENERATED_FILES += qapi/qapi-commands-block.h qapi/qapi-commands-block.c
-GENERATED_FILES += qapi/qapi-commands-char.h qapi/qapi-commands-char.c
-GENERATED_FILES += qapi/qapi-commands-common.h qapi/qapi-commands-common.c
-GENERATED_FILES += qapi/qapi-commands-crypto.h qapi/qapi-commands-crypto.c
-GENERATED_FILES += qapi/qapi-commands-introspect.h qapi/qapi-commands-introspect.c
-GENERATED_FILES += qapi/qapi-commands-job.h qapi/qapi-commands-job.c
-GENERATED_FILES += qapi/qapi-commands-migration.h qapi/qapi-commands-migration.c
-GENERATED_FILES += qapi/qapi-commands-misc.h qapi/qapi-commands-misc.c
-GENERATED_FILES += qapi/qapi-commands-net.h qapi/qapi-commands-net.c
-GENERATED_FILES += qapi/qapi-commands-rocker.h qapi/qapi-commands-rocker.c
-GENERATED_FILES += qapi/qapi-commands-run-state.h qapi/qapi-commands-run-state.c
-GENERATED_FILES += qapi/qapi-commands-sockets.h qapi/qapi-commands-sockets.c
-GENERATED_FILES += qapi/qapi-commands-tpm.h qapi/qapi-commands-tpm.c
-GENERATED_FILES += qapi/qapi-commands-trace.h qapi/qapi-commands-trace.c
-GENERATED_FILES += qapi/qapi-commands-transaction.h qapi/qapi-commands-transaction.c
-GENERATED_FILES += qapi/qapi-commands-ui.h qapi/qapi-commands-ui.c
-GENERATED_FILES += qapi/qapi-events.h qapi/qapi-events.c
-GENERATED_FILES += qapi/qapi-events-block-core.h qapi/qapi-events-block-core.c
-GENERATED_FILES += qapi/qapi-events-block.h qapi/qapi-events-block.c
-GENERATED_FILES += qapi/qapi-events-char.h qapi/qapi-events-char.c
-GENERATED_FILES += qapi/qapi-events-common.h qapi/qapi-events-common.c
-GENERATED_FILES += qapi/qapi-events-crypto.h qapi/qapi-events-crypto.c
-GENERATED_FILES += qapi/qapi-events-introspect.h qapi/qapi-events-introspect.c
-GENERATED_FILES += qapi/qapi-events-job.h qapi/qapi-events-job.c
-GENERATED_FILES += qapi/qapi-events-migration.h qapi/qapi-events-migration.c
-GENERATED_FILES += qapi/qapi-events-misc.h qapi/qapi-events-misc.c
-GENERATED_FILES += qapi/qapi-events-net.h qapi/qapi-events-net.c
-GENERATED_FILES += qapi/qapi-events-rocker.h qapi/qapi-events-rocker.c
-GENERATED_FILES += qapi/qapi-events-run-state.h qapi/qapi-events-run-state.c
-GENERATED_FILES += qapi/qapi-events-sockets.h qapi/qapi-events-sockets.c
-GENERATED_FILES += qapi/qapi-events-tpm.h qapi/qapi-events-tpm.c
-GENERATED_FILES += qapi/qapi-events-trace.h qapi/qapi-events-trace.c
-GENERATED_FILES += qapi/qapi-events-transaction.h qapi/qapi-events-transaction.c
-GENERATED_FILES += qapi/qapi-events-ui.h qapi/qapi-events-ui.c
-GENERATED_FILES += qapi/qapi-introspect.c qapi/qapi-introspect.h
-GENERATED_FILES += qapi/qapi-doc.texi
+
+#see Makefile.objs for the definition of QAPI_MODULES
+GENERATED_QAPI_FILES = qapi/qapi-builtin-types.h qapi/qapi-builtin-types.c
+GENERATED_QAPI_FILES += qapi/qapi-types.h qapi/qapi-types.c
+GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-types-%.h)
+GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-types-%.c)
+GENERATED_QAPI_FILES += qapi/qapi-builtin-visit.h qapi/qapi-builtin-visit.c
+GENERATED_QAPI_FILES += qapi/qapi-visit.h qapi/qapi-visit.c
+GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-visit-%.h)
+GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-visit-%.c)
+GENERATED_QAPI_FILES += qapi/qapi-commands.h qapi/qapi-commands.c
+GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-commands-%.h)
+GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-commands-%.c)
+GENERATED_QAPI_FILES += qapi/qapi-events.h qapi/qapi-events.c
+GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-events-%.h)
+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
+
+GENERATED_FILES += $(GENERATED_QAPI_FILES)
GENERATED_FILES += trace/generated-tcg-tracers.h
"GEN","$(@:%-timestamp=%)")
@>$@
-qapi-modules = $(SRC_PATH)/qapi/qapi-schema.json $(SRC_PATH)/qapi/common.json \
- $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
- $(SRC_PATH)/qapi/char.json \
- $(SRC_PATH)/qapi/crypto.json \
- $(SRC_PATH)/qapi/introspect.json \
- $(SRC_PATH)/qapi/job.json \
- $(SRC_PATH)/qapi/migration.json \
- $(SRC_PATH)/qapi/misc.json \
- $(SRC_PATH)/qapi/net.json \
- $(SRC_PATH)/qapi/rocker.json \
- $(SRC_PATH)/qapi/run-state.json \
- $(SRC_PATH)/qapi/sockets.json \
- $(SRC_PATH)/qapi/tpm.json \
- $(SRC_PATH)/qapi/trace.json \
- $(SRC_PATH)/qapi/transaction.json \
- $(SRC_PATH)/qapi/ui.json
-
-qapi/qapi-builtin-types.c qapi/qapi-builtin-types.h \
-qapi/qapi-types.c qapi/qapi-types.h \
-qapi/qapi-types-block-core.c qapi/qapi-types-block-core.h \
-qapi/qapi-types-block.c qapi/qapi-types-block.h \
-qapi/qapi-types-char.c qapi/qapi-types-char.h \
-qapi/qapi-types-common.c qapi/qapi-types-common.h \
-qapi/qapi-types-crypto.c qapi/qapi-types-crypto.h \
-qapi/qapi-types-introspect.c qapi/qapi-types-introspect.h \
-qapi/qapi-types-job.c qapi/qapi-types-job.h \
-qapi/qapi-types-migration.c qapi/qapi-types-migration.h \
-qapi/qapi-types-misc.c qapi/qapi-types-misc.h \
-qapi/qapi-types-net.c qapi/qapi-types-net.h \
-qapi/qapi-types-rocker.c qapi/qapi-types-rocker.h \
-qapi/qapi-types-run-state.c qapi/qapi-types-run-state.h \
-qapi/qapi-types-sockets.c qapi/qapi-types-sockets.h \
-qapi/qapi-types-tpm.c qapi/qapi-types-tpm.h \
-qapi/qapi-types-trace.c qapi/qapi-types-trace.h \
-qapi/qapi-types-transaction.c qapi/qapi-types-transaction.h \
-qapi/qapi-types-ui.c qapi/qapi-types-ui.h \
-qapi/qapi-builtin-visit.c qapi/qapi-builtin-visit.h \
-qapi/qapi-visit.c qapi/qapi-visit.h \
-qapi/qapi-visit-block-core.c qapi/qapi-visit-block-core.h \
-qapi/qapi-visit-block.c qapi/qapi-visit-block.h \
-qapi/qapi-visit-char.c qapi/qapi-visit-char.h \
-qapi/qapi-visit-common.c qapi/qapi-visit-common.h \
-qapi/qapi-visit-crypto.c qapi/qapi-visit-crypto.h \
-qapi/qapi-visit-introspect.c qapi/qapi-visit-introspect.h \
-qapi/qapi-visit-job.c qapi/qapi-visit-job.h \
-qapi/qapi-visit-migration.c qapi/qapi-visit-migration.h \
-qapi/qapi-visit-misc.c qapi/qapi-visit-misc.h \
-qapi/qapi-visit-net.c qapi/qapi-visit-net.h \
-qapi/qapi-visit-rocker.c qapi/qapi-visit-rocker.h \
-qapi/qapi-visit-run-state.c qapi/qapi-visit-run-state.h \
-qapi/qapi-visit-sockets.c qapi/qapi-visit-sockets.h \
-qapi/qapi-visit-tpm.c qapi/qapi-visit-tpm.h \
-qapi/qapi-visit-trace.c qapi/qapi-visit-trace.h \
-qapi/qapi-visit-transaction.c qapi/qapi-visit-transaction.h \
-qapi/qapi-visit-ui.c qapi/qapi-visit-ui.h \
-qapi/qapi-commands.h qapi/qapi-commands.c \
-qapi/qapi-commands-block-core.c qapi/qapi-commands-block-core.h \
-qapi/qapi-commands-block.c qapi/qapi-commands-block.h \
-qapi/qapi-commands-char.c qapi/qapi-commands-char.h \
-qapi/qapi-commands-common.c qapi/qapi-commands-common.h \
-qapi/qapi-commands-crypto.c qapi/qapi-commands-crypto.h \
-qapi/qapi-commands-introspect.c qapi/qapi-commands-introspect.h \
-qapi/qapi-commands-job.c qapi/qapi-commands-job.h \
-qapi/qapi-commands-migration.c qapi/qapi-commands-migration.h \
-qapi/qapi-commands-misc.c qapi/qapi-commands-misc.h \
-qapi/qapi-commands-net.c qapi/qapi-commands-net.h \
-qapi/qapi-commands-rocker.c qapi/qapi-commands-rocker.h \
-qapi/qapi-commands-run-state.c qapi/qapi-commands-run-state.h \
-qapi/qapi-commands-sockets.c qapi/qapi-commands-sockets.h \
-qapi/qapi-commands-tpm.c qapi/qapi-commands-tpm.h \
-qapi/qapi-commands-trace.c qapi/qapi-commands-trace.h \
-qapi/qapi-commands-transaction.c qapi/qapi-commands-transaction.h \
-qapi/qapi-commands-ui.c qapi/qapi-commands-ui.h \
-qapi/qapi-events.c qapi/qapi-events.h \
-qapi/qapi-events-block-core.c qapi/qapi-events-block-core.h \
-qapi/qapi-events-block.c qapi/qapi-events-block.h \
-qapi/qapi-events-char.c qapi/qapi-events-char.h \
-qapi/qapi-events-common.c qapi/qapi-events-common.h \
-qapi/qapi-events-crypto.c qapi/qapi-events-crypto.h \
-qapi/qapi-events-introspect.c qapi/qapi-events-introspect.h \
-qapi/qapi-events-job.c qapi/qapi-events-job.h \
-qapi/qapi-events-migration.c qapi/qapi-events-migration.h \
-qapi/qapi-events-misc.c qapi/qapi-events-misc.h \
-qapi/qapi-events-net.c qapi/qapi-events-net.h \
-qapi/qapi-events-rocker.c qapi/qapi-events-rocker.h \
-qapi/qapi-events-run-state.c qapi/qapi-events-run-state.h \
-qapi/qapi-events-sockets.c qapi/qapi-events-sockets.h \
-qapi/qapi-events-tpm.c qapi/qapi-events-tpm.h \
-qapi/qapi-events-trace.c qapi/qapi-events-trace.h \
-qapi/qapi-events-transaction.c qapi/qapi-events-transaction.h \
-qapi/qapi-events-ui.c qapi/qapi-events-ui.h \
-qapi/qapi-introspect.h qapi/qapi-introspect.c \
-qapi/qapi-doc.texi: \
-qapi-gen-timestamp ;
+qapi-modules = $(SRC_PATH)/qapi/qapi-schema.json \
+ $(QAPI_MODULES:%=$(SRC_PATH)/qapi/%.json)
+
+$(GENERATED_QAPI_FILES): qapi-gen-timestamp ;
qapi-gen-timestamp: $(qapi-modules) $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
-o "qapi" -b $<, \
+QAPI_MODULES = block-core block char common crypto introspect job migration
+QAPI_MODULES += misc net rocker run-state sockets tpm trace transaction ui
+
#######################################################################
# Common libraries for tools and emulators
stub-obj-y = stubs/ crypto/
util-obj-y = util/ qobject/ qapi/
util-obj-y += qapi/qapi-builtin-types.o
util-obj-y += qapi/qapi-types.o
-util-obj-y += qapi/qapi-types-block-core.o
-util-obj-y += qapi/qapi-types-block.o
-util-obj-y += qapi/qapi-types-char.o
-util-obj-y += qapi/qapi-types-common.o
-util-obj-y += qapi/qapi-types-crypto.o
-util-obj-y += qapi/qapi-types-introspect.o
-util-obj-y += qapi/qapi-types-job.o
-util-obj-y += qapi/qapi-types-migration.o
-util-obj-y += qapi/qapi-types-misc.o
-util-obj-y += qapi/qapi-types-net.o
-util-obj-y += qapi/qapi-types-rocker.o
-util-obj-y += qapi/qapi-types-run-state.o
-util-obj-y += qapi/qapi-types-sockets.o
-util-obj-y += qapi/qapi-types-tpm.o
-util-obj-y += qapi/qapi-types-trace.o
-util-obj-y += qapi/qapi-types-transaction.o
-util-obj-y += qapi/qapi-types-ui.o
+util-obj-y += $(QAPI_MODULES:%=qapi/qapi-types-%.o)
util-obj-y += qapi/qapi-builtin-visit.o
util-obj-y += qapi/qapi-visit.o
-util-obj-y += qapi/qapi-visit-block-core.o
-util-obj-y += qapi/qapi-visit-block.o
-util-obj-y += qapi/qapi-visit-char.o
-util-obj-y += qapi/qapi-visit-common.o
-util-obj-y += qapi/qapi-visit-crypto.o
-util-obj-y += qapi/qapi-visit-introspect.o
-util-obj-y += qapi/qapi-visit-job.o
-util-obj-y += qapi/qapi-visit-migration.o
-util-obj-y += qapi/qapi-visit-misc.o
-util-obj-y += qapi/qapi-visit-net.o
-util-obj-y += qapi/qapi-visit-rocker.o
-util-obj-y += qapi/qapi-visit-run-state.o
-util-obj-y += qapi/qapi-visit-sockets.o
-util-obj-y += qapi/qapi-visit-tpm.o
-util-obj-y += qapi/qapi-visit-trace.o
-util-obj-y += qapi/qapi-visit-transaction.o
-util-obj-y += qapi/qapi-visit-ui.o
+util-obj-y += $(QAPI_MODULES:%=qapi/qapi-visit-%.o)
util-obj-y += qapi/qapi-events.o
-util-obj-y += qapi/qapi-events-block-core.o
-util-obj-y += qapi/qapi-events-block.o
-util-obj-y += qapi/qapi-events-char.o
-util-obj-y += qapi/qapi-events-common.o
-util-obj-y += qapi/qapi-events-crypto.o
-util-obj-y += qapi/qapi-events-introspect.o
-util-obj-y += qapi/qapi-events-job.o
-util-obj-y += qapi/qapi-events-migration.o
-util-obj-y += qapi/qapi-events-misc.o
-util-obj-y += qapi/qapi-events-net.o
-util-obj-y += qapi/qapi-events-rocker.o
-util-obj-y += qapi/qapi-events-run-state.o
-util-obj-y += qapi/qapi-events-sockets.o
-util-obj-y += qapi/qapi-events-tpm.o
-util-obj-y += qapi/qapi-events-trace.o
-util-obj-y += qapi/qapi-events-transaction.o
-util-obj-y += qapi/qapi-events-ui.o
+util-obj-y += $(QAPI_MODULES:%=qapi/qapi-events-%.o)
util-obj-y += qapi/qapi-introspect.o
chardev-obj-y = chardev/
# qapi
common-obj-y += qapi/qapi-commands.o
-common-obj-y += qapi/qapi-commands-block-core.o
-common-obj-y += qapi/qapi-commands-block.o
-common-obj-y += qapi/qapi-commands-char.o
-common-obj-y += qapi/qapi-commands-common.o
-common-obj-y += qapi/qapi-commands-crypto.o
-common-obj-y += qapi/qapi-commands-introspect.o
-common-obj-y += qapi/qapi-commands-job.o
-common-obj-y += qapi/qapi-commands-migration.o
-common-obj-y += qapi/qapi-commands-misc.o
-common-obj-y += qapi/qapi-commands-net.o
-common-obj-y += qapi/qapi-commands-rocker.o
-common-obj-y += qapi/qapi-commands-run-state.o
-common-obj-y += qapi/qapi-commands-sockets.o
-common-obj-y += qapi/qapi-commands-tpm.o
-common-obj-y += qapi/qapi-commands-trace.o
-common-obj-y += qapi/qapi-commands-transaction.o
-common-obj-y += qapi/qapi-commands-ui.o
+common-obj-y += $(QAPI_MODULES:%=qapi/qapi-commands-%.o)
common-obj-y += qapi/qapi-introspect.o
common-obj-y += qmp.o hmp.o
endif
endif # CONFIG_SOFTMMU
-# Workaround for http://gcc.gnu.org/PR55489, see configure.
-%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
-
dummy := $(call unnest-vars,,obj-y)
all-obj-y := $(obj-y)
#include "audio.h"
#include "trace.h"
-#if QEMU_GNUC_PREREQ(4, 3)
#pragma GCC diagnostic ignored "-Waddress"
-#endif
#define AUDIO_CAP "alsa"
#include "audio_int.h"
block_crypto_read_func,
bs,
cflags,
+ 1,
errp);
if (!crypto->block) {
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
}
s->crypto = qcrypto_block_open(crypto_opts, "encrypt.",
- NULL, NULL, cflags, errp);
+ NULL, NULL, cflags, 1, errp);
if (!s->crypto) {
ret = -EINVAL;
goto fail;
}
s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
qcow2_crypto_hdr_read_func,
- bs, cflags, errp);
+ bs, cflags, 1, errp);
if (!s->crypto) {
return -EINVAL;
}
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
}
s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
- NULL, NULL, cflags, errp);
+ NULL, NULL, cflags, 1, errp);
if (!s->crypto) {
ret = -EINVAL;
goto fail;
{
ChardevClass *cc = CHARDEV_GET_CLASS(s);
+ assert(qemu_chr_has_feature(s, QEMU_CHAR_FEATURE_GCONTEXT)
+ || !context);
s->gcontext = context;
if (cc->chr_update_read_handler) {
cc->chr_update_read_handler(s);
chr->logfd = -1;
qemu_mutex_init(&chr->chr_write_lock);
+
+ /*
+ * Assume if chr_update_read_handler is implemented it will
+ * take the updated gcontext into account.
+ */
+ if (CHARDEV_GET_CLASS(chr)->chr_update_read_handler) {
+ qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT);
+ }
+
}
static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
error_exit "Unrecognized host OS (uname -s reports '$(uname -s)')"
fi
+# Check whether the compiler matches our minimum requirements:
+cat > $TMPC << EOF
+#if defined(__clang_major__) && defined(__clang_minor__)
+# ifdef __apple_build_version__
+# if __clang_major__ < 5 || (__clang_major__ == 5 && __clang_minor__ < 1)
+# error You need at least XCode Clang v5.1 to compile QEMU
+# endif
+# else
+# if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 4)
+# error You need at least Clang v3.4 to compile QEMU
+# endif
+# endif
+#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
+# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
+# error You need at least GCC v4.8 to compile QEMU
+# endif
+#else
+# error You either need GCC or Clang to compiler QEMU
+#endif
+int main (void) { return 0; }
+EOF
+if ! compile_prog "" "" ; then
+ error_exit "You need at least GCC v4.8 or Clang v3.4 (or XCode Clang v5.1)"
+fi
+
gcc_flags="-Wold-style-declaration -Wold-style-definition -Wtype-limits"
gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_flags"
gcc_flags="-Wno-missing-include-dirs -Wempty-body -Wnested-externs $gcc_flags"
QEMU_CFLAGS="$QEMU_CFLAGS -Wno-missing-braces"
fi
-# Workaround for http://gcc.gnu.org/PR55489. Happens with -fPIE/-fPIC and
-# large functions that use global variables. The bug is in all releases of
-# GCC, but it became particularly acute in 4.6.x and 4.7.x. It is fixed in
-# 4.7.3 and 4.8.0. We should be able to delete this at the end of 2013.
-cat > $TMPC << EOF
-#if __GNUC__ == 4 && (__GNUC_MINOR__ == 6 || (__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ <= 2))
-int main(void) { return 0; }
-#else
-#error No bug in this compiler.
-#endif
-EOF
-if compile_prog "-Werror -fno-gcse" "" ; then
- TRANSLATE_OPT_CFLAGS=-fno-gcse
-fi
-
+# Static linking is not possible with modules or PIE
if test "$static" = "yes" ; then
if test "$modules" = "yes" ; then
error_exit "static and modules are mutually incompatible"
int128=no
cat > $TMPC << EOF
-#if defined(__clang_major__) && defined(__clang_minor__)
-# if ((__clang_major__ < 3) || (__clang_major__ == 3) && (__clang_minor__ < 2))
-# error __int128_t does not work in CLANG before 3.2
-# endif
-#endif
__int128_t a;
__uint128_t b;
int main (void) {
echo "TASN1_LIBS=$tasn1_libs" >> $config_host_mak
echo "TASN1_CFLAGS=$tasn1_cflags" >> $config_host_mak
echo "POD2MAN=$POD2MAN" >> $config_host_mak
-echo "TRANSLATE_OPT_CFLAGS=$TRANSLATE_OPT_CFLAGS" >> $config_host_mak
if test "$gcov" = "yes" ; then
echo "CONFIG_GCOV=y" >> $config_host_mak
echo "GCOV=$gcov_tool" >> $config_host_mak
* to reset the encryption cipher every time the master
* key crosses a sector boundary.
*/
- if (qcrypto_block_decrypt_helper(cipher,
- niv,
- ivgen,
- QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
- 0,
- splitkey,
- splitkeylen,
- errp) < 0) {
+ if (qcrypto_block_cipher_decrypt_helper(cipher,
+ niv,
+ ivgen,
+ QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
+ 0,
+ splitkey,
+ splitkeylen,
+ errp) < 0) {
goto cleanup;
}
QCryptoBlockReadFunc readfunc,
void *opaque,
unsigned int flags,
+ size_t n_threads,
Error **errp)
{
QCryptoBlockLUKS *luks;
goto fail;
}
- block->cipher = qcrypto_cipher_new(cipheralg,
- ciphermode,
- masterkey, masterkeylen,
- errp);
- if (!block->cipher) {
+ ret = qcrypto_block_init_cipher(block, cipheralg, ciphermode,
+ masterkey, masterkeylen, n_threads,
+ errp);
+ if (ret < 0) {
ret = -ENOTSUP;
goto fail;
}
fail:
g_free(masterkey);
- qcrypto_cipher_free(block->cipher);
+ qcrypto_block_free_cipher(block);
qcrypto_ivgen_free(block->ivgen);
g_free(luks);
g_free(password);
/* Setup the block device payload encryption objects */
- block->cipher = qcrypto_cipher_new(luks_opts.cipher_alg,
- luks_opts.cipher_mode,
- masterkey, luks->header.key_bytes,
- errp);
- if (!block->cipher) {
+ if (qcrypto_block_init_cipher(block, luks_opts.cipher_alg,
+ luks_opts.cipher_mode, masterkey,
+ luks->header.key_bytes, 1, errp) < 0) {
goto error;
}
/* Now we encrypt the split master key with the key generated
* from the user's password, before storing it */
- if (qcrypto_block_encrypt_helper(cipher, block->niv, ivgen,
- QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
- 0,
- splitkey,
- splitkeylen,
- errp) < 0) {
+ if (qcrypto_block_cipher_encrypt_helper(cipher, block->niv, ivgen,
+ QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
+ 0,
+ splitkey,
+ splitkeylen,
+ errp) < 0) {
goto error;
}
qcrypto_ivgen_free(ivgen);
qcrypto_cipher_free(cipher);
+ qcrypto_block_free_cipher(block);
+ qcrypto_ivgen_free(block->ivgen);
+
g_free(luks);
return -1;
}
{
assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE));
assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE));
- return qcrypto_block_decrypt_helper(block->cipher,
- block->niv, block->ivgen,
+ return qcrypto_block_decrypt_helper(block,
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
offset, buf, len, errp);
}
{
assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE));
assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE));
- return qcrypto_block_encrypt_helper(block->cipher,
- block->niv, block->ivgen,
+ return qcrypto_block_encrypt_helper(block,
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
offset, buf, len, errp);
}
static int
qcrypto_block_qcow_init(QCryptoBlock *block,
const char *keysecret,
+ size_t n_threads,
Error **errp)
{
char *password;
goto fail;
}
- block->cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
- QCRYPTO_CIPHER_MODE_CBC,
- keybuf, G_N_ELEMENTS(keybuf),
- errp);
- if (!block->cipher) {
+ ret = qcrypto_block_init_cipher(block, QCRYPTO_CIPHER_ALG_AES_128,
+ QCRYPTO_CIPHER_MODE_CBC,
+ keybuf, G_N_ELEMENTS(keybuf),
+ n_threads, errp);
+ if (ret < 0) {
ret = -ENOTSUP;
goto fail;
}
return 0;
fail:
- qcrypto_cipher_free(block->cipher);
+ qcrypto_block_free_cipher(block);
qcrypto_ivgen_free(block->ivgen);
return ret;
}
QCryptoBlockReadFunc readfunc G_GNUC_UNUSED,
void *opaque G_GNUC_UNUSED,
unsigned int flags,
+ size_t n_threads,
Error **errp)
{
if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
optprefix ? optprefix : "");
return -1;
}
- return qcrypto_block_qcow_init(block,
- options->u.qcow.key_secret, errp);
+ return qcrypto_block_qcow_init(block, options->u.qcow.key_secret,
+ n_threads, errp);
}
}
return -1;
}
/* QCow2 has no special header, since everything is hardwired */
- return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, errp);
+ return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, 1, errp);
}
{
assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
- return qcrypto_block_decrypt_helper(block->cipher,
- block->niv, block->ivgen,
+ return qcrypto_block_decrypt_helper(block,
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE,
offset, buf, len, errp);
}
{
assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
- return qcrypto_block_encrypt_helper(block->cipher,
- block->niv, block->ivgen,
+ return qcrypto_block_encrypt_helper(block,
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE,
offset, buf, len, errp);
}
QCryptoBlockReadFunc readfunc,
void *opaque,
unsigned int flags,
+ size_t n_threads,
Error **errp)
{
QCryptoBlock *block = g_new0(QCryptoBlock, 1);
block->driver = qcrypto_block_drivers[options->format];
if (block->driver->open(block, options, optprefix,
- readfunc, opaque, flags, errp) < 0) {
+ readfunc, opaque, flags, n_threads, errp) < 0)
+ {
g_free(block);
return NULL;
}
+ qemu_mutex_init(&block->mutex);
+
return block;
}
return NULL;
}
+ qemu_mutex_init(&block->mutex);
+
return block;
}
QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block)
{
- return block->cipher;
+ /* Ciphers should be accessed through pop/push method to be thread-safe.
+ * Better, they should not be accessed externally at all (note, that
+ * pop/push are static functions)
+ * This function is used only in test with one thread (it's safe to skip
+ * pop/push interface), so it's enough to assert it here:
+ */
+ assert(block->n_ciphers <= 1);
+ return block->ciphers ? block->ciphers[0] : NULL;
+}
+
+
+static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block)
+{
+ QCryptoCipher *cipher;
+
+ qemu_mutex_lock(&block->mutex);
+
+ assert(block->n_free_ciphers > 0);
+ block->n_free_ciphers--;
+ cipher = block->ciphers[block->n_free_ciphers];
+
+ qemu_mutex_unlock(&block->mutex);
+
+ return cipher;
+}
+
+
+static void qcrypto_block_push_cipher(QCryptoBlock *block,
+ QCryptoCipher *cipher)
+{
+ qemu_mutex_lock(&block->mutex);
+
+ assert(block->n_free_ciphers < block->n_ciphers);
+ block->ciphers[block->n_free_ciphers] = cipher;
+ block->n_free_ciphers++;
+
+ qemu_mutex_unlock(&block->mutex);
}
+int qcrypto_block_init_cipher(QCryptoBlock *block,
+ QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key, size_t nkey,
+ size_t n_threads, Error **errp)
+{
+ size_t i;
+
+ assert(!block->ciphers && !block->n_ciphers && !block->n_free_ciphers);
+
+ block->ciphers = g_new0(QCryptoCipher *, n_threads);
+
+ for (i = 0; i < n_threads; i++) {
+ block->ciphers[i] = qcrypto_cipher_new(alg, mode, key, nkey, errp);
+ if (!block->ciphers[i]) {
+ qcrypto_block_free_cipher(block);
+ return -1;
+ }
+ block->n_ciphers++;
+ block->n_free_ciphers++;
+ }
+
+ return 0;
+}
+
+
+void qcrypto_block_free_cipher(QCryptoBlock *block)
+{
+ size_t i;
+
+ if (!block->ciphers) {
+ return;
+ }
+
+ assert(block->n_ciphers == block->n_free_ciphers);
+
+ for (i = 0; i < block->n_ciphers; i++) {
+ qcrypto_cipher_free(block->ciphers[i]);
+ }
+
+ g_free(block->ciphers);
+ block->ciphers = NULL;
+ block->n_ciphers = block->n_free_ciphers = 0;
+}
+
QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block)
{
+ /* ivgen should be accessed under mutex. However, this function is used only
+ * in test with one thread, so it's enough to assert it here:
+ */
+ assert(block->n_ciphers <= 1);
return block->ivgen;
}
block->driver->cleanup(block);
- qcrypto_cipher_free(block->cipher);
+ qcrypto_block_free_cipher(block);
qcrypto_ivgen_free(block->ivgen);
+ qemu_mutex_destroy(&block->mutex);
g_free(block);
}
-int qcrypto_block_decrypt_helper(QCryptoCipher *cipher,
- size_t niv,
- QCryptoIVGen *ivgen,
- int sectorsize,
- uint64_t offset,
- uint8_t *buf,
- size_t len,
- Error **errp)
+typedef int (*QCryptoCipherEncDecFunc)(QCryptoCipher *cipher,
+ const void *in,
+ void *out,
+ size_t len,
+ Error **errp);
+
+static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher,
+ size_t niv,
+ QCryptoIVGen *ivgen,
+ QemuMutex *ivgen_mutex,
+ int sectorsize,
+ uint64_t offset,
+ uint8_t *buf,
+ size_t len,
+ QCryptoCipherEncDecFunc func,
+ Error **errp)
{
uint8_t *iv;
int ret = -1;
while (len > 0) {
size_t nbytes;
if (niv) {
- if (qcrypto_ivgen_calculate(ivgen,
- startsector,
- iv, niv,
- errp) < 0) {
+ if (ivgen_mutex) {
+ qemu_mutex_lock(ivgen_mutex);
+ }
+ ret = qcrypto_ivgen_calculate(ivgen, startsector, iv, niv, errp);
+ if (ivgen_mutex) {
+ qemu_mutex_unlock(ivgen_mutex);
+ }
+
+ if (ret < 0) {
goto cleanup;
}
}
nbytes = len > sectorsize ? sectorsize : len;
- if (qcrypto_cipher_decrypt(cipher, buf, buf,
- nbytes, errp) < 0) {
+ if (func(cipher, buf, buf, nbytes, errp) < 0) {
goto cleanup;
}
}
-int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
- size_t niv,
- QCryptoIVGen *ivgen,
+int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *cipher,
+ size_t niv,
+ QCryptoIVGen *ivgen,
+ int sectorsize,
+ uint64_t offset,
+ uint8_t *buf,
+ size_t len,
+ Error **errp)
+{
+ return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sectorsize,
+ offset, buf, len,
+ qcrypto_cipher_decrypt, errp);
+}
+
+
+int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *cipher,
+ size_t niv,
+ QCryptoIVGen *ivgen,
+ int sectorsize,
+ uint64_t offset,
+ uint8_t *buf,
+ size_t len,
+ Error **errp)
+{
+ return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sectorsize,
+ offset, buf, len,
+ qcrypto_cipher_encrypt, errp);
+}
+
+int qcrypto_block_decrypt_helper(QCryptoBlock *block,
int sectorsize,
uint64_t offset,
uint8_t *buf,
size_t len,
Error **errp)
{
- uint8_t *iv;
- int ret = -1;
- uint64_t startsector = offset / sectorsize;
+ int ret;
+ QCryptoCipher *cipher = qcrypto_block_pop_cipher(block);
- assert(QEMU_IS_ALIGNED(offset, sectorsize));
- assert(QEMU_IS_ALIGNED(len, sectorsize));
+ ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen,
+ &block->mutex, sectorsize, offset, buf,
+ len, qcrypto_cipher_decrypt, errp);
- iv = niv ? g_new0(uint8_t, niv) : NULL;
+ qcrypto_block_push_cipher(block, cipher);
- while (len > 0) {
- size_t nbytes;
- if (niv) {
- if (qcrypto_ivgen_calculate(ivgen,
- startsector,
- iv, niv,
- errp) < 0) {
- goto cleanup;
- }
+ return ret;
+}
- if (qcrypto_cipher_setiv(cipher,
- iv, niv,
- errp) < 0) {
- goto cleanup;
- }
- }
+int qcrypto_block_encrypt_helper(QCryptoBlock *block,
+ int sectorsize,
+ uint64_t offset,
+ uint8_t *buf,
+ size_t len,
+ Error **errp)
+{
+ int ret;
+ QCryptoCipher *cipher = qcrypto_block_pop_cipher(block);
- nbytes = len > sectorsize ? sectorsize : len;
- if (qcrypto_cipher_encrypt(cipher, buf, buf,
- nbytes, errp) < 0) {
- goto cleanup;
- }
+ ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen,
+ &block->mutex, sectorsize, offset, buf,
+ len, qcrypto_cipher_encrypt, errp);
- startsector++;
- buf += nbytes;
- len -= nbytes;
- }
+ qcrypto_block_push_cipher(block, cipher);
- ret = 0;
- cleanup:
- g_free(iv);
return ret;
}
#define QCRYPTO_BLOCKPRIV_H
#include "crypto/block.h"
+#include "qemu/thread.h"
typedef struct QCryptoBlockDriver QCryptoBlockDriver;
const QCryptoBlockDriver *driver;
void *opaque;
- QCryptoCipher *cipher;
+ QCryptoCipher **ciphers;
+ size_t n_ciphers;
+ size_t n_free_ciphers;
QCryptoIVGen *ivgen;
+ QemuMutex mutex;
+
QCryptoHashAlgorithm kdfhash;
size_t niv;
uint64_t payload_offset; /* In bytes */
QCryptoBlockReadFunc readfunc,
void *opaque,
unsigned int flags,
+ size_t n_threads,
Error **errp);
int (*create)(QCryptoBlock *block,
};
-int qcrypto_block_decrypt_helper(QCryptoCipher *cipher,
- size_t niv,
- QCryptoIVGen *ivgen,
+int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *cipher,
+ size_t niv,
+ QCryptoIVGen *ivgen,
+ int sectorsize,
+ uint64_t offset,
+ uint8_t *buf,
+ size_t len,
+ Error **errp);
+
+int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *cipher,
+ size_t niv,
+ QCryptoIVGen *ivgen,
+ int sectorsize,
+ uint64_t offset,
+ uint8_t *buf,
+ size_t len,
+ Error **errp);
+
+int qcrypto_block_decrypt_helper(QCryptoBlock *block,
int sectorsize,
uint64_t offset,
uint8_t *buf,
size_t len,
Error **errp);
-int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
- size_t niv,
- QCryptoIVGen *ivgen,
+int qcrypto_block_encrypt_helper(QCryptoBlock *block,
int sectorsize,
uint64_t offset,
uint8_t *buf,
size_t len,
Error **errp);
+int qcrypto_block_init_cipher(QCryptoBlock *block,
+ QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key, size_t nkey,
+ size_t n_threads, Error **errp);
+
+void qcrypto_block_free_cipher(QCryptoBlock *block);
+
#endif /* QCRYPTO_BLOCKPRIV_H */
is recommended for clients that accept capability "oob".
If the client sends in-band commands faster than the server can
-execute them, the server will eventually drop commands to limit the
-queue length. The sever sends event COMMAND_DROPPED then.
+execute them, the server will stop reading the requests from the QMP
+channel until the request queue length is reduced to an acceptable
+range.
Only a few commands support out-of-band execution. The ones that do
have "allow-oob": true in output of query-qmp-schema.
FIXUP_TERMINATOR, /* end of insns */
FIXUP_BOARDID, /* overwrite with board ID number */
FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
- FIXUP_ARGPTR, /* overwrite with pointer to kernel args */
- FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */
+ FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */
+ FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
+ FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
+ FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
FIXUP_BOOTREG, /* overwrite with boot register address */
FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
{ 0xaa1f03e3 }, /* mov x3, xzr */
{ 0x58000084 }, /* ldr x4, entry ; Load the lower 32-bits of kernel entry */
{ 0xd61f0080 }, /* br x4 ; Jump to the kernel entry point */
- { 0, FIXUP_ARGPTR }, /* arg: .word @DTB Lower 32-bits */
- { 0 }, /* .word @DTB Higher 32-bits */
- { 0, FIXUP_ENTRYPOINT }, /* entry: .word @Kernel Entry Lower 32-bits */
- { 0 }, /* .word @Kernel Entry Higher 32-bits */
+ { 0, FIXUP_ARGPTR_LO }, /* arg: .word @DTB Lower 32-bits */
+ { 0, FIXUP_ARGPTR_HI}, /* .word @DTB Higher 32-bits */
+ { 0, FIXUP_ENTRYPOINT_LO }, /* entry: .word @Kernel Entry Lower 32-bits */
+ { 0, FIXUP_ENTRYPOINT_HI }, /* .word @Kernel Entry Higher 32-bits */
{ 0, FIXUP_TERMINATOR }
};
{ 0xe59f2004 }, /* ldr r2, [pc, #4] */
{ 0xe59ff004 }, /* ldr pc, [pc, #4] */
{ 0, FIXUP_BOARDID },
- { 0, FIXUP_ARGPTR },
- { 0, FIXUP_ENTRYPOINT },
+ { 0, FIXUP_ARGPTR_LO },
+ { 0, FIXUP_ENTRYPOINT_LO },
{ 0, FIXUP_TERMINATOR }
};
break;
case FIXUP_BOARDID:
case FIXUP_BOARD_SETUP:
- case FIXUP_ARGPTR:
- case FIXUP_ENTRYPOINT:
+ case FIXUP_ARGPTR_LO:
+ case FIXUP_ARGPTR_HI:
+ case FIXUP_ENTRYPOINT_LO:
+ case FIXUP_ENTRYPOINT_HI:
case FIXUP_GIC_CPU_IF:
case FIXUP_BOOTREG:
case FIXUP_DSB:
/* Place the DTB after the initrd in memory with alignment. */
info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
align);
- fixupcontext[FIXUP_ARGPTR] = info->dtb_start;
+ fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
+ fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
} else {
- fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR;
+ fixupcontext[FIXUP_ARGPTR_LO] =
+ info->loader_start + KERNEL_ARGS_ADDR;
+ fixupcontext[FIXUP_ARGPTR_HI] =
+ (info->loader_start + KERNEL_ARGS_ADDR) >> 32;
if (info->ram_size >= (1ULL << 32)) {
error_report("RAM size must be less than 4GB to boot"
" Linux kernel using ATAGS (try passing a device tree"
exit(1);
}
}
- fixupcontext[FIXUP_ENTRYPOINT] = entry;
+ fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
+ fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
write_bootloader("bootloader", info->loader_start,
primary_loader, fixupcontext, as);
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int mv88w8618_wlan_init(SysBusDevice *dev)
+static void mv88w8618_wlan_realize(DeviceState *dev, Error **errp)
{
MemoryRegion *iomem = g_new(MemoryRegion, 1);
memory_region_init_io(iomem, OBJECT(dev), &mv88w8618_wlan_ops, NULL,
"musicpal-wlan", MP_WLAN_SIZE);
- sysbus_init_mmio(dev, iomem);
- return 0;
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), iomem);
}
/* GPIO register offsets */
dev = qdev_create(NULL, TYPE_MV88W8618_AUDIO);
s = SYS_BUS_DEVICE(dev);
object_property_set_link(OBJECT(dev), OBJECT(wm8750_dev),
- TYPE_WM8750, NULL);
+ "wm8750", NULL);
qdev_init_nofail(dev);
sysbus_mmio_map(s, 0, MP_AUDIO_BASE);
sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);
static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- sdc->init = mv88w8618_wlan_init;
+ dc->realize = mv88w8618_wlan_realize;
}
static const TypeInfo mv88w8618_wlan_info = {
return board->fdt;
}
-#define NUM_VIRTIO_TRANSPORT 32
+#define NUM_VIRTIO_TRANSPORT 8
static void create_virtio_regions(VersalVirt *s)
{
int virtio_mmio_size = 0x200;
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
char *name = g_strdup_printf("virtio%d", i);;
hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size;
- int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i;
+ int irq = VERSAL_RSVD_IRQ_FIRST + i;
MemoryRegion *mr;
DeviceState *dev;
qemu_irq pic_irq;
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq);
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
memory_region_add_subregion(&s->soc.mr_ps, base, mr);
- sysbus_create_simple("virtio-mmio", base, pic_irq);
}
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size;
- int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i;
+ int irq = VERSAL_RSVD_IRQ_FIRST + i;
char *name = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
qemu_fdt_add_subnode(s->fdt, name);
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int onenand_initfn(SysBusDevice *sbd)
+static void onenand_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
OneNANDState *s = ONE_NAND(dev);
uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
void *ram;
0xff, size + (size >> 5));
} else {
if (blk_is_read_only(s->blk)) {
- error_report("Can't use a read-only drive");
- return -1;
+ error_setg(errp, "Can't use a read-only drive");
+ return;
}
blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
BLK_PERM_ALL, &local_err);
if (local_err) {
- error_report_err(local_err);
- return -1;
+ error_propagate(errp, local_err);
+ return;
}
s->blk_cur = s->blk;
}
| ((s->id.dev & 0xff) << 8)
| (s->id.ver & 0xff),
&vmstate_onenand, s);
- return 0;
}
static Property onenand_properties[] = {
static void onenand_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = onenand_initfn;
+ dc->realize = onenand_realize;
dc->reset = onenand_system_reset;
dc->props = onenand_properties;
}
trace_virtio_blk_rw_complete(vdev, req, ret);
if (req->qiov.nalloc != -1) {
- /* If nalloc is != 1 req->qiov is a local copy of the original
+ /* If nalloc is != -1 req->qiov is a local copy of the original
* external iovec. It was allocated in submit_requests to be
* able to merge requests. */
qemu_iovec_destroy(&req->qiov);
{
uint32_t type;
struct iovec *in_iov = req->elem.in_sg;
- struct iovec *iov = req->elem.out_sg;
+ struct iovec *out_iov = req->elem.out_sg;
unsigned in_num = req->elem.in_num;
unsigned out_num = req->elem.out_num;
VirtIOBlock *s = req->dev;
return -1;
}
- if (unlikely(iov_to_buf(iov, out_num, 0, &req->out,
+ if (unlikely(iov_to_buf(out_iov, out_num, 0, &req->out,
sizeof(req->out)) != sizeof(req->out))) {
virtio_error(vdev, "virtio-blk request outhdr too short");
return -1;
}
- iov_discard_front(&iov, &out_num, sizeof(req->out));
+ iov_discard_front(&out_iov, &out_num, sizeof(req->out));
if (in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) {
virtio_error(vdev, "virtio-blk request inhdr too short");
&req->out.sector);
if (is_write) {
- qemu_iovec_init_external(&req->qiov, iov, out_num);
+ qemu_iovec_init_external(&req->qiov, out_iov, out_num);
trace_virtio_blk_handle_write(vdev, req, req->sector_num,
req->qiov.size / BDRV_SECTOR_SIZE);
} else {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int grlib_apbuart_init(SysBusDevice *dev)
+static void grlib_apbuart_realize(DeviceState *dev, Error **errp)
{
UART *uart = GRLIB_APB_UART(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
qemu_chr_fe_set_handlers(&uart->chr,
grlib_apbuart_can_receive,
grlib_apbuart_event,
NULL, uart, NULL, true);
- sysbus_init_irq(dev, &uart->irq);
+ sysbus_init_irq(sbd, &uart->irq);
memory_region_init_io(&uart->iomem, OBJECT(uart), &grlib_apbuart_ops, uart,
"uart", UART_REG_SIZE);
- sysbus_init_mmio(dev, &uart->iomem);
-
- return 0;
+ sysbus_init_mmio(sbd, &uart->iomem);
}
static void grlib_apbuart_reset(DeviceState *d)
static void grlib_apbuart_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = grlib_apbuart_init;
+ dc->realize = grlib_apbuart_realize;
dc->reset = grlib_apbuart_reset;
dc->props = grlib_apbuart_properties;
}
}
}
-static int empty_slot_init1(SysBusDevice *dev)
+static void empty_slot_realize(DeviceState *dev, Error **errp)
{
EmptySlot *s = EMPTY_SLOT(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &empty_slot_ops, s,
"empty-slot", s->size);
- sysbus_init_mmio(dev, &s->iomem);
- return 0;
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
}
static void empty_slot_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = empty_slot_init1;
+ dc->realize = empty_slot_realize;
}
static const TypeInfo empty_slot_info = {
}
for (i = 0; i < queues; i++) {
- if (peers[i] == NULL) {
- err = -ENOENT;
- goto out;
- }
if (peers[i]->peer) {
err = -EEXIST;
}
}
-/* TODO remove once all sysbus devices have been converted to realize */
+/* The purpose of preserving this empty realize function
+ * is to prevent the parent_realize field of some subclasses
+ * from being set to NULL to break the normal init/realize
+ * of some devices.
+ */
static void sysbus_realize(DeviceState *dev, Error **errp)
{
- SysBusDevice *sd = SYS_BUS_DEVICE(dev);
- SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd);
-
- if (!sbc->init) {
- return;
- }
- if (sbc->init(sd) < 0) {
- error_setg(errp, "Device initialization failed");
- }
}
DeviceState *sysbus_create_varargs(const char *name,
G364State g364;
} G364SysBusState;
-static int g364fb_sysbus_init(SysBusDevice *sbd)
+static void g364fb_sysbus_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
G364SysBusState *sbs = G364(dev);
G364State *s = &sbs->g364;
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
g364fb_init(dev, s);
sysbus_init_irq(sbd, &s->irq);
sysbus_init_mmio(sbd, &s->mem_ctrl);
sysbus_init_mmio(sbd, &s->mem_vram);
-
- return 0;
}
static void g364fb_sysbus_reset(DeviceState *d)
static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = g364fb_sysbus_init;
+ dc->realize = g364fb_sysbus_realize;
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->desc = "G364 framebuffer";
dc->reset = g364fb_sysbus_reset;
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int puv3_dma_init(SysBusDevice *dev)
+static void puv3_dma_realize(DeviceState *dev, Error **errp)
{
PUV3DMAState *s = PUV3_DMA(dev);
int i;
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_dma_ops, s, "puv3_dma",
PUV3_REGS_OFFSET);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
}
static void puv3_dma_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- sdc->init = puv3_dma_init;
+ dc->realize = puv3_dma_realize;
}
static const TypeInfo puv3_dma_info = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int puv3_gpio_init(SysBusDevice *dev)
+static void puv3_gpio_realize(DeviceState *dev, Error **errp)
{
PUV3GPIOState *s = PUV3_GPIO(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
s->reg_GPLR = 0;
s->reg_GPDR = 0;
/* FIXME: these irqs not handled yet */
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW0]);
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW1]);
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW2]);
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW3]);
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW4]);
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW5]);
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW6]);
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW7]);
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOHIGH]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW0]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW1]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW2]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW3]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW4]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW5]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW6]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW7]);
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOHIGH]);
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_gpio_ops, s, "puv3_gpio",
PUV3_REGS_OFFSET);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
+ sysbus_init_mmio(sbd, &s->iomem);
}
static void puv3_gpio_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- sdc->init = puv3_gpio_init;
+ dc->realize = puv3_gpio_realize;
}
static const TypeInfo puv3_gpio_info = {
#include "hw/i2c/i2c.h"
-typedef struct bitbang_i2c_interface bitbang_i2c_interface;
-
#define BITBANG_I2C_SDA 0
#define BITBANG_I2C_SCL 1
s->regs[R_CTRL] = CTRL_RESET;
}
-static int milkymist_softusb_init(SysBusDevice *dev)
+static void milkymist_softusb_realize(DeviceState *dev, Error **errp)
{
MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
- sysbus_init_irq(dev, &s->irq);
+ sysbus_init_irq(sbd, &s->irq);
memory_region_init_io(&s->regs_region, OBJECT(s), &softusb_mmio_ops, s,
"milkymist-softusb", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
+ sysbus_init_mmio(sbd, &s->regs_region);
/* register pmem and dmem */
memory_region_init_ram_nomigrate(&s->pmem, OBJECT(s), "milkymist-softusb.pmem",
s->pmem_size, &error_fatal);
vmstate_register_ram_global(&s->pmem);
s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem);
- sysbus_init_mmio(dev, &s->pmem);
+ sysbus_init_mmio(sbd, &s->pmem);
memory_region_init_ram_nomigrate(&s->dmem, OBJECT(s), "milkymist-softusb.dmem",
s->dmem_size, &error_fatal);
vmstate_register_ram_global(&s->dmem);
s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem);
- sysbus_init_mmio(dev, &s->dmem);
+ sysbus_init_mmio(sbd, &s->dmem);
hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
-
- return 0;
}
static const VMStateDescription vmstate_milkymist_softusb = {
static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = milkymist_softusb_init;
+ dc->realize = milkymist_softusb_realize;
dc->reset = milkymist_softusb_reset;
dc->vmsd = &vmstate_milkymist_softusb;
dc->props = milkymist_softusb_properties;
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int pl050_initfn(SysBusDevice *dev)
+static void pl050_realize(DeviceState *dev, Error **errp)
{
PL050State *s = PL050(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &pl050_ops, s, "pl050", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
- sysbus_init_irq(dev, &s->irq);
+ sysbus_init_mmio(sbd, &s->iomem);
+ sysbus_init_irq(sbd, &s->irq);
if (s->is_mouse) {
s->dev = ps2_mouse_init(pl050_update, s);
} else {
s->dev = ps2_kbd_init(pl050_update, s);
}
- return 0;
}
static void pl050_keyboard_init(Object *obj)
static void pl050_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(oc);
- sdc->init = pl050_initfn;
+ dc->realize = pl050_realize;
dc->vmsd = &vmstate_pl050;
}
* * access if NS EL1 and either IMO or FMO == 1:
* CTLR, DIR, PMR, RPR
*/
- bool flagmatch = ((hcr_flags & HCR_IMO) && arm_hcr_el2_imo(env)) ||
- ((hcr_flags & HCR_FMO) && arm_hcr_el2_fmo(env));
+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
+ bool flagmatch = hcr_el2 & hcr_flags & (HCR_IMO | HCR_FMO);
return flagmatch && arm_current_el(env) == 1
&& !arm_is_secure_below_el3(env);
/* No need to include !IsSecure in route_*_to_el2 as it's only
* tested in cases where we know !IsSecure is true.
*/
- route_fiq_to_el2 = arm_hcr_el2_fmo(env);
- route_irq_to_el2 = arm_hcr_el2_imo(env);
+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
+ route_fiq_to_el2 = hcr_el2 & HCR_FMO;
+ route_irq_to_el2 = hcr_el2 & HCR_IMO;
switch (arm_current_el(env)) {
case 3:
if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) {
switch (el) {
case 1:
- if (arm_is_secure_below_el3(env) ||
- (arm_hcr_el2_imo(env) == 0 && arm_hcr_el2_fmo(env) == 0)) {
+ /* Note that arm_hcr_el2_eff takes secure state into account. */
+ if ((arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) == 0) {
r = CP_ACCESS_TRAP_EL3;
}
break;
static CPAccessResult gicv3_sgi_access(CPUARMState *env,
const ARMCPRegInfo *ri, bool isread)
{
- if ((arm_hcr_el2_imo(env) || arm_hcr_el2_fmo(env)) &&
- arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) {
+ if (arm_current_el(env) == 1 &&
+ (arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) != 0) {
/* Takes priority over a possible EL3 trap */
return CP_ACCESS_TRAP_EL2;
}
if (env->cp15.scr_el3 & SCR_FIQ) {
switch (el) {
case 1:
- if (arm_is_secure_below_el3(env) || !arm_hcr_el2_fmo(env)) {
+ if ((arm_hcr_el2_eff(env) & HCR_FMO) == 0) {
r = CP_ACCESS_TRAP_EL3;
}
break;
if (env->cp15.scr_el3 & SCR_IRQ) {
switch (el) {
case 1:
- if (arm_is_secure_below_el3(env) || !arm_hcr_el2_imo(env)) {
+ if ((arm_hcr_el2_eff(env) & HCR_IMO) == 0) {
r = CP_ACCESS_TRAP_EL3;
}
break;
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int puv3_intc_init(SysBusDevice *sbd)
+static void puv3_intc_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
PUV3INTCState *s = PUV3_INTC(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
qdev_init_gpio_in(dev, puv3_intc_handler, PUV3_IRQS_NR);
sysbus_init_irq(sbd, &s->parent_irq);
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_intc_ops, s, "puv3_intc",
PUV3_REGS_OFFSET);
sysbus_init_mmio(sbd, &s->iomem);
-
- return 0;
}
static void puv3_intc_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-
- sdc->init = puv3_intc_init;
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->realize = puv3_intc_realize;
}
static const TypeInfo puv3_intc_info = {
| IODELAY_PLL2_LOCKED;
}
-static int milkymist_hpdmc_init(SysBusDevice *dev)
+static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp)
{
MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev);
memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s,
"milkymist-hpdmc", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-
- return 0;
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region);
}
static const VMStateDescription vmstate_milkymist_hpdmc = {
static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = milkymist_hpdmc_init;
+ dc->realize = milkymist_hpdmc_realize;
dc->reset = milkymist_hpdmc_reset;
dc->vmsd = &vmstate_milkymist_hpdmc;
}
}
}
-static int milkymist_pfpu_init(SysBusDevice *dev)
+static void milkymist_pfpu_realize(DeviceState *dev, Error **errp)
{
MilkymistPFPUState *s = MILKYMIST_PFPU(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
- sysbus_init_irq(dev, &s->irq);
+ sysbus_init_irq(sbd, &s->irq);
memory_region_init_io(&s->regs_region, OBJECT(dev), &pfpu_mmio_ops, s,
"milkymist-pfpu", MICROCODE_END * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-
- return 0;
+ sysbus_init_mmio(sbd, &s->regs_region);
}
static const VMStateDescription vmstate_milkymist_pfpu = {
static void milkymist_pfpu_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = milkymist_pfpu_init;
+ dc->realize = milkymist_pfpu_realize;
dc->reset = milkymist_pfpu_reset;
dc->vmsd = &vmstate_milkymist_pfpu;
}
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int puv3_pm_init(SysBusDevice *dev)
+static void puv3_pm_realize(DeviceState *dev, Error **errp)
{
PUV3PMState *s = PUV3_PM(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_pm_ops, s, "puv3_pm",
PUV3_REGS_OFFSET);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
}
static void puv3_pm_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- sdc->init = puv3_pm_init;
+ dc->realize = puv3_pm_realize;
}
static const TypeInfo puv3_pm_info = {
return;
}
if (temp >= 128000 || temp < -128000) {
- error_setg(errp, "value %" PRId64 ".%03" PRIu64 " °C is out of range",
+ error_setg(errp, "value %" PRId64 ".%03" PRIu64 " C is out of range",
temp / 1000, temp % 1000);
return;
}
}
if (temp >= maxs[ext_range] || temp < mins[ext_range]) {
- error_setg(errp, "value %" PRId64 ".%03" PRIu64 " °C is out of range",
+ error_setg(errp, "value %" PRId64 ".%03" PRIu64 " C is out of range",
temp / 1000, temp % 1000);
return;
}
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "trace.h"
+#include "qemu/error-report.h"
typedef struct {
MemoryRegion iomem;
NvRamState nvram;
} SysBusNvRamState;
-static int nvram_sysbus_initfn(SysBusDevice *dev)
+static void nvram_sysbus_realize(DeviceState *dev, Error **errp)
{
SysBusNvRamState *sys = DS1225Y(dev);
NvRamState *s = &sys->nvram;
memory_region_init_io(&s->iomem, OBJECT(s), &nvram_ops, s,
"nvram", s->chip_size);
- sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
/* Read current file */
file = s->filename ? fopen(s->filename, "rb") : NULL;
if (file) {
/* Read nvram contents */
if (fread(s->contents, s->chip_size, 1, file) != 1) {
- printf("nvram_sysbus_initfn: short read\n");
+ error_report("nvram_sysbus_realize: short read");
}
fclose(file);
}
nvram_post_load(s, 0);
-
- return 0;
}
static Property nvram_sysbus_properties[] = {
static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = nvram_sysbus_initfn;
+ dc->realize = nvram_sysbus_realize;
dc->vmsd = &vmstate_nvram;
dc->props = nvram_sysbus_properties;
}
return pci_bridge_get_sec_bus(br);
}
-static int pci_dec_21154_device_init(SysBusDevice *dev)
+static void pci_dec_21154_device_realize(DeviceState *dev, Error **errp)
{
PCIHostState *phb;
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
phb = PCI_HOST_BRIDGE(dev);
dev, "pci-conf-idx", 0x1000);
memory_region_init_io(&phb->data_mem, OBJECT(dev), &pci_host_data_le_ops,
dev, "pci-data-idx", 0x1000);
- sysbus_init_mmio(dev, &phb->conf_mem);
- sysbus_init_mmio(dev, &phb->data_mem);
- return 0;
+ sysbus_init_mmio(sbd, &phb->conf_mem);
+ sysbus_init_mmio(sbd, &phb->data_mem);
}
static void dec_21154_pci_host_realize(PCIDevice *d, Error **errp)
static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- sdc->init = pci_dec_21154_device_init;
+ dc->realize = pci_dec_21154_device_realize;
}
static const TypeInfo pci_dec_21154_device_info = {
pos = pci_find_capability(pbdev->pdev, PCI_CAP_ID_MSIX);
if (!pos) {
- pbdev->msix.available = false;
return -1;
}
pbdev->msix.pba_bar = pba & PCI_MSIX_FLAGS_BIRMASK;
pbdev->msix.pba_offset = pba & ~PCI_MSIX_FLAGS_BIRMASK;
pbdev->msix.entries = (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1;
- pbdev->msix.available = true;
name = g_strdup_printf("msix-s390-%04x", pbdev->uid);
memory_region_init_io(&pbdev->msix_notify_mr, OBJECT(pbdev),
} QEMU_PACKED ChscSeiNt2Res;
typedef struct S390MsixInfo {
- bool available;
uint8_t table_bar;
uint8_t pba_bar;
uint16_t entries;
} \
type_init(ccw_machine_register_##suffix)
+#define CCW_COMPAT_3_1 \
+ HW_COMPAT_3_1
+
#define CCW_COMPAT_3_0 \
HW_COMPAT_3_0
.value = "0",\
},
+static void ccw_machine_4_0_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_machine_4_0_class_options(MachineClass *mc)
+{
+}
+DEFINE_CCW_MACHINE(4_0, "4.0", true);
+
static void ccw_machine_3_1_instance_options(MachineState *machine)
{
+ ccw_machine_4_0_instance_options(machine);
}
static void ccw_machine_3_1_class_options(MachineClass *mc)
{
+ ccw_machine_4_0_class_options(mc);
+ SET_MACHINE_COMPAT(mc, CCW_COMPAT_3_1);
}
-DEFINE_CCW_MACHINE(3_1, "3.1", true);
+DEFINE_CCW_MACHINE(3_1, "3.1", false);
static void ccw_machine_3_0_instance_options(MachineState *machine)
{
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "sysemu/sysemu.h"
#include "hw/s390x/tod.h"
#include "kvm_s390x.h"
-static void kvm_s390_tod_get(const S390TODState *td, S390TOD *tod, Error **errp)
+static void kvm_s390_get_tod_raw(S390TOD *tod, Error **errp)
{
int r;
}
}
-static void kvm_s390_tod_set(S390TODState *td, const S390TOD *tod, Error **errp)
+static void kvm_s390_tod_get(const S390TODState *td, S390TOD *tod, Error **errp)
+{
+ if (td->stopped) {
+ *tod = td->base;
+ return;
+ }
+
+ kvm_s390_get_tod_raw(tod, errp);
+}
+
+static void kvm_s390_set_tod_raw(const S390TOD *tod, Error **errp)
{
int r;
}
}
+static void kvm_s390_tod_set(S390TODState *td, const S390TOD *tod, Error **errp)
+{
+ Error *local_err = NULL;
+
+ /*
+ * Somebody (e.g. migration) set the TOD. We'll store it into KVM to
+ * properly detect errors now but take a look at the runstate to decide
+ * whether really to keep the tod running. E.g. during migration, this
+ * is the point where we want to stop the initially running TOD to fire
+ * it back up when actually starting the migrated guest.
+ */
+ kvm_s390_set_tod_raw(tod, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ if (runstate_is_running()) {
+ td->stopped = false;
+ } else {
+ td->stopped = true;
+ td->base = *tod;
+ }
+}
+
+static void kvm_s390_tod_vm_state_change(void *opaque, int running,
+ RunState state)
+{
+ S390TODState *td = opaque;
+ Error *local_err = NULL;
+
+ if (running && td->stopped) {
+ /* Set the old TOD when running the VM - start the TOD clock. */
+ kvm_s390_set_tod_raw(&td->base, &local_err);
+ if (local_err) {
+ warn_report_err(local_err);
+ }
+ /* Treat errors like the TOD was running all the time. */
+ td->stopped = false;
+ } else if (!running && !td->stopped) {
+ /* Store the TOD when stopping the VM - stop the TOD clock. */
+ kvm_s390_get_tod_raw(&td->base, &local_err);
+ if (local_err) {
+ /* Keep the TOD running in case we could not back it up. */
+ warn_report_err(local_err);
+ } else {
+ td->stopped = true;
+ }
+ }
+}
+
+static void kvm_s390_tod_realize(DeviceState *dev, Error **errp)
+{
+ S390TODState *td = S390_TOD(dev);
+ S390TODClass *tdc = S390_TOD_GET_CLASS(td);
+ Error *local_err = NULL;
+
+ tdc->parent_realize(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /*
+ * We need to know when the VM gets started/stopped to start/stop the TOD.
+ * As we can never have more than one TOD instance (and that will never be
+ * removed), registering here and never unregistering is good enough.
+ */
+ qemu_add_vm_change_state_handler(kvm_s390_tod_vm_state_change, td);
+}
+
static void kvm_s390_tod_class_init(ObjectClass *oc, void *data)
{
S390TODClass *tdc = S390_TOD_CLASS(oc);
+ device_class_set_parent_realize(DEVICE_CLASS(oc), kvm_s390_tod_realize,
+ &tdc->parent_realize);
tdc->get = kvm_s390_tod_get;
tdc->set = kvm_s390_tod_set;
}
+static void kvm_s390_tod_init(Object *obj)
+{
+ S390TODState *td = S390_TOD(obj);
+
+ /*
+ * The TOD is initially running (value stored in KVM). Avoid needless
+ * loading/storing of the TOD when starting a simple VM, so let it
+ * run although the (never started) VM is stopped. For migration, we
+ * will properly set the TOD later.
+ */
+ td->stopped = false;
+}
+
static TypeInfo kvm_s390_tod_info = {
.name = TYPE_KVM_S390_TOD,
.parent = TYPE_S390_TOD,
.instance_size = sizeof(S390TODState),
+ .instance_init = kvm_s390_tod_init,
.class_init = kvm_s390_tod_class_init,
.class_size = sizeof(S390TODClass),
};
}
if (is_legacy) {
ccw_dstream_read(&sch->cds, linfo);
- be64_to_cpus(&linfo.queue);
- be32_to_cpus(&linfo.align);
- be16_to_cpus(&linfo.index);
- be16_to_cpus(&linfo.num);
+ linfo.queue = be64_to_cpu(linfo.queue);
+ linfo.align = be32_to_cpu(linfo.align);
+ linfo.index = be16_to_cpu(linfo.index);
+ linfo.num = be16_to_cpu(linfo.num);
ret = virtio_ccw_set_vqs(sch, NULL, &linfo);
} else {
ccw_dstream_read(&sch->cds, info);
- be64_to_cpus(&info.desc);
- be16_to_cpus(&info.index);
- be16_to_cpus(&info.num);
- be64_to_cpus(&info.avail);
- be64_to_cpus(&info.used);
+ info.desc = be64_to_cpu(info.desc);
+ info.index = be16_to_cpu(info.index);
+ info.num = be16_to_cpu(info.num);
+ info.avail = be64_to_cpu(info.avail);
+ info.used = be64_to_cpu(info.used);
ret = virtio_ccw_set_vqs(sch, &info, NULL);
}
sch->curr_status.scsw.count = 0;
features.features = 0;
}
ccw_dstream_rewind(&sch->cds);
- cpu_to_le32s(&features.features);
+ features.features = cpu_to_le32(features.features);
ccw_dstream_write(&sch->cds, features.features);
sch->curr_status.scsw.count = ccw.count - sizeof(features);
ret = 0;
ret = -EFAULT;
} else {
ccw_dstream_read(&sch->cds, features);
- le32_to_cpus(&features.features);
+ features.features = le32_to_cpu(features.features);
if (features.index == 0) {
virtio_set_features(vdev,
(vdev->guest_features & 0xffffffff00000000ULL) |
ret = -EFAULT;
} else {
ccw_dstream_read(&sch->cds, indicators);
- be64_to_cpus(&indicators);
+ indicators = be64_to_cpu(indicators);
dev->indicators = get_indicator(indicators, sizeof(uint64_t));
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
ret = 0;
ret = -EFAULT;
} else {
ccw_dstream_read(&sch->cds, indicators);
- be64_to_cpus(&indicators);
+ indicators = be64_to_cpu(indicators);
dev->indicators2 = get_indicator(indicators, sizeof(uint64_t));
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
ret = 0;
ret = -EFAULT;
} else {
ccw_dstream_read(&sch->cds, vq_config.index);
- be16_to_cpus(&vq_config.index);
+ vq_config.index = be16_to_cpu(vq_config.index);
if (vq_config.index >= VIRTIO_QUEUE_MAX) {
ret = -EINVAL;
break;
}
vq_config.num_max = virtio_queue_get_num(vdev,
vq_config.index);
- cpu_to_be16s(&vq_config.num_max);
+ vq_config.num_max = cpu_to_be16(vq_config.num_max);
ccw_dstream_write(&sch->cds, vq_config.num_max);
sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
ret = 0;
if (ccw_dstream_read(&sch->cds, thinint)) {
ret = -EFAULT;
} else {
- be64_to_cpus(&thinint.ind_bit);
- be64_to_cpus(&thinint.summary_indicator);
- be64_to_cpus(&thinint.device_indicator);
+ thinint.ind_bit = be64_to_cpu(thinint.ind_bit);
+ thinint.summary_indicator =
+ be64_to_cpu(thinint.summary_indicator);
+ thinint.device_indicator =
+ be64_to_cpu(thinint.device_indicator);
dev->summary_indicator =
get_indicator(thinint.summary_indicator, sizeof(uint8_t));
break;
}
ccw_dstream_read_buf(&sch->cds, &revinfo, 4);
- be16_to_cpus(&revinfo.revision);
- be16_to_cpus(&revinfo.length);
+ revinfo.revision = be16_to_cpu(revinfo.revision);
+ revinfo.length = be16_to_cpu(revinfo.length);
if (ccw.count < len + revinfo.length ||
(check_len && ccw.count > len + revinfo.length)) {
ret = -EINVAL;
qemu_irq_lower(t->irq);
}
-static int etraxfs_timer_init(SysBusDevice *dev)
+static void etraxfs_timer_realize(DeviceState *dev, Error **errp)
{
ETRAXTimerState *t = ETRAX_TIMER(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
t->bh_t0 = qemu_bh_new(timer0_hit, t);
t->bh_t1 = qemu_bh_new(timer1_hit, t);
t->ptimer_t1 = ptimer_init(t->bh_t1, PTIMER_POLICY_DEFAULT);
t->ptimer_wd = ptimer_init(t->bh_wd, PTIMER_POLICY_DEFAULT);
- sysbus_init_irq(dev, &t->irq);
- sysbus_init_irq(dev, &t->nmi);
+ sysbus_init_irq(sbd, &t->irq);
+ sysbus_init_irq(sbd, &t->nmi);
memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t,
"etraxfs-timer", 0x5c);
- sysbus_init_mmio(dev, &t->mmio);
+ sysbus_init_mmio(sbd, &t->mmio);
qemu_register_reset(etraxfs_timer_reset, t);
- return 0;
}
static void etraxfs_timer_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- sdc->init = etraxfs_timer_init;
+ dc->realize = etraxfs_timer_realize;
}
static const TypeInfo etraxfs_timer_info = {
}
}
-static int grlib_gptimer_init(SysBusDevice *dev)
+static void grlib_gptimer_realize(DeviceState *dev, Error **errp)
{
GPTimerUnit *unit = GRLIB_GPTIMER(dev);
unsigned int i;
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
assert(unit->nr_timers > 0);
assert(unit->nr_timers <= GPTIMER_MAX_TIMERS);
timer->id = i;
/* One IRQ line for each timer */
- sysbus_init_irq(dev, &timer->irq);
+ sysbus_init_irq(sbd, &timer->irq);
ptimer_set_freq(timer->ptimer, unit->freq_hz);
}
unit, "gptimer",
UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers);
- sysbus_init_mmio(dev, &unit->iomem);
- return 0;
+ sysbus_init_mmio(sbd, &unit->iomem);
}
static Property grlib_gptimer_properties[] = {
static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = grlib_gptimer_init;
+ dc->realize = grlib_gptimer_realize;
dc->reset = grlib_gptimer_reset;
dc->props = grlib_gptimer_properties;
}
}
}
-static int puv3_ost_init(SysBusDevice *dev)
+static void puv3_ost_realize(DeviceState *dev, Error **errp)
{
PUV3OSTState *s = PUV3_OST(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
s->reg_OIER = 0;
s->reg_OSSR = 0;
s->reg_OSMR0 = 0;
s->reg_OSCR = 0;
- sysbus_init_irq(dev, &s->irq);
+ sysbus_init_irq(sbd, &s->irq);
s->bh = qemu_bh_new(puv3_ost_tick, s);
s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT);
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_ost_ops, s, "puv3_ost",
PUV3_REGS_OFFSET);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
+ sysbus_init_mmio(sbd, &s->iomem);
}
static void puv3_ost_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- sdc->init = puv3_ost_init;
+ dc->realize = puv3_ost_realize;
}
static const TypeInfo puv3_ost_info = {
}
/* abort -- this function switches the locality */
-static void tpm_tis_abort(TPMState *s, uint8_t locty)
+static void tpm_tis_abort(TPMState *s)
{
s->rw_offset = 0;
{
uint8_t busy_locty;
- s->aborting_locty = 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 */
/*
}
}
- tpm_tis_abort(s, locty);
+ tpm_tis_abort(s);
}
/*
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;
}
if (TPM_TIS_IS_VALID_LOCTY(s->next_locty)) {
- tpm_tis_abort(s, locty);
+ tpm_tis_abort(s);
}
tpm_tis_raise_irq(s, locty,
musb_reset(s->musb);
}
-static int tusb6010_init(SysBusDevice *sbd)
+static void tusb6010_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
TUSBState *s = TUSB(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
s->otg_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_otg_tick, s);
s->pwr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_power_tick, s);
sysbus_init_irq(sbd, &s->irq);
qdev_init_gpio_in(dev, tusb6010_irq, musb_irq_max + 1);
s->musb = musb_init(dev, 1);
- return 0;
}
static void tusb6010_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = tusb6010_init;
+ dc->realize = tusb6010_realize;
dc->reset = tusb6010_reset;
}
vapdev->vdev.name = g_strdup_printf("%s", mdevid);
vapdev->vdev.dev = dev;
+ /*
+ * vfio-ap devices operate in a way compatible with
+ * memory ballooning, as no pages are pinned in the host.
+ * This needs to be set before vfio_get_device() for vfio common to
+ * handle the balloon inhibitor.
+ */
+ vapdev->vdev.balloon_allowed = true;
+
ret = vfio_get_device(vfio_group, mdevid, &vapdev->vdev, &local_err);
if (ret) {
goto out_get_dev_err;
}
static void virtqueue_map_iovec(VirtIODevice *vdev, struct iovec *sg,
- hwaddr *addr, unsigned int *num_sg,
+ hwaddr *addr, unsigned int num_sg,
int is_write)
{
unsigned int i;
hwaddr len;
- for (i = 0; i < *num_sg; i++) {
+ for (i = 0; i < num_sg; i++) {
len = sg[i].iov_len;
sg[i].iov_base = dma_memory_map(vdev->dma_as,
addr[i], &len, is_write ?
void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem)
{
- virtqueue_map_iovec(vdev, elem->in_sg, elem->in_addr, &elem->in_num, 1);
- virtqueue_map_iovec(vdev, elem->out_sg, elem->out_addr, &elem->out_num, 0);
+ virtqueue_map_iovec(vdev, elem->in_sg, elem->in_addr, elem->in_num, 1);
+ virtqueue_map_iovec(vdev, elem->out_sg, elem->out_addr, elem->out_num, 0);
}
static void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num)
}
};
-static int xen_sysdev_init(SysBusDevice *dev)
-{
- return 0;
-}
-
static Property xen_sysdev_properties[] = {
{/* end of property list */},
};
static void xen_sysdev_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = xen_sysdev_init;
dc->props = xen_sysdev_properties;
dc->bus_type = TYPE_XENSYSBUS;
}
QEMU_CHAR_FEATURE_FD_PASS,
/* Whether replay or record mode is enabled */
QEMU_CHAR_FEATURE_REPLAY,
+ /* Whether the gcontext can be changed after calling
+ * qemu_chr_be_update_read_handlers() */
+ QEMU_CHAR_FEATURE_GCONTEXT,
QEMU_CHAR_FEATURE_LAST,
} ChardevFeature;
* @readfunc: callback for reading data from the volume
* @opaque: data to pass to @readfunc
* @flags: bitmask of QCryptoBlockOpenFlags values
+ * @n_threads: allow concurrent I/O from up to @n_threads threads
* @errp: pointer to a NULL-initialized error object
*
* Create a new block encryption object for an existing
QCryptoBlockReadFunc readfunc,
void *opaque,
unsigned int flags,
+ size_t n_threads,
Error **errp);
/**
#define XLNX_VERSAL_NR_ACPUS 2
#define XLNX_VERSAL_NR_UARTS 2
#define XLNX_VERSAL_NR_GEMS 2
-#define XLNX_VERSAL_NR_IRQS 256
+#define XLNX_VERSAL_NR_IRQS 192
typedef struct Versal {
/*< private >*/
#define VERSAL_GEM1_IRQ_0 58
#define VERSAL_GEM1_WAKE_IRQ_0 59
-/* Architecturally eserved IRQs suitable for virtualization. */
-#define VERSAL_RSVD_HIGH_IRQ_FIRST 160
-#define VERSAL_RSVD_HIGH_IRQ_LAST 255
+/* Architecturally reserved IRQs suitable for virtualization. */
+#define VERSAL_RSVD_IRQ_FIRST 111
+#define VERSAL_RSVD_IRQ_LAST 118
#define MM_TOP_RSVD 0xa0000000U
#define MM_TOP_RSVD_SIZE 0x4000000
DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr);
+typedef struct bitbang_i2c_interface bitbang_i2c_interface;
+
/* lm832x.c */
void lm832x_key_event(DeviceState *dev, int key, int state);
#include "hw/sysbus.h"
#include "hw/i2c/i2c.h"
-/* from hw/i2c/bitbang_i2c.h */
-typedef struct bitbang_i2c_interface bitbang_i2c_interface;
-
#define TYPE_PPC4xx_I2C "ppc4xx-i2c"
#define PPC4xx_I2C(obj) OBJECT_CHECK(PPC4xxI2CState, (obj), TYPE_PPC4xx_I2C)
/**
* BusState:
- * @hotplug_device: link to a hotplug device associated with bus.
+ * @hotplug_handler: link to a hotplug handler associated with bus.
*/
struct BusState {
Object obj;
/* private */
DeviceState parent_obj;
- /* unused by KVM implementation */
+ /*
+ * Used by TCG to remember the time base. Used by KVM to backup the TOD
+ * while the TOD is stopped.
+ */
S390TOD base;
+ /* Used by KVM to remember if the TOD is stopped and base is valid. */
+ bool stopped;
} S390TODState;
typedef struct S390TODClass {
/* private */
DeviceClass parent_class;
+ void (*parent_realize)(DeviceState *dev, Error **errp);
/* public */
void (*get)(const S390TODState *td, S390TOD *tod, Error **errp);
typedef struct SysBusDeviceClass {
/*< private >*/
DeviceClass parent_class;
- /*< public >*/
-
- int (*init)(SysBusDevice *dev);
/*
* Let the sysbus device format its own non-PIO, non-MMIO unit address.
#define MONITOR_USE_READLINE 0x02
#define MONITOR_USE_CONTROL 0x04
#define MONITOR_USE_PRETTY 0x08
-#define MONITOR_USE_OOB 0x10
+
+#define QMP_REQ_QUEUE_LEN_MAX 8
bool monitor_cur_is_qmp(void);
#define QEMU_SENTINEL __attribute__((sentinel))
-#if QEMU_GNUC_PREREQ(4, 3)
-#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial))
-#else
-#define QEMU_ARTIFICIAL
-#endif
-
#if defined(_WIN32)
# define QEMU_PACKED __attribute__((gcc_struct, packed))
#else
#define __has_builtin(x) 0 /* compatibility with non-clang compilers */
#endif
-#if __has_builtin(__builtin_assume_aligned) || QEMU_GNUC_PREREQ(4, 7)
+#if __has_builtin(__builtin_assume_aligned) || !defined(__clang__)
#define HAS_ASSUME_ALIGNED
#endif
*/
static inline int clrsb32(uint32_t val)
{
-#if QEMU_GNUC_PREREQ(4, 7)
+#if __has_builtin(__builtin_clrsb) || !defined(__clang__)
return __builtin_clrsb(val);
#else
return clz32(val ^ ((int32_t)val >> 1)) - 1;
*/
static inline int clrsb64(uint64_t val)
{
-#if QEMU_GNUC_PREREQ(4, 7)
+#if __has_builtin(__builtin_clrsbll) || !defined(__clang__)
return __builtin_clrsbll(val);
#else
return clz64(val ^ ((int64_t)val >> 1)) - 1;
/* QMP checker flags */
#define QMP_ACCEPT_UNKNOWNS 1
-/* Protects mon_list, monitor_qapi_event_state. */
+/* Protects mon_list, monitor_qapi_event_state, monitor_destroyed. */
static QemuMutex monitor_lock;
static GHashTable *monitor_qapi_event_state;
static QTAILQ_HEAD(mon_list, Monitor) mon_list;
+static bool monitor_destroyed;
/* Protects mon_fdsets */
static QemuMutex mon_fdsets_lock;
* processing commands only on a very busy monitor. To achieve that,
* when we process one request on a specific monitor, we put that
* monitor to the end of mon_list queue.
+ *
+ * Note: if the function returned with non-NULL, then the caller will
+ * be with mon->qmp.qmp_queue_lock held, and the caller is responsible
+ * to release it.
*/
-static QMPRequest *monitor_qmp_requests_pop_any(void)
+static QMPRequest *monitor_qmp_requests_pop_any_with_lock(void)
{
QMPRequest *req_obj = NULL;
Monitor *mon;
QTAILQ_FOREACH(mon, &mon_list, entry) {
qemu_mutex_lock(&mon->qmp.qmp_queue_lock);
req_obj = g_queue_pop_head(mon->qmp.qmp_requests);
- qemu_mutex_unlock(&mon->qmp.qmp_queue_lock);
if (req_obj) {
+ /* With the lock of corresponding queue held */
break;
}
+ qemu_mutex_unlock(&mon->qmp.qmp_queue_lock);
}
if (req_obj) {
static void monitor_qmp_bh_dispatcher(void *data)
{
- QMPRequest *req_obj = monitor_qmp_requests_pop_any();
+ QMPRequest *req_obj = monitor_qmp_requests_pop_any_with_lock();
QDict *rsp;
bool need_resume;
+ Monitor *mon;
if (!req_obj) {
return;
}
+ mon = req_obj->mon;
/* qmp_oob_enabled() might change after "qmp_capabilities" */
- need_resume = !qmp_oob_enabled(req_obj->mon);
+ need_resume = !qmp_oob_enabled(mon) ||
+ mon->qmp.qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1;
+ qemu_mutex_unlock(&mon->qmp.qmp_queue_lock);
if (req_obj->req) {
trace_monitor_qmp_cmd_in_band(qobject_get_try_str(req_obj->id) ?: "");
- monitor_qmp_dispatch(req_obj->mon, req_obj->req, req_obj->id);
+ monitor_qmp_dispatch(mon, req_obj->req, req_obj->id);
} else {
assert(req_obj->err);
rsp = qmp_error_response(req_obj->err);
req_obj->err = NULL;
- monitor_qmp_respond(req_obj->mon, rsp, NULL);
+ monitor_qmp_respond(mon, rsp, NULL);
qobject_unref(rsp);
}
if (need_resume) {
/* Pairs with the monitor_suspend() in handle_qmp_command() */
- monitor_resume(req_obj->mon);
+ monitor_resume(mon);
}
qmp_request_free(req_obj);
qemu_bh_schedule(qmp_dispatcher_bh);
}
-#define QMP_REQ_QUEUE_LEN_MAX (8)
-
static void handle_qmp_command(void *opaque, QObject *req, Error *err)
{
Monitor *mon = opaque;
qemu_mutex_lock(&mon->qmp.qmp_queue_lock);
/*
- * If OOB is not enabled on the current monitor, we'll emulate the
- * old behavior that we won't process the current monitor any more
- * until it has responded. This helps make sure that as long as
- * OOB is not enabled, the server will never drop any command.
+ * Suspend the monitor when we can't queue more requests after
+ * this one. Dequeuing in monitor_qmp_bh_dispatcher() will resume
+ * it. Note that when OOB is disabled, we queue at most one
+ * command, for backward compatibility.
*/
- if (!qmp_oob_enabled(mon)) {
+ if (!qmp_oob_enabled(mon) ||
+ mon->qmp.qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
monitor_suspend(mon);
- } else {
- /* Drop the request if queue is full. */
- if (mon->qmp.qmp_requests->length >= QMP_REQ_QUEUE_LEN_MAX) {
- qemu_mutex_unlock(&mon->qmp.qmp_queue_lock);
- /*
- * FIXME @id's scope is just @mon, and broadcasting it is
- * wrong. If another monitor's client has a command with
- * the same ID in flight, the event will incorrectly claim
- * that command was dropped.
- */
- qapi_event_send_command_dropped(id,
- COMMAND_DROP_REASON_QUEUE_FULL);
- qmp_request_free(req_obj);
- return;
- }
}
/*
* handled in time order. Ownership for req_obj, req, id,
* etc. will be delivered to the handler side.
*/
+ assert(mon->qmp.qmp_requests->length < QMP_REQ_QUEUE_LEN_MAX);
g_queue_push_tail(mon->qmp.qmp_requests, req_obj);
qemu_mutex_unlock(&mon->qmp.qmp_queue_lock);
atomic_inc(&mon->suspend_cnt);
- if (monitor_is_qmp(mon) && mon->use_io_thread) {
+ if (mon->use_io_thread) {
/*
* Kick I/O thread to make sure this takes effect. It'll be
* evaluated again in prepare() of the watch object.
return 0;
}
+static void monitor_accept_input(void *opaque)
+{
+ Monitor *mon = opaque;
+
+ qemu_chr_fe_accept_input(&mon->chr);
+}
+
void monitor_resume(Monitor *mon)
{
if (monitor_is_hmp_non_interactive(mon)) {
}
if (atomic_dec_fetch(&mon->suspend_cnt) == 0) {
- if (monitor_is_qmp(mon)) {
- /*
- * For QMP monitors that are running in the I/O thread,
- * let's kick the thread in case it's sleeping.
- */
- if (mon->use_io_thread) {
- aio_notify(iothread_get_aio_context(mon_iothread));
- }
+ AioContext *ctx;
+
+ if (mon->use_io_thread) {
+ ctx = iothread_get_aio_context(mon_iothread);
} else {
+ ctx = qemu_get_aio_context();
+ }
+
+ if (!monitor_is_qmp(mon)) {
assert(mon->rs);
readline_show_prompt(mon->rs);
}
- qemu_chr_fe_accept_input(&mon->chr);
+
+ aio_bh_schedule_oneshot(ctx, monitor_accept_input, mon);
}
+
trace_monitor_suspend(mon, -1);
}
qsort((void *)info_cmds, array_num, elem_size, compare_mon_cmd);
}
-static GMainContext *monitor_get_io_context(void)
-{
- return iothread_get_g_main_context(mon_iothread);
-}
-
-static AioContext *monitor_get_aio_context(void)
-{
- return iothread_get_aio_context(mon_iothread);
-}
-
static void monitor_iothread_init(void)
{
mon_iothread = iothread_create("mon_iothread", &error_abort);
static void monitor_list_append(Monitor *mon)
{
qemu_mutex_lock(&monitor_lock);
- QTAILQ_INSERT_HEAD(&mon_list, mon, entry);
+ /*
+ * This prevents inserting new monitors during monitor_cleanup().
+ * A cleaner solution would involve the main thread telling other
+ * threads to terminate, waiting for their termination.
+ */
+ if (!monitor_destroyed) {
+ QTAILQ_INSERT_HEAD(&mon_list, mon, entry);
+ mon = NULL;
+ }
qemu_mutex_unlock(&monitor_lock);
+
+ if (mon) {
+ monitor_data_destroy(mon);
+ g_free(mon);
+ }
}
static void monitor_qmp_setup_handlers_bh(void *opaque)
GMainContext *context;
assert(mon->use_io_thread);
- context = monitor_get_io_context();
+ context = iothread_get_g_main_context(mon_iothread);
assert(context);
qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_qmp_read,
monitor_qmp_event, NULL, mon, context, true);
{
Monitor *mon = g_malloc(sizeof(*mon));
bool use_readline = flags & MONITOR_USE_READLINE;
- bool use_oob = flags & MONITOR_USE_OOB;
- if (use_oob) {
- if (CHARDEV_IS_MUX(chr)) {
- error_report("Monitor out-of-band is not supported with "
- "MUX typed chardev backend");
- exit(1);
- }
- if (use_readline) {
- error_report("Monitor out-of-band is only supported by QMP");
- exit(1);
- }
- }
-
- monitor_data_init(mon, false, use_oob);
+ /* Note: we run QMP monitor in I/O thread when @chr supports that */
+ monitor_data_init(mon, false,
+ (flags & MONITOR_USE_CONTROL)
+ && qemu_chr_has_feature(chr,
+ QEMU_CHAR_FEATURE_GCONTEXT));
qemu_chr_fe_init(&mon->chr, chr, &error_abort);
mon->flags = flags;
* since chardev might be running in the monitor I/O
* thread. Schedule a bottom half.
*/
- aio_bh_schedule_oneshot(monitor_get_aio_context(),
+ aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread),
monitor_qmp_setup_handlers_bh, mon);
/* The bottom half will add @mon to @mon_list */
return;
/* Flush output buffers and destroy monitors */
qemu_mutex_lock(&monitor_lock);
+ monitor_destroyed = true;
QTAILQ_FOREACH_SAFE(mon, &mon_list, entry, next) {
QTAILQ_REMOVE(&mon_list, mon, entry);
+ /* Permit QAPI event emission from character frontend release */
+ qemu_mutex_unlock(&monitor_lock);
monitor_flush(mon);
monitor_data_destroy(mon);
+ qemu_mutex_lock(&monitor_lock);
g_free(mon);
}
qemu_mutex_unlock(&monitor_lock);
},{
.name = "pretty",
.type = QEMU_OPT_BOOL,
- },{
- .name = "x-oob",
- .type = QEMU_OPT_BOOL,
},
{ /* end of list */ }
},
return 1;
}
+ if (!qemu_chr_has_feature(*chr, QEMU_CHAR_FEATURE_GCONTEXT)) {
+ error_setg(errp, "chardev \"%s\" cannot switch context",
+ chr_name);
+ return 1;
+ }
+
return 0;
}
# The options that apply to LUKS encryption format initialization
#
# @cipher-alg: the cipher algorithm for data encryption
-# Currently defaults to 'aes'.
+# Currently defaults to 'aes-256'.
# @cipher-mode: the cipher mode for data encryption
-# Currently defaults to 'cbc'
+# Currently defaults to 'xts'
# @ivgen-alg: the initialization vector generator
-# Currently defaults to 'essiv'
+# Currently defaults to 'plain64'
# @ivgen-hash-alg: the initialization vector generator hash
# Currently defaults to 'sha256'
# @hash-alg: the master key hash algorithm
##
{ 'command': 'query-sev-capabilities', 'returns': 'SevCapability' }
-##
-# @CommandDropReason:
-#
-# Reasons that caused one command to be dropped.
-#
-# @queue-full: the command queue is full. This can only occur when
-# the client sends a new non-oob command before the
-# response to the previous non-oob command has been
-# received.
-#
-# Since: 2.12
-##
-{ 'enum': 'CommandDropReason',
- 'data': [ 'queue-full' ] }
-
-##
-# @COMMAND_DROPPED:
-#
-# Emitted when a command is dropped due to some reason. Commands can
-# only be dropped when the oob capability is enabled.
-#
-# @id: The dropped command's "id" field.
-# FIXME Broken by design. Events are broadcast to all monitors. If
-# another monitor's client has a command with the same ID in flight,
-# the event will incorrectly claim that command was dropped.
-#
-# @reason: The reason why the command is dropped.
-#
-# Since: 2.12
-#
-# Example:
-#
-# { "event": "COMMAND_DROPPED",
-# "data": {"result": {"id": "libvirt-102",
-# "reason": "queue-full" } } }
-#
-##
-{ 'event': 'COMMAND_DROPPED' ,
- 'data': { 'id': 'any', 'reason': 'CommandDropReason' } }
-
##
# @set-numa-node:
#
QEMU_NORETURN|
QEMU_WARN_UNUSED_RESULT|
QEMU_SENTINEL|
- QEMU_ARTIFICIAL|
QEMU_PACKED|
GCC_FMT_ATTR
}x;
#define QEMU_NORETURN __attribute__ ((__noreturn__))
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#define QEMU_SENTINEL __attribute__((sentinel))
-#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial))
#define QEMU_PACKED __attribute__((gcc_struct, packed))
#define cat(x,y) x ## y
' struct timeval _now;',
' gettimeofday(&_now, NULL);',
' qemu_log("%%d@%%zu.%%06zu:%(name)s " %(fmt)s "\\n",',
- ' getpid(),',
+ ' qemu_get_thread_id(),',
' (size_t)_now.tv_sec, (size_t)_now.tv_usec',
' %(argnames)s);',
' }',
t = cpu->isar.id_isar6;
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
cpu->isar.id_isar6 = t;
+
+ t = cpu->id_mmfr4;
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
+ cpu->id_mmfr4 = t;
}
#endif
}
uint64_t id_aa64isar1;
uint64_t id_aa64pfr0;
uint64_t id_aa64pfr1;
+ uint64_t id_aa64mmfr0;
+ uint64_t id_aa64mmfr1;
} isar;
uint32_t midr;
uint32_t revidr;
uint64_t id_aa64dfr1;
uint64_t id_aa64afr0;
uint64_t id_aa64afr1;
- uint64_t id_aa64mmfr0;
- uint64_t id_aa64mmfr1;
uint32_t dbgdidr;
uint32_t clidr;
uint64_t mp_affinity; /* MP ID without feature bits */
#define HCR_TIDCP (1ULL << 20)
#define HCR_TACR (1ULL << 21)
#define HCR_TSW (1ULL << 22)
-#define HCR_TPC (1ULL << 23)
+#define HCR_TPCP (1ULL << 23)
#define HCR_TPU (1ULL << 24)
#define HCR_TTLB (1ULL << 25)
#define HCR_TVM (1ULL << 26)
#define HCR_CD (1ULL << 32)
#define HCR_ID (1ULL << 33)
#define HCR_E2H (1ULL << 34)
+#define HCR_TLOR (1ULL << 35)
+#define HCR_TERR (1ULL << 36)
+#define HCR_TEA (1ULL << 37)
+#define HCR_MIOCNCE (1ULL << 38)
+#define HCR_APK (1ULL << 40)
+#define HCR_API (1ULL << 41)
+#define HCR_NV (1ULL << 42)
+#define HCR_NV1 (1ULL << 43)
+#define HCR_AT (1ULL << 44)
+#define HCR_NV2 (1ULL << 45)
+#define HCR_FWB (1ULL << 46)
+#define HCR_FIEN (1ULL << 47)
+#define HCR_TID4 (1ULL << 49)
+#define HCR_TICAB (1ULL << 50)
+#define HCR_TOCU (1ULL << 52)
+#define HCR_TTLBIS (1ULL << 54)
+#define HCR_TTLBOS (1ULL << 55)
+#define HCR_ATA (1ULL << 56)
+#define HCR_DCT (1ULL << 57)
+
/*
* When we actually implement ARMv8.1-VHE we should add HCR_E2H to
* HCR_MASK and then clear it again if the feature bit is not set in
#define SCR_ST (1U << 11)
#define SCR_TWI (1U << 12)
#define SCR_TWE (1U << 13)
-#define SCR_AARCH32_MASK (0x3fff & ~(SCR_RW | SCR_ST))
-#define SCR_AARCH64_MASK (0x3fff & ~SCR_NET)
+#define SCR_TLOR (1U << 14)
+#define SCR_TERR (1U << 15)
+#define SCR_APK (1U << 16)
+#define SCR_API (1U << 17)
+#define SCR_EEL2 (1U << 18)
+#define SCR_EASE (1U << 19)
+#define SCR_NMEA (1U << 20)
+#define SCR_FIEN (1U << 21)
+#define SCR_ENSCXT (1U << 25)
+#define SCR_ATA (1U << 26)
/* Return the current FPSCR value. */
uint32_t vfp_get_fpscr(CPUARMState *env);
FIELD(ID_ISAR6, SB, 12, 4)
FIELD(ID_ISAR6, SPECRES, 16, 4)
+FIELD(ID_MMFR4, SPECSEI, 0, 4)
+FIELD(ID_MMFR4, AC2, 4, 4)
+FIELD(ID_MMFR4, XNX, 8, 4)
+FIELD(ID_MMFR4, CNP, 12, 4)
+FIELD(ID_MMFR4, HPDS, 16, 4)
+FIELD(ID_MMFR4, LSM, 20, 4)
+FIELD(ID_MMFR4, CCIDX, 24, 4)
+FIELD(ID_MMFR4, EVT, 28, 4)
+
FIELD(ID_AA64ISAR0, AES, 4, 4)
FIELD(ID_AA64ISAR0, SHA1, 8, 4)
FIELD(ID_AA64ISAR0, SHA2, 12, 4)
FIELD(ID_AA64PFR0, RAS, 28, 4)
FIELD(ID_AA64PFR0, SVE, 32, 4)
+FIELD(ID_AA64MMFR0, PARANGE, 0, 4)
+FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4)
+FIELD(ID_AA64MMFR0, BIGEND, 8, 4)
+FIELD(ID_AA64MMFR0, SNSMEM, 12, 4)
+FIELD(ID_AA64MMFR0, BIGENDEL0, 16, 4)
+FIELD(ID_AA64MMFR0, TGRAN16, 20, 4)
+FIELD(ID_AA64MMFR0, TGRAN64, 24, 4)
+FIELD(ID_AA64MMFR0, TGRAN4, 28, 4)
+FIELD(ID_AA64MMFR0, TGRAN16_2, 32, 4)
+FIELD(ID_AA64MMFR0, TGRAN64_2, 36, 4)
+FIELD(ID_AA64MMFR0, TGRAN4_2, 40, 4)
+FIELD(ID_AA64MMFR0, EXS, 44, 4)
+
+FIELD(ID_AA64MMFR1, HAFDBS, 0, 4)
+FIELD(ID_AA64MMFR1, VMIDBITS, 4, 4)
+FIELD(ID_AA64MMFR1, VH, 8, 4)
+FIELD(ID_AA64MMFR1, HPDS, 12, 4)
+FIELD(ID_AA64MMFR1, LO, 16, 4)
+FIELD(ID_AA64MMFR1, PAN, 20, 4)
+FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
+FIELD(ID_AA64MMFR1, XNX, 28, 4)
+
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
/* If adding a feature bit which corresponds to a Linux ELF
}
#endif
+/**
+ * arm_hcr_el2_eff(): Return the effective value of HCR_EL2.
+ * E.g. when in secure state, fields in HCR_EL2 are suppressed,
+ * "for all purposes other than a direct read or write access of HCR_EL2."
+ * Not included here is HCR_RW.
+ */
+uint64_t arm_hcr_el2_eff(CPUARMState *env);
+
/* Return true if the specified exception level is running in AArch64 state. */
static inline bool arm_el_is_aa64(CPUARMState *env, int el)
{
# define TARGET_VIRT_ADDR_SPACE_BITS 32
#endif
-/**
- * arm_hcr_el2_imo(): Return the effective value of HCR_EL2.IMO.
- * Depending on the values of HCR_EL2.E2H and TGE, this may be
- * "behaves as 1 for all purposes other than direct read/write" or
- * "behaves as 0 for all purposes other than direct read/write"
- */
-static inline bool arm_hcr_el2_imo(CPUARMState *env)
-{
- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
- case HCR_TGE:
- return true;
- case HCR_TGE | HCR_E2H:
- return false;
- default:
- return env->cp15.hcr_el2 & HCR_IMO;
- }
-}
-
-/**
- * arm_hcr_el2_fmo(): Return the effective value of HCR_EL2.FMO.
- */
-static inline bool arm_hcr_el2_fmo(CPUARMState *env)
-{
- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
- case HCR_TGE:
- return true;
- case HCR_TGE | HCR_E2H:
- return false;
- default:
- return env->cp15.hcr_el2 & HCR_FMO;
- }
-}
-
-/**
- * arm_hcr_el2_amo(): Return the effective value of HCR_EL2.AMO.
- */
-static inline bool arm_hcr_el2_amo(CPUARMState *env)
-{
- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
- case HCR_TGE:
- return true;
- case HCR_TGE | HCR_E2H:
- return false;
- default:
- return env->cp15.hcr_el2 & HCR_AMO;
- }
-}
-
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
unsigned int target_el)
{
bool secure = arm_is_secure(env);
bool pstate_unmasked;
int8_t unmasked = 0;
+ uint64_t hcr_el2;
/* Don't take exceptions if they target a lower EL.
* This check should catch any exceptions that would not be taken but left
return false;
}
+ hcr_el2 = arm_hcr_el2_eff(env);
+
switch (excp_idx) {
case EXCP_FIQ:
pstate_unmasked = !(env->daif & PSTATE_F);
break;
case EXCP_VFIQ:
- if (secure || !arm_hcr_el2_fmo(env) || (env->cp15.hcr_el2 & HCR_TGE)) {
+ if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
/* VFIQs are only taken when hypervized and non-secure. */
return false;
}
return !(env->daif & PSTATE_F);
case EXCP_VIRQ:
- if (secure || !arm_hcr_el2_imo(env) || (env->cp15.hcr_el2 & HCR_TGE)) {
+ if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
/* VIRQs are only taken when hypervized and non-secure. */
return false;
}
* to the CPSR.F setting otherwise we further assess the state
* below.
*/
- hcr = arm_hcr_el2_fmo(env);
+ hcr = hcr_el2 & HCR_FMO;
scr = (env->cp15.scr_el3 & SCR_FIQ);
/* When EL3 is 32-bit, the SCR.FW bit controls whether the
* when setting the target EL, so it does not have a further
* affect here.
*/
- hcr = arm_hcr_el2_imo(env);
+ hcr = hcr_el2 & HCR_IMO;
scr = false;
break;
default:
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
}
+static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
+}
+
/*
* Forward to the above feature tests given an ARMCPU pointer.
*/
cpu->pmceid0 = 0x00000000;
cpu->pmceid1 = 0x00000000;
cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->id_aa64mmfr0 = 0x00001124;
+ cpu->isar.id_aa64mmfr0 = 0x00001124;
cpu->dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
cpu->isar.id_aa64pfr0 = 0x00002222;
cpu->id_aa64dfr0 = 0x10305106;
cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
+ cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
cpu->dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
cpu->pmceid0 = 0x00000000;
cpu->pmceid1 = 0x00000000;
cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->id_aa64mmfr0 = 0x00001124;
+ cpu->isar.id_aa64mmfr0 = 0x00001124;
cpu->dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
cpu->isar.id_aa64pfr0 = t;
+ t = cpu->isar.id_aa64mmfr1;
+ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
+ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
+ cpu->isar.id_aa64mmfr1 = t;
+
/* Replicate the same data to the 32-bit id registers. */
u = cpu->isar.id_isar5;
u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
int el = arm_current_el(env);
bool mdcr_el2_tdosa = (env->cp15.mdcr_el2 & MDCR_TDOSA) ||
(env->cp15.mdcr_el2 & MDCR_TDE) ||
- (env->cp15.hcr_el2 & HCR_TGE);
+ (arm_hcr_el2_eff(env) & HCR_TGE);
if (el < 2 && mdcr_el2_tdosa && !arm_is_secure_below_el3(env)) {
return CP_ACCESS_TRAP_EL2;
int el = arm_current_el(env);
bool mdcr_el2_tdra = (env->cp15.mdcr_el2 & MDCR_TDRA) ||
(env->cp15.mdcr_el2 & MDCR_TDE) ||
- (env->cp15.hcr_el2 & HCR_TGE);
+ (arm_hcr_el2_eff(env) & HCR_TGE);
if (el < 2 && mdcr_el2_tdra && !arm_is_secure_below_el3(env)) {
return CP_ACCESS_TRAP_EL2;
int el = arm_current_el(env);
bool mdcr_el2_tda = (env->cp15.mdcr_el2 & MDCR_TDA) ||
(env->cp15.mdcr_el2 & MDCR_TDE) ||
- (env->cp15.hcr_el2 & HCR_TGE);
+ (arm_hcr_el2_eff(env) & HCR_TGE);
if (el < 2 && mdcr_el2_tda && !arm_is_secure_below_el3(env)) {
return CP_ACCESS_TRAP_EL2;
static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
- /* We only mask off bits that are RES0 both for AArch64 and AArch32.
- * For bits that vary between AArch32/64, code needs to check the
- * current execution mode before directly using the feature bit.
- */
- uint32_t valid_mask = SCR_AARCH64_MASK | SCR_AARCH32_MASK;
+ /* Begin with base v8.0 state. */
+ uint32_t valid_mask = 0x3fff;
+ ARMCPU *cpu = arm_env_get_cpu(env);
+
+ if (arm_el_is_aa64(env, 3)) {
+ value |= SCR_FW | SCR_AW; /* these two bits are RES1. */
+ valid_mask &= ~SCR_NET;
+ } else {
+ valid_mask &= ~(SCR_RW | SCR_ST);
+ }
if (!arm_feature(env, ARM_FEATURE_EL2)) {
valid_mask &= ~SCR_HCE;
valid_mask &= ~SCR_SMD;
}
}
+ if (cpu_isar_feature(aa64_lor, cpu)) {
+ valid_mask |= SCR_TLOR;
+ }
/* Clear all-context RES0 bits. */
value &= valid_mask;
static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
CPUState *cs = ENV_GET_CPU(env);
+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
uint64_t ret = 0;
- if (arm_hcr_el2_imo(env)) {
+ if (hcr_el2 & HCR_IMO) {
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
ret |= CPSR_I;
}
}
}
- if (arm_hcr_el2_fmo(env)) {
+ if (hcr_el2 & HCR_FMO) {
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
ret |= CPSR_F;
}
uint64_t value)
{
ARMCPU *cpu = arm_env_get_cpu(env);
+ TCR *tcr = raw_ptr(env, ri);
if (arm_feature(env, ARM_FEATURE_LPAE)) {
/* With LPAE the TTBCR could result in a change of ASID
*/
tlb_flush(CPU(cpu));
}
+ /* Preserve the high half of TCR_EL1, set via TTBCR2. */
+ value = deposit64(tcr->raw_tcr, 0, 32, value);
vmsa_ttbcr_raw_write(env, ri, value);
}
REGINFO_SENTINEL
};
+/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
+ * qemu tlbs nor adjusting cached masks.
+ */
+static const ARMCPRegInfo ttbcr2_reginfo = {
+ .name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
+ .access = PL1_RW, .type = ARM_CP_ALIAS,
+ .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]),
+ offsetofhigh32(CPUARMState, cp15.tcr_el[1]) },
+};
+
static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
*/
valid_mask &= ~HCR_TSC;
}
+ if (cpu_isar_feature(aa64_lor, cpu)) {
+ valid_mask |= HCR_TLOR;
+ }
/* Clear RES0 bits. */
value &= valid_mask;
hcr_write(env, NULL, value);
}
+/*
+ * Return the effective value of HCR_EL2.
+ * Bits that are not included here:
+ * RW (read from SCR_EL3.RW as needed)
+ */
+uint64_t arm_hcr_el2_eff(CPUARMState *env)
+{
+ uint64_t ret = env->cp15.hcr_el2;
+
+ if (arm_is_secure_below_el3(env)) {
+ /*
+ * "This register has no effect if EL2 is not enabled in the
+ * current Security state". This is ARMv8.4-SecEL2 speak for
+ * !(SCR_EL3.NS==1 || SCR_EL3.EEL2==1).
+ *
+ * Prior to that, the language was "In an implementation that
+ * includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves
+ * as if this field is 0 for all purposes other than a direct
+ * read or write access of HCR_EL2". With lots of enumeration
+ * on a per-field basis. In current QEMU, this is condition
+ * is arm_is_secure_below_el3.
+ *
+ * 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. */
+ 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);
+ } else {
+ ret |= HCR_FMO | HCR_IMO | HCR_AMO;
+ }
+ ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
+ HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
+ HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
+ HCR_TLOR);
+ }
+
+ return ret;
+}
+
static const ARMCPRegInfo el2_cp_reginfo[] = {
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_IO,
if (disabled) {
/* route_to_el2 */
return (arm_feature(env, ARM_FEATURE_EL2)
- && !arm_is_secure(env)
- && (env->cp15.hcr_el2 & HCR_TGE) ? 2 : 1);
+ && (arm_hcr_el2_eff(env) & HCR_TGE) ? 2 : 1);
}
/* Check CPACR.FPEN. */
return pfr0;
}
+/* Shared logic between LORID and the rest of the LOR* registers.
+ * Secure state has already been delt with.
+ */
+static CPAccessResult access_lor_ns(CPUARMState *env)
+{
+ int el = arm_current_el(env);
+
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) {
+ return CP_ACCESS_TRAP_EL3;
+ }
+ return CP_ACCESS_OK;
+}
+
+static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ if (arm_is_secure_below_el3(env)) {
+ /* Access ok in secure mode. */
+ return CP_ACCESS_OK;
+ }
+ return access_lor_ns(env);
+}
+
+static CPAccessResult access_lor_other(CPUARMState *env,
+ const ARMCPRegInfo *ri, bool isread)
+{
+ if (arm_is_secure_below_el3(env)) {
+ /* Access denied in secure mode. */
+ return CP_ACCESS_TRAP;
+ }
+ return access_lor_ns(env);
+}
+
void register_cp_regs_for_features(ARMCPU *cpu)
{
/* Register all the coprocessor registers based on feature bits */
{ .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_aa64mmfr0 },
+ .resetvalue = cpu->isar.id_aa64mmfr0 },
{ .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_aa64mmfr1 },
+ .resetvalue = cpu->isar.id_aa64mmfr1 },
{ .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
} else {
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
+ /* TTCBR2 is introduced with ARMv8.2-A32HPD. */
+ if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) {
+ define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
+ }
}
if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
define_arm_cp_regs(cpu, t2ee_cp_reginfo);
define_one_arm_cp_reg(cpu, &sctlr);
}
+ if (cpu_isar_feature(aa64_lor, cpu)) {
+ /*
+ * A trivial implementation of ARMv8.1-LOR leaves all of these
+ * registers fixed at 0, which indicates that there are zero
+ * supported Limited Ordering regions.
+ */
+ static const ARMCPRegInfo lor_reginfo[] = {
+ { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
+ .access = PL1_RW, .accessfn = access_lor_other,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
+ .access = PL1_RW, .accessfn = access_lor_other,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
+ .access = PL1_RW, .accessfn = access_lor_other,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
+ .access = PL1_RW, .accessfn = access_lor_other,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
+ .access = PL1_R, .accessfn = access_lorid,
+ .type = ARM_CP_CONST, .resetvalue = 0 },
+ REGINFO_SENTINEL
+ };
+ define_arm_cp_regs(cpu, lor_reginfo);
+ }
+
if (cpu_isar_feature(aa64_sve, cpu)) {
define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
if (arm_feature(env, ARM_FEATURE_EL2)) {
* and CPS are treated as illegal mode changes.
*/
if (write_type == CPSRWriteByInstr &&
- (env->cp15.hcr_el2 & HCR_TGE) &&
(env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON &&
- !arm_is_secure_below_el3(env)) {
+ (arm_hcr_el2_eff(env) & HCR_TGE)) {
return 1;
}
return 0;
uint32_t cur_el, bool secure)
{
CPUARMState *env = cs->env_ptr;
- int rw;
- int scr;
- int hcr;
+ bool rw;
+ bool scr;
+ bool hcr;
int target_el;
/* Is the highest EL AArch64? */
- int is64 = arm_feature(env, ARM_FEATURE_AARCH64);
+ bool is64 = arm_feature(env, ARM_FEATURE_AARCH64);
+ uint64_t hcr_el2;
if (arm_feature(env, ARM_FEATURE_EL3)) {
rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
rw = is64;
}
+ hcr_el2 = arm_hcr_el2_eff(env);
switch (excp_idx) {
case EXCP_IRQ:
scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
- hcr = arm_hcr_el2_imo(env);
+ hcr = hcr_el2 & HCR_IMO;
break;
case EXCP_FIQ:
scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
- hcr = arm_hcr_el2_fmo(env);
+ hcr = hcr_el2 & HCR_FMO;
break;
default:
scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
- hcr = arm_hcr_el2_amo(env);
+ hcr = hcr_el2 & HCR_AMO;
break;
};
- /* If HCR.TGE is set then HCR is treated as being 1 */
- hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE);
-
/* Perform a table-lookup for the target EL given the current state */
target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el];
bool ttbr1_valid = true;
uint64_t descaddrmask;
bool aarch64 = arm_el_is_aa64(env, el);
+ bool hpd = false;
/* TODO:
* This code does not handle the different format TCR for VTCR_EL2.
if (tg == 2) { /* 16KB pages */
stride = 11;
}
+ if (aarch64 && el > 1) {
+ hpd = extract64(tcr->raw_tcr, 24, 1);
+ } else {
+ hpd = extract64(tcr->raw_tcr, 41, 1);
+ }
+ if (!aarch64) {
+ /* For aarch32, hpd0 is not enabled without t2e as well. */
+ hpd &= extract64(tcr->raw_tcr, 6, 1);
+ }
} else {
/* We should only be here if TTBR1 is valid */
assert(ttbr1_valid);
if (tg == 1) { /* 16KB pages */
stride = 11;
}
+ hpd = extract64(tcr->raw_tcr, 42, 1);
+ if (!aarch64) {
+ /* For aarch32, hpd1 is not enabled without t2e as well. */
+ hpd &= extract64(tcr->raw_tcr, 6, 1);
+ }
}
/* Here we should have set up all the parameters for the translation:
descaddr = descriptor & descaddrmask;
if ((descriptor & 2) && (level < 3)) {
- /* Table entry. The top five bits are attributes which may
+ /* Table entry. The top five bits are attributes which may
* propagate down through lower levels of the table (and
* which are all arranged so that 0 means "no effect", so
* we can gather them up by ORing in the bits at each level).
break;
}
/* Merge in attributes from table descriptors */
- attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
- attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */
+ attrs |= nstable << 3; /* NS */
+ if (hpd) {
+ /* HPD disables all the table attributes except NSTable. */
+ break;
+ }
+ attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
/* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
* means "force PL1 access only", which means forcing AP[1] to 0.
*/
- if (extract32(tableattrs, 2, 1)) {
- attrs &= ~(1 << 4);
- }
- attrs |= nstable << 3; /* NS */
+ attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
+ attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
break;
}
/* Here descaddr is the final physical address, and attributes
[4] = 44,
[5] = 48,
};
- unsigned int parange = extract32(cpu->id_aa64mmfr0, 0, 4);
+ unsigned int parange =
+ FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
/* id_aa64mmfr0 is a read-only register so values outside of the
* supported mappings can be considered an implementation error. */
ARM64_SYS_REG(3, 0, 0, 6, 0));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
ARM64_SYS_REG(3, 0, 0, 6, 1));
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0,
+ ARM64_SYS_REG(3, 0, 0, 7, 0));
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
+ ARM64_SYS_REG(3, 0, 0, 7, 1));
/*
* Note that if AArch32 support is not present in the host,
{
CPUState *cs = CPU(arm_env_get_cpu(env));
- if ((env->cp15.hcr_el2 & HCR_TGE) &&
- target_el == 1 && !arm_is_secure(env)) {
+ if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
/*
* Redirect NS EL1 exceptions to NS EL2. These are reported with
* their original syndrome register value, with the exception of
* No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the
* bits will be zero indicating no trap.
*/
- if (cur_el < 2 && !arm_is_secure(env)) {
- mask = (is_wfe) ? HCR_TWE : HCR_TWI;
- if (env->cp15.hcr_el2 & mask) {
+ if (cur_el < 2) {
+ mask = is_wfe ? HCR_TWE : HCR_TWI;
+ if (arm_hcr_el2_eff(env) & mask) {
return 2;
}
}
exception_target_el(env));
}
- if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) {
+ if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) {
/* In NS EL1, HCR controlled routing to EL2 has priority over SMD.
* We also want an EL2 guest to be able to forbid its EL1 from
* making PSCI calls into QEMU's "firmware" via HCR.TSC.
goto illegal_return;
}
- if (new_el == 1 && (env->cp15.hcr_el2 & HCR_TGE)
- && !arm_is_secure_below_el3(env)) {
+ if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
goto illegal_return;
}
}
return;
+ case 0x8: /* STLLR */
+ if (!dc_isar_feature(aa64_lor, s)) {
+ break;
+ }
+ /* StoreLORelease is the same as Store-Release for QEMU. */
+ /* fall through */
case 0x9: /* STLR */
/* Generate ISS for non-exclusive accesses including LASR. */
if (rn == 31) {
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
return;
+ case 0xc: /* LDLAR */
+ if (!dc_isar_feature(aa64_lor, s)) {
+ break;
+ }
+ /* LoadLOAcquire is the same as Load-Acquire for QEMU. */
+ /* fall through */
case 0xd: /* LDAR */
/* Generate ISS for non-exclusive accesses including LASR. */
if (rn == 31) {
"avx512bitalg", NULL, "avx512-vpopcntdq", NULL,
"la57", NULL, NULL, NULL,
NULL, NULL, "rdpid", NULL,
- NULL, "cldemote", NULL, NULL,
- NULL, NULL, NULL, NULL,
+ NULL, "cldemote", NULL, "movdiri",
+ "movdir64b", NULL, NULL, NULL,
},
.cpuid = {
.eax = 7,
NULL, NULL, NULL, NULL,
NULL, NULL, "pconfig", NULL,
NULL, NULL, NULL, NULL,
- NULL, NULL, "spec-ctrl", NULL,
+ NULL, NULL, "spec-ctrl", "stibp",
NULL, "arch-capabilities", NULL, "ssbd",
},
.cpuid = {
x86_cpu_to_dict_full(xc, props);
break;
default:
- error_setg(&err, "Unsupportted expansion type");
+ error_setg(&err, "Unsupported expansion type");
goto out;
}
#define CPUID_7_0_ECX_LA57 (1U << 16)
#define CPUID_7_0_ECX_RDPID (1U << 22)
#define CPUID_7_0_ECX_CLDEMOTE (1U << 25) /* CLDEMOTE Instruction */
+#define CPUID_7_0_ECX_MOVDIRI (1U << 27) /* MOVDIRI Instruction */
+#define CPUID_7_0_ECX_MOVDIR64B (1U << 28) /* MOVDIR64B Instruction */
#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network Instructions */
#define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation Single Precision */
return 0;
}
- vcpu = g_malloc(sizeof(struct hax_vcpu_state));
- if (!vcpu) {
- fprintf(stderr, "Failed to alloc vcpu state\n");
- return -ENOMEM;
- }
-
- memset(vcpu, 0, sizeof(struct hax_vcpu_state));
+ vcpu = g_new0(struct hax_vcpu_state, 1);
ret = hax_host_create_vcpu(hax_global.vm->fd, id);
if (ret) {
}
/*
- * 1. The hax_tunnel is also destroied when vcpu destroy
+ * 1. The hax_tunnel is also destroyed when vcpu is destroyed
* 2. close fd will cause hax module vcpu be cleaned
*/
hax_close_fd(vcpu->fd);
return hax->vm;
}
- vm = g_malloc(sizeof(struct hax_vm));
- if (!vm) {
- return NULL;
- }
- memset(vm, 0, sizeof(struct hax_vm));
+ vm = g_new0(struct hax_vm, 1);
+
ret = hax_host_create_vm(hax, &vm_id);
if (ret) {
fprintf(stderr, "Failed to create vm %x\n", ret);
struct {
struct kvm_cpuid2 cpuid;
struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES];
- } QEMU_PACKED cpuid_data;
+ } cpuid_data;
+ /*
+ * The kernel defines these structs with padding fields so there
+ * should be no extra padding in our cpuid_data struct.
+ */
+ QEMU_BUILD_BUG_ON(sizeof(cpuid_data) !=
+ sizeof(struct kvm_cpuid2) +
+ sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES);
+
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
uint32_t limit, i, j, cpuid_i;
#if defined CONFIG_DEBUG_TCG || defined QEMU_STATIC_ANALYSIS
# define tcg_debug_assert(X) do { assert(X); } while (0)
-#elif QEMU_GNUC_PREREQ(4, 5)
+#else
# define tcg_debug_assert(X) \
do { if (!(X)) { __builtin_unreachable(); } } while (0)
-#else
-# define tcg_debug_assert(X) do { (void)(X); } while (0)
#endif
typedef struct TCGRelocation {
return qemu_bin;
}
-QTestState *qtest_init_without_qmp_handshake(bool use_oob,
- const char *extra_args)
+QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
{
QTestState *s;
int sock, qmpsock, i;
"-qtest unix:%s,nowait "
"-qtest-log %s "
"-chardev socket,path=%s,nowait,id=char0 "
- "-mon chardev=char0,mode=control%s "
+ "-mon chardev=char0,mode=control "
"-machine accel=qtest "
"-display none "
"%s", qemu_binary, socket_path,
getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null",
- qmp_socket_path, use_oob ? ",x-oob=on" : "",
+ qmp_socket_path,
extra_args ?: "");
g_test_message("starting QEMU: %s", command);
QTestState *qtest_init(const char *extra_args)
{
- QTestState *s = qtest_init_without_qmp_handshake(false, extra_args);
+ QTestState *s = qtest_init_without_qmp_handshake(extra_args);
QDict *greeting;
/* Read the QMP greeting and then do the handshake */
/**
* qtest_init_without_qmp_handshake:
- * @use_oob: true to have the server advertise OOB support
* @extra_args: other arguments to pass to QEMU. CAUTION: these
* arguments are subject to word splitting and shell evaluation.
*
* Returns: #QTestState instance.
*/
-QTestState *qtest_init_without_qmp_handshake(bool use_oob,
- const char *extra_args);
+QTestState *qtest_init_without_qmp_handshake(const char *extra_args);
/**
* qtest_quit:
QList *capabilities;
QTestState *qts;
- qts = qtest_init_without_qmp_handshake(false, common_args);
+ qts = qtest_init_without_qmp_handshake(common_args);
/* Test greeting */
resp = qtest_qmp_receive(qts);
g_assert(q);
test_version(qdict_get(q, "version"));
capabilities = qdict_get_qlist(q, "capabilities");
- g_assert(capabilities && qlist_empty(capabilities));
+ g_assert(capabilities);
qobject_unref(resp);
/* Test valid command before handshake */
QList *capabilities;
QString *qstr;
- qts = qtest_init_without_qmp_handshake(true, common_args);
+ qts = qtest_init_without_qmp_handshake(common_args);
/* Check the greeting message. */
resp = qtest_qmp_receive(qts);
TEST_XCHG(xchgb, "b", "+q");
#if defined(__x86_64__)
- TEST_XCHG(xchgq, "", "=m");
+ TEST_XCHG(xchgq, "", "+m");
#endif
TEST_XCHG(xchgl, "k", "+m");
TEST_XCHG(xchgw, "w", "+m");
test_block_read_func,
&header,
0,
+ 1,
NULL);
g_assert(blk == NULL);
test_block_read_func,
&header,
QCRYPTO_BLOCK_OPEN_NO_IO,
+ 1,
&error_abort);
g_assert(qcrypto_block_get_cipher(blk) == NULL);
test_block_read_func,
&header,
0,
+ 1,
&error_abort);
g_assert(blk);
qobject_unref(req);
}
+static void test_dispatch_cmd_oob(void)
+{
+ QDict *req = qdict_new();
+ QDict *resp;
+
+ qdict_put_str(req, "exec-oob", "test-flags-command");
+
+ resp = qmp_dispatch(&qmp_commands, QOBJECT(req), true);
+ assert(resp != NULL);
+ assert(!qdict_haskey(resp, "error"));
+
+ qobject_unref(resp);
+ qobject_unref(req);
+}
+
/* test commands that return an error due to invalid parameters */
static void test_dispatch_cmd_failure(void)
{
g_test_init(&argc, &argv, NULL);
g_test_add_func("/qmp/dispatch_cmd", test_dispatch_cmd);
+ g_test_add_func("/qmp/dispatch_cmd_oob", test_dispatch_cmd_oob);
g_test_add_func("/qmp/dispatch_cmd_failure", test_dispatch_cmd_failure);
g_test_add_func("/qmp/dispatch_cmd_io", test_dispatch_cmd_io);
g_test_add_func("/qmp/dispatch_cmd_success_response",
wait_for_trace_records_available();
if (g_atomic_int_get(&dropped_events)) {
- dropped.rec.event = DROPPED_EVENT_ID,
+ dropped.rec.event = DROPPED_EVENT_ID;
dropped.rec.timestamp_ns = get_clock();
- dropped.rec.length = sizeof(TraceRecord) + sizeof(uint64_t),
+ dropped.rec.length = sizeof(TraceRecord) + sizeof(uint64_t);
dropped.rec.pid = trace_pid;
do {
dropped_count = g_atomic_int_get(&dropped_events);
static int check_strtox_error(const char *nptr, char *ep,
const char **endptr, int libc_errno)
{
+ assert(ep >= nptr);
if (endptr) {
*endptr = ep;
}
char *ep;
long long lresult;
+ assert((unsigned) base <= 36 && base != 1);
if (!nptr) {
if (endptr) {
*endptr = nptr;
char *ep;
long long lresult;
+ assert((unsigned) base <= 36 && base != 1);
if (!nptr) {
if (endptr) {
*endptr = nptr;
{
char *ep;
+ assert((unsigned) base <= 36 && base != 1);
if (!nptr) {
if (endptr) {
*endptr = nptr;
{
char *ep;
+ assert((unsigned) base <= 36 && base != 1);
if (!nptr) {
if (endptr) {
*endptr = nptr;
{
char *ep;
+ assert((unsigned) base <= 36 && base != 1);
if (!nptr) {
if (endptr) {
*endptr = nptr;
{
char *ep;
+ assert((unsigned) base <= 36 && base != 1);
if (!nptr) {
if (endptr) {
*endptr = nptr;
char *endp = (char *)s;
unsigned long long val = 0;
+ assert((unsigned) base <= 36 && base != 1);
if (!s) {
r = -EINVAL;
goto out;
goto fail;
}
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < ARRAY_SIZE(s->bar_region_info); i++) {
ret = qemu_vfio_pci_init_bar(s, i, errp);
if (ret) {
goto fail;
if (qemu_opt_get_bool(opts, "pretty", 0))
flags |= MONITOR_USE_PRETTY;
- /* OOB is off by default */
- if (qemu_opt_get_bool(opts, "x-oob", 0)) {
- flags |= MONITOR_USE_OOB;
- }
-
chardev = qemu_opt_get(opts, "chardev");
if (!chardev) {
error_report("chardev is required");