diff options
116 files changed, 1161 insertions, 767 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index ca4dd0482b..7364af0d8b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -437,6 +437,17 @@ F: include/hw/block/dataplane/xen* F: include/hw/xen/ F: include/sysemu/xen-mapcache.h +Guest CPU Cores (HAXM) +--------------------- +X86 HAXM CPUs +M: Wenchao Wang <wenchao.wang@intel.com> +M: Colin Xu <colin.xu@intel.com> +L: haxm-team@intel.com +W: https://github.com/intel/haxm/issues +S: Maintained +F: include/sysemu/hax.h +F: target/i386/hax-* + Hosts ----- LINUX @@ -2040,6 +2051,7 @@ F: include/exec/ramblock.h F: memory.c F: include/exec/memory-internal.h F: exec.c +F: scripts/coccinelle/memory-region-housekeeping.cocci SPICE M: Gerd Hoffmann <kraxel@redhat.com> @@ -1235,50 +1235,57 @@ endif include $(SRC_PATH)/tests/docker/Makefile.include include $(SRC_PATH)/tests/vm/Makefile.include +print-help-run = printf " %-30s - %s\\n" "$1" "$2" +print-help = $(quiet-@)$(call print-help-run,$1,$2) + .PHONY: help help: @echo 'Generic targets:' - @echo ' all - Build all' + $(call print-help,all,Build all) ifdef CONFIG_MODULES - @echo ' modules - Build all modules' + $(call print-help,modules,Build all modules) endif - @echo ' dir/file.o - Build specified target only' - @echo ' install - Install QEMU, documentation and tools' - @echo ' ctags/TAGS - Generate tags file for editors' - @echo ' cscope - Generate cscope index' + $(call print-help,dir/file.o,Build specified target only) + $(call print-help,install,Install QEMU, documentation and tools) + $(call print-help,ctags/TAGS,Generate tags file for editors) + $(call print-help,cscope,Generate cscope index) @echo '' @$(if $(TARGET_DIRS), \ echo 'Architecture specific targets:'; \ $(foreach t, $(TARGET_DIRS), \ - printf " %-30s - Build for %s\\n" $(t)/all $(t);) \ + $(call print-help-run,$(t)/all,Build for $(t));) \ + echo '') + @$(if $(TOOLS), \ + echo 'Tools targets:'; \ + $(foreach t, $(TOOLS), \ + $(call print-help-run,$(t),Build $(shell basename $(t)) tool);) \ echo '') @echo 'Cleaning targets:' - @echo ' clean - Remove most generated files but keep the config' + $(call print-help,clean,Remove most generated files but keep the config) ifdef CONFIG_GCOV - @echo ' clean-coverage - Remove coverage files' + $(call print-help,clean-coverage,Remove coverage files) endif - @echo ' distclean - Remove all generated files' - @echo ' dist - Build a distributable tarball' + $(call print-help,distclean,Remove all generated files) + $(call print-help,dist,Build a distributable tarball) @echo '' @echo 'Test targets:' - @echo ' check - Run all tests (check-help for details)' - @echo ' docker - Help about targets running tests inside containers' - @echo ' vm-help - Help about targets running tests inside VM' + $(call print-help,check,Run all tests (check-help for details)) + $(call print-help,docker,Help about targets running tests inside containers) + $(call print-help,vm-help,Help about targets running tests inside VM) @echo '' @echo 'Documentation targets:' - @echo ' html info pdf txt' - @echo ' - Build documentation in specified format' + $(call print-help,html info pdf txt,Build documentation in specified format) ifdef CONFIG_GCOV - @echo ' coverage-report - Create code coverage report' + $(call print-help,coverage-report,Create code coverage report) endif @echo '' ifdef CONFIG_WIN32 @echo 'Windows targets:' - @echo ' installer - Build NSIS-based installer for QEMU' + $(call print-help,installer,Build NSIS-based installer for QEMU) ifdef QEMU_GA_MSI_ENABLED - @echo ' msi - Build MSI-based installer for qemu-ga' + $(call print-help,msi,Build MSI-based installer for qemu-ga) endif @echo '' endif - @echo ' $(MAKE) [targets] (quiet build, default)' - @echo ' $(MAKE) V=1 [targets] (verbose build)' + $(call print-help,$(MAKE) [targets],(quiet build, default)) + $(call print-help,$(MAKE) V=1 [targets],(verbose build)) diff --git a/Makefile.target b/Makefile.target index 2d43dc586a..934a9f7431 100644 --- a/Makefile.target +++ b/Makefile.target @@ -12,7 +12,7 @@ endif $(call set-vpath, $(SRC_PATH):$(BUILD_DIR)) ifdef CONFIG_LINUX -QEMU_CFLAGS += -I../linux-headers +QEMU_CFLAGS += -isystem ../linux-headers endif QEMU_CFLAGS += -iquote .. -iquote $(SRC_PATH)/target/$(TARGET_BASE_ARCH) -DNEED_CPU_H diff --git a/block/linux-aio.c b/block/linux-aio.c index 91204a25a2..3c0527c2bf 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -121,7 +121,7 @@ struct aio_ring { unsigned incompat_features; unsigned header_length; /* size of aio_ring */ - struct io_event io_events[0]; + struct io_event io_events[]; }; /** diff --git a/block/vmdk.c b/block/vmdk.c index 20e909d997..8466051bc9 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -187,7 +187,7 @@ typedef struct VmdkMetaData { typedef struct VmdkGrainMarker { uint64_t lba; uint32_t size; - uint8_t data[0]; + uint8_t data[]; } QEMU_PACKED VmdkGrainMarker; enum { diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 09e8aed9c7..f8bb1e5459 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -95,7 +95,7 @@ typedef struct TaskState { struct sigqueue *first_free; /* first free siginfo queue entry */ int signal_pending; /* non zero if a signal may be pending */ - uint8_t stack[0]; + uint8_t stack[]; } __attribute__((aligned(16))) TaskState; void init_task_state(TaskState *ts); @@ -405,6 +405,7 @@ EXESUF="" DSOSUF=".so" LDFLAGS_SHARED="-shared" modules="no" +module_upgrades="no" prefix="/usr/local" mandir="\${prefix}/share/man" datadir="\${prefix}/share" @@ -899,7 +900,7 @@ Linux) linux="yes" linux_user="yes" kvm="yes" - QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$PWD/linux-headers $QEMU_INCLUDES" + QEMU_INCLUDES="-isystem \$(SRC_PATH)/linux-headers -isystem $PWD/linux-headers $QEMU_INCLUDES" supported_os="yes" libudev="yes" ;; @@ -1032,6 +1033,10 @@ for opt do --disable-modules) modules="no" ;; + --disable-module-upgrades) module_upgrades="no" + ;; + --enable-module-upgrades) module_upgrades="yes" + ;; --cpu=*) ;; --target-list=*) target_list="$optarg" @@ -1421,6 +1426,11 @@ for opt do ;; --enable-avx2) avx2_opt="yes" ;; + --disable-avx512f) avx512f_opt="no" + ;; + --enable-avx512f) avx512f_opt="yes" + ;; + --enable-glusterfs) glusterfs="yes" ;; --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane) @@ -1786,6 +1796,7 @@ disabled with --disable-FEATURE, default is enabled if available: guest-agent-msi build guest agent Windows MSI installation package pie Position Independent Executables modules modules support (non-Windows) + module-upgrades try to load modules from alternate paths for upgrades debug-tcg TCG debugging (default is disabled) debug-info debugging information sparse sparse checker @@ -1857,6 +1868,7 @@ disabled with --disable-FEATURE, default is enabled if available: tcmalloc tcmalloc support jemalloc jemalloc support avx2 AVX2 optimization support + avx512f AVX512F optimization support replication replication support opengl opengl support virglrenderer virgl rendering support @@ -2049,6 +2061,11 @@ if test "$modules" = "yes" && test "$mingw32" = "yes" ; then error_exit "Modules are not available for Windows" fi +# module_upgrades is only reasonable if modules are enabled +if test "$modules" = "no" && test "$module_upgrades" = "yes" ; then + error_exit "Can't enable module-upgrades as Modules are not enabled" +fi + # Static linking is not possible with modules or PIE if test "$static" = "yes" ; then if test "$modules" = "yes" ; then @@ -3350,7 +3367,9 @@ if test "$vnc" = "yes" && test "$vnc_sasl" != "no" ; then int main(void) { sasl_server_init(NULL, "qemu"); return 0; } EOF # Assuming Cyrus-SASL installed in /usr prefix - vnc_sasl_cflags="" + # QEMU defines struct iovec in "qemu/osdep.h", + # we don't want libsasl to redefine it in <sasl/sasl.h>. + vnc_sasl_cflags="-DSTRUCT_IOVEC_DEFINED" vnc_sasl_libs="-lsasl2" if compile_prog "$vnc_sasl_cflags" "$vnc_sasl_libs" ; then vnc_sasl=yes @@ -5574,6 +5593,36 @@ EOF fi fi +########################################## +# avx512f optimization requirement check +# +# There is no point enabling this if cpuid.h is not usable, +# since we won't be able to select the new routines. +# by default, it is turned off. +# if user explicitly want to enable it, check environment + +if test "$cpuid_h" = "yes" && test "$avx512f_opt" = "yes"; then + cat > $TMPC << EOF +#pragma GCC push_options +#pragma GCC target("avx512f") +#include <cpuid.h> +#include <immintrin.h> +static int bar(void *a) { + __m512i x = *(__m512i *)a; + return _mm512_test_epi64_mask(x, x); +} +int main(int argc, char *argv[]) +{ + return bar(argv[0]); +} +EOF + if ! compile_object "" ; then + avx512f_opt="no" + fi +else + avx512f_opt="no" +fi + ######################################## # check if __[u]int128_t is usable. @@ -6590,6 +6639,7 @@ if test "$slirp" != "no" ; then echo "smbd $smbd" fi echo "module support $modules" +echo "alt path mod load $module_upgrades" echo "host CPU $cpu" echo "host big endian $bigendian" echo "target list $target_list" @@ -6717,6 +6767,7 @@ echo "libxml2 $libxml2" echo "tcmalloc support $tcmalloc" echo "jemalloc support $jemalloc" echo "avx2 optimization $avx2_opt" +echo "avx512f optimization $avx512f_opt" echo "replication support $replication" echo "VxHS block device $vxhs" echo "bochs support $bochs" @@ -6943,6 +6994,9 @@ if test "$modules" = "yes"; then echo "CONFIG_STAMP=_$( (echo $qemu_version; echo $pkgversion; cat $0) | $shacmd - | cut -f1 -d\ )" >> $config_host_mak echo "CONFIG_MODULES=y" >> $config_host_mak fi +if test "$module_upgrades" = "yes"; then + echo "CONFIG_MODULE_UPGRADES=y" >> $config_host_mak +fi if test "$have_x11" = "yes" && test "$need_x11" = "yes"; then echo "CONFIG_X11=y" >> $config_host_mak echo "X11_CFLAGS=$x11_cflags" >> $config_host_mak @@ -7268,6 +7322,10 @@ if test "$avx2_opt" = "yes" ; then echo "CONFIG_AVX2_OPT=y" >> $config_host_mak fi +if test "$avx512f_opt" = "yes" ; then + echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak +fi + if test "$lzo" = "yes" ; then echo "CONFIG_LZO=y" >> $config_host_mak fi diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h index 6fc8000e99..f30394fab6 100644 --- a/contrib/libvhost-user/libvhost-user.h +++ b/contrib/libvhost-user/libvhost-user.h @@ -286,7 +286,7 @@ typedef struct VuVirtqInflight { uint16_t used_idx; /* Used to track the state of each descriptor in descriptor table */ - VuDescStateSplit desc[0]; + VuDescStateSplit desc[]; } VuVirtqInflight; typedef struct VuVirtqInflightDesc { diff --git a/contrib/vhost-user-gpu/Makefile.objs b/contrib/vhost-user-gpu/Makefile.objs index 6170c919e4..09296091be 100644 --- a/contrib/vhost-user-gpu/Makefile.objs +++ b/contrib/vhost-user-gpu/Makefile.objs @@ -1,7 +1,7 @@ -vhost-user-gpu-obj-y = main.o virgl.o vugbm.o +vhost-user-gpu-obj-y = vhost-user-gpu.o virgl.o vugbm.o -main.o-cflags := $(PIXMAN_CFLAGS) $(GBM_CFLAGS) -main.o-libs := $(PIXMAN_LIBS) +vhost-user-gpu.o-cflags := $(PIXMAN_CFLAGS) $(GBM_CFLAGS) +vhost-user-gpu.o-libs := $(PIXMAN_LIBS) virgl.o-cflags := $(VIRGL_CFLAGS) $(GBM_CFLAGS) virgl.o-libs := $(VIRGL_LIBS) diff --git a/contrib/vhost-user-gpu/main.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index b45d2019b4..b45d2019b4 100644 --- a/contrib/vhost-user-gpu/main.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -1026,9 +1026,9 @@ static int do_vm_stop(RunState state, bool send_stop) int ret = 0; if (runstate_is_running()) { + runstate_set(state); cpu_disable_ticks(); pause_all_vcpus(); - runstate_set(state); vm_state_notify(0, state); if (send_stop) { qapi_event_send_stop(); @@ -1899,6 +1899,10 @@ void resume_all_vcpus(void) { CPUState *cpu; + if (!runstate_is_running()) { + return; + } + qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); CPU_FOREACH(cpu) { cpu_resume(cpu); diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst index 401652397c..3b1b6602c7 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -568,7 +568,7 @@ For split virtqueue, queue region can be implemented as: uint16_t used_idx; /* Used to track the state of each descriptor in descriptor table */ - DescStateSplit desc[0]; + DescStateSplit desc[]; } QueueRegionSplit; To track inflight I/O, the queue region should be processed as follows: @@ -690,7 +690,7 @@ For packed virtqueue, queue region can be implemented as: uint8_t padding[7]; /* Used to track the state of each descriptor fetched from descriptor ring */ - DescStatePacked desc[0]; + DescStatePacked desc[]; } QueueRegionPacked; To track inflight I/O, the queue region should be processed as follows: diff --git a/docs/system/cpu-models-x86.rst.inc b/docs/system/cpu-models-x86.rst.inc index cbad930c70..9a2327828e 100644 --- a/docs/system/cpu-models-x86.rst.inc +++ b/docs/system/cpu-models-x86.rst.inc @@ -49,10 +49,15 @@ mixture of host CPU models between machines, if live migration compatibility is required, use the newest CPU model that is compatible across all desired hosts. -``Skylake-Server``, ``Skylake-Server-IBRS`` +``Cascadelake-Server``, ``Cascadelake-Server-noTSX`` + Intel Xeon Processor (Cascade Lake, 2019), with "stepping" levels 6 + or 7 only. (The Cascade Lake Xeon processor with *stepping 5 is + vulnerable to MDS variants*.) + +``Skylake-Server``, ``Skylake-Server-IBRS``, ``Skylake-Server-IBRS-noTSX`` Intel Xeon Processor (Skylake, 2016) -``Skylake-Client``, ``Skylake-Client-IBRS`` +``Skylake-Client``, ``Skylake-Client-IBRS``, ``Skylake-Client-noTSX-IBRS}`` Intel Core Processor (Skylake, 2015) ``Broadwell``, ``Broadwell-IBRS``, ``Broadwell-noTSX``, ``Broadwell-noTSX-IBRS`` @@ -148,6 +153,54 @@ features are included if using "Host passthrough" or "Host model". Requires the host CPU microcode to support this feature before it can be used for guest CPUs. +``mds-no`` + Recommended to inform the guest OS that the host is *not* vulnerable + to any of the MDS variants ([MFBDS] CVE-2018-12130, [MLPDS] + CVE-2018-12127, [MSBDS] CVE-2018-12126). + + This is an MSR (Model-Specific Register) feature rather than a CPUID feature, + so it will not appear in the Linux ``/proc/cpuinfo`` in the host or + guest. Instead, the host kernel uses it to populate the MDS + vulnerability file in ``sysfs``. + + So it should only be enabled for VMs if the host reports @code{Not + affected} in the ``/sys/devices/system/cpu/vulnerabilities/mds`` file. + +``taa-no`` + Recommended to inform that the guest that the host is ``not`` + vulnerable to CVE-2019-11135, TSX Asynchronous Abort (TAA). + + This too is an MSR feature, so it does not show up in the Linux + ``/proc/cpuinfo`` in the host or guest. + + It should only be enabled for VMs if the host reports ``Not affected`` + in the ``/sys/devices/system/cpu/vulnerabilities/tsx_async_abort`` + file. + +``tsx-ctrl`` + Recommended to inform the guest that it can disable the Intel TSX + (Transactional Synchronization Extensions) feature; or, if the + processor is vulnerable, use the Intel VERW instruction (a + processor-level instruction that performs checks on memory access) as + a mitigation for the TAA vulnerability. (For details, refer to + Intel's `deep dive into MDS + <https://software.intel.com/security-software-guidance/insights/deep-dive-intel-analysis-microarchitectural-data-sampling>`_.) + + Expose this to the guest OS if and only if: (a) the host has TSX + enabled; *and* (b) the guest has ``rtm`` CPU flag enabled. + + By disabling TSX, KVM-based guests can avoid paying the price of + mitigating TSX-based attacks. + + Note that ``tsx-ctrl`` too is an MSR feature, so it does not show + up in the Linux ``/proc/cpuinfo`` in the host or guest. + + To validate that Intel TSX is indeed disabled for the guest, there are + two ways: (a) check for the *absence* of ``rtm`` in the guest's + ``/proc/cpuinfo``; or (b) the + ``/sys/devices/system/cpu/vulnerabilities/tsx_async_abort`` file in + the guest should report ``Mitigation: TSX disabled``. + Preferred CPU models for AMD x86 hosts ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1315,7 +1315,7 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start, unsigned client) { DirtyMemoryBlocks *blocks; - unsigned long end, page; + unsigned long end, page, start_page; bool dirty = false; RAMBlock *ramblock; uint64_t mr_offset, mr_size; @@ -1325,7 +1325,8 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start, } end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS; - page = start >> TARGET_PAGE_BITS; + start_page = start >> TARGET_PAGE_BITS; + page = start_page; WITH_RCU_READ_LOCK_GUARD() { blocks = atomic_rcu_read(&ram_list.dirty_memory[client]); @@ -1345,8 +1346,8 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start, page += num; } - mr_offset = (ram_addr_t)(page << TARGET_PAGE_BITS) - ramblock->offset; - mr_size = (end - page) << TARGET_PAGE_BITS; + mr_offset = (ram_addr_t)(start_page << TARGET_PAGE_BITS) - ramblock->offset; + mr_size = (end - start_page) << TARGET_PAGE_BITS; memory_region_clear_dirty_bitmap(ramblock->mr, mr_offset, mr_size); } diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 4e74284b65..336cacea41 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -357,81 +357,6 @@ static void ich9_pm_set_cpu_hotplug_legacy(Object *obj, bool value, s->pm.cpu_hotplug_legacy = value; } -static void ich9_pm_get_disable_s3(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ICH9LPCPMRegs *pm = opaque; - uint8_t value = pm->disable_s3; - - visit_type_uint8(v, name, &value, errp); -} - -static void ich9_pm_set_disable_s3(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ICH9LPCPMRegs *pm = opaque; - Error *local_err = NULL; - uint8_t value; - - visit_type_uint8(v, name, &value, &local_err); - if (local_err) { - goto out; - } - pm->disable_s3 = value; -out: - error_propagate(errp, local_err); -} - -static void ich9_pm_get_disable_s4(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ICH9LPCPMRegs *pm = opaque; - uint8_t value = pm->disable_s4; - - visit_type_uint8(v, name, &value, errp); -} - -static void ich9_pm_set_disable_s4(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ICH9LPCPMRegs *pm = opaque; - Error *local_err = NULL; - uint8_t value; - - visit_type_uint8(v, name, &value, &local_err); - if (local_err) { - goto out; - } - pm->disable_s4 = value; -out: - error_propagate(errp, local_err); -} - -static void ich9_pm_get_s4_val(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ICH9LPCPMRegs *pm = opaque; - uint8_t value = pm->s4_val; - - visit_type_uint8(v, name, &value, errp); -} - -static void ich9_pm_set_s4_val(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ICH9LPCPMRegs *pm = opaque; - Error *local_err = NULL; - uint8_t value; - - visit_type_uint8(v, name, &value, &local_err); - if (local_err) { - goto out; - } - pm->s4_val = value; -out: - error_propagate(errp, local_err); -} - static bool ich9_pm_get_enable_tco(Object *obj, Error **errp) { ICH9LPCState *s = ICH9_LPC_DEVICE(obj); @@ -454,12 +379,12 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) pm->s4_val = 2; object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, - &pm->pm_io_base, errp); + &pm->pm_io_base, OBJ_PROP_FLAG_READ, errp); object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32", ich9_pm_get_gpe0_blk, NULL, NULL, pm, NULL); object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, - &gpe0_len, errp); + &gpe0_len, OBJ_PROP_FLAG_READ, errp); object_property_add_bool(obj, "memory-hotplug-support", ich9_pm_get_memory_hotplug_support, ich9_pm_set_memory_hotplug_support, @@ -468,18 +393,14 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) ich9_pm_get_cpu_hotplug_legacy, ich9_pm_set_cpu_hotplug_legacy, NULL); - object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", - ich9_pm_get_disable_s3, - ich9_pm_set_disable_s3, - NULL, pm, NULL); - object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8", - ich9_pm_get_disable_s4, - ich9_pm_set_disable_s4, - NULL, pm, NULL); - object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8", - ich9_pm_get_s4_val, - ich9_pm_set_s4_val, - NULL, pm, NULL); + object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S3_DISABLED, + &pm->disable_s3, OBJ_PROP_FLAG_READWRITE, + NULL); + object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S4_DISABLED, + &pm->disable_s4, OBJ_PROP_FLAG_READWRITE, + NULL); + object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S4_VAL, + &pm->s4_val, OBJ_PROP_FLAG_READWRITE, NULL); object_property_add_bool(obj, ACPI_PM_PROP_TCO_ENABLED, ich9_pm_get_enable_tco, ich9_pm_set_enable_tco, diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 5219dd0e2e..eb6a37b14e 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -485,7 +485,7 @@ struct NvdimmFuncGetLabelDataOut { /* the size of buffer filled by QEMU. */ uint32_t len; uint32_t func_ret_status; /* return status code. */ - uint8_t out_buf[0]; /* the data got via Get Namesapce Label function. */ + uint8_t out_buf[]; /* the data got via Get Namesapce Label function. */ } QEMU_PACKED; typedef struct NvdimmFuncGetLabelDataOut NvdimmFuncGetLabelDataOut; QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE); @@ -493,7 +493,7 @@ QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE); struct NvdimmFuncSetLabelDataIn { uint32_t offset; /* the offset in the namespace label data area. */ uint32_t length; /* the size of data is to be written via the function. */ - uint8_t in_buf[0]; /* the data written to label data area. */ + uint8_t in_buf[]; /* the data written to label data area. */ } QEMU_PACKED; typedef struct NvdimmFuncSetLabelDataIn NvdimmFuncSetLabelDataIn; QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncSetLabelDataIn) + @@ -510,7 +510,7 @@ struct NvdimmFuncReadFITOut { /* the size of buffer filled by QEMU. */ uint32_t len; uint32_t func_ret_status; /* return status code. */ - uint8_t fit[0]; /* the FIT data. */ + uint8_t fit[]; /* the FIT data. */ } QEMU_PACKED; typedef struct NvdimmFuncReadFITOut NvdimmFuncReadFITOut; QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncReadFITOut) > NVDIMM_DSM_MEMORY_SIZE); diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 8413348a33..4dcef372bf 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -80,7 +80,8 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque) *bus_bsel = (*bsel_alloc)++; object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, - bus_bsel, &error_abort); + bus_bsel, OBJ_PROP_FLAG_READ, + &error_abort); } return bsel_alloc; @@ -373,9 +374,9 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus, memory_region_add_subregion(address_space_io, s->io_base, &s->io); object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base, - &error_abort); + OBJ_PROP_FLAG_READ, &error_abort); object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_LEN_PROP, &s->io_len, - &error_abort); + OBJ_PROP_FLAG_READ, &error_abort); } const VMStateDescription vmstate_acpi_pcihp_pci_status = { diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index b84dbba2c3..964d6f5990 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -444,17 +444,17 @@ static void piix4_pm_add_propeties(PIIX4PMState *s) static const uint16_t sci_int = 9; object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_ENABLE_CMD, - &acpi_enable_cmd, NULL); + &acpi_enable_cmd, OBJ_PROP_FLAG_READ, NULL); object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_DISABLE_CMD, - &acpi_disable_cmd, NULL); + &acpi_disable_cmd, OBJ_PROP_FLAG_READ, NULL); object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK, - &gpe0_blk, NULL); + &gpe0_blk, OBJ_PROP_FLAG_READ, NULL); object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK_LEN, - &gpe0_blk_len, NULL); + &gpe0_blk_len, OBJ_PROP_FLAG_READ, NULL); object_property_add_uint16_ptr(OBJECT(s), ACPI_PM_PROP_SCI_INT, - &sci_int, NULL); + &sci_int, OBJ_PROP_FLAG_READ, NULL); object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_PM_IO_BASE, - &s->io_base, NULL); + &s->io_base, OBJ_PROP_FLAG_READ, NULL); } static void piix4_pm_realize(PCIDevice *dev, Error **errp) diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 59a27bdd68..1f7253ef6f 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -305,23 +305,21 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp) /*** Memory ***/ /* Chip-ID and OMR */ - memory_region_init_io(&s->chipid_mem, NULL, &exynos4210_chipid_and_omr_ops, - NULL, "exynos4210.chipid", sizeof(chipid_and_omr)); + memory_region_init_io(&s->chipid_mem, OBJECT(socdev), + &exynos4210_chipid_and_omr_ops, NULL, + "exynos4210.chipid", sizeof(chipid_and_omr)); memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR, &s->chipid_mem); /* Internal ROM */ - memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom", + memory_region_init_rom(&s->irom_mem, OBJECT(socdev), "exynos4210.irom", EXYNOS4210_IROM_SIZE, &error_fatal); - memory_region_set_readonly(&s->irom_mem, true); memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR, &s->irom_mem); /* mirror of iROM */ - memory_region_init_alias(&s->irom_alias_mem, NULL, "exynos4210.irom_alias", - &s->irom_mem, - 0, + memory_region_init_alias(&s->irom_alias_mem, OBJECT(socdev), + "exynos4210.irom_alias", &s->irom_mem, 0, EXYNOS4210_IROM_SIZE); - memory_region_set_readonly(&s->irom_alias_mem, true); memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR, &s->irom_alias_mem); diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c index a3f829f436..6f1a82ce3d 100644 --- a/hw/arm/fsl-imx25.c +++ b/hw/arm/fsl-imx25.c @@ -303,16 +303,16 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp) } /* initialize 2 x 16 KB ROM */ - memory_region_init_rom(&s->rom[0], NULL, - "imx25.rom0", FSL_IMX25_ROM0_SIZE, &err); + memory_region_init_rom(&s->rom[0], OBJECT(dev), "imx25.rom0", + FSL_IMX25_ROM0_SIZE, &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR, &s->rom[0]); - memory_region_init_rom(&s->rom[1], NULL, - "imx25.rom1", FSL_IMX25_ROM1_SIZE, &err); + memory_region_init_rom(&s->rom[1], OBJECT(dev), "imx25.rom1", + FSL_IMX25_ROM1_SIZE, &err); if (err) { error_propagate(errp, err); return; @@ -331,7 +331,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp) &s->iram); /* internal RAM (128 KB) is aliased over 128 MB - 128 KB */ - memory_region_init_alias(&s->iram_alias, NULL, "imx25.iram_alias", + memory_region_init_alias(&s->iram_alias, OBJECT(dev), "imx25.iram_alias", &s->iram, 0, FSL_IMX25_IRAM_ALIAS_SIZE); memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ALIAS_ADDR, &s->iram_alias); diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c index 55e90d104b..8472d2e911 100644 --- a/hw/arm/fsl-imx31.c +++ b/hw/arm/fsl-imx31.c @@ -206,7 +206,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp) } /* On a real system, the first 16k is a `secure boot rom' */ - memory_region_init_rom(&s->secure_rom, NULL, "imx31.secure_rom", + memory_region_init_rom(&s->secure_rom, OBJECT(dev), "imx31.secure_rom", FSL_IMX31_SECURE_ROM_SIZE, &err); if (err) { error_propagate(errp, err); @@ -216,7 +216,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp) &s->secure_rom); /* There is also a 16k ROM */ - memory_region_init_rom(&s->rom, NULL, "imx31.rom", + memory_region_init_rom(&s->rom, OBJECT(dev), "imx31.rom", FSL_IMX31_ROM_SIZE, &err); if (err) { error_propagate(errp, err); @@ -236,7 +236,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp) &s->iram); /* internal RAM (16 KB) is aliased over 256 MB - 16 KB */ - memory_region_init_alias(&s->iram_alias, NULL, "imx31.iram_alias", + memory_region_init_alias(&s->iram_alias, OBJECT(dev), "imx31.iram_alias", &s->iram, 0, FSL_IMX31_IRAM_ALIAS_SIZE); memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ALIAS_ADDR, &s->iram_alias); diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c index e095e4abc6..13f1bf23a6 100644 --- a/hw/arm/fsl-imx6.c +++ b/hw/arm/fsl-imx6.c @@ -441,7 +441,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) } /* ROM memory */ - memory_region_init_rom(&s->rom, NULL, "imx6.rom", + memory_region_init_rom(&s->rom, OBJECT(dev), "imx6.rom", FSL_IMX6_ROM_SIZE, &err); if (err) { error_propagate(errp, err); @@ -451,7 +451,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) &s->rom); /* CAAM memory */ - memory_region_init_rom(&s->caam, NULL, "imx6.caam", + memory_region_init_rom(&s->caam, OBJECT(dev), "imx6.caam", FSL_IMX6_CAAM_MEM_SIZE, &err); if (err) { error_propagate(errp, err); @@ -471,7 +471,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) &s->ocram); /* internal OCRAM (256 KB) is aliased over 1 MB */ - memory_region_init_alias(&s->ocram_alias, NULL, "imx6.ocram_alias", + memory_region_init_alias(&s->ocram_alias, OBJECT(dev), "imx6.ocram_alias", &s->ocram, 0, FSL_IMX6_OCRAM_ALIAS_SIZE); memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ALIAS_ADDR, &s->ocram_alias); diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c index 99a5859a4e..56dfd7cecc 100644 --- a/hw/arm/fsl-imx6ul.c +++ b/hw/arm/fsl-imx6ul.c @@ -592,7 +592,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) /* * ROM memory */ - memory_region_init_rom(&s->rom, NULL, "imx6ul.rom", + memory_region_init_rom(&s->rom, OBJECT(dev), "imx6ul.rom", FSL_IMX6UL_ROM_SIZE, &error_abort); memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR, &s->rom); @@ -600,7 +600,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) /* * CAAM memory */ - memory_region_init_rom(&s->caam, NULL, "imx6ul.caam", + memory_region_init_rom(&s->caam, OBJECT(dev), "imx6ul.caam", FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort); memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR, &s->caam); @@ -617,8 +617,9 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) /* * internal OCRAM (128 KB) is aliased over 512 KB */ - memory_region_init_alias(&s->ocram_alias, NULL, "imx6ul.ocram_alias", - &s->ocram, 0, FSL_IMX6UL_OCRAM_ALIAS_SIZE); + memory_region_init_alias(&s->ocram_alias, OBJECT(dev), + "imx6ul.ocram_alias", &s->ocram, 0, + FSL_IMX6UL_OCRAM_ALIAS_SIZE); memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias); } diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c index 1042017086..6bc643651b 100644 --- a/hw/arm/mainstone.c +++ b/hw/arm/mainstone.c @@ -124,9 +124,8 @@ static void mainstone_common_init(MemoryRegion *address_space_mem, /* Setup CPU & memory */ mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size, machine->cpu_type); - memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM, + memory_region_init_rom(rom, NULL, "mainstone.rom", MAINSTONE_ROM, &error_fatal); - memory_region_set_readonly(rom, true); memory_region_add_subregion(address_space_mem, 0, rom); /* There are two 32MiB flash devices on the board */ diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c index 8f84692e64..588d643b8d 100644 --- a/hw/arm/msf2-soc.c +++ b/hw/arm/msf2-soc.c @@ -96,7 +96,7 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp) MemoryRegion *nvm_alias = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); - memory_region_init_rom(nvm, NULL, "MSF2.eNVM", s->envm_size, + memory_region_init_rom(nvm, OBJECT(dev_soc), "MSF2.eNVM", s->envm_size, &error_fatal); /* * On power-on, the eNVM region 0x60000000 is automatically @@ -104,8 +104,8 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp) * start address (0x0). We do not support remapping other eNVM, * eSRAM and DDR regions by guest(via Sysreg) currently. */ - memory_region_init_alias(nvm_alias, NULL, "MSF2.eNVM", - nvm, 0, s->envm_size); + memory_region_init_alias(nvm_alias, OBJECT(dev_soc), "MSF2.eNVM", nvm, 0, + s->envm_size); memory_region_add_subregion(system_memory, ENVM_BASE_ADDRESS, nvm); memory_region_add_subregion(system_memory, 0, nvm_alias); diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c index 4817a76ae0..57eff63f0d 100644 --- a/hw/arm/nrf51_soc.c +++ b/hw/arm/nrf51_soc.c @@ -165,7 +165,7 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp) } /* STUB Peripherals */ - memory_region_init_io(&s->clock, NULL, &clock_ops, NULL, + memory_region_init_io(&s->clock, OBJECT(dev_soc), &clock_ops, NULL, "nrf51_soc.clock", 0x1000); memory_region_add_subregion_overlap(&s->container, NRF51_IOMEM_BASE, &s->clock, -1); diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c index de5ff447dc..57829b3744 100644 --- a/hw/arm/omap_sx1.c +++ b/hw/arm/omap_sx1.c @@ -131,9 +131,8 @@ static void sx1_init(MachineState *machine, const int version) mpu = omap310_mpu_init(machine->ram, machine->cpu_type); /* External Flash (EMIFS) */ - memory_region_init_ram(flash, NULL, "omap_sx1.flash0-0", flash_size, + memory_region_init_rom(flash, NULL, "omap_sx1.flash0-0", flash_size, &error_fatal); - memory_region_set_readonly(flash, true); memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash); memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val, @@ -167,9 +166,8 @@ static void sx1_init(MachineState *machine, const int version) if ((version == 1) && (dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) { MemoryRegion *flash_1 = g_new(MemoryRegion, 1); - memory_region_init_ram(flash_1, NULL, "omap_sx1.flash1-0", + memory_region_init_rom(flash_1, NULL, "omap_sx1.flash1-0", flash1_size, &error_fatal); - memory_region_set_readonly(flash_1, true); memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1); memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val, diff --git a/hw/arm/palm.c b/hw/arm/palm.c index 99554bda19..97ca105d29 100644 --- a/hw/arm/palm.c +++ b/hw/arm/palm.c @@ -213,9 +213,8 @@ static void palmte_init(MachineState *machine) mpu = omap310_mpu_init(machine->ram, machine->cpu_type); /* External Flash (EMIFS) */ - memory_region_init_ram(flash, NULL, "palmte.flash", flash_size, + memory_region_init_rom(flash, NULL, "palmte.flash", flash_size, &error_fatal); - memory_region_set_readonly(flash, true); memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash); memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val, "palmte-cs0", diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c index cbfa6934cf..c28d9b5ed7 100644 --- a/hw/arm/spitz.c +++ b/hw/arm/spitz.c @@ -929,8 +929,7 @@ static void spitz_common_init(MachineState *machine, sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M); - memory_region_init_ram(rom, NULL, "spitz.rom", SPITZ_ROM, &error_fatal); - memory_region_set_readonly(rom, true); + memory_region_init_rom(rom, NULL, "spitz.rom", SPITZ_ROM, &error_fatal); memory_region_add_subregion(address_space_mem, 0, rom); /* Setup peripherals */ diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 221a78674e..d136ba1a92 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1300,9 +1300,8 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) sram_size = ((board->dc0 >> 18) + 1) * 1024; /* Flash programming is done via the SCU, so pretend it is ROM. */ - memory_region_init_ram(flash, NULL, "stellaris.flash", flash_size, + memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size, &error_fatal); - memory_region_set_readonly(flash, true); memory_region_add_subregion(system_memory, 0, flash); memory_region_init_ram(sram, NULL, "stellaris.sram", sram_size, diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c index 627fd446f5..118c342559 100644 --- a/hw/arm/stm32f205_soc.c +++ b/hw/arm/stm32f205_soc.c @@ -93,13 +93,10 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) MemoryRegion *flash = g_new(MemoryRegion, 1); MemoryRegion *flash_alias = g_new(MemoryRegion, 1); - memory_region_init_ram(flash, NULL, "STM32F205.flash", FLASH_SIZE, - &error_fatal); - memory_region_init_alias(flash_alias, NULL, "STM32F205.flash.alias", - flash, 0, FLASH_SIZE); - - memory_region_set_readonly(flash, true); - memory_region_set_readonly(flash_alias, true); + memory_region_init_rom(flash, OBJECT(dev_soc), "STM32F205.flash", + FLASH_SIZE, &error_fatal); + memory_region_init_alias(flash_alias, OBJECT(dev_soc), + "STM32F205.flash.alias", flash, 0, FLASH_SIZE); memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash); memory_region_add_subregion(system_memory, 0, flash_alias); diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c index 9bcad97853..4f10ce6176 100644 --- a/hw/arm/stm32f405_soc.c +++ b/hw/arm/stm32f405_soc.c @@ -95,17 +95,15 @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp) Error *err = NULL; int i; - memory_region_init_ram(&s->flash, NULL, "STM32F405.flash", FLASH_SIZE, - &err); + memory_region_init_rom(&s->flash, OBJECT(dev_soc), "STM32F405.flash", + FLASH_SIZE, &err); if (err != NULL) { error_propagate(errp, err); return; } - memory_region_init_alias(&s->flash_alias, NULL, "STM32F405.flash.alias", - &s->flash, 0, FLASH_SIZE); - - memory_region_set_readonly(&s->flash, true); - memory_region_set_readonly(&s->flash_alias, true); + memory_region_init_alias(&s->flash_alias, OBJECT(dev_soc), + "STM32F405.flash.alias", &s->flash, 0, + FLASH_SIZE); memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash); memory_region_add_subregion(system_memory, 0, &s->flash_alias); diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index 4d95a1f3e2..5dee2d76c6 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -226,8 +226,7 @@ static void tosa_init(MachineState *machine) mpu = pxa255_init(address_space_mem, tosa_binfo.ram_size); - memory_region_init_ram(rom, NULL, "tosa.rom", TOSA_ROM, &error_fatal); - memory_region_set_readonly(rom, true); + memory_region_init_rom(rom, NULL, "tosa.rom", TOSA_ROM, &error_fatal); memory_region_add_subregion(address_space_mem, 0, rom); tmio = tc6393xb_init(address_space_mem, 0x10000000, diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index cab0160ae9..49f1c8d0de 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -318,9 +318,9 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) ddr_low_size = XLNX_ZYNQMP_MAX_LOW_RAM_SIZE; ddr_high_size = ram_size - XLNX_ZYNQMP_MAX_LOW_RAM_SIZE; - memory_region_init_alias(&s->ddr_ram_high, NULL, - "ddr-ram-high", s->ddr_ram, - ddr_low_size, ddr_high_size); + memory_region_init_alias(&s->ddr_ram_high, OBJECT(dev), + "ddr-ram-high", s->ddr_ram, ddr_low_size, + ddr_high_size); memory_region_add_subregion(get_system_memory(), XLNX_ZYNQMP_HIGH_RAM_START, &s->ddr_ram_high); @@ -330,9 +330,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) ddr_low_size = ram_size; } - memory_region_init_alias(&s->ddr_ram_low, NULL, - "ddr-ram-low", s->ddr_ram, - 0, ddr_low_size); + memory_region_init_alias(&s->ddr_ram_low, OBJECT(dev), "ddr-ram-low", + s->ddr_ram, 0, ddr_low_size); memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram_low); /* Create the four OCM banks */ diff --git a/hw/audio/fmopl.c b/hw/audio/fmopl.c index 173a7521f2..356d4dfbca 100644 --- a/hw/audio/fmopl.c +++ b/hw/audio/fmopl.c @@ -186,7 +186,7 @@ static int32_t *VIB_TABLE; /* envelope output curve table */ /* attack + decay + OFF */ -static int32_t ENV_CURVE[2*EG_ENT+1]; +static int32_t *ENV_CURVE; /* multiple table */ #define ML 2 @@ -1090,6 +1090,7 @@ FM_OPL *OPLCreate(int clock, int rate) OPL->clock = clock; OPL->rate = rate; OPL->max_ch = max_ch; + ENV_CURVE = g_new(int32_t, 2 * EG_ENT + 1); /* init grobal tables */ OPL_initialize(OPL); /* reset chip */ @@ -1127,6 +1128,7 @@ void OPLDestroy(FM_OPL *OPL) #endif OPL_UnLockTable(); free(OPL); + g_free(ENV_CURVE); } /* ---------- Option handlers ---------- */ diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index 1bcc3e5cf8..e8d18b7c58 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -181,7 +181,9 @@ struct IntelHDAState { IntelHDAStream st[8]; /* state */ + MemoryRegion container; MemoryRegion mmio; + MemoryRegion alias; uint32_t rirb_count; int64_t wall_base_ns; @@ -670,12 +672,6 @@ static const struct IntelHDAReg regtab[] = { .offset = offsetof(IntelHDAState, wall_clk), .rhandler = intel_hda_get_wall_clk, }, - [ ICH6_REG_WALLCLK + 0x2000 ] = { - .name = "WALLCLK(alias)", - .size = 4, - .offset = offsetof(IntelHDAState, wall_clk), - .rhandler = intel_hda_get_wall_clk, - }, /* dma engine */ [ ICH6_REG_CORBLBASE ] = { @@ -837,12 +833,6 @@ static const struct IntelHDAReg regtab[] = { .size = 4, \ .offset = offsetof(IntelHDAState, st[_i].lpib), \ }, \ - [ ST_REG(_i, ICH6_REG_SD_LPIB) + 0x2000 ] = { \ - .stream = _i, \ - .name = _t stringify(_i) " LPIB(alias)", \ - .size = 4, \ - .offset = offsetof(IntelHDAState, st[_i].lpib), \ - }, \ [ ST_REG(_i, ICH6_REG_SD_CBL) ] = { \ .stream = _i, \ .name = _t stringify(_i) " CBL", \ @@ -1125,9 +1115,15 @@ static void intel_hda_realize(PCIDevice *pci, Error **errp) error_free(err); } + memory_region_init(&d->container, OBJECT(d), + "intel-hda-container", 0x4000); memory_region_init_io(&d->mmio, OBJECT(d), &intel_hda_mmio_ops, d, - "intel-hda", 0x4000); - pci_register_bar(&d->pci, 0, 0, &d->mmio); + "intel-hda", 0x2000); + memory_region_add_subregion(&d->container, 0x0000, &d->mmio); + memory_region_init_alias(&d->alias, OBJECT(d), "intel-hda-alias", + &d->mmio, 0, 0x2000); + memory_region_add_subregion(&d->container, 0x2000, &d->alias); + pci_register_bar(&d->pci, 0, 0, &d->container); hda_codec_bus_init(DEVICE(pci), &d->codecs, sizeof(d->codecs), intel_hda_response, intel_hda_xfer); diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c index c420dc066e..2b5f37b6a2 100644 --- a/hw/char/sclpconsole-lm.c +++ b/hw/char/sclpconsole-lm.c @@ -31,7 +31,7 @@ typedef struct OprtnsCommand { EventBufferHeader header; MDMSU message_unit; - char data[0]; + char data[]; } QEMU_PACKED OprtnsCommand; /* max size for line-mode data in 4K SCCB page */ diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index 1fa124dab9..5c7664905e 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -25,7 +25,7 @@ typedef struct ASCIIConsoleData { EventBufferHeader ebh; - char data[0]; + char data[]; } QEMU_PACKED ASCIIConsoleData; /* max size for ASCII data in 4K SCCB page */ diff --git a/hw/char/serial.c b/hw/char/serial.c index 9298881af9..2ab8b69e03 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -997,7 +997,7 @@ static void serial_io_realize(DeviceState *dev, Error **errp) return; } - memory_region_init_io(&s->io, NULL, &serial_io_ops, s, "serial", 8); + memory_region_init_io(&s->io, OBJECT(dev), &serial_io_ops, s, "serial", 8); sysbus_init_mmio(SYS_BUS_DEVICE(sio), &s->io); sysbus_init_irq(SYS_BUS_DEVICE(sio), &s->irq); } @@ -1106,8 +1106,9 @@ static void serial_mm_realize(DeviceState *dev, Error **errp) return; } - memory_region_init_io(&s->io, NULL, &serial_mm_ops[smm->endianness], smm, - "serial", 8 << smm->regshift); + memory_region_init_io(&s->io, OBJECT(dev), + &serial_mm_ops[smm->endianness], smm, "serial", + 8 << smm->regshift); sysbus_init_mmio(SYS_BUS_DEVICE(smm), &s->io); sysbus_init_irq(SYS_BUS_DEVICE(smm), &smm->serial.irq); } diff --git a/hw/core/loader.c b/hw/core/loader.c index d1b78f60cd..eeef6da9a1 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -1119,19 +1119,26 @@ static void rom_reset(void *unused) { Rom *rom; - /* - * We don't need to fill in the RAM with ROM data because we'll fill - * the data in during the next incoming migration in all cases. Note - * that some of those RAMs can actually be modified by the guest on ARM - * so this is probably the only right thing to do here. - */ - if (runstate_check(RUN_STATE_INMIGRATE)) - return; - QTAILQ_FOREACH(rom, &roms, next) { if (rom->fw_file) { continue; } + /* + * We don't need to fill in the RAM with ROM data because we'll fill + * the data in during the next incoming migration in all cases. Note + * that some of those RAMs can actually be modified by the guest. + */ + if (runstate_check(RUN_STATE_INMIGRATE)) { + if (rom->data && rom->isrom) { + /* + * Free it so that a rom_reset after migration doesn't + * overwrite a potentially modified 'rom'. + */ + rom_free_data(rom); + } + continue; + } + if (rom->data == NULL) { continue; } diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c index 22c5f76dd0..d494e5cec1 100644 --- a/hw/core/platform-bus.c +++ b/hw/core/platform-bus.c @@ -187,7 +187,8 @@ static void platform_bus_realize(DeviceState *dev, Error **errp) d = SYS_BUS_DEVICE(dev); pbus = PLATFORM_BUS_DEVICE(dev); - memory_region_init(&pbus->mmio, NULL, "platform bus", pbus->mmio_size); + memory_region_init(&pbus->mmio, OBJECT(dev), "platform bus", + pbus->mmio_size); sysbus_init_mmio(d, &pbus->mmio); pbus->used_irqs = bitmap_new(pbus->num_irqs); diff --git a/hw/display/cg3.c b/hw/display/cg3.c index 4fb67c6b1c..a1ede10394 100644 --- a/hw/display/cg3.c +++ b/hw/display/cg3.c @@ -287,9 +287,8 @@ static void cg3_initfn(Object *obj) SysBusDevice *sbd = SYS_BUS_DEVICE(obj); CG3State *s = CG3(obj); - memory_region_init_ram_nomigrate(&s->rom, obj, "cg3.prom", FCODE_MAX_ROM_SIZE, - &error_fatal); - memory_region_set_readonly(&s->rom, true); + memory_region_init_rom_nomigrate(&s->rom, obj, "cg3.prom", + FCODE_MAX_ROM_SIZE, &error_fatal); sysbus_init_mmio(sbd, &s->rom); memory_region_init_io(&s->reg, obj, &cg3_reg_ops, s, "cg3.reg", diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index 55185c95c6..adcba96e34 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -477,7 +477,8 @@ static void g364fb_init(DeviceState *dev, G364State *s) s->con = graphic_console_init(dev, 0, &g364fb_ops, s); - memory_region_init_io(&s->mem_ctrl, NULL, &g364fb_ctrl_ops, s, "ctrl", 0x180000); + memory_region_init_io(&s->mem_ctrl, OBJECT(dev), &g364fb_ctrl_ops, s, + "ctrl", 0x180000); memory_region_init_ram_ptr(&s->mem_vram, NULL, "vram", s->vram_size, s->vram); vmstate_register_ram(&s->mem_vram, dev); diff --git a/hw/display/macfb.c b/hw/display/macfb.c index 8bff16d535..b68faff4bb 100644 --- a/hw/display/macfb.c +++ b/hw/display/macfb.c @@ -362,8 +362,8 @@ static void macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp) return; } - memory_region_init_io(&s->mem_ctrl, NULL, &macfb_ctrl_ops, s, "macfb-ctrl", - 0x1000); + memory_region_init_io(&s->mem_ctrl, OBJECT(dev), &macfb_ctrl_ops, s, + "macfb-ctrl", 0x1000); memory_region_init_ram_nomigrate(&s->mem_vram, OBJECT(s), "macfb-vram", MACFB_VRAM_SIZE, errp); diff --git a/hw/display/tcx.c b/hw/display/tcx.c index ca458f94fe..76de16e8ea 100644 --- a/hw/display/tcx.c +++ b/hw/display/tcx.c @@ -755,9 +755,8 @@ static void tcx_initfn(Object *obj) SysBusDevice *sbd = SYS_BUS_DEVICE(obj); TCXState *s = TCX(obj); - memory_region_init_ram_nomigrate(&s->rom, obj, "tcx.prom", FCODE_MAX_ROM_SIZE, - &error_fatal); - memory_region_set_readonly(&s->rom, true); + memory_region_init_rom_nomigrate(&s->rom, obj, "tcx.prom", + FCODE_MAX_ROM_SIZE, &error_fatal); sysbus_init_mmio(sbd, &s->rom); /* 2/STIP : Stippler */ diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index bad8debae4..ef15c06d77 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -553,7 +553,7 @@ static void i8257_realize(DeviceState *dev, Error **errp) I8257State *d = I8257(dev); int i; - memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d, + memory_region_init_io(&d->channel_io, OBJECT(dev), &channel_io_ops, d, "dma-chan", 8 << d->dshift); memory_region_add_subregion(isa_address_space_io(isa), d->base, &d->channel_io); diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c index 21e2c360ac..7434d274aa 100644 --- a/hw/dma/rc4030.c +++ b/hw/dma/rc4030.c @@ -679,9 +679,9 @@ static void rc4030_realize(DeviceState *dev, Error **errp) s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rc4030_periodic_timer, s); - memory_region_init_io(&s->iomem_chipset, NULL, &rc4030_ops, s, + memory_region_init_io(&s->iomem_chipset, o, &rc4030_ops, s, "rc4030.chipset", 0x300); - memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s, + memory_region_init_io(&s->iomem_jazzio, o, &jazzio_ops, s, "rc4030.jazzio", 0x00001000); memory_region_init_iommu(&s->dma_mr, sizeof(s->dma_mr), diff --git a/hw/dma/soc_dma.c b/hw/dma/soc_dma.c index c3e41581b6..3a430057f5 100644 --- a/hw/dma/soc_dma.c +++ b/hw/dma/soc_dma.c @@ -80,7 +80,7 @@ struct dma_s { } *memmap; int memmap_size; - struct soc_dma_ch_s ch[0]; + struct soc_dma_ch_s ch[]; }; static void soc_dma_ch_schedule(struct soc_dma_ch_s *ch, int delay_bytes) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 204b6841ec..df7ad254ac 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -3094,6 +3094,12 @@ static int vtd_irte_get(IntelIOMMUState *iommu, uint16_t index, uint16_t mask, source_id; uint8_t bus, bus_max, bus_min; + if (index >= iommu->intr_size) { + error_report_once("%s: index too large: ind=0x%x", + __func__, index); + return -VTD_FR_IR_INDEX_OVER; + } + addr = iommu->intr_root + index * sizeof(*entry); if (dma_memory_read(&address_space_memory, addr, entry, sizeof(*entry))) { diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 7f38e6ba8b..08246523f2 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -328,7 +328,7 @@ struct setup_data { uint64_t next; uint32_t type; uint32_t len; - uint8_t data[0]; + uint8_t data[]; } __attribute__((packed)); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index cb79616ced..fbc3165d03 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -625,36 +625,21 @@ static const MemoryRegionOps ich9_rst_cnt_ops = { .endianness = DEVICE_LITTLE_ENDIAN }; -static void ich9_lpc_get_sci_int(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) +static void ich9_lpc_initfn(Object *obj) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj); - uint32_t value = lpc->sci_gsi; - - visit_type_uint32(v, name, &value, errp); -} -static void ich9_lpc_add_properties(ICH9LPCState *lpc) -{ static const uint8_t acpi_enable_cmd = ICH9_APM_ACPI_ENABLE; static const uint8_t acpi_disable_cmd = ICH9_APM_ACPI_DISABLE; - object_property_add(OBJECT(lpc), ACPI_PM_PROP_SCI_INT, "uint32", - ich9_lpc_get_sci_int, - NULL, NULL, NULL, NULL); + object_property_add_uint8_ptr(obj, ACPI_PM_PROP_SCI_INT, + &lpc->sci_gsi, OBJ_PROP_FLAG_READ, NULL); object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_ENABLE_CMD, - &acpi_enable_cmd, NULL); + &acpi_enable_cmd, OBJ_PROP_FLAG_READ, NULL); object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_DISABLE_CMD, - &acpi_disable_cmd, NULL); - - ich9_pm_add_properties(OBJECT(lpc), &lpc->pm, NULL); -} - -static void ich9_lpc_initfn(Object *obj) -{ - ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj); + &acpi_disable_cmd, OBJ_PROP_FLAG_READ, NULL); - ich9_lpc_add_properties(lpc); + ich9_pm_add_properties(obj, &lpc->pm, NULL); } static void ich9_lpc_realize(PCIDevice *d, Error **errp) diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h index 5f8ded2686..c954270aad 100644 --- a/hw/m68k/bootinfo.h +++ b/hw/m68k/bootinfo.h @@ -14,7 +14,7 @@ struct bi_record { uint16_t tag; /* tag ID */ uint16_t size; /* size of record */ - uint32_t data[0]; /* data */ + uint32_t data[]; /* data */ }; /* machine independent tags */ diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index c5699f6f3e..81749e7ec6 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -399,13 +399,12 @@ static void q800_init(MachineState *machine) uint8_t *ptr; /* allocate and load BIOS */ rom = g_malloc(sizeof(*rom)); - memory_region_init_ram(rom, NULL, "m68k_mac.rom", MACROM_SIZE, + memory_region_init_rom(rom, NULL, "m68k_mac.rom", MACROM_SIZE, &error_abort); if (bios_name == NULL) { bios_name = MACROM_FILENAME; } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - memory_region_set_readonly(rom, true); memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom); /* Load MacROM binary */ diff --git a/hw/misc/edu.c b/hw/misc/edu.c index d5e2bdbb57..ff10f5b794 100644 --- a/hw/misc/edu.c +++ b/hw/misc/edu.c @@ -396,21 +396,14 @@ static void pci_edu_uninit(PCIDevice *pdev) msi_uninit(pdev); } -static void edu_obj_uint64(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint64_t *val = opaque; - - visit_type_uint64(v, name, val, errp); -} - static void edu_instance_init(Object *obj) { EduState *edu = EDU(obj); edu->dma_mask = (1UL << 28) - 1; - object_property_add(obj, "dma_mask", "uint64", edu_obj_uint64, - edu_obj_uint64, NULL, &edu->dma_mask, NULL); + object_property_add_uint64_ptr(obj, "dma_mask", + &edu->dma_mask, OBJ_PROP_FLAG_READWRITE, + NULL); } static void edu_class_init(ObjectClass *class, void *data) diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c index 61b6df564a..54aeaecd69 100644 --- a/hw/misc/omap_l4.c +++ b/hw/misc/omap_l4.c @@ -24,7 +24,7 @@ struct omap_l4_s { MemoryRegion *address_space; hwaddr base; int ta_num; - struct omap_target_agent_s ta[0]; + struct omap_target_agent_s ta[]; }; struct omap_l4_s *omap_l4_init(MemoryRegion *address_space, diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index 81fc13ee9f..1563c11b9e 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -986,13 +986,12 @@ static void dp8393x_realize(DeviceState *dev, Error **errp) s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s); - memory_region_init_ram(&s->prom, OBJECT(dev), - "dp8393x-prom", SONIC_PROM_SIZE, &local_err); + memory_region_init_rom(&s->prom, OBJECT(dev), "dp8393x-prom", + SONIC_PROM_SIZE, &local_err); if (local_err) { error_propagate(errp, local_err); return; } - memory_region_set_readonly(&s->prom, true); prom = memory_region_get_ram_ptr(&s->prom); checksum = 0; for (i = 0; i < 6; i++) { diff --git a/hw/nvram/eeprom93xx.c b/hw/nvram/eeprom93xx.c index 07f09549ed..ca6f591c84 100644 --- a/hw/nvram/eeprom93xx.c +++ b/hw/nvram/eeprom93xx.c @@ -86,7 +86,7 @@ struct _eeprom_t { uint8_t addrbits; uint16_t size; uint16_t data; - uint16_t contents[0]; + uint16_t contents[]; }; /* Code for saving and restoring of EEPROM state. */ diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index 1aff72bec6..1a02e9a670 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -325,9 +325,8 @@ static void raven_realize(PCIDevice *d, Error **errp) d->config[0x0D] = 0x10; // latency_timer d->config[0x34] = 0x00; // capabilities_pointer - memory_region_init_ram_nomigrate(&s->bios, OBJECT(s), "bios", BIOS_SIZE, - &error_fatal); - memory_region_set_readonly(&s->bios, true); + memory_region_init_rom_nomigrate(&s->bios, OBJECT(s), "bios", BIOS_SIZE, + &error_fatal); memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE), &s->bios); if (s->bios_name) { diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 993f467668..2bbc90b28f 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -166,14 +166,6 @@ static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v, visit_type_uint64(v, name, &value, errp); } -static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - PCIExpressHost *e = PCIE_HOST_BRIDGE(obj); - - visit_type_uint64(v, name, &e->size, errp); -} - /* * NOTE: setting defaults for the mch.* fields in this table * doesn't work, because mch is a separate QOM object that is @@ -214,6 +206,7 @@ static void q35_host_initfn(Object *obj) { Q35PCIHost *s = Q35_HOST_DEVICE(obj); PCIHostState *phb = PCI_HOST_BRIDGE(obj); + PCIExpressHost *pehb = PCIE_HOST_BRIDGE(obj); memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb, "pci-conf-idx", 4); @@ -243,9 +236,8 @@ static void q35_host_initfn(Object *obj) q35_host_get_pci_hole64_end, NULL, NULL, NULL, NULL); - object_property_add(obj, PCIE_HOST_MCFG_SIZE, "uint64", - q35_host_get_mmcfg_size, - NULL, NULL, NULL, NULL); + object_property_add_uint64_ptr(obj, PCIE_HOST_MCFG_SIZE, + &pehb->size, OBJ_PROP_FLAG_READ, NULL); object_property_add_link(obj, MCH_HOST_PROP_RAM_MEM, TYPE_MEMORY_REGION, (Object **) &s->mch.ram_memory, diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index b8189bf7a4..b2ec372958 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -155,13 +155,12 @@ static void ppc_core99_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), 0, machine->ram); /* allocate and load BIOS */ - memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE, + memory_region_init_rom(bios, NULL, "ppc_core99.bios", BIOS_SIZE, &error_fatal); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - memory_region_set_readonly(bios, true); memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 440c406eb4..faaa165f3f 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -129,13 +129,12 @@ static void ppc_heathrow_init(MachineState *machine) memory_region_add_subregion(sysmem, 0, machine->ram); /* allocate and load BIOS */ - memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE, + memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE, &error_fatal); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - memory_region_set_readonly(bios, true); memory_region_add_subregion(sysmem, PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index de93c40f1a..e6bffb9e1a 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -199,7 +199,7 @@ static void ref405ep_init(MachineState *machine) #endif { bios = g_new(MemoryRegion, 1); - memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE, + memory_region_init_rom(bios, NULL, "ef405ep.bios", BIOS_SIZE, &error_fatal); if (bios_name == NULL) @@ -223,7 +223,6 @@ static void ref405ep_init(MachineState *machine) /* Avoid an uninitialized variable warning */ bios_size = -1; } - memory_region_set_readonly(bios, true); } /* Register FPGA */ ref405ep_fpga_init(sysmem, 0xF0300000); @@ -471,7 +470,7 @@ static void taihu_405ep_init(MachineState *machine) if (bios_name == NULL) bios_name = BIOS_FILENAME; bios = g_new(MemoryRegion, 1); - memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE, + memory_region_init_rom(bios, NULL, "taihu_405ep.bios", BIOS_SIZE, &error_fatal); filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { @@ -489,7 +488,6 @@ static void taihu_405ep_init(MachineState *machine) error_report("Could not load PowerPC BIOS '%s'", bios_name); exit(1); } - memory_region_set_readonly(bios, true); } /* Register Linux flash */ dinfo = drive_get(IF_PFLASH, 0, fl_idx); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index cc10798be4..41c0f2401f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3223,30 +3223,6 @@ static void spapr_set_resize_hpt(Object *obj, const char *value, Error **errp) } } -static void spapr_get_vsmt(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - visit_type_uint32(v, name, (uint32_t *)opaque, errp); -} - -static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - visit_type_uint32(v, name, (uint32_t *)opaque, errp); -} - -static void spapr_get_kernel_addr(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - visit_type_uint64(v, name, (uint64_t *)opaque, errp); -} - -static void spapr_set_kernel_addr(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - visit_type_uint64(v, name, (uint64_t *)opaque, errp); -} - static char *spapr_get_ic_mode(Object *obj, Error **errp) { SpaprMachineState *spapr = SPAPR_MACHINE(obj); @@ -3344,17 +3320,19 @@ static void spapr_instance_init(Object *obj) object_property_set_description(obj, "resize-hpt", "Resizing of the Hash Page Table (enabled, disabled, required)", NULL); - object_property_add(obj, "vsmt", "uint32", spapr_get_vsmt, - spapr_set_vsmt, NULL, &spapr->vsmt, &error_abort); + object_property_add_uint32_ptr(obj, "vsmt", + &spapr->vsmt, OBJ_PROP_FLAG_READWRITE, + &error_abort); object_property_set_description(obj, "vsmt", "Virtual SMT: KVM behaves as if this were" " the host's SMT mode", &error_abort); + object_property_add_bool(obj, "vfio-no-msix-emulation", spapr_get_msix_emulation, NULL, NULL); - object_property_add(obj, "kernel-addr", "uint64", spapr_get_kernel_addr, - spapr_set_kernel_addr, NULL, &spapr->kernel_addr, - &error_abort); + object_property_add_uint64_ptr(obj, "kernel-addr", + &spapr->kernel_addr, OBJ_PROP_FLAG_READWRITE, + &error_abort); object_property_set_description(obj, "kernel-addr", stringify(KERNEL_LOAD_ADDR) " for -kernel is the default", diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index e373d342eb..47e6bb12f9 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -583,7 +583,8 @@ static void spapr_dr_connector_instance_init(Object *obj) SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj); SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); - object_property_add_uint32_ptr(obj, "id", &drc->id, NULL); + object_property_add_uint32_ptr(obj, "id", &drc->id, OBJ_PROP_FLAG_READ, + NULL); object_property_add(obj, "index", "uint32", prop_get_index, NULL, NULL, NULL, NULL); object_property_add(obj, "fdt", "struct", prop_get_fdt, diff --git a/hw/rdma/vmw/pvrdma_qp_ops.c b/hw/rdma/vmw/pvrdma_qp_ops.c index bd6db858de..8050287a6c 100644 --- a/hw/rdma/vmw/pvrdma_qp_ops.c +++ b/hw/rdma/vmw/pvrdma_qp_ops.c @@ -34,13 +34,13 @@ typedef struct CompHandlerCtx { /* Send Queue WQE */ typedef struct PvrdmaSqWqe { struct pvrdma_sq_wqe_hdr hdr; - struct pvrdma_sge sge[0]; + struct pvrdma_sge sge[]; } PvrdmaSqWqe; /* Recv Queue WQE */ typedef struct PvrdmaRqWqe { struct pvrdma_rq_wqe_hdr hdr; - struct pvrdma_sge sge[0]; + struct pvrdma_sge sge[]; } PvrdmaRqWqe; /* diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index a254cad489..646553a7c3 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -145,8 +145,8 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp) &error_abort); /* Mask ROM */ - memory_region_init_rom(&s->mask_rom, NULL, "riscv.sifive.e.mrom", - memmap[SIFIVE_E_MROM].size, &error_fatal); + memory_region_init_rom(&s->mask_rom, OBJECT(dev), "riscv.sifive.e.mrom", + memmap[SIFIVE_E_MROM].size, &error_fatal); memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_MROM].base, &s->mask_rom); @@ -208,9 +208,8 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp) memmap[SIFIVE_E_PWM2].base, memmap[SIFIVE_E_PWM2].size); /* Flash memory */ - memory_region_init_ram(&s->xip_mem, NULL, "riscv.sifive.e.xip", - memmap[SIFIVE_E_XIP].size, &error_fatal); - memory_region_set_readonly(&s->xip_mem, true); + memory_region_init_rom(&s->xip_mem, OBJECT(dev), "riscv.sifive.e.xip", + memmap[SIFIVE_E_XIP].size, &error_fatal); memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base, &s->xip_mem); } diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 4409ea1ccc..56351c4faa 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -501,7 +501,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp) &error_abort); /* boot rom */ - memory_region_init_rom(mask_rom, NULL, "riscv.sifive.u.mrom", + memory_region_init_rom(mask_rom, OBJECT(dev), "riscv.sifive.u.mrom", memmap[SIFIVE_U_MROM].size, &error_fatal); memory_region_add_subregion(system_memory, memmap[SIFIVE_U_MROM].base, mask_rom); diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 50cf95b781..64f928fc7d 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -193,7 +193,7 @@ typedef struct VirtioThinintInfo { typedef struct VirtioRevInfo { uint16_t revision; uint16_t length; - uint8_t data[0]; + uint8_t data[]; } QEMU_PACKED VirtioRevInfo; /* Specify where the virtqueues for the subchannel are in guest memory. */ diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c index 68b14ee5e7..f410c08883 100644 --- a/hw/sh4/shix.c +++ b/hw/sh4/shix.c @@ -53,8 +53,7 @@ static void shix_init(MachineState *machine) cpu = SUPERH_CPU(cpu_create(machine->cpu_type)); /* Allocate memory space */ - memory_region_init_ram(rom, NULL, "shix.rom", 0x4000, &error_fatal); - memory_region_set_readonly(rom, true); + memory_region_init_rom(rom, NULL, "shix.rom", 0x4000, &error_fatal); memory_region_add_subregion(sysmem, 0x00000000, rom); memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000, &error_fatal); diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 5fa58aa55f..8f024dab7b 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -255,8 +255,7 @@ static void leon3_generic_hw_init(MachineState *machine) /* Allocate BIOS */ prom_size = 8 * MiB; - memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size, &error_fatal); - memory_region_set_readonly(prom, true); + memory_region_init_rom(prom, NULL, "Leon3.bios", prom_size, &error_fatal); memory_region_add_subregion(address_space_mem, LEON3_PROM_OFFSET, prom); /* Load boot prom */ diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c index 9a78ad928b..6210427544 100644 --- a/hw/usb/dev-network.c +++ b/hw/usb/dev-network.c @@ -626,7 +626,7 @@ static const uint32_t oid_supported_list[] = struct rndis_response { QTAILQ_ENTRY(rndis_response) entries; uint32_t length; - uint8_t buf[0]; + uint8_t buf[]; }; typedef struct USBNetState { diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c index 02693a26ad..ef72738ced 100644 --- a/hw/usb/dev-smartcard-reader.c +++ b/hw/usb/dev-smartcard-reader.c @@ -227,7 +227,7 @@ typedef struct QEMU_PACKED CCID_Parameter { typedef struct QEMU_PACKED CCID_DataBlock { CCID_BULK_IN b; uint8_t bChainParameter; - uint8_t abData[0]; + uint8_t abData[]; } CCID_DataBlock; /* 6.1.4 PC_to_RDR_XfrBlock */ @@ -235,7 +235,7 @@ typedef struct QEMU_PACKED CCID_XferBlock { CCID_Header hdr; uint8_t bBWI; /* Block Waiting Timeout */ uint16_t wLevelParameter; /* XXX currently unused */ - uint8_t abData[0]; + uint8_t abData[]; } CCID_XferBlock; typedef struct QEMU_PACKED CCID_IccPowerOn { diff --git a/hw/usb/quirks.c b/hw/usb/quirks.c index 38a9c5634a..23ea7a23ea 100644 --- a/hw/usb/quirks.c +++ b/hw/usb/quirks.c @@ -22,10 +22,10 @@ static bool usb_id_match(const struct usb_device_id *ids, uint8_t interface_protocol) { int i; - for (i = 0; ids[i].vendor_id != -1; i++) { + for (i = 0; ids[i].terminating_entry == 0; i++) { if (ids[i].vendor_id == vendor_id && ids[i].product_id == product_id && - (ids[i].interface_class == -1 || + (ids[i].interface_protocol_used == 0 || (ids[i].interface_class == interface_class && ids[i].interface_subclass == interface_subclass && ids[i].interface_protocol == interface_protocol))) { diff --git a/hw/usb/quirks.h b/hw/usb/quirks.h index 89480befd7..50ef2f9c2e 100644 --- a/hw/usb/quirks.h +++ b/hw/usb/quirks.h @@ -21,19 +21,23 @@ #include "quirks-pl2303-ids.h" struct usb_device_id { - int vendor_id; - int product_id; - int interface_class; - int interface_subclass; - int interface_protocol; + uint16_t vendor_id; + uint16_t product_id; + uint8_t interface_class; + uint8_t interface_subclass; + uint8_t interface_protocol; + uint8_t interface_protocol_used:1, + terminating_entry:1, + reserved:6; }; #define USB_DEVICE(vendor, product) \ - .vendor_id = vendor, .product_id = product, .interface_class = -1, + .vendor_id = vendor, .product_id = product, .interface_protocol_used = 0, #define USB_DEVICE_AND_INTERFACE_INFO(vend, prod, iclass, isubclass, iproto) \ .vendor_id = vend, .product_id = prod, .interface_class = iclass, \ - .interface_subclass = isubclass, .interface_protocol = iproto + .interface_subclass = isubclass, .interface_protocol = iproto, \ + .interface_protocol_used = 1 static const struct usb_device_id usbredir_raw_serial_ids[] = { /* @@ -206,7 +210,7 @@ static const struct usb_device_id usbredir_raw_serial_ids[] = { { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, - { USB_DEVICE(-1, -1) } /* Terminating Entry */ + { .terminating_entry = 1 } /* Terminating Entry */ }; static const struct usb_device_id usbredir_ftdi_serial_ids[] = { @@ -906,7 +910,7 @@ static const struct usb_device_id usbredir_ftdi_serial_ids[] = { { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID) }, { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) }, - { USB_DEVICE(-1, -1) } /* Terminating Entry */ + { .terminating_entry = 1 } /* Terminating Entry */ }; #undef USB_DEVICE diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index b2d415e5dd..b6c8ef5bc0 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -54,7 +54,7 @@ typedef struct VRingAvail { uint16_t flags; uint16_t idx; - uint16_t ring[0]; + uint16_t ring[]; } VRingAvail; typedef struct VRingUsedElem @@ -67,7 +67,7 @@ typedef struct VRingUsed { uint16_t flags; uint16_t idx; - VRingUsedElem ring[0]; + VRingUsedElem ring[]; } VRingUsed; typedef struct VRingMemoryRegionCaches { diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h index 9167bbaf6d..179775db7b 100644 --- a/hw/xen/xen_pt.h +++ b/hw/xen/xen_pt.h @@ -203,7 +203,7 @@ typedef struct XenPTMSIX { uint64_t mmio_base_addr; MemoryRegion mmio; void *phys_iomem_base; - XenPTMSIXEntry msix_entry[0]; + XenPTMSIXEntry msix_entry[]; } XenPTMSIX; struct XenPCIPassthroughState { diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index 57a3f58b0c..c13327fa78 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -152,7 +152,7 @@ typedef struct AcpiSerialPortConsoleRedirection */ struct AcpiRsdtDescriptorRev1 { ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - uint32_t table_offset_entry[0]; /* Array of pointers to other */ + uint32_t table_offset_entry[]; /* Array of pointers to other */ /* ACPI tables */ } QEMU_PACKED; typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1; @@ -162,7 +162,7 @@ typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1; */ struct AcpiXsdtDescriptorRev2 { ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - uint64_t table_offset_entry[0]; /* Array of pointers to other */ + uint64_t table_offset_entry[]; /* Array of pointers to other */ /* ACPI tables */ } QEMU_PACKED; typedef struct AcpiXsdtDescriptorRev2 AcpiXsdtDescriptorRev2; @@ -518,7 +518,7 @@ struct AcpiDmarDeviceScope { struct { uint8_t device; uint8_t function; - } path[0]; + } path[]; } QEMU_PACKED; typedef struct AcpiDmarDeviceScope AcpiDmarDeviceScope; @@ -530,7 +530,7 @@ struct AcpiDmarHardwareUnit { uint8_t reserved; uint16_t pci_segment; /* The PCI Segment associated with this unit */ uint64_t address; /* Base address of remapping hardware register-set */ - AcpiDmarDeviceScope scope[0]; + AcpiDmarDeviceScope scope[]; } QEMU_PACKED; typedef struct AcpiDmarHardwareUnit AcpiDmarHardwareUnit; @@ -541,7 +541,7 @@ struct AcpiDmarRootPortATS { uint8_t flags; uint8_t reserved; uint16_t pci_segment; - AcpiDmarDeviceScope scope[0]; + AcpiDmarDeviceScope scope[]; } QEMU_PACKED; typedef struct AcpiDmarRootPortATS AcpiDmarRootPortATS; @@ -604,7 +604,7 @@ typedef struct AcpiIortMemoryAccess AcpiIortMemoryAccess; struct AcpiIortItsGroup { ACPI_IORT_NODE_HEADER_DEF uint32_t its_count; - uint32_t identifiers[0]; + uint32_t identifiers[]; } QEMU_PACKED; typedef struct AcpiIortItsGroup AcpiIortItsGroup; @@ -621,7 +621,7 @@ struct AcpiIortSmmu3 { uint32_t pri_gsiv; uint32_t gerr_gsiv; uint32_t sync_gsiv; - AcpiIortIdMapping id_mapping_array[0]; + AcpiIortIdMapping id_mapping_array[]; } QEMU_PACKED; typedef struct AcpiIortSmmu3 AcpiIortSmmu3; @@ -630,7 +630,7 @@ struct AcpiIortRC { AcpiIortMemoryAccess memory_properties; uint32_t ats_attribute; uint32_t pci_segment_number; - AcpiIortIdMapping id_mapping_array[0]; + AcpiIortIdMapping id_mapping_array[]; } QEMU_PACKED; typedef struct AcpiIortRC AcpiIortRC; diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 1f37844e5c..ca4a4b1ad1 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -85,7 +85,7 @@ typedef struct SMMUDevice { typedef struct SMMUPciBus { PCIBus *bus; - SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */ + SMMUDevice *pbdev[]; /* Parent array is sparse, so dynamically alloc */ } SMMUPciBus; typedef struct SMMUIOTLBKey { diff --git a/include/hw/boards.h b/include/hw/boards.h index 9bc42dfb22..c96120d15f 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -71,7 +71,7 @@ typedef struct CPUArchId { */ typedef struct { int len; - CPUArchId cpus[0]; + CPUArchId cpus[]; } CPUArchIdList; /** diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index a1c4afcda5..3870052f5f 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -114,7 +114,8 @@ struct VTDAddressSpace { struct VTDBus { PCIBus* bus; /* A reference to the bus to provide translation for */ - VTDAddressSpace *dev_as[0]; /* A table of VTDAddressSpace objects indexed by devfn */ + /* A table of VTDAddressSpace objects indexed by devfn */ + VTDAddressSpace *dev_as[]; }; struct VTDIOTLBEntry { diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index bdc32a3c09..700a610f33 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -122,7 +122,7 @@ typedef struct MDBO { typedef struct MDB { MdbHeader header; - MDBO mdbo[0]; + MDBO mdbo[]; } QEMU_PACKED MDB; typedef struct SclpMsg { diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h index c54413b78c..cd7b24359f 100644 --- a/include/hw/s390x/sclp.h +++ b/include/hw/s390x/sclp.h @@ -132,7 +132,7 @@ typedef struct ReadInfo { uint16_t highest_cpu; uint8_t _reserved5[124 - 122]; /* 122-123 */ uint32_t hmfai; - struct CPUEntry entries[0]; + struct CPUEntry entries[]; } QEMU_PACKED ReadInfo; typedef struct ReadCpuInfo { @@ -142,7 +142,7 @@ typedef struct ReadCpuInfo { uint16_t nr_standby; /* 12-13 */ uint16_t offset_standby; /* 14-15 */ uint8_t reserved0[24-16]; /* 16-23 */ - struct CPUEntry entries[0]; + struct CPUEntry entries[]; } QEMU_PACKED ReadCpuInfo; typedef struct ReadStorageElementInfo { @@ -151,7 +151,7 @@ typedef struct ReadStorageElementInfo { uint16_t assigned; uint16_t standby; uint8_t _reserved0[16 - 14]; /* 14-15 */ - uint32_t entries[0]; + uint32_t entries[]; } QEMU_PACKED ReadStorageElementInfo; typedef struct AttachStorageElement { @@ -159,7 +159,7 @@ typedef struct AttachStorageElement { uint8_t _reserved0[10 - 8]; /* 8-9 */ uint16_t assigned; uint8_t _reserved1[16 - 12]; /* 12-15 */ - uint32_t entries[0]; + uint32_t entries[]; } QEMU_PACKED AttachStorageElement; typedef struct AssignStorage { diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h index 6f67f1020a..e653004d7c 100644 --- a/include/hw/virtio/virtio-iommu.h +++ b/include/hw/virtio/virtio-iommu.h @@ -41,7 +41,7 @@ typedef struct IOMMUDevice { typedef struct IOMMUPciBus { PCIBus *bus; - IOMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */ + IOMMUDevice *pbdev[]; /* Parent array is sparse, so dynamically alloc */ } IOMMUPciBus; typedef struct VirtIOIOMMU { diff --git a/include/qemu/cpuid.h b/include/qemu/cpuid.h index 69301700bd..09fc245b91 100644 --- a/include/qemu/cpuid.h +++ b/include/qemu/cpuid.h @@ -45,6 +45,9 @@ #ifndef bit_AVX2 #define bit_AVX2 (1 << 5) #endif +#ifndef bit_AVX512F +#define bit_AVX512F (1 << 16) +#endif #ifndef bit_BMI2 #define bit_BMI2 (1 << 8) #endif diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h index 84ea794bcf..1aeb2cb1a6 100644 --- a/include/qemu/lockable.h +++ b/include/qemu/lockable.h @@ -50,6 +50,7 @@ qemu_make_lockable(void *x, QemuLockable *lockable) #define QEMU_LOCK_FUNC(x) ((QemuLockUnlockFunc *) \ QEMU_GENERIC(x, \ (QemuMutex *, qemu_mutex_lock), \ + (QemuRecMutex *, qemu_rec_mutex_lock), \ (CoMutex *, qemu_co_mutex_lock), \ (QemuSpin *, qemu_spin_lock), \ unknown_lock_type)) @@ -57,6 +58,7 @@ qemu_make_lockable(void *x, QemuLockable *lockable) #define QEMU_UNLOCK_FUNC(x) ((QemuLockUnlockFunc *) \ QEMU_GENERIC(x, \ (QemuMutex *, qemu_mutex_unlock), \ + (QemuRecMutex *, qemu_rec_mutex_unlock), \ (CoMutex *, qemu_co_mutex_unlock), \ (QemuSpin *, qemu_spin_unlock), \ unknown_lock_type)) @@ -65,7 +67,7 @@ qemu_make_lockable(void *x, QemuLockable *lockable) * In C++ it would be different, but then C++ wouldn't need QemuLockable * either... */ -#define QEMU_MAKE_LOCKABLE_(x) qemu_make_lockable((x), &(QemuLockable) { \ +#define QEMU_MAKE_LOCKABLE_(x) (&(QemuLockable) { \ .object = (x), \ .lock = QEMU_LOCK_FUNC(x), \ .unlock = QEMU_UNLOCK_FUNC(x), \ @@ -73,14 +75,27 @@ qemu_make_lockable(void *x, QemuLockable *lockable) /* QEMU_MAKE_LOCKABLE - Make a polymorphic QemuLockable * - * @x: a lock object (currently one of QemuMutex, CoMutex, QemuSpin). + * @x: a lock object (currently one of QemuMutex, QemuRecMutex, CoMutex, QemuSpin). * * Returns a QemuLockable object that can be passed around - * to a function that can operate with locks of any kind. + * to a function that can operate with locks of any kind, or + * NULL if @x is %NULL. */ #define QEMU_MAKE_LOCKABLE(x) \ QEMU_GENERIC(x, \ (QemuLockable *, (x)), \ + qemu_make_lockable((x), QEMU_MAKE_LOCKABLE_(x))) + +/* QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable + * + * @x: a lock object (currently one of QemuMutex, QemuRecMutex, CoMutex, QemuSpin). + * + * Returns a QemuLockable object that can be passed around + * to a function that can operate with locks of any kind. + */ +#define QEMU_MAKE_LOCKABLE_NONNULL(x) \ + QEMU_GENERIC(x, \ + (QemuLockable *, (x)), \ QEMU_MAKE_LOCKABLE_(x)) static inline void qemu_lockable_lock(QemuLockable *x) @@ -93,4 +108,69 @@ static inline void qemu_lockable_unlock(QemuLockable *x) x->unlock(x->object); } +static inline QemuLockable *qemu_lockable_auto_lock(QemuLockable *x) +{ + qemu_lockable_lock(x); + return x; +} + +static inline void qemu_lockable_auto_unlock(QemuLockable *x) +{ + if (x) { + qemu_lockable_unlock(x); + } +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuLockable, qemu_lockable_auto_unlock) + +#define WITH_QEMU_LOCK_GUARD_(x, var) \ + for (g_autoptr(QemuLockable) var = \ + qemu_lockable_auto_lock(QEMU_MAKE_LOCKABLE_NONNULL((x))); \ + var; \ + qemu_lockable_auto_unlock(var), var = NULL) + +/** + * WITH_QEMU_LOCK_GUARD - Lock a lock object for scope + * + * @x: a lock object (currently one of QemuMutex, CoMutex, QemuSpin). + * + * This macro defines a lock scope such that entering the scope takes the lock + * and leaving the scope releases the lock. Return statements are allowed + * within the scope and release the lock. Break and continue statements leave + * the scope early and release the lock. + * + * WITH_QEMU_LOCK_GUARD(&mutex) { + * ... + * if (error) { + * return; <-- mutex is automatically unlocked + * } + * + * if (early_exit) { + * break; <-- leave this scope early + * } + * ... + * } + */ +#define WITH_QEMU_LOCK_GUARD(x) \ + WITH_QEMU_LOCK_GUARD_((x), qemu_lockable_auto##__COUNTER__) + +/** + * QEMU_LOCK_GUARD - Lock an object until the end of the scope + * + * @x: a lock object (currently one of QemuMutex, CoMutex, QemuSpin). + * + * This macro takes a lock until the end of the scope. Return statements + * release the lock. + * + * ... <-- mutex not locked + * QEMU_LOCK_GUARD(&mutex); <-- mutex locked from here onwards + * ... + * if (error) { + * return; <-- mutex is automatically unlocked + * } + */ +#define QEMU_LOCK_GUARD(x) \ + g_autoptr(QemuLockable) qemu_lockable_auto##__COUNTER__ = \ + qemu_lockable_auto_lock(QEMU_MAKE_LOCKABLE((x))) + #endif diff --git a/include/qom/object.h b/include/qom/object.h index 29546496c1..784c97c0e1 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1664,69 +1664,101 @@ ObjectProperty *object_class_property_add_tm(ObjectClass *klass, void (*get)(Object *, struct tm *, Error **), Error **errp); +typedef enum { + /* Automatically add a getter to the property */ + OBJ_PROP_FLAG_READ = 1 << 0, + /* Automatically add a setter to the property */ + OBJ_PROP_FLAG_WRITE = 1 << 1, + /* Automatically add a getter and a setter to the property */ + OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE), +} ObjectPropertyFlags; + /** * object_property_add_uint8_ptr: * @obj: the object to add a property to * @name: the name of the property * @v: pointer to value + * @flags: bitwise-or'd ObjectPropertyFlags * @errp: if an error occurs, a pointer to an area to store the error * * Add an integer property in memory. This function will add a * property of type 'uint8'. */ void object_property_add_uint8_ptr(Object *obj, const char *name, - const uint8_t *v, Error **errp); + const uint8_t *v, ObjectPropertyFlags flags, + Error **errp); + ObjectProperty *object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name, - const uint8_t *v, Error **errp); + const uint8_t *v, + ObjectPropertyFlags flags, + Error **errp); /** * object_property_add_uint16_ptr: * @obj: the object to add a property to * @name: the name of the property * @v: pointer to value + * @flags: bitwise-or'd ObjectPropertyFlags * @errp: if an error occurs, a pointer to an area to store the error * * Add an integer property in memory. This function will add a * property of type 'uint16'. */ void object_property_add_uint16_ptr(Object *obj, const char *name, - const uint16_t *v, Error **errp); + const uint16_t *v, + ObjectPropertyFlags flags, + Error **errp); + ObjectProperty *object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name, - const uint16_t *v, Error **errp); + const uint16_t *v, + ObjectPropertyFlags flags, + Error **errp); /** * object_property_add_uint32_ptr: * @obj: the object to add a property to * @name: the name of the property * @v: pointer to value + * @flags: bitwise-or'd ObjectPropertyFlags * @errp: if an error occurs, a pointer to an area to store the error * * Add an integer property in memory. This function will add a * property of type 'uint32'. */ void object_property_add_uint32_ptr(Object *obj, const char *name, - const uint32_t *v, Error **errp); + const uint32_t *v, + ObjectPropertyFlags flags, + Error **errp); + ObjectProperty *object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name, - const uint32_t *v, Error **errp); + const uint32_t *v, + ObjectPropertyFlags flags, + Error **errp); /** * object_property_add_uint64_ptr: * @obj: the object to add a property to * @name: the name of the property * @v: pointer to value + * @flags: bitwise-or'd ObjectPropertyFlags * @errp: if an error occurs, a pointer to an area to store the error * * Add an integer property in memory. This function will add a * property of type 'uint64'. */ void object_property_add_uint64_ptr(Object *obj, const char *name, - const uint64_t *v, Error **errp); + const uint64_t *v, + ObjectPropertyFlags flags, + Error **Errp); + ObjectProperty *object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name, - const uint64_t *v, Error **errp); + const uint64_t *v, + ObjectPropertyFlags flags, + Error **Errp); /** * object_property_add_alias: diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h index a9afb7e5b5..35eab06d0e 100644 --- a/include/sysemu/cryptodev.h +++ b/include/sysemu/cryptodev.h @@ -143,7 +143,7 @@ typedef struct CryptoDevBackendSymOpInfo { uint8_t *dst; uint8_t *aad_data; uint8_t *digest_result; - uint8_t data[0]; + uint8_t data[]; } CryptoDevBackendSymOpInfo; typedef struct CryptoDevBackendClass { diff --git a/include/sysemu/whpx.h b/include/sysemu/whpx.h index 4794e8effe..a84b49e749 100644 --- a/include/sysemu/whpx.h +++ b/include/sysemu/whpx.h @@ -35,4 +35,11 @@ int whpx_enabled(void); #endif /* CONFIG_WHPX */ +/* state subset only touched by the VCPU itself during runtime */ +#define WHPX_SET_RUNTIME_STATE 1 +/* state subset modified during VCPU reset */ +#define WHPX_SET_RESET_STATE 2 +/* full state set, modified during initialization or on vmload */ +#define WHPX_SET_FULL_STATE 3 + #endif /* QEMU_WHPX_H */ diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index 54e5446880..c48bd76b0a 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -267,7 +267,7 @@ struct TCGLabel { typedef struct TCGPool { struct TCGPool *next; int size; - uint8_t data[0] __attribute__ ((aligned)); + uint8_t data[] __attribute__ ((aligned)); } TCGPool; #define TCG_POOL_CHUNK_SIZE 32768 @@ -1170,15 +1170,6 @@ void memory_region_init(MemoryRegion *mr, memory_region_do_init(mr, owner, name, size); } -static void memory_region_get_addr(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - MemoryRegion *mr = MEMORY_REGION(obj); - uint64_t value = mr->addr; - - visit_type_uint64(v, name, &value, errp); -} - static void memory_region_get_container(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) @@ -1242,10 +1233,8 @@ static void memory_region_initfn(Object *obj) NULL, NULL, &error_abort); op->resolve = memory_region_resolve_container; - object_property_add(OBJECT(mr), "addr", "uint64", - memory_region_get_addr, - NULL, /* memory_region_set_addr */ - NULL, NULL, &error_abort); + object_property_add_uint64_ptr(OBJECT(mr), "addr", + &mr->addr, OBJ_PROP_FLAG_READ, &error_abort); object_property_add(OBJECT(mr), "priority", "uint32", memory_region_get_priority, NULL, /* memory_region_set_priority */ @@ -1671,19 +1660,8 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr, uint64_t size, Error **errp) { - Error *err = NULL; - memory_region_init(mr, owner, name, size); - mr->ram = true; + memory_region_init_ram_shared_nomigrate(mr, owner, name, size, false, errp); mr->readonly = true; - mr->terminates = true; - mr->destructor = memory_region_destructor_ram; - mr->ram_block = qemu_ram_alloc(size, false, mr, &err); - mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; - if (err) { - mr->size = int128_zero(); - object_unparent(OBJECT(mr)); - error_propagate(errp, err); - } } void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, @@ -2830,6 +2808,9 @@ void address_space_destroy(AddressSpace *as) static const char *memory_region_type(MemoryRegion *mr) { + if (mr->alias) { + return memory_region_type(mr->alias); + } if (memory_region_is_ram_device(mr)) { return "ramd"; } else if (memory_region_is_romd(mr)) { diff --git a/net/queue.c b/net/queue.c index 61276ca4be..0164727e39 100644 --- a/net/queue.c +++ b/net/queue.c @@ -46,7 +46,7 @@ struct NetPacket { unsigned flags; int size; NetPacketSent *sent_cb; - uint8_t data[0]; + uint8_t data[]; }; struct NetQueue { diff --git a/pc-bios/optionrom/pvh_main.c b/pc-bios/optionrom/pvh_main.c index a015e1bf22..28e79d7fc4 100644 --- a/pc-bios/optionrom/pvh_main.c +++ b/pc-bios/optionrom/pvh_main.c @@ -29,7 +29,7 @@ asm (".code32"); /* this code will be executed in protected mode */ #define RSDP_SIGNATURE 0x2052545020445352LL /* "RSD PTR " */ #define RSDP_AREA_ADDR 0x000E0000 -#define RSDP_AREA_SIZE 2048 +#define RSDP_AREA_SIZE 0x00020000 #define EBDA_BASE_ADDR 0x0000040E #define EBDA_SIZE 1024 diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 94f53a5f1e..12a0166aae 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -136,7 +136,7 @@ typedef struct BootMapScriptHeader { typedef struct BootMapScript { BootMapScriptHeader header; - BootMapScriptEntry entry[0]; + BootMapScriptEntry entry[]; } __attribute__ ((packed)) BootMapScript; /* diff --git a/pc-bios/s390-ccw/sclp.h b/pc-bios/s390-ccw/sclp.h index 8450161ba7..64b53cad29 100644 --- a/pc-bios/s390-ccw/sclp.h +++ b/pc-bios/s390-ccw/sclp.h @@ -95,7 +95,7 @@ typedef struct EventBufferHeader { typedef struct WriteEventData { SCCBHeader h; EventBufferHeader ebh; - char data[0]; + char data[]; } __attribute__((packed)) WriteEventData; typedef struct ReadEventData { diff --git a/plugins/core.c b/plugins/core.c index ed863011ba..51bfc94787 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -15,6 +15,7 @@ #include "qemu/error-report.h" #include "qemu/config-file.h" #include "qapi/error.h" +#include "qemu/lockable.h" #include "qemu/option.h" #include "qemu/rcu_queue.h" #include "qemu/xxhash.h" @@ -150,11 +151,11 @@ do_plugin_register_cb(qemu_plugin_id_t id, enum qemu_plugin_event ev, { struct qemu_plugin_ctx *ctx; - qemu_rec_mutex_lock(&plugin.lock); + QEMU_LOCK_GUARD(&plugin.lock); ctx = plugin_id_to_ctx_locked(id); /* if the plugin is on its way out, ignore this request */ if (unlikely(ctx->uninstalling)) { - goto out_unlock; + return; } if (func) { struct qemu_plugin_cb *cb = ctx->callbacks[ev]; @@ -178,8 +179,6 @@ do_plugin_register_cb(qemu_plugin_id_t id, enum qemu_plugin_event ev, } else { plugin_unregister_cb__locked(ctx, ev); } - out_unlock: - qemu_rec_mutex_unlock(&plugin.lock); } void plugin_register_cb(qemu_plugin_id_t id, enum qemu_plugin_event ev, diff --git a/plugins/loader.c b/plugins/loader.c index 15fc7e5515..685d334e1a 100644 --- a/plugins/loader.c +++ b/plugins/loader.c @@ -19,6 +19,7 @@ #include "qemu/error-report.h" #include "qemu/config-file.h" #include "qapi/error.h" +#include "qemu/lockable.h" #include "qemu/option.h" #include "qemu/rcu_queue.h" #include "qemu/qht.h" @@ -367,15 +368,14 @@ void plugin_reset_uninstall(qemu_plugin_id_t id, struct qemu_plugin_reset_data *data; struct qemu_plugin_ctx *ctx; - qemu_rec_mutex_lock(&plugin.lock); - ctx = plugin_id_to_ctx_locked(id); - if (ctx->uninstalling || (reset && ctx->resetting)) { - qemu_rec_mutex_unlock(&plugin.lock); - return; + WITH_QEMU_LOCK_GUARD(&plugin.lock) { + ctx = plugin_id_to_ctx_locked(id); + if (ctx->uninstalling || (reset && ctx->resetting)) { + return; + } + ctx->resetting = reset; + ctx->uninstalling = !reset; } - ctx->resetting = reset; - ctx->uninstalling = !reset; - qemu_rec_mutex_unlock(&plugin.lock); data = g_new(struct qemu_plugin_reset_data, 1); data->ctx = ctx; diff --git a/qom/object.c b/qom/object.c index 555c8b9d07..1812f79224 100644 --- a/qom/object.c +++ b/qom/object.c @@ -2498,6 +2498,22 @@ static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name, visit_type_uint8(v, name, &value, errp); } +static void property_set_uint8_ptr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint8_t *field = opaque; + uint8_t value; + Error *local_err = NULL; + + visit_type_uint8(v, name, &value, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + *field = value; +} + static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -2505,6 +2521,22 @@ static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name, visit_type_uint16(v, name, &value, errp); } +static void property_set_uint16_ptr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint16_t *field = opaque; + uint16_t value; + Error *local_err = NULL; + + visit_type_uint16(v, name, &value, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + *field = value; +} + static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -2512,6 +2544,22 @@ static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name, visit_type_uint32(v, name, &value, errp); } +static void property_set_uint32_ptr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint32_t *field = opaque; + uint32_t value; + Error *local_err = NULL; + + visit_type_uint32(v, name, &value, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + *field = value; +} + static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -2519,68 +2567,184 @@ static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name, visit_type_uint64(v, name, &value, errp); } +static void property_set_uint64_ptr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint64_t *field = opaque; + uint64_t value; + Error *local_err = NULL; + + visit_type_uint64(v, name, &value, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + *field = value; +} + void object_property_add_uint8_ptr(Object *obj, const char *name, - const uint8_t *v, Error **errp) + const uint8_t *v, + ObjectPropertyFlags flags, + Error **errp) { - object_property_add(obj, name, "uint8", property_get_uint8_ptr, - NULL, NULL, (void *)v, errp); + ObjectPropertyAccessor *getter = NULL; + ObjectPropertyAccessor *setter = NULL; + + if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { + getter = property_get_uint8_ptr; + } + + if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { + setter = property_set_uint8_ptr; + } + + object_property_add(obj, name, "uint8", + getter, setter, NULL, (void *)v, errp); } ObjectProperty * object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name, - const uint8_t *v, Error **errp) + const uint8_t *v, + ObjectPropertyFlags flags, + Error **errp) { + ObjectPropertyAccessor *getter = NULL; + ObjectPropertyAccessor *setter = NULL; + + if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { + getter = property_get_uint8_ptr; + } + + if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { + setter = property_set_uint8_ptr; + } + return object_class_property_add(klass, name, "uint8", - property_get_uint8_ptr, - NULL, NULL, (void *)v, errp); + getter, setter, NULL, (void *)v, errp); } void object_property_add_uint16_ptr(Object *obj, const char *name, - const uint16_t *v, Error **errp) + const uint16_t *v, + ObjectPropertyFlags flags, + Error **errp) { - object_property_add(obj, name, "uint16", property_get_uint16_ptr, - NULL, NULL, (void *)v, errp); + ObjectPropertyAccessor *getter = NULL; + ObjectPropertyAccessor *setter = NULL; + + if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { + getter = property_get_uint16_ptr; + } + + if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { + setter = property_set_uint16_ptr; + } + + object_property_add(obj, name, "uint16", + getter, setter, NULL, (void *)v, errp); } ObjectProperty * object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name, - const uint16_t *v, Error **errp) + const uint16_t *v, + ObjectPropertyFlags flags, + Error **errp) { + ObjectPropertyAccessor *getter = NULL; + ObjectPropertyAccessor *setter = NULL; + + if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { + getter = property_get_uint16_ptr; + } + + if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { + setter = property_set_uint16_ptr; + } + return object_class_property_add(klass, name, "uint16", - property_get_uint16_ptr, - NULL, NULL, (void *)v, errp); + getter, setter, NULL, (void *)v, errp); } void object_property_add_uint32_ptr(Object *obj, const char *name, - const uint32_t *v, Error **errp) + const uint32_t *v, + ObjectPropertyFlags flags, + Error **errp) { - object_property_add(obj, name, "uint32", property_get_uint32_ptr, - NULL, NULL, (void *)v, errp); + ObjectPropertyAccessor *getter = NULL; + ObjectPropertyAccessor *setter = NULL; + + if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { + getter = property_get_uint32_ptr; + } + + if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { + setter = property_set_uint32_ptr; + } + + object_property_add(obj, name, "uint32", + getter, setter, NULL, (void *)v, errp); } ObjectProperty * object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name, - const uint32_t *v, Error **errp) + const uint32_t *v, + ObjectPropertyFlags flags, + Error **errp) { + ObjectPropertyAccessor *getter = NULL; + ObjectPropertyAccessor *setter = NULL; + + if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { + getter = property_get_uint32_ptr; + } + + if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { + setter = property_set_uint32_ptr; + } + return object_class_property_add(klass, name, "uint32", - property_get_uint32_ptr, - NULL, NULL, (void *)v, errp); + getter, setter, NULL, (void *)v, errp); } void object_property_add_uint64_ptr(Object *obj, const char *name, - const uint64_t *v, Error **errp) + const uint64_t *v, + ObjectPropertyFlags flags, + Error **errp) { - object_property_add(obj, name, "uint64", property_get_uint64_ptr, - NULL, NULL, (void *)v, errp); + ObjectPropertyAccessor *getter = NULL; + ObjectPropertyAccessor *setter = NULL; + + if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { + getter = property_get_uint64_ptr; + } + + if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { + setter = property_set_uint64_ptr; + } + + object_property_add(obj, name, "uint64", + getter, setter, NULL, (void *)v, errp); } ObjectProperty * object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name, - const uint64_t *v, Error **errp) + const uint64_t *v, + ObjectPropertyFlags flags, + Error **errp) { + ObjectPropertyAccessor *getter = NULL; + ObjectPropertyAccessor *setter = NULL; + + if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { + getter = property_get_uint64_ptr; + } + + if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { + setter = property_set_uint64_ptr; + } + return object_class_property_add(klass, name, "uint64", - property_get_uint64_ptr, - NULL, NULL, (void *)v, errp); + getter, setter, NULL, (void *)v, errp); } typedef struct { diff --git a/scripts/coccinelle/memory-region-housekeeping.cocci b/scripts/coccinelle/memory-region-housekeeping.cocci new file mode 100644 index 0000000000..c768d8140a --- /dev/null +++ b/scripts/coccinelle/memory-region-housekeeping.cocci @@ -0,0 +1,159 @@ +/* + Usage: + + spatch \ + --macro-file scripts/cocci-macro-file.h \ + --sp-file scripts/coccinelle/memory-region-housekeeping.cocci \ + --keep-comments \ + --in-place \ + --dir . + +*/ + + +// Replace memory_region_init_ram(readonly) by memory_region_init_rom() +@@ +expression E1, E2, E3, E4, E5; +symbol true; +@@ +( +- memory_region_init_ram(E1, E2, E3, E4, E5); ++ memory_region_init_rom(E1, E2, E3, E4, E5); + ... WHEN != E1 +- memory_region_set_readonly(E1, true); +| +- memory_region_init_ram_nomigrate(E1, E2, E3, E4, E5); ++ memory_region_init_rom_nomigrate(E1, E2, E3, E4, E5); + ... WHEN != E1 +- memory_region_set_readonly(E1, true); +) + + +@possible_memory_region_init_rom@ +expression E1, E2, E3, E4, E5; +position p; +@@ +( + memory_region_init_ram@p(E1, E2, E3, E4, E5); + ... + memory_region_set_readonly(E1, true); +| + memory_region_init_ram_nomigrate@p(E1, E2, E3, E4, E5); + ... + memory_region_set_readonly(E1, true); +) +@script:python@ +p << possible_memory_region_init_rom.p; +@@ +cocci.print_main("potential use of memory_region_init_rom*() in ", p) + + +// Do not call memory_region_set_readonly() on ROM alias +@@ +expression ROM, E1, E2, E3, E4; +expression ALIAS, E5, E6, E7, E8; +@@ +( + memory_region_init_rom(ROM, E1, E2, E3, E4); +| + memory_region_init_rom_nomigrate(ROM, E1, E2, E3, E4); +) + ... + memory_region_init_alias(ALIAS, E5, E6, ROM, E7, E8); +- memory_region_set_readonly(ALIAS, true); + + +// Replace by-hand memory_region_init_ram_nomigrate/vmstate_register_ram +// code sequences with use of the new memory_region_init_ram function. +// Similarly for the _rom and _rom_device functions. +// We don't try to replace sequences with a non-NULL owner, because +// there are none in the tree that can be automatically converted +// (and only a handful that can be manually converted). +@@ +expression MR; +expression NAME; +expression SIZE; +expression ERRP; +@@ +-memory_region_init_ram_nomigrate(MR, NULL, NAME, SIZE, ERRP); ++memory_region_init_ram(MR, NULL, NAME, SIZE, ERRP); + ... +-vmstate_register_ram_global(MR); +@@ +expression MR; +expression NAME; +expression SIZE; +expression ERRP; +@@ +-memory_region_init_rom_nomigrate(MR, NULL, NAME, SIZE, ERRP); ++memory_region_init_rom(MR, NULL, NAME, SIZE, ERRP); + ... +-vmstate_register_ram_global(MR); +@@ +expression MR; +expression OPS; +expression OPAQUE; +expression NAME; +expression SIZE; +expression ERRP; +@@ +-memory_region_init_rom_device_nomigrate(MR, NULL, OPS, OPAQUE, NAME, SIZE, ERRP); ++memory_region_init_rom_device(MR, NULL, OPS, OPAQUE, NAME, SIZE, ERRP); + ... +-vmstate_register_ram_global(MR); + + +// Device is owner +@@ +typedef DeviceState; +identifier device_fn, dev, obj; +expression E1, E2, E3, E4, E5; +@@ +static void device_fn(DeviceState *dev, ...) +{ + ... + Object *obj = OBJECT(dev); + <+... +( +- memory_region_init(E1, NULL, E2, E3); ++ memory_region_init(E1, obj, E2, E3); +| +- memory_region_init_io(E1, NULL, E2, E3, E4, E5); ++ memory_region_init_io(E1, obj, E2, E3, E4, E5); +| +- memory_region_init_alias(E1, NULL, E2, E3, E4, E5); ++ memory_region_init_alias(E1, obj, E2, E3, E4, E5); +| +- memory_region_init_rom(E1, NULL, E2, E3, E4); ++ memory_region_init_rom(E1, obj, E2, E3, E4); +| +- memory_region_init_ram_shared_nomigrate(E1, NULL, E2, E3, E4, E5); ++ memory_region_init_ram_shared_nomigrate(E1, obj, E2, E3, E4, E5); +) + ...+> +} +@@ +identifier device_fn, dev; +expression E1, E2, E3, E4, E5; +@@ +static void device_fn(DeviceState *dev, ...) +{ + <+... +( +- memory_region_init(E1, NULL, E2, E3); ++ memory_region_init(E1, OBJECT(dev), E2, E3); +| +- memory_region_init_io(E1, NULL, E2, E3, E4, E5); ++ memory_region_init_io(E1, OBJECT(dev), E2, E3, E4, E5); +| +- memory_region_init_alias(E1, NULL, E2, E3, E4, E5); ++ memory_region_init_alias(E1, OBJECT(dev), E2, E3, E4, E5); +| +- memory_region_init_rom(E1, NULL, E2, E3, E4); ++ memory_region_init_rom(E1, OBJECT(dev), E2, E3, E4); +| +- memory_region_init_ram_shared_nomigrate(E1, NULL, E2, E3, E4, E5); ++ memory_region_init_ram_shared_nomigrate(E1, OBJECT(dev), E2, E3, E4, E5); +) + ...+> +} diff --git a/scripts/coccinelle/memory-region-init-ram.cocci b/scripts/coccinelle/memory-region-init-ram.cocci deleted file mode 100644 index d290150872..0000000000 --- a/scripts/coccinelle/memory-region-init-ram.cocci +++ /dev/null @@ -1,38 +0,0 @@ -// Replace by-hand memory_region_init_ram_nomigrate/vmstate_register_ram -// code sequences with use of the new memory_region_init_ram function. -// Similarly for the _rom and _rom_device functions. -// We don't try to replace sequences with a non-NULL owner, because -// there are none in the tree that can be automatically converted -// (and only a handful that can be manually converted). -@@ -expression MR; -expression NAME; -expression SIZE; -expression ERRP; -@@ --memory_region_init_ram_nomigrate(MR, NULL, NAME, SIZE, ERRP); -+memory_region_init_ram(MR, NULL, NAME, SIZE, ERRP); - ... --vmstate_register_ram_global(MR); -@@ -expression MR; -expression NAME; -expression SIZE; -expression ERRP; -@@ --memory_region_init_rom_nomigrate(MR, NULL, NAME, SIZE, ERRP); -+memory_region_init_rom(MR, NULL, NAME, SIZE, ERRP); - ... --vmstate_register_ram_global(MR); -@@ -expression MR; -expression OPS; -expression OPAQUE; -expression NAME; -expression SIZE; -expression ERRP; -@@ --memory_region_init_rom_device_nomigrate(MR, NULL, OPS, OPAQUE, NAME, SIZE, ERRP); -+memory_region_init_rom_device(MR, NULL, OPS, OPAQUE, NAME, SIZE, ERRP); - ... --vmstate_register_ram_global(MR); diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c index 0659ceef09..181ed4a186 100644 --- a/scsi/qemu-pr-helper.c +++ b/scsi/qemu-pr-helper.c @@ -421,10 +421,13 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense, int rq_servact = cdb[1]; int rq_scope = cdb[2] >> 4; int rq_type = cdb[2] & 0xf; - struct prout_param_descriptor paramp; + g_autofree struct prout_param_descriptor *paramp = NULL; char transportids[PR_HELPER_DATA_SIZE]; int r; + paramp = g_malloc0(sizeof(struct prout_param_descriptor) + + sizeof(struct transportid *) * MPATH_MX_TIDS); + if (sz < PR_OUT_FIXED_PARAM_SIZE) { /* Illegal request, Parameter list length error. This isn't fatal; * we have read the data, send an error without closing the socket. @@ -454,10 +457,9 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense, * used by libmpathpersist (which, of course, will immediately * do the opposite). */ - memset(¶mp, 0, sizeof(paramp)); - memcpy(¶mp.key, ¶m[0], 8); - memcpy(¶mp.sa_key, ¶m[8], 8); - paramp.sa_flags = param[20]; + memcpy(¶mp->key, ¶m[0], 8); + memcpy(¶mp->sa_key, ¶m[8], 8); + paramp->sa_flags = param[20]; if (sz > PR_OUT_FIXED_PARAM_SIZE) { size_t transportid_len; int i, j; @@ -520,12 +522,13 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense, return CHECK_CONDITION; } - paramp.trnptid_list[paramp.num_transportid++] = id; + assert(paramp->num_transportid < MPATH_MX_TIDS); + paramp->trnptid_list[paramp->num_transportid++] = id; } } r = mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type, - ¶mp, noisy, verbose); + paramp, noisy, verbose); return mpath_reconstruct_sense(fd, r, sense); } #endif diff --git a/softmmu/vl.c b/softmmu/vl.c index ff2685dff8..6a285925b3 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -3789,6 +3789,22 @@ void qemu_init(int argc, char **argv, char **envp) */ loc_set_none(); + /* + * Check for -cpu help and -device help before we call select_machine(), + * which will return an error if the architecture has no default machine + * type and the user did not specify one, so that the user doesn't need + * to say '-cpu help -machine something'. + */ + if (cpu_option && is_help_option(cpu_option)) { + list_cpus(cpu_option); + exit(0); + } + + if (qemu_opts_foreach(qemu_find_opts("device"), + device_help_func, NULL, NULL)) { + exit(0); + } + user_register_global_props(); replay_configure(icount_opts); @@ -3877,11 +3893,6 @@ void qemu_init(int argc, char **argv, char **envp) qemu_set_hw_version(machine_class->hw_version); } - if (cpu_option && is_help_option(cpu_option)) { - list_cpus(cpu_option); - exit(0); - } - if (!trace_init_backends()) { exit(1); } @@ -4112,11 +4123,6 @@ void qemu_init(int argc, char **argv, char **envp) fsdev_init_func, NULL, &error_fatal); #endif - if (qemu_opts_foreach(qemu_find_opts("device"), - device_help_func, NULL, NULL)) { - exit(0); - } - /* * Note: we need to create block backends before * machine_set_property(), so machine properties can refer to diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3623ecefbd..7fe367078c 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1153,22 +1153,6 @@ static void arm_set_pmu(Object *obj, bool value, Error **errp) cpu->has_pmu = value; } -static void arm_get_init_svtor(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ARMCPU *cpu = ARM_CPU(obj); - - visit_type_uint32(v, name, &cpu->init_svtor, errp); -} - -static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - ARMCPU *cpu = ARM_CPU(obj); - - visit_type_uint32(v, name, &cpu->init_svtor, errp); -} - unsigned int gt_cntfrq_period_ns(ARMCPU *cpu) { /* @@ -1288,9 +1272,9 @@ void arm_cpu_post_init(Object *obj) * a simple DEFINE_PROP_UINT32 for this because we want to permit * the property to be set after realize. */ - object_property_add(obj, "init-svtor", "uint32", - arm_get_init_svtor, arm_set_init_svtor, - NULL, NULL, &error_abort); + object_property_add_uint32_ptr(obj, "init-svtor", + &cpu->init_svtor, + OBJ_PROP_FLAG_READWRITE, &error_abort); } qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property); diff --git a/target/i386/hax-posix.c b/target/i386/hax-posix.c index a5426a6dac..3bad89f133 100644 --- a/target/i386/hax-posix.c +++ b/target/i386/hax-posix.c @@ -108,41 +108,12 @@ int hax_mod_version(struct hax_state *hax, struct hax_module_version *version) static char *hax_vm_devfs_string(int vm_id) { - char *name; - - if (vm_id > MAX_VM_ID) { - fprintf(stderr, "Too big VM id\n"); - return NULL; - } - -#define HAX_VM_DEVFS "/dev/hax_vm/vmxx" - name = g_strdup(HAX_VM_DEVFS); - if (!name) { - return NULL; - } - - snprintf(name, sizeof HAX_VM_DEVFS, "/dev/hax_vm/vm%02d", vm_id); - return name; + return g_strdup_printf("/dev/hax_vm/vm%02d", vm_id); } static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id) { - char *name; - - if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) { - fprintf(stderr, "Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id); - return NULL; - } - -#define HAX_VCPU_DEVFS "/dev/hax_vmxx/vcpuxx" - name = g_strdup(HAX_VCPU_DEVFS); - if (!name) { - return NULL; - } - - snprintf(name, sizeof HAX_VCPU_DEVFS, "/dev/hax_vm%02d/vcpu%02d", - vm_id, vcpu_id); - return name; + return g_strdup_printf("/dev/hax_vm%02d/vcpu%02d", vm_id, vcpu_id); } int hax_host_create_vm(struct hax_state *hax, int *vmid) diff --git a/target/i386/hax-windows.c b/target/i386/hax-windows.c index 5729ad9b48..0ba488c468 100644 --- a/target/i386/hax-windows.c +++ b/target/i386/hax-windows.c @@ -185,41 +185,12 @@ int hax_mod_version(struct hax_state *hax, struct hax_module_version *version) static char *hax_vm_devfs_string(int vm_id) { - char *name; - - if (vm_id > MAX_VM_ID) { - fprintf(stderr, "Too big VM id\n"); - return NULL; - } - -#define HAX_VM_DEVFS "\\\\.\\hax_vmxx" - name = g_strdup(HAX_VM_DEVFS); - if (!name) { - return NULL; - } - - snprintf(name, sizeof HAX_VM_DEVFS, "\\\\.\\hax_vm%02d", vm_id); - return name; + return g_strdup_printf("/dev/hax_vm/vm%02d", vm_id); } static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id) { - char *name; - - if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) { - fprintf(stderr, "Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id); - return NULL; - } - -#define HAX_VCPU_DEVFS "\\\\.\\hax_vmxx_vcpuxx" - name = g_strdup(HAX_VCPU_DEVFS); - if (!name) { - return NULL; - } - - snprintf(name, sizeof HAX_VCPU_DEVFS, "\\\\.\\hax_vm%02d_vcpu%02d", - vm_id, vcpu_id); - return name; + return g_strdup_printf("/dev/hax_vm%02d/vcpu%02d", vm_id, vcpu_id); } int hax_host_create_vm(struct hax_state *hax, int *vmid) diff --git a/target/i386/sev.c b/target/i386/sev.c index 024bb24e51..846018a12d 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -267,109 +267,21 @@ qsev_guest_class_init(ObjectClass *oc, void *data) } static void -qsev_guest_set_handle(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - uint32_t value; - - visit_type_uint32(v, name, &value, errp); - sev->handle = value; -} - -static void -qsev_guest_set_policy(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - uint32_t value; - - visit_type_uint32(v, name, &value, errp); - sev->policy = value; -} - -static void -qsev_guest_set_cbitpos(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - uint32_t value; - - visit_type_uint32(v, name, &value, errp); - sev->cbitpos = value; -} - -static void -qsev_guest_set_reduced_phys_bits(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - uint32_t value; - - visit_type_uint32(v, name, &value, errp); - sev->reduced_phys_bits = value; -} - -static void -qsev_guest_get_policy(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint32_t value; - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - - value = sev->policy; - visit_type_uint32(v, name, &value, errp); -} - -static void -qsev_guest_get_handle(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint32_t value; - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - - value = sev->handle; - visit_type_uint32(v, name, &value, errp); -} - -static void -qsev_guest_get_cbitpos(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint32_t value; - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - - value = sev->cbitpos; - visit_type_uint32(v, name, &value, errp); -} - -static void -qsev_guest_get_reduced_phys_bits(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - uint32_t value; - QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); - - value = sev->reduced_phys_bits; - visit_type_uint32(v, name, &value, errp); -} - -static void qsev_guest_init(Object *obj) { QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE); sev->policy = DEFAULT_GUEST_POLICY; - object_property_add(obj, "policy", "uint32", qsev_guest_get_policy, - qsev_guest_set_policy, NULL, NULL, NULL); - object_property_add(obj, "handle", "uint32", qsev_guest_get_handle, - qsev_guest_set_handle, NULL, NULL, NULL); - object_property_add(obj, "cbitpos", "uint32", qsev_guest_get_cbitpos, - qsev_guest_set_cbitpos, NULL, NULL, NULL); - object_property_add(obj, "reduced-phys-bits", "uint32", - qsev_guest_get_reduced_phys_bits, - qsev_guest_set_reduced_phys_bits, NULL, NULL, NULL); + object_property_add_uint32_ptr(obj, "policy", &sev->policy, + OBJ_PROP_FLAG_READWRITE, NULL); + object_property_add_uint32_ptr(obj, "handle", &sev->handle, + OBJ_PROP_FLAG_READWRITE, NULL); + object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos, + OBJ_PROP_FLAG_READWRITE, NULL); + object_property_add_uint32_ptr(obj, "reduced-phys-bits", + &sev->reduced_phys_bits, + OBJ_PROP_FLAG_READWRITE, NULL); } /* sev guest info */ diff --git a/target/i386/whp-dispatch.h b/target/i386/whp-dispatch.h index 87d049ceab..e4695c349f 100644 --- a/target/i386/whp-dispatch.h +++ b/target/i386/whp-dispatch.h @@ -23,6 +23,12 @@ X(HRESULT, WHvGetVirtualProcessorRegisters, (WHV_PARTITION_HANDLE Partition, UINT32 VpIndex, const WHV_REGISTER_NAME* RegisterNames, UINT32 RegisterCount, WHV_REGISTER_VALUE* RegisterValues)) \ X(HRESULT, WHvSetVirtualProcessorRegisters, (WHV_PARTITION_HANDLE Partition, UINT32 VpIndex, const WHV_REGISTER_NAME* RegisterNames, UINT32 RegisterCount, const WHV_REGISTER_VALUE* RegisterValues)) \ +/* + * These are supplemental functions that may not be present + * on all versions and are not critical for basic functionality. + */ +#define LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(X) \ + X(HRESULT, WHvSuspendPartitionTime, (WHV_PARTITION_HANDLE Partition)) \ #define LIST_WINHVEMULATION_FUNCTIONS(X) \ X(HRESULT, WHvEmulatorCreateEmulator, (const WHV_EMULATOR_CALLBACKS* Callbacks, WHV_EMULATOR_HANDLE* Emulator)) \ @@ -40,10 +46,12 @@ /* Define function typedef */ LIST_WINHVPLATFORM_FUNCTIONS(WHP_DEFINE_TYPE) LIST_WINHVEMULATION_FUNCTIONS(WHP_DEFINE_TYPE) +LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_DEFINE_TYPE) struct WHPDispatch { LIST_WINHVPLATFORM_FUNCTIONS(WHP_DECLARE_MEMBER) LIST_WINHVEMULATION_FUNCTIONS(WHP_DECLARE_MEMBER) + LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_DECLARE_MEMBER) }; extern struct WHPDispatch whp_dispatch; @@ -53,6 +61,7 @@ bool init_whp_dispatch(void); typedef enum WHPFunctionList { WINHV_PLATFORM_FNS_DEFAULT, WINHV_EMULATION_FNS_DEFAULT, + WINHV_PLATFORM_FNS_SUPPLEMENTAL } WHPFunctionList; #endif /* WHP_DISPATCH_H */ diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 683d49d217..c78baac6df 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -114,7 +114,6 @@ static const WHV_REGISTER_NAME whpx_register_names[] = { WHvX64RegisterXmmControlStatus, /* X64 MSRs */ - WHvX64RegisterTsc, WHvX64RegisterEfer, #ifdef TARGET_X86_64 WHvX64RegisterKernelGsBase, @@ -215,7 +214,44 @@ static SegmentCache whpx_seg_h2q(const WHV_X64_SEGMENT_REGISTER *hs) return qs; } -static void whpx_set_registers(CPUState *cpu) +static int whpx_set_tsc(CPUState *cpu) +{ + struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr); + WHV_REGISTER_NAME tsc_reg = WHvX64RegisterTsc; + WHV_REGISTER_VALUE tsc_val; + HRESULT hr; + struct whpx_state *whpx = &whpx_global; + + /* + * Suspend the partition prior to setting the TSC to reduce the variance + * in TSC across vCPUs. When the first vCPU runs post suspend, the + * partition is automatically resumed. + */ + if (whp_dispatch.WHvSuspendPartitionTime) { + + /* + * Unable to suspend partition while setting TSC is not a fatal + * error. It just increases the likelihood of TSC variance between + * vCPUs and some guest OS are able to handle that just fine. + */ + hr = whp_dispatch.WHvSuspendPartitionTime(whpx->partition); + if (FAILED(hr)) { + warn_report("WHPX: Failed to suspend partition, hr=%08lx", hr); + } + } + + tsc_val.Reg64 = env->tsc; + hr = whp_dispatch.WHvSetVirtualProcessorRegisters( + whpx->partition, cpu->cpu_index, &tsc_reg, 1, &tsc_val); + if (FAILED(hr)) { + error_report("WHPX: Failed to set TSC, hr=%08lx", hr); + return -1; + } + + return 0; +} + +static void whpx_set_registers(CPUState *cpu, int level) { struct whpx_state *whpx = &whpx_global; struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu); @@ -230,6 +266,14 @@ static void whpx_set_registers(CPUState *cpu) assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + /* + * Following MSRs have side effects on the guest or are too heavy for + * runtime. Limit them to full state update. + */ + if (level >= WHPX_SET_RESET_STATE) { + whpx_set_tsc(cpu); + } + memset(&vcxt, 0, sizeof(struct whpx_register_set)); v86 = (env->eflags & VM_MASK); @@ -330,8 +374,6 @@ static void whpx_set_registers(CPUState *cpu) idx += 1; /* MSRs */ - assert(whpx_register_names[idx] == WHvX64RegisterTsc); - vcxt.values[idx++].Reg64 = env->tsc; assert(whpx_register_names[idx] == WHvX64RegisterEfer); vcxt.values[idx++].Reg64 = env->efer; #ifdef TARGET_X86_64 @@ -379,6 +421,25 @@ static void whpx_set_registers(CPUState *cpu) return; } +static int whpx_get_tsc(CPUState *cpu) +{ + struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr); + WHV_REGISTER_NAME tsc_reg = WHvX64RegisterTsc; + WHV_REGISTER_VALUE tsc_val; + HRESULT hr; + struct whpx_state *whpx = &whpx_global; + + hr = whp_dispatch.WHvGetVirtualProcessorRegisters( + whpx->partition, cpu->cpu_index, &tsc_reg, 1, &tsc_val); + if (FAILED(hr)) { + error_report("WHPX: Failed to get TSC, hr=%08lx", hr); + return -1; + } + + env->tsc = tsc_val.Reg64; + return 0; +} + static void whpx_get_registers(CPUState *cpu) { struct whpx_state *whpx = &whpx_global; @@ -394,6 +455,11 @@ static void whpx_get_registers(CPUState *cpu) assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + if (!env->tsc_valid) { + whpx_get_tsc(cpu); + env->tsc_valid = !runstate_is_running(); + } + hr = whp_dispatch.WHvGetVirtualProcessorRegisters( whpx->partition, cpu->cpu_index, whpx_register_names, @@ -492,8 +558,6 @@ static void whpx_get_registers(CPUState *cpu) idx += 1; /* MSRs */ - assert(whpx_register_names[idx] == WHvX64RegisterTsc); - env->tsc = vcxt.values[idx++].Reg64; assert(whpx_register_names[idx] == WHvX64RegisterEfer); env->efer = vcxt.values[idx++].Reg64; #ifdef TARGET_X86_64 @@ -841,9 +905,8 @@ static void whpx_vcpu_process_async_events(CPUState *cpu) if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) && !(env->hflags & HF_SMM_MASK)) { - + whpx_cpu_synchronize_state(cpu); do_cpu_init(x86_cpu); - cpu->vcpu_dirty = true; vcpu->interruptable = true; } @@ -859,17 +922,13 @@ static void whpx_vcpu_process_async_events(CPUState *cpu) } if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) { - if (!cpu->vcpu_dirty) { - whpx_get_registers(cpu); - } + whpx_cpu_synchronize_state(cpu); do_cpu_sipi(x86_cpu); } if (cpu->interrupt_request & CPU_INTERRUPT_TPR) { cpu->interrupt_request &= ~CPU_INTERRUPT_TPR; - if (!cpu->vcpu_dirty) { - whpx_get_registers(cpu); - } + whpx_cpu_synchronize_state(cpu); apic_handle_tpr_access_report(x86_cpu->apic_state, env->eip, env->tpr_access_type); } @@ -896,7 +955,7 @@ static int whpx_vcpu_run(CPUState *cpu) do { if (cpu->vcpu_dirty) { - whpx_set_registers(cpu); + whpx_set_registers(cpu, WHPX_SET_RUNTIME_STATE); cpu->vcpu_dirty = false; } @@ -980,38 +1039,32 @@ static int whpx_vcpu_run(CPUState *cpu) WHV_REGISTER_VALUE reg_values[5]; WHV_REGISTER_NAME reg_names[5]; UINT32 reg_count = 5; - UINT64 rip, rax, rcx, rdx, rbx; + UINT64 cpuid_fn, rip = 0, rax = 0, rcx = 0, rdx = 0, rbx = 0; + X86CPU *x86_cpu = X86_CPU(cpu); + CPUX86State *env = &x86_cpu->env; memset(reg_values, 0, sizeof(reg_values)); rip = vcpu->exit_ctx.VpContext.Rip + vcpu->exit_ctx.VpContext.InstructionLength; - switch (vcpu->exit_ctx.CpuidAccess.Rax) { - case 1: - rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax; - /* Advertise that we are running on a hypervisor */ - rcx = - vcpu->exit_ctx.CpuidAccess.DefaultResultRcx | - CPUID_EXT_HYPERVISOR; - - rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx; - rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx; - break; + cpuid_fn = vcpu->exit_ctx.CpuidAccess.Rax; + + /* + * Ideally, these should be supplied to the hypervisor during VCPU + * initialization and it should be able to satisfy this request. + * But, currently, WHPX doesn't support setting CPUID values in the + * hypervisor once the partition has been setup, which is too late + * since VCPUs are realized later. For now, use the values from + * QEMU to satisfy these requests, until WHPX adds support for + * being able to set these values in the hypervisor at runtime. + */ + cpu_x86_cpuid(env, cpuid_fn, 0, (UINT32 *)&rax, (UINT32 *)&rbx, + (UINT32 *)&rcx, (UINT32 *)&rdx); + switch (cpuid_fn) { case 0x80000001: - rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax; /* Remove any support of OSVW */ - rcx = - vcpu->exit_ctx.CpuidAccess.DefaultResultRcx & - ~CPUID_EXT3_OSVW; - - rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx; - rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx; + rcx &= ~CPUID_EXT3_OSVW; break; - default: - rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax; - rcx = vcpu->exit_ctx.CpuidAccess.DefaultResultRcx; - rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx; - rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx; } reg_names[0] = WHvX64RegisterRip; @@ -1067,21 +1120,23 @@ static int whpx_vcpu_run(CPUState *cpu) static void do_whpx_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) { - whpx_get_registers(cpu); - cpu->vcpu_dirty = true; + if (!cpu->vcpu_dirty) { + whpx_get_registers(cpu); + cpu->vcpu_dirty = true; + } } static void do_whpx_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg) { - whpx_set_registers(cpu); + whpx_set_registers(cpu, WHPX_SET_RESET_STATE); cpu->vcpu_dirty = false; } static void do_whpx_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) { - whpx_set_registers(cpu); + whpx_set_registers(cpu, WHPX_SET_FULL_STATE); cpu->vcpu_dirty = false; } @@ -1123,6 +1178,15 @@ void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu) static Error *whpx_migration_blocker; +static void whpx_cpu_update_state(void *opaque, int running, RunState state) +{ + CPUX86State *env = opaque; + + if (running) { + env->tsc_valid = false; + } +} + int whpx_init_vcpu(CPUState *cpu) { HRESULT hr; @@ -1178,6 +1242,7 @@ int whpx_init_vcpu(CPUState *cpu) cpu->vcpu_dirty = true; cpu->hax_vcpu = (struct hax_vcpu_state *)vcpu; + qemu_add_vm_change_state_handler(whpx_cpu_update_state, cpu->env_ptr); return 0; } @@ -1367,6 +1432,10 @@ static bool load_whp_dispatch_fns(HMODULE *handle, #define WINHV_PLATFORM_DLL "WinHvPlatform.dll" #define WINHV_EMULATION_DLL "WinHvEmulation.dll" + #define WHP_LOAD_FIELD_OPTIONAL(return_type, function_name, signature) \ + whp_dispatch.function_name = \ + (function_name ## _t)GetProcAddress(hLib, #function_name); \ + #define WHP_LOAD_FIELD(return_type, function_name, signature) \ whp_dispatch.function_name = \ (function_name ## _t)GetProcAddress(hLib, #function_name); \ @@ -1394,6 +1463,11 @@ static bool load_whp_dispatch_fns(HMODULE *handle, WHP_LOAD_LIB(WINHV_EMULATION_DLL, hLib) LIST_WINHVEMULATION_FUNCTIONS(WHP_LOAD_FIELD) break; + + case WINHV_PLATFORM_FNS_SUPPLEMENTAL: + WHP_LOAD_LIB(WINHV_PLATFORM_DLL, hLib) + LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_LOAD_FIELD_OPTIONAL) + break; } *handle = hLib; @@ -1554,6 +1628,8 @@ bool init_whp_dispatch(void) goto error; } + assert(load_whp_dispatch_fns(&hWinHvPlatform, + WINHV_PLATFORM_FNS_SUPPLEMENTAL)); whp_dispatch_initialized = true; return true; diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c index c437a1d8c6..0e840cc579 100644 --- a/target/s390x/ioinst.c +++ b/target/s390x/ioinst.c @@ -347,7 +347,7 @@ typedef struct ChscResp { uint16_t len; uint16_t code; uint32_t param; - char data[0]; + char data[]; } QEMU_PACKED ChscResp; #define CHSC_MIN_RESP_LEN 0x0008 diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker index 3b860af106..0456fc7a0c 100644 --- a/tests/docker/dockerfiles/debian-amd64.docker +++ b/tests/docker/dockerfiles/debian-amd64.docker @@ -17,6 +17,7 @@ RUN apt update && \ libbz2-dev \ liblzo2-dev \ librdmacm-dev \ + libsasl2-dev \ libsnappy-dev \ libvte-dev diff --git a/tests/qtest/libqos/ahci.h b/tests/qtest/libqos/ahci.h index f05b3e5fce..44ab1104b5 100644 --- a/tests/qtest/libqos/ahci.h +++ b/tests/qtest/libqos/ahci.h @@ -351,7 +351,7 @@ typedef struct AHCIQState { typedef struct FIS { uint8_t fis_type; uint8_t flags; - char data[0]; + char data[]; } __attribute__((__packed__)) FIS; /** diff --git a/ui/console.c b/ui/console.c index 179901c35e..184e173687 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1299,8 +1299,8 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type, object_property_allow_set_link, OBJ_PROP_LINK_STRONG, &error_abort); - object_property_add_uint32_ptr(obj, "head", - &s->head, &error_abort); + object_property_add_uint32_ptr(obj, "head", &s->head, + OBJ_PROP_FLAG_READ, &error_abort); if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) && (console_type == GRAPHIC_CONSOLE))) { diff --git a/ui/curses.c b/ui/curses.c index 3a1b71451c..a59b23a9cf 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -54,13 +54,13 @@ enum maybe_keycode { }; static DisplayChangeListener *dcl; -static console_ch_t screen[160 * 100]; +static console_ch_t *screen; static WINDOW *screenpad = NULL; static int width, height, gwidth, gheight, invalidate; static int px, py, sminx, sminy, smaxx, smaxy; static const char *font_charset = "CP437"; -static cchar_t vga_to_curses[256]; +static cchar_t *vga_to_curses; static void curses_update(DisplayChangeListener *dcl, int x, int y, int w, int h) @@ -405,6 +405,8 @@ static void curses_refresh(DisplayChangeListener *dcl) static void curses_atexit(void) { endwin(); + g_free(vga_to_curses); + g_free(screen); } /* @@ -529,7 +531,7 @@ static void font_setup(void) * Control characters are normally non-printable, but VGA does have * well-known glyphs for them. */ - static uint16_t control_characters[0x20] = { + static const uint16_t control_characters[0x20] = { 0x0020, 0x263a, 0x263b, @@ -783,6 +785,8 @@ static void curses_display_init(DisplayState *ds, DisplayOptions *opts) if (opts->u.curses.charset) { font_charset = opts->u.curses.charset; } + screen = g_new0(console_ch_t, 160 * 100); + vga_to_curses = g_new0(cchar_t, 256); curses_setup(); curses_keyboard_setup(); atexit(curses_atexit); diff --git a/util/bufferiszero.c b/util/bufferiszero.c index bfb2605466..663903553a 100644 --- a/util/bufferiszero.c +++ b/util/bufferiszero.c @@ -63,11 +63,11 @@ buffer_zero_int(const void *buf, size_t len) } } -#if defined(CONFIG_AVX2_OPT) || defined(__SSE2__) +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) || defined(__SSE2__) /* Do not use push_options pragmas unnecessarily, because clang * does not support them. */ -#ifdef CONFIG_AVX2_OPT +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) #pragma GCC push_options #pragma GCC target("sse2") #endif @@ -104,7 +104,7 @@ buffer_zero_sse2(const void *buf, size_t len) return _mm_movemask_epi8(_mm_cmpeq_epi8(t, zero)) == 0xFFFF; } -#ifdef CONFIG_AVX2_OPT +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) #pragma GCC pop_options #endif @@ -187,18 +187,54 @@ buffer_zero_avx2(const void *buf, size_t len) #pragma GCC pop_options #endif /* CONFIG_AVX2_OPT */ +#ifdef CONFIG_AVX512F_OPT +#pragma GCC push_options +#pragma GCC target("avx512f") +#include <immintrin.h> + +static bool +buffer_zero_avx512(const void *buf, size_t len) +{ + /* Begin with an unaligned head of 64 bytes. */ + __m512i t = _mm512_loadu_si512(buf); + __m512i *p = (__m512i *)(((uintptr_t)buf + 5 * 64) & -64); + __m512i *e = (__m512i *)(((uintptr_t)buf + len) & -64); + + /* Loop over 64-byte aligned blocks of 256. */ + while (p <= e) { + __builtin_prefetch(p); + if (unlikely(_mm512_test_epi64_mask(t, t))) { + return false; + } + t = p[-4] | p[-3] | p[-2] | p[-1]; + p += 4; + } + + t |= _mm512_loadu_si512(buf + len - 4 * 64); + t |= _mm512_loadu_si512(buf + len - 3 * 64); + t |= _mm512_loadu_si512(buf + len - 2 * 64); + t |= _mm512_loadu_si512(buf + len - 1 * 64); + + return !_mm512_test_epi64_mask(t, t); + +} +#pragma GCC pop_options +#endif + + /* Note that for test_buffer_is_zero_next_accel, the most preferred * ISA must have the least significant bit. */ -#define CACHE_AVX2 1 -#define CACHE_SSE4 2 -#define CACHE_SSE2 4 +#define CACHE_AVX512F 1 +#define CACHE_AVX2 2 +#define CACHE_SSE4 4 +#define CACHE_SSE2 8 /* Make sure that these variables are appropriately initialized when * SSE2 is enabled on the compiler command-line, but the compiler is * too old to support CONFIG_AVX2_OPT. */ -#ifdef CONFIG_AVX2_OPT +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) # define INIT_CACHE 0 # define INIT_ACCEL buffer_zero_int #else @@ -211,6 +247,7 @@ buffer_zero_avx2(const void *buf, size_t len) static unsigned cpuid_cache = INIT_CACHE; static bool (*buffer_accel)(const void *, size_t) = INIT_ACCEL; +static int length_to_accel = 64; static void init_accel(unsigned cache) { @@ -226,10 +263,16 @@ static void init_accel(unsigned cache) fn = buffer_zero_avx2; } #endif +#ifdef CONFIG_AVX512F_OPT + if (cache & CACHE_AVX512F) { + fn = buffer_zero_avx512; + length_to_accel = 256; + } +#endif buffer_accel = fn; } -#ifdef CONFIG_AVX2_OPT +#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) #include "qemu/cpuid.h" static void __attribute__((constructor)) init_cpuid_cache(void) @@ -252,9 +295,17 @@ static void __attribute__((constructor)) init_cpuid_cache(void) int bv; __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0)); __cpuid_count(7, 0, a, b, c, d); - if ((bv & 6) == 6 && (b & bit_AVX2)) { + if ((bv & 0x6) == 0x6 && (b & bit_AVX2)) { cache |= CACHE_AVX2; } + /* 0xe6: + * XCR0[7:5] = 111b (OPMASK state, upper 256-bit of ZMM0-ZMM15 + * and ZMM16-ZMM31 state are enabled by OS) + * XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS) + */ + if ((bv & 0xe6) == 0xe6 && (b & bit_AVX512F)) { + cache |= CACHE_AVX512F; + } } } cpuid_cache = cache; @@ -277,7 +328,7 @@ bool test_buffer_is_zero_next_accel(void) static bool select_accel_fn(const void *buf, size_t len) { - if (likely(len >= 64)) { + if (likely(len >= length_to_accel)) { return buffer_accel(buf, len); } return buffer_zero_int(buf, len); diff --git a/util/module.c b/util/module.c index 236a7bb52a..5f7896870a 100644 --- a/util/module.c +++ b/util/module.c @@ -19,6 +19,9 @@ #endif #include "qemu/queue.h" #include "qemu/module.h" +#ifdef CONFIG_MODULE_UPGRADES +#include "qemu-version.h" +#endif typedef struct ModuleEntry { @@ -170,6 +173,9 @@ bool module_load_one(const char *prefix, const char *lib_name) #ifdef CONFIG_MODULES char *fname = NULL; char *exec_dir; +#ifdef CONFIG_MODULE_UPGRADES + char *version_dir; +#endif const char *search_dir; char *dirs[4]; char *module_name; @@ -201,6 +207,14 @@ bool module_load_one(const char *prefix, const char *lib_name) dirs[n_dirs++] = g_strdup_printf("%s", CONFIG_QEMU_MODDIR); dirs[n_dirs++] = g_strdup_printf("%s/..", exec_dir ? : ""); dirs[n_dirs++] = g_strdup_printf("%s", exec_dir ? : ""); + +#ifdef CONFIG_MODULE_UPGRADES + version_dir = g_strcanon(g_strdup(QEMU_PKGVERSION), + G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "+-.~", + '_'); + dirs[n_dirs++] = g_strdup_printf("/var/run/qemu/%s", version_dir); +#endif + assert(n_dirs <= ARRAY_SIZE(dirs)); g_free(exec_dir); diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 897e8f3ba6..4dd6d7d4b4 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -466,10 +466,17 @@ static inline int get_memset_num_threads(int smp_cpus) static bool touch_all_pages(char *area, size_t hpagesize, size_t numpages, int smp_cpus) { + static gsize initialized = 0; size_t numpages_per_thread, leftover; char *addr = area; int i = 0; + if (g_once_init_enter(&initialized)) { + qemu_mutex_init(&page_mutex); + qemu_cond_init(&page_cond); + g_once_init_leave(&initialized, 1); + } + memset_thread_failed = false; threads_created_flag = false; memset_num_threads = get_memset_num_threads(smp_cpus); diff --git a/util/qemu-timer.c b/util/qemu-timer.c index ef52d28d37..d548d3c1ad 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" #include "qemu/timer.h" +#include "qemu/lockable.h" #include "sysemu/replay.h" #include "sysemu/cpus.h" @@ -186,13 +187,12 @@ bool timerlist_expired(QEMUTimerList *timer_list) return false; } - qemu_mutex_lock(&timer_list->active_timers_lock); - if (!timer_list->active_timers) { - qemu_mutex_unlock(&timer_list->active_timers_lock); - return false; + WITH_QEMU_LOCK_GUARD(&timer_list->active_timers_lock) { + if (!timer_list->active_timers) { + return false; + } + expire_time = timer_list->active_timers->expire_time; } - expire_time = timer_list->active_timers->expire_time; - qemu_mutex_unlock(&timer_list->active_timers_lock); return expire_time <= qemu_clock_get_ns(timer_list->clock->type); } @@ -225,13 +225,12 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) * value but ->notify_cb() is called when the deadline changes. Therefore * the caller should notice the change and there is no race condition. */ - qemu_mutex_lock(&timer_list->active_timers_lock); - if (!timer_list->active_timers) { - qemu_mutex_unlock(&timer_list->active_timers_lock); - return -1; + WITH_QEMU_LOCK_GUARD(&timer_list->active_timers_lock) { + if (!timer_list->active_timers) { + return -1; + } + expire_time = timer_list->active_timers->expire_time; } - expire_time = timer_list->active_timers->expire_time; - qemu_mutex_unlock(&timer_list->active_timers_lock); delta = expire_time - qemu_clock_get_ns(timer_list->clock->type); |