:p
atchew
Login
Hi; here's an arm pullreq. This is pretty much all bugfixes; it includes a few items not strictly arm-specific which I've put in here since I was rolling the pullreq anyway. thanks -- PMM The following changes since commit edcc429e9e41a8e0e415dcdab6aa52ad17ef8889: Merge tag 'pbouvier/pr/docs-20260513' of https://gitlab.com/p-b-o/qemu into staging (2026-05-14 10:18:06 -0400) are available in the Git repository at: https://gitlab.com/pm215/qemu.git tags/pull-target-arm-20260515 for you to fetch changes up to a86024eb2df56f7664cef16ec8e9a50a1dc3dd2f: target/arm/hvf: Fix WFI halting to stop idle vCPU spinning (2026-05-15 09:55:25 +0100) ---------------------------------------------------------------- target-arm queue: * docs: Document TIMEOUT_MULTIPLIER for raising test timeouts * meson.build: Add -fzero-init-padding-bits=all * hw/remote/machine.c: Mark x-remote machine as OK for AArch64 and AArch32 * tests/functional: Fix tests to not fail on a KVM-only aarch64 build * target/arm: Rename Aarch64-specific methods * target/arm: Extract IDAU interface to its own unit * target/arm/hvf: Stop pre-allocating cpreg_vmstate arrays * target/arm/hvf: Fix WFI halting to stop idle vCPU spinning * GICv5: Fix minor bugs spotted by Coverity * hw/arm: Build ARM/HVF GICv3 stub once * hw/arm: fsl-imx8mm: Don't call qdev_get_machine in init * hw/misc/bcm2835_control.c: Don't assert on local timer zero reload value * hw/display/exynos4210_fimd: Assume display surface is 32bpp * hw/display/exynos4210_fimd: Use LOG_GUEST_ERROR instead of hw_error() * hw/arm/integratorcp: Use LOG_UNIMP rather than hw_error() * tests/functional/qemu_test/asset.py: Don't use setxattr when it doesn't exist ---------------------------------------------------------------- Peter Maydell (17): docs: Document TIMEOUT_MULTIPLIER for raising test timeouts target/arm: GICv5 cpuif: Fix overflow in left shift target/arm: GICv5 cpuif: Don't set HPPIV bit in GICv5PendingIrq::intid hw/intc/arm_gicv5: Avoid NULL dereference in trace line hw/intc/arm_gicv5: Add missing early return in gicv5_set_handling() meson.build: Add -fzero-init-padding-bits=all hw/misc/bcm2835_control.c: Don't assert on local timer zero reload value hw/arm/integratorcp: Use LOG_UNIMP rather than hw_error() hw/display/exynos4210_fimd: Use LOG_GUEST_ERROR instead of hw_error() hw/display/exynos4210_fimd: Assume display surface is 32bpp hw/remote/machine.c: Mark x-remote machine as OK for AArch64 and AArch32 tests/functional/test_virt_vbsa: Skip UEFI test if virtualization not supported tests/functional/test_kvm.py: Use -cpu max, not cortex-a72 tests/functional/test_kvm.py: Skip if virtualization not supported tests/functional/test_hotplug_pci.py: Require TCG tests/functional/test_tuxrun: Restrict to TCG tests/functional/qemu_test/asset.py: Don't use setxattr when it doesn't exist Philippe Mathieu-Daudé (3): hw/arm: Build ARM/HVF GICv3 stub once target/arm: Rename Aarch64-specific methods target/arm: Extract IDAU interface to its own unit Scott J. Goldman (2): target/arm/hvf: Stop pre-allocating cpreg_vmstate arrays target/arm/hvf: Fix WFI halting to stop idle vCPU spinning Vineet Agarwal (1): hw/arm: fsl-imx8mm: Don't call qdev_get_machine in init docs/devel/testing/main.rst | 18 ++++ hw/arm/armv7m.c | 2 +- hw/arm/fsl-imx8mm.c | 15 +-- hw/arm/integratorcp.c | 16 ++- hw/display/exynos4210_fimd.c | 69 ++----------- hw/intc/arm_gicv5.c | 3 +- hw/intc/bcm2836_control.c | 15 ++- hw/intc/meson.build | 2 +- hw/remote/machine.c | 3 + include/hw/arm/armv7m.h | 2 +- include/hw/intc/arm_gicv5_types.h | 2 + include/hw/misc/tz-msc.h | 2 +- include/system/hvf_int.h | 1 + meson.build | 6 ++ target/arm/cpu.c | 10 +- target/arm/cpu32-stubs.c | 8 +- target/arm/cpu64.c | 12 +-- target/arm/hvf/hvf.c | 147 +++++++++++++++++++++++++-- target/arm/internals.h | 8 +- target/arm/ptw.c | 2 +- target/arm/tcg/cpu32.c | 8 -- target/arm/tcg/gicv5-cpuif.c | 26 ++--- target/arm/tcg/idau.c | 20 ++++ target/arm/{ => tcg}/idau.h | 0 target/arm/tcg/meson.build | 1 + tests/functional/aarch64/test_hotplug_pci.py | 1 + tests/functional/aarch64/test_kvm.py | 12 ++- tests/functional/aarch64/test_tuxrun.py | 2 + tests/functional/aarch64/test_virt_vbsa.py | 10 +- tests/functional/qemu_test/asset.py | 13 ++- 30 files changed, 298 insertions(+), 138 deletions(-) create mode 100644 target/arm/tcg/idau.c rename target/arm/{ => tcg}/idau.h (100%)
Our test infrastructure allows you to set the TIMEOUT_MULTIPLIER environment variable to raise the test timeouts if you're building for a slow environment. (scripts/mtest2make.py reads it and sets the meson test -t argument accordingly.) Document this so it's not a secret feature only known to a select few. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Message-id: 20260427161132.1463385-1-peter.maydell@linaro.org --- docs/devel/testing/main.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/devel/testing/main.rst b/docs/devel/testing/main.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/devel/testing/main.rst +++ b/docs/devel/testing/main.rst @@ -XXX,XX +XXX,XX @@ Before running tests, it is best to build QEMU programs first. Some tests expect the executables to exist and will fail with obscure messages if they cannot find them. +The timeouts for QEMU tests are set conservatively so you should not +in general find that tests time out. However, if you are running on a +particularly slow host or with a slow configuration (such as a build +with the clang address-sanitizer enabled) you can globally raise all +the timeouts, by setting the ``TIMEOUT_MULTIPLIER`` environment +variable. For instance: + +.. code:: + + TIMEOUT_MULTIPLIER=3 make check + +will run with all the default timeouts multiplied by three. You can +also disable timeouts entirely by setting the environment variable to +``0``. + .. _unit-tests: Unit tests @@ -XXX,XX +XXX,XX @@ Python. You can run the functional tests simply by executing: See :ref:`checkfunctional-ref` for more details. +The harness for the functional tests also honours the +``TIMEOUT_MULTIPLIER`` environment variable. + .. _checktcg-ref: Testing with "make check-tcg" -- 2.43.0
From: Philippe Mathieu-Daudé <philmd@linaro.org> Move arm_gicv3_hvf_stub.c, introduced in commit 48396ad6ce9 ("hw/intc: arm_gicv3_hvf: save/restore Apple GIC state"), to the global stub_ss[] source set which holds stub files being built once for all binaries, instead of one time per system binary. This prevents symbol clash when trying to build a single QEMU system binary: clang: error: linker command failed with exit code 1 (use -v to see invocation) duplicate symbol '_vmstate_gicv3_hvf' in: libqemu-aarch64-softmmu.a.p/hw_intc_arm_gicv3_hvf_stub.c.o libqemu-arm-softmmu.a.p/hw_intc_arm_gicv3_hvf_stub.c.o ld: 1 duplicate symbols Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr> Message-id: 20260507135816.71171-1-philmd@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/intc/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/intc/meson.build b/hw/intc/meson.build index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -XXX,XX +XXX,XX @@ arm_common_ss.add(when: 'CONFIG_ARM_GICV3', if_true: files('arm_gicv3_cpuif.c')) specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c')) specific_ss.add(when: ['CONFIG_WHPX', 'TARGET_AARCH64'], if_true: files('arm_gicv3_whpx.c')) specific_ss.add(when: ['CONFIG_HVF', 'CONFIG_ARM_GICV3'], if_true: files('arm_gicv3_hvf.c')) -specific_ss.add(when: ['CONFIG_HVF', 'CONFIG_ARM_GICV3'], if_false: files('arm_gicv3_hvf_stub.c')) +stub_ss.add(files('arm_gicv3_hvf_stub.c')) specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c')) arm_common_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c')) specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c')) -- 2.43.0
From: Vineet Agarwal <agarwal.vineet2006@gmail.com> Calling qdev_get_machine() from fsl_imx8mm_init() can trigger an assertion failure because the machine may not be created yet. Reproducer: ./qemu-system-aarch64 -S -display none \ -M virt -device fsl-imx8mm,help This hits: ../hw/core/qdev.c:844: Object *qdev_get_machine(void): Assertion `dev' failed. Move the CPU initialization into realize(), where accessing the machine state is safe. (This is the same issue we fixed in the fsl-imx8mp machine in commit b67d0bcdd41c; we apply the same fix here.) Signed-off-by: Vineet Agarwal <agarwal.vineet2006@gmail.com> Message-id: 20260511115918.32765-1-agarwal.vineet2006@gmail.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/fsl-imx8mm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/fsl-imx8mm.c +++ b/hw/arm/fsl-imx8mm.c @@ -XXX,XX +XXX,XX @@ static const struct { static void fsl_imx8mm_init(Object *obj) { - MachineState *ms = MACHINE(qdev_get_machine()); FslImx8mmState *s = FSL_IMX8MM(obj); - const char *cpu_type = ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53"); int i; - for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX8MM_NUM_CPUS); i++) { - g_autofree char *name = g_strdup_printf("cpu%d", i); - object_initialize_child(obj, name, &s->cpu[i], cpu_type); - } - object_initialize_child(obj, "gic", &s->gic, gicv3_class_name()); object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX8MP_CCM); @@ -XXX,XX +XXX,XX @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp) MachineState *ms = MACHINE(qdev_get_machine()); FslImx8mmState *s = FSL_IMX8MM(dev); DeviceState *gicdev = DEVICE(&s->gic); + const char *cpu_type = + ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53"); int i; if (ms->smp.cpus > FSL_IMX8MM_NUM_CPUS) { @@ -XXX,XX +XXX,XX @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp) return; } + for (i = 0; i < ms->smp.cpus; i++) { + g_autofree char *name = g_strdup_printf("cpu%d", i); + object_initialize_child(OBJECT(dev), name, + &s->cpu[i], cpu_type); + } + /* CPUs */ for (i = 0; i < ms->smp.cpus; i++) { /* On uniprocessor, the CBAR is set to 0 */ -- 2.43.0
From: Philippe Mathieu-Daudé <philmd@linaro.org> Various Aarch64 specific methods start with the 'aarch64_' prefix. Rename few more emphasizing Aarch64 specific features. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Message-id: 20260507134709.70507-2-philmd@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/cpu.c | 8 ++++---- target/arm/cpu32-stubs.c | 8 ++++---- target/arm/cpu64.c | 12 ++++++------ target/arm/internals.h | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -XXX,XX +XXX,XX @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp) Error *local_err = NULL; if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - arm_cpu_sve_finalize(cpu, &local_err); + aarch64_cpu_sve_finalize(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; } - arm_cpu_sme_finalize(cpu, &local_err); + aarch64_cpu_sme_finalize(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; } - arm_cpu_pauth_finalize(cpu, &local_err); + aarch64_cpu_pauth_finalize(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; } - arm_cpu_lpa2_finalize(cpu, &local_err); + aarch64_cpu_lpa2_finalize(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; diff --git a/target/arm/cpu32-stubs.c b/target/arm/cpu32-stubs.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu32-stubs.c +++ b/target/arm/cpu32-stubs.c @@ -XXX,XX +XXX,XX @@ #include "target/arm/cpu.h" #include "target/arm/internals.h" -void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp) +void aarch64_cpu_sme_finalize(ARMCPU *cpu, Error **errp) { g_assert_not_reached(); } -void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) +void aarch64_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { g_assert_not_reached(); } -void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) +void aarch64_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { g_assert_not_reached(); } -void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) +void aarch64_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) { g_assert_not_reached(); } diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -XXX,XX +XXX,XX @@ int get_sysreg_idx(ARMSysRegs sysreg) #undef DEF -void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) +void aarch64_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { /* * If any vector lengths are explicitly enabled with sve<N> properties, @@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) * Disable all SVE extensions as well. Note that some ZFR0 * fields are used also by SME so must not be wiped in * an SME-no-SVE config. We will clear the rest in - * arm_cpu_sme_finalize() if necessary. + * aarch_cpu_sme_finalize() if necessary. */ FIELD_DP64_IDREG(&cpu->isar, ID_AA64ZFR0, F64MM, 0); FIELD_DP64_IDREG(&cpu->isar, ID_AA64ZFR0, F32MM, 0); @@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, bool value, Error **errp) FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, SVE, value); } -void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp) +void aarch64_cpu_sme_finalize(ARMCPU *cpu, Error **errp) { uint32_t vq_map = cpu->sme_vq.map; uint32_t vq_init = cpu->sme_vq.init; @@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sme(Object *obj, bool value, Error **errp) /* * For now, write 0 for "off" and 1 for "on" into the PFR1 field. * We will correct this value to report the right SME - * level (SME vs SME2) in arm_cpu_sme_finalize() later. + * level (SME vs SME2) in aarch_cpu_sme_finalize() later. */ FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, value); } @@ -XXX,XX +XXX,XX @@ void aarch64_add_sme_properties(Object *obj) #endif } -void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) +void aarch64_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu); ARMISARegisters *isar = &cpu->isar; @@ -XXX,XX +XXX,XX @@ void aarch64_add_pauth_properties(Object *obj) } } -void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) +void aarch64_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) { uint64_t t; diff --git a/target/arm/internals.h b/target/arm/internals.h index XXXXXXX..XXXXXXX 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -XXX,XX +XXX,XX @@ int aarch64_gdb_get_tag_ctl_reg(CPUState *cs, GByteArray *buf, int reg); int aarch64_gdb_set_tag_ctl_reg(CPUState *cs, uint8_t *buf, int reg); int aarch64_gdb_get_tls_reg(CPUState *cs, GByteArray *buf, int reg); int aarch64_gdb_set_tls_reg(CPUState *cs, uint8_t *buf, int reg); -void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp); -void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp); -void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp); -void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp); +void aarch64_cpu_sve_finalize(ARMCPU *cpu, Error **errp); +void aarch64_cpu_sme_finalize(ARMCPU *cpu, Error **errp); +void aarch64_cpu_pauth_finalize(ARMCPU *cpu, Error **errp); +void aarch64_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp); void aarch64_max_tcg_initfn(Object *obj); void aarch64_add_pauth_properties(Object *obj); void aarch64_add_sve_properties(Object *obj); -- 2.43.0
From: Philippe Mathieu-Daudé <philmd@linaro.org> Move IDAU TypeInfo structure to its own source file and build it once as common ARM object. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Message-id: 20260507134709.70507-3-philmd@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/armv7m.c | 2 +- include/hw/arm/armv7m.h | 2 +- include/hw/misc/tz-msc.h | 2 +- target/arm/cpu.c | 2 +- target/arm/ptw.c | 2 +- target/arm/tcg/cpu32.c | 8 -------- target/arm/tcg/idau.c | 20 ++++++++++++++++++++ target/arm/{ => tcg}/idau.h | 0 target/arm/tcg/meson.build | 1 + 9 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 target/arm/tcg/idau.c rename target/arm/{ => tcg}/idau.h (100%) diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -XXX,XX +XXX,XX @@ #include "qemu/error-report.h" #include "qemu/module.h" #include "qemu/log.h" -#include "target/arm/idau.h" +#include "target/arm/tcg/idau.h" #include "target/arm/cpu.h" #include "target/arm/cpu-features.h" #include "target/arm/cpu-qom.h" diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/armv7m.h @@ -XXX,XX +XXX,XX @@ #include "hw/core/sysbus.h" #include "hw/intc/armv7m_nvic.h" #include "hw/misc/armv7m_ras.h" -#include "target/arm/idau.h" +#include "target/arm/tcg/idau.h" #include "qom/object.h" #include "hw/core/clock.h" diff --git a/include/hw/misc/tz-msc.h b/include/hw/misc/tz-msc.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/misc/tz-msc.h +++ b/include/hw/misc/tz-msc.h @@ -XXX,XX +XXX,XX @@ #define TZ_MSC_H #include "hw/core/sysbus.h" -#include "target/arm/idau.h" +#include "target/arm/tcg/idau.h" #include "qom/object.h" #define TYPE_TZ_MSC "tz-msc" diff --git a/target/arm/cpu.c b/target/arm/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -XXX,XX +XXX,XX @@ #include "qemu/log.h" #include "exec/page-vary.h" #include "system/whpx.h" -#include "target/arm/idau.h" +#include "target/arm/tcg/idau.h" #include "qemu/module.h" #include "qapi/error.h" #include "cpu.h" diff --git a/target/arm/ptw.c b/target/arm/ptw.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -XXX,XX +XXX,XX @@ #include "cpu.h" #include "internals.h" #include "cpu-features.h" -#include "idau.h" +#include "target/arm/tcg/idau.h" typedef struct S1Translate { /* diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c @@ -XXX,XX +XXX,XX @@ #include "cpu.h" #include "accel/tcg/cpu-ops.h" #include "internals.h" -#include "target/arm/idau.h" #if !defined(CONFIG_USER_ONLY) #include "hw/core/boards.h" #endif @@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = { #endif }; -static const TypeInfo idau_interface_type_info = { - .name = TYPE_IDAU_INTERFACE, - .parent = TYPE_INTERFACE, - .class_size = sizeof(IDAUInterfaceClass), -}; - static void arm_tcg_cpu_register_types(void) { size_t i; - type_register_static(&idau_interface_type_info); for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) { arm_cpu_register(&arm_tcg_cpus[i]); } diff --git a/target/arm/tcg/idau.c b/target/arm/tcg/idau.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/target/arm/tcg/idau.c @@ -XXX,XX +XXX,XX @@ +/* + * QEMU ARM CPU -- interface for the Arm v8M IDAU + * + * Copyright (c) 2018 Linaro Ltd + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "target/arm/tcg/idau.h" + +static const TypeInfo idau_types[] = { + { + .name = TYPE_IDAU_INTERFACE, + .parent = TYPE_INTERFACE, + .class_size = sizeof(IDAUInterfaceClass), + } +}; + +DEFINE_TYPES(idau_types) diff --git a/target/arm/idau.h b/target/arm/tcg/idau.h similarity index 100% rename from target/arm/idau.h rename to target/arm/tcg/idau.h diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build index XXXXXXX..XXXXXXX 100644 --- a/target/arm/tcg/meson.build +++ b/target/arm/tcg/meson.build @@ -XXX,XX +XXX,XX @@ arm_common_ss.add(zlib) arm_common_ss.add(files( 'arith_helper.c', 'crypto_helper.c', + 'idau.c', )) arm_common_system_ss.add( -- 2.43.0
From: "Scott J. Goldman" <scottjgo@gmail.com> Commit ab2ddc7b66 ("target/arm/machine: Use VMSTATE_VARRAY_INT32_ALLOC for cpreg arrays") moved cpreg_vmstate_indexes / cpreg_vmstate_values to be allocated by VMSTATE_VARRAY_INT32_ALLOC and added an assertion in cpu_pre_load() that they are NULL on entry. The same commit dropped the redundant g_renew()/array_len assignments from the kvm, whpx and helper.c cpu init paths, but the hvf cpu init path still pre-allocates them. The result is that loading a snapshot or migration stream into an HVF guest immediately aborts: ERROR:target/arm/machine.c:1043:cpu_pre_load: assertion failed: (!cpu->cpreg_vmstate_indexes) Drop the leftover cpreg_vmstate_indexes / cpreg_vmstate_values allocations and the cpreg_vmstate_array_len assignment from hvf_arch_init_vcpu(), matching what was already done for the other arm accelerators. Signed-off-by: Scott J. Goldman <scottjgo@gmail.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/hvf/hvf.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -XXX,XX +XXX,XX @@ int hvf_arch_init_vcpu(CPUState *cpu) sregs_match_len); arm_cpu->cpreg_values = g_renew(uint64_t, arm_cpu->cpreg_values, sregs_match_len); - arm_cpu->cpreg_vmstate_indexes = g_renew(uint64_t, - arm_cpu->cpreg_vmstate_indexes, - sregs_match_len); - arm_cpu->cpreg_vmstate_values = g_renew(uint64_t, - arm_cpu->cpreg_vmstate_values, - sregs_match_len); memset(arm_cpu->cpreg_values, 0, sregs_match_len * sizeof(uint64_t)); @@ -XXX,XX +XXX,XX @@ int hvf_arch_init_vcpu(CPUState *cpu) } } arm_cpu->cpreg_array_len = sregs_cnt; - arm_cpu->cpreg_vmstate_array_len = sregs_cnt; /* cpreg tuples must be in strictly ascending order */ qsort(arm_cpu->cpreg_indexes, sregs_cnt, sizeof(uint64_t), compare_u64); -- 2.43.0
Coverity points out that we forgot the "ULL" suffix when shifting 1 right by a bitcount in various places, so for bit counts above 31 we end up shifting off the end of the word. Fix the three problems Coverity noticed and one more of the same kind that it didn't. CID: 1659588, 1659591, 1659559 Fixes: ce245ac6957 ("target/arm: GICv5 cpuif: Calculate the highest priority PPI") Fixes: 3f79212abae ("target/arm: GICv5 cpuif: Implement GICR CDIA command") Fixes: 49f4c98648c ("target/arm: GICv5 cpuif: Implement GIC CDDI") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260512093856.3197700-2-peter.maydell@linaro.org --- target/arm/tcg/gicv5-cpuif.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/tcg/gicv5-cpuif.c +++ b/target/arm/tcg/gicv5-cpuif.c @@ -XXX,XX +XXX,XX @@ static void gic_recalc_ppi_hppi(CPUARMState *env) int ppi; int bit = ctz64(en_pend_nact); - en_pend_nact &= ~(1 << bit); + en_pend_nact &= ~(1ULL << bit); ppi = i * 64 + bit; prio = extract64(env->gicv5_cpuif.ppi_priority[ppi / 8], @@ -XXX,XX +XXX,XX @@ static uint64_t gicr_cdia_read(CPUARMState *env, const ARMCPRegInfo *ri) * gicv5_activate() cause a re-evaluation of HPPIs they use the * right (new) running priority. */ - env->gicv5_cpuif.icc_apr[domain] |= (1 << hppi.prio); + env->gicv5_cpuif.icc_apr[domain] |= (1ULL << hppi.prio); switch (type) { case GICV5_PPI: { @@ -XXX,XX +XXX,XX @@ static uint64_t gicr_cdia_read(CPUARMState *env, const ARMCPRegInfo *ri) assert(id < GICV5_NUM_PPIS); ppireg = id / 64; - ppibit = 1 << (id % 64); + ppibit = 1ULL << (id % 64); env->gicv5_cpuif.ppi_active[ppireg] |= ppibit; if (!(env->gicv5_cpuif.ppi_hm[ppireg] & ppibit)) { @@ -XXX,XX +XXX,XX @@ static void gic_cddi_write(CPUARMState *env, const ARMCPRegInfo *ri, } ppireg = id / 64; - ppibit = 1 << (id % 64); + ppibit = 1ULL << (id % 64); env->gicv5_cpuif.ppi_active[ppireg] &= ~ppibit; gic_recalc_ppi_hppi(env); -- 2.43.0
In gic_hppi() we return the current highest priority pending interrupt in a GICv5PendingIrq struct. We try to set up the intid field of that struct to be the form that is used by the ICC_HPPIR register, which has a "valid" bit in bit 33. Unfortunately the GICv5PendingIrq defines the intid field as a uint32_t, so Coverity points out that the bit doesn't actually fit. Move the handling of the valid bit to the callsite, and make this function report "no pending interrupt" with GICv5PendingIrq::prio == PRIO_IDLE, consistently with how we use this struct in other places. CID: 1659594 Fixes: 9edad4ff3 ("target/arm: GICv5 cpuif: Implement ICC_HPPIR_EL1") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260512093856.3197700-3-peter.maydell@linaro.org --- include/hw/intc/arm_gicv5_types.h | 2 ++ target/arm/tcg/gicv5-cpuif.c | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/hw/intc/arm_gicv5_types.h b/include/hw/intc/arm_gicv5_types.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/intc/arm_gicv5_types.h +++ b/include/hw/intc/arm_gicv5_types.h @@ -XXX,XX +XXX,XX @@ typedef enum GICv5TriggerMode { * * In this struct the intid includes the interrupt type in bits * [31:29] (i.e. it is in the form defined by R_TJPHS). + * + * "No pending interrupt" is represented by @prio == PRIO_IDLE. */ typedef struct GICv5PendingIrq { uint32_t intid; diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/tcg/gicv5-cpuif.c +++ b/target/arm/tcg/gicv5-cpuif.c @@ -XXX,XX +XXX,XX @@ static GICv5PendingIrq gic_hppi(CPUARMState *env, GICv5Domain domain) { /* * Return the current highest priority pending interrupt for the - * specified domain, if it has sufficient priority to preempt. The - * intid field of the return value will be in the format of the - * ICC_HPPIR register (and will be zero if and only if there is no - * interrupt that can preempt). + * specified domain, if it has sufficient priority to preempt. + * If there is no interrupt that can preempt we signal this by + * returning a struct with prio == PRIO_IDLE. */ GICv5Common *gic = gicv5_get_gic(env); @@ -XXX,XX +XXX,XX @@ static GICv5PendingIrq gic_hppi(CPUARMState *env, GICv5Domain domain) best.prio >= gic_running_prio(env, domain)) { return (GICv5PendingIrq) { .intid = 0, .prio = PRIO_IDLE }; } - best.intid |= R_ICC_HPPIR_EL1_HPPIV_MASK; return best; } @@ -XXX,XX +XXX,XX @@ static uint64_t gic_icc_hppir_el1_read(CPUARMState *env, const ARMCPRegInfo *ri) { GICv5Domain domain = gicv5_logical_domain(env); GICv5PendingIrq hppi = gic_hppi(env, domain); - return hppi.intid; + + if (hppi.prio == PRIO_IDLE) { + /* No valid interrupt */ + return 0; + } + return hppi.intid | R_ICC_HPPIR_EL1_HPPIV_MASK; } static bool gic_hppi_is_nmi(CPUARMState *env, GICv5PendingIrq hppi, @@ -XXX,XX +XXX,XX @@ static uint64_t gicr_cdia_read(CPUARMState *env, const ARMCPRegInfo *ri) bool cdnmia = ri->opc2 == 1; - if (!hppi.intid) { + if (hppi.prio == PRIO_IDLE) { /* No interrupt available to acknowledge */ trace_gicv5_gicr_cdia_fail(domain, "no available interrupt to acknowledge"); return 0; } - assert(hppi.prio != PRIO_IDLE); if (gic_hppi_is_nmi(env, hppi, domain) != cdnmia) { /* GICR CDIA only acknowledges non-NMI; GICR CDNMIA only NMI */ -- 2.43.0
In the handling of writes to the IRS_SPI_RESAMPLER register, we call a trace function, passing it information about the SPI being resampled. However, spi could be NULL if the guest tried to resample a nonexistent SPI or one configured for a different domain. Move the trace statement inside the "if (spi)" block, as it's only interesting trace if we actually did a resample and potentially changed the state of the SPI. CID: 1959593 Fixes: 33185e1d64e ("hw/intc/arm_gicv5: Update SPI state for CLEAR/SET events") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260512093856.3197700-4-peter.maydell@linaro.org --- hw/intc/arm_gicv5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv5.c +++ b/hw/intc/arm_gicv5.c @@ -XXX,XX +XXX,XX @@ static bool config_writel(GICv5 *s, GICv5Domain domain, hwaddr offset, if (spi) { spi_sample(spi); irs_recalc_hppi(s, spi->domain, spi->iaffid); + trace_gicv5_spi_state(id, spi->level, spi->pending, spi->active); } - trace_gicv5_spi_state(id, spi->level, spi->pending, spi->active); return true; } case A_IRS_CR0: -- 2.43.0
In gicv5_set_handling(), if the guest tried to set the handling mode on a nonexistent SPI then we print a GUEST_ERROR log message. However, we forgot to then return, so execution continues into a NULL pointer dereference. Add the missing "return", bringing the code structure in to line with the equivalent parts in other functions like gicv5_set_pending() and gicv5_set_target(). CID: 1659596 Fixes: 5beb48ab53d ("hw/intc/arm_gicv5: Make gicv5_set_* update SPI state") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260512093856.3197700-5-peter.maydell@linaro.org --- hw/intc/arm_gicv5.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv5.c +++ b/hw/intc/arm_gicv5.c @@ -XXX,XX +XXX,XX @@ void gicv5_set_handling(GICv5Common *cs, uint32_t id, if (!spi) { qemu_log_mask(LOG_GUEST_ERROR, "gicv5_set_handling: tried to set " "priority of unreachable SPI %d\n", id); + return; } spi->hm = handling; -- 2.43.0
The C standard doesn't always guarantee that struct and union padding bits are zero initialized, even if the code initializes a struct. For QEMU, this is potentially problematic, because we often have structs that match data structures in guest memory, where we initialize them and then bulk copy them into the guest. If the compiler didn't zero init the whole of the memory containing the struct, we could potentially leak random data from the host into the guest via the padding bytes. We already use -ftrivial-auto-var-init=zero, which will zero out padding in many of these cases, but -fzero-init-padding-bits=all closes some gaps, for example cases where we initialize a variable with a struct initializer, and cases involving unions. Follow the Linux kernel in using both options. Compare kernel commit dce4aab8441 ("kbuild: Use -fzero-init-padding-bits=all"). This option exists in gcc-15 and above; it's not supported by clang, but clang documents that it guarantees zero init of these cases always: https://clang.llvm.org/docs/LanguageExtensions.html#union-and-aggregate-initialization-in-c Older gcc which don't have the option behave as if it were set. (These options are passed through the cc.get_supported_arguments() filter, so we don't need to do anything extra to avoid passing it to a compiler that doesn't recognize it.) Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Message-id: 20260508104723.2144051-1-peter.maydell@linaro.org --- meson.build | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/meson.build b/meson.build index XXXXXXX..XXXXXXX 100644 --- a/meson.build +++ b/meson.build @@ -XXX,XX +XXX,XX @@ hardening_flags = [ # it harder to take advantage of uninitialized stack # data to drive exploits '-ftrivial-auto-var-init=zero', + # Ensure GCC zero-initializes padding bits and trailing fields in + # unions. This avoids potentially leaking host data into the guest + # when we init a struct and copy it into guest memory. GCC prior + # to GCC 15 and clang don't have this, but they zero the padding + # and trailing portions of a union by default. + '-fzero-init-padding-bits=all', ] # Zero out registers used during a function call -- 2.43.0
The bcm2836 local timer has a basic "counts down, fires at zero, and reloads to programmed value to count down again" functionality, as documented in https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2836/QA7_rev3.4.pdf The documentation is very sparse and doesn't say what actually happens if the guest programs the reload value to zero. Currently we trip an assert in this case. Instead, log this as a guest error and disable the timer (which seems a reasonable guess -- effectively the timer will stop counting). Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3395 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260508162013.2751001-2-peter.maydell@linaro.org --- hw/intc/bcm2836_control.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/bcm2836_control.c +++ b/hw/intc/bcm2836_control.c @@ -XXX,XX +XXX,XX @@ static void bcm2836_control_local_timer_set_next(void *opaque) { BCM2836ControlState *s = opaque; uint64_t next_event; + uint64_t reload_value = LOCALTIMER_VALUE(s->local_timer_control); - assert(LOCALTIMER_VALUE(s->local_timer_control) > 0); + if (reload_value == 0) { + /* + * Spec doesn't say what happens in this case; treat as a + * guest error and stop the timer running. + */ + qemu_log_mask(LOG_GUEST_ERROR, "%s: local timer reload value is 0\n", + __func__); + timer_del(&s->timer); + return; + } next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - muldiv64(LOCALTIMER_VALUE(s->local_timer_control), - NANOSECONDS_PER_SECOND, LOCALTIMER_FREQ); + muldiv64(reload_value, NANOSECONDS_PER_SECOND, LOCALTIMER_FREQ); timer_mod(&s->timer, next_event); } -- 2.43.0
The integratorcp board has some onboard registers which can be used to raise IRQ and FIQ to the CPU; these outputs are supposed to be ORed together with the main ones from the PIC. We've never implemented this obscure bit of functionality, and instead call hw_error() if the guest does try to raise an interrupt this way. Replace the hw_error() call with the more modern way to note unimplemented QEMU behaviour, a LOG_UNIMP log. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3406 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260508162013.2751001-3-peter.maydell@linaro.org --- hw/arm/integratorcp.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -XXX,XX +XXX,XX @@ #include "qemu/log.h" #include "qemu/error-report.h" #include "hw/char/pl011.h" -#include "hw/core/hw-error.h" #include "hw/core/irq.h" #include "hw/sd/sd.h" #include "qom/object.h" @@ -XXX,XX +XXX,XX @@ static void integratorcm_set_ctrl(IntegratorCMState *s, uint32_t value) static void integratorcm_update(IntegratorCMState *s) { - /* ??? The CPU irq/fiq is raised when either the core module or base PIC - are active. */ - if (s->int_level & (s->irq_enabled | s->fiq_enabled)) - hw_error("Core module interrupt\n"); + /* + * ??? The CPU irq/fiq is raised when either the core module or base PIC + * are active. To implement this we would need to run these signals + * through an OR gate with the PIC outputs. In practice guests don't + * use this, which is intended for an external debugger. + */ + if (s->int_level & (s->irq_enabled | s->fiq_enabled)) { + qemu_log_mask(LOG_UNIMP, + "%s: raising IRQ/FIQ via core module registers is not implemented\n", + __func__); + } } static void integratorcm_write(void *opaque, hwaddr offset, -- 2.43.0
The exynos4210_fimd device model uses hw_error() in several places for "the guest set this register field to something out of range"; update to the more modern LOG_GUEST_ERROR. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3405 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260508162013.2751001-4-peter.maydell@linaro.org --- hw/display/exynos4210_fimd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -XXX,XX +XXX,XX @@ exynos4210_fimd_palette_format(Exynos4210fimdState *s, int window) ((s->wpalcon[1] >> FIMD_WPAL_W4PAL_L_SHT) & FIMD_WPAL_W4PAL_L); break; default: - hw_error("exynos4210.fimd: incorrect window number %d\n", window); + qemu_log_mask(LOG_GUEST_ERROR, + "exynos4210.fimd: incorrect window number %d\n", window); ret = 0; break; } @@ -XXX,XX +XXX,XX @@ exynos4210_fimd_blend_pixel(Exynos4210fimdWindow *w, rgba p_bg, rgba *ret) blend_param[i] = FIMD_1_MINUS_COLOR(bg_color); break; default: - hw_error("exynos4210.fimd: blend equation coef illegal value\n"); + qemu_log_mask(LOG_GUEST_ERROR, + "exynos4210.fimd: blend equation coef illegal value\n"); + blend_param[i] = 0; break; } } -- 2.43.0
For a long time QEMU has guaranteed that the console surface is 32bpp and not anything else. This old display device still has code assuming it might be something else. Remove the code that made put_pixel_toqemu a function pointer indirection, and use put_to_qemufb_pixel32() directly. This removes the last hw_error() in this file. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260508162013.2751001-5-peter.maydell@linaro.org --- hw/display/exynos4210_fimd.c | 62 ++---------------------------------- 1 file changed, 2 insertions(+), 60 deletions(-) diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include "hw/core/qdev-properties.h" -#include "hw/core/hw-error.h" #include "hw/core/irq.h" #include "hw/core/sysbus.h" #include "exec/cpu-common.h" @@ -XXX,XX +XXX,XX @@ static void draw_line_mapcolor(Exynos4210fimdWindow *w, uint8_t *src, } /* Write RGB to QEMU's GraphicConsole framebuffer */ - -static int put_to_qemufb_pixel8(const rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel8(p.r, p.g, p.b); - *(uint8_t *)d = pixel; - return 1; -} - -static int put_to_qemufb_pixel15(const rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel15(p.r, p.g, p.b); - *(uint16_t *)d = pixel; - return 2; -} - -static int put_to_qemufb_pixel16(const rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel16(p.r, p.g, p.b); - *(uint16_t *)d = pixel; - return 2; -} - -static int put_to_qemufb_pixel24(const rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel24(p.r, p.g, p.b); - *(uint8_t *)d++ = (pixel >> 0) & 0xFF; - *(uint8_t *)d++ = (pixel >> 8) & 0xFF; - *(uint8_t *)d++ = (pixel >> 16) & 0xFF; - return 3; -} - static int put_to_qemufb_pixel32(const rgba p, uint8_t *d) { uint32_t pixel = rgb_to_pixel24(p.r, p.g, p.b); @@ -XXX,XX +XXX,XX @@ static int put_to_qemufb_pixel32(const rgba p, uint8_t *d) return 4; } -/* Routine to copy pixel from internal buffer to QEMU buffer */ -static int (*put_pixel_toqemu)(const rgba p, uint8_t *pixel); -static inline void fimd_update_putpix_qemu(int bpp) -{ - switch (bpp) { - case 8: - put_pixel_toqemu = put_to_qemufb_pixel8; - break; - case 15: - put_pixel_toqemu = put_to_qemufb_pixel15; - break; - case 16: - put_pixel_toqemu = put_to_qemufb_pixel16; - break; - case 24: - put_pixel_toqemu = put_to_qemufb_pixel24; - break; - case 32: - put_pixel_toqemu = put_to_qemufb_pixel32; - break; - default: - hw_error("exynos4210.fimd: unsupported BPP (%d)", bpp); - break; - } -} - /* Routine to copy a line from internal frame buffer to QEMU display */ static void fimd_copy_line_toqemu(int width, uint8_t *src, uint8_t *dst) { @@ -XXX,XX +XXX,XX @@ static void fimd_copy_line_toqemu(int width, uint8_t *src, uint8_t *dst) do { src += get_pixel_ifb(src, &p); - dst += put_pixel_toqemu(p, dst); + dst += put_to_qemufb_pixel32(p, dst); } while (--width); } @@ -XXX,XX +XXX,XX @@ static bool exynos4210_fimd_update(void *opaque) int bpp; bpp = surface_bits_per_pixel(surface); - fimd_update_putpix_qemu(bpp); + assert(bpp == 32); bpp = (bpp + 1) >> 3; d = surface_data(surface); for (line = first_line; line <= last_line; line++) { -- 2.43.0
When we updated Arm and AArch64 board types to mark them for the target_machine_typename() filter, we forgot about the "x-remote" machine type, which meant that it disappeared from the set of board types exposed on the qemu-system-arm and qemu-system-aarch64 binaries. We didn't notice this, because although we have a functional test for it, it requires the KVM accelerator and we don't run the functional tests on an AArch64 host in CI. Mark the machine as being OK to expose in qemu-system-arm and qemu-system-aarch64, in the same way we do for the "none" machine type. This fixes a check-functional failure on aarch64 host, where it would otherwise fail with: qemu-system-aarch64: unsupported machine type: "x-remote" Cc: qemu-stable@nongnu.org Fixes: eb796c55513d9d39 ("hw/core: Allow ARM/Aarch64 binaries to use the 'none' machine") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260507194728.2034696-2-peter.maydell@linaro.org --- hw/remote/machine.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/remote/machine.c b/hw/remote/machine.c index XXXXXXX..XXXXXXX 100644 --- a/hw/remote/machine.c +++ b/hw/remote/machine.c @@ -XXX,XX +XXX,XX @@ #include "hw/core/qdev.h" #include "hw/remote/vfio-user-obj.h" #include "hw/pci/msi.h" +#include "hw/arm/machines-qom.h" static void remote_machine_init(MachineState *machine) { @@ -XXX,XX +XXX,XX @@ static const TypeInfo remote_machine = { .class_init = remote_machine_class_init, .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, + { TYPE_TARGET_AARCH64_MACHINE }, + { TYPE_TARGET_ARM_MACHINE }, { } } }; -- 2.43.0
If you try to run the functional tests on an AArch64 host which doesn't support nested virtualization in KVM, the UEFI test fails with: Output: qemu-system-aarch64: mach-virt: host kernel KVM does not support providing Virtualization extensions to the guest CPU Catch the VMLaunchFailure exception and if it matches the error messages the virt board puts out for virtualization not being supported, skip the test. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260507194728.2034696-3-peter.maydell@linaro.org --- tests/functional/aarch64/test_virt_vbsa.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/functional/aarch64/test_virt_vbsa.py b/tests/functional/aarch64/test_virt_vbsa.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_virt_vbsa.py +++ b/tests/functional/aarch64/test_virt_vbsa.py @@ -XXX,XX +XXX,XX @@ from qemu_test import get_qemu_img, skipIfMissingCommands from qemu_test import wait_for_console_pattern from qemu_test import exec_command_and_wait_for_pattern as ec_and_wait +from qemu.machine.machine import VMLaunchFailure @skipIfMissingCommands("mformat", "mcopy", "mmd") @@ -XXX,XX +XXX,XX @@ def test_aarch64_vbsa_uefi_tests(self): f'file={img_path},format=raw,if=none,id=drive0') self.vm.add_args('-device', 'virtio-blk-pci,drive=drive0') - self.vm.launch() + try: + self.vm.launch() + except VMLaunchFailure as excp: + if "does not support providing Virtualization" in excp.output: + self.skipTest("accelerator has no virtualization support") + else: + self.log.info("unhandled launch failure: %s", excp.output) + raise excp # wait for EFI prompt self.wait_for_console_pattern('Shell>') -- 2.43.0
The test_kvm test claims to run on any accelerator supporting nested virtualization, but it specifies the cortex-a72 CPU. This doesn't exist for KVM-only builds. Use max instead. This fixes a failure like Output: qemu-system-aarch64: unable to find CPU model 'cortex-a72' Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260507194728.2034696-4-peter.maydell@linaro.org --- tests/functional/aarch64/test_kvm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/aarch64/test_kvm.py b/tests/functional/aarch64/test_kvm.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_kvm.py +++ b/tests/functional/aarch64/test_kvm.py @@ -XXX,XX +XXX,XX @@ def _launch_guest(self, kvm_mode="nvhe"): kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + f"console=ttyAMA0 kvm-arm.mode={kvm_mode}") - self.vm.add_args("-cpu", "cortex-a72") + self.vm.add_args("-cpu", "max") self.vm.add_args("-machine", "virt,gic-version=3,virtualization=on", '-kernel', kernel_path, '-append', kernel_command_line) -- 2.43.0
The test_kvm test runs the virt board with virtualization=on, which will fail if run with an accelerator that doesn't support nested virtualization. Catch the VMLaunchFailure exception and skip the test if startup failed because the accelerator can't support virtualization. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260507194728.2034696-5-peter.maydell@linaro.org --- tests/functional/aarch64/test_kvm.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/functional/aarch64/test_kvm.py b/tests/functional/aarch64/test_kvm.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_kvm.py +++ b/tests/functional/aarch64/test_kvm.py @@ -XXX,XX +XXX,XX @@ from qemu_test import Asset from qemu_test import exec_command_and_wait_for_pattern as ec_and_wait from qemu_test.linuxkernel import LinuxKernelTest +from qemu.machine.machine import VMLaunchFailure class Aarch64VirtKVMTests(LinuxKernelTest): @@ -XXX,XX +XXX,XX @@ def _launch_guest(self, kvm_mode="nvhe"): '-append', kernel_command_line) self.vm.add_args("-smp", "2", "-m", "320") - self.vm.launch() + try: + self.vm.launch() + except VMLaunchFailure as excp: + if "does not support providing Virtualization" in excp.output: + self.skipTest("accelerator has no virtualization support") + else: + self.log.info("unhandled launch failure: %s", excp.output) + raise excp self.wait_for_console_pattern('buildroot login:') ec_and_wait(self, 'root', '#') -- 2.43.0
The hotplug test asks for the cortex-a57 CPU type, so it will fail on an AArch64 system using KVM where TCG is not compiled into QEMU and the default accelerator is KVM: Output: qemu-system-aarch64: kvm_init_vcpu: kvm_arch_init_vcpu failed (0): Invalid argument Restrict it to the TCG accelerator. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260507194728.2034696-6-peter.maydell@linaro.org --- tests/functional/aarch64/test_hotplug_pci.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/functional/aarch64/test_hotplug_pci.py b/tests/functional/aarch64/test_hotplug_pci.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_hotplug_pci.py +++ b/tests/functional/aarch64/test_hotplug_pci.py @@ -XXX,XX +XXX,XX @@ class HotplugPCI(LinuxKernelTest): def test_hotplug_pci(self): self.set_machine('virt') + self.require_accelerator('tcg') self.vm.add_args('-m', '512M', '-cpu', 'cortex-a57', -- 2.43.0
The tuxrun tests specify the cortex-a57 CPU; this doesn't work on a KVM-only QEMU build, where the default accelerator is KVM but KVM doesn't support that CPU type. Restrict the test to TCG, to avoid failures on KVM-only AArch64 builds: Output: qemu-system-aarch64: kvm_init_vcpu: kvm_arch_init_vcpu failed (0): Invalid argument Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260507194728.2034696-7-peter.maydell@linaro.org --- tests/functional/aarch64/test_tuxrun.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/functional/aarch64/test_tuxrun.py b/tests/functional/aarch64/test_tuxrun.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_tuxrun.py +++ b/tests/functional/aarch64/test_tuxrun.py @@ -XXX,XX +XXX,XX @@ class TuxRunAarch64Test(TuxRunBaselineTest): def test_arm64(self): self.set_machine('virt') + self.require_accelerator('tcg') self.cpu='cortex-a57' self.console='ttyAMA0' self.wait_for_shutdown=False @@ -XXX,XX +XXX,XX @@ def test_arm64(self): def test_arm64be(self): self.set_machine('virt') + self.require_accelerator('tcg') self.cpu='cortex-a57' self.console='ttyAMA0' self.wait_for_shutdown=False -- 2.43.0
The Python os.setxattr() API is Linux-specific, so trying to use it on other OSes triggers a failure: File "/Users/pm215/src/qemu/tests/functional/qemu_test/asset.py", line 227, in fetch os.setxattr(str(tmp_cache_file), "user.qemu-asset-url", ^^^^^^^^^^^ AttributeError: module 'os' has no attribute 'setxattr' Since we only set the attributes here for informational purposes, skip them when os.setxattr() isn't available. Cc: qemu-stable@nongnu.org Fixes: 9903217a4ed013 ("tests/functional: add a module for handling asset download & caching") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Thomas Huth <th.huth+qemu@posteo.eu> Message-id: 20260501115506.3792110-1-peter.maydell@linaro.org --- tests/functional/qemu_test/asset.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/functional/qemu_test/asset.py b/tests/functional/qemu_test/asset.py index XXXXXXX..XXXXXXX 100644 --- a/tests/functional/qemu_test/asset.py +++ b/tests/functional/qemu_test/asset.py @@ -XXX,XX +XXX,XX @@ def fetch(self): raise AssetError(self, "Download retries exceeded", transient=True) try: - # Set these just for informational purposes - os.setxattr(str(tmp_cache_file), "user.qemu-asset-url", - self.url.encode('utf8')) - os.setxattr(str(tmp_cache_file), "user.qemu-asset-hash", - self.hash.encode('utf8')) + # Set these just for informational purposes. Note that + # setxattr is Linux-only; as this is only informational + # we can simply skip it on other platforms. + if hasattr(os, "setxattr"): + os.setxattr(str(tmp_cache_file), "user.qemu-asset-url", + self.url.encode('utf8')) + os.setxattr(str(tmp_cache_file), "user.qemu-asset-hash", + self.hash.encode('utf8')) except OSError as e: self.log.debug("Unable to set xattr on %s: %s", tmp_cache_file, e) -- 2.43.0
From: "Scott J. Goldman" <scottjgo@gmail.com> Commit b5f8f77271 ("accel/hvf: Implement WFI without using pselect()") changed hvf_wfi() from blocking the vCPU thread with pselect() to returning EXCP_HLT, intending QEMU's main event loop to handle the idle wait. However, cpu->halted was never set, so cpu_thread_is_idle() always returns false and the vCPU thread spins at 100% CPU per core while the guest is idle. Fix this by: 1. Setting cpu->halted = 1 in hvf_wfi() so the vCPU thread sleeps on halt_cond in qemu_process_cpu_events(). 2. Arming a per-vCPU QEMU_CLOCK_VIRTUAL timer to fire when the guest's virtual timer (CNTV_CVAL_EL0) would expire. This is necessary because HVF only delivers HV_EXIT_REASON_VTIMER_ACTIVATED during hv_vcpu_run(), which is not called while the CPU is halted. The timer callback mirrors the VTIMER_ACTIVATED handler: it raises the vtimer IRQ through the GIC and marks vtimer_masked, causing the interrupt delivery chain to wake the vCPU via qemu_cpu_kick(). 3. Clearing cpu->halted in hvf_arch_vcpu_exec() when cpu_has_work() indicates a pending interrupt, and cancelling the WFI timer. 4. Re-arming the WFI timer from hvf_vm_state_change() on the resume transition for any halted vCPU, since the QEMUTimer is per-instance state and is not migrated. After cpu_synchronize_all_states() the migrated vtimer state is mirrored in env, so we can read CNTV_CTL and CNTV_CVAL from there. If the vtimer has already expired by the time the destination resumes, hvf_wfi_timer_cb() is invoked directly so the halted vCPU is woken up. All wfi_timer handling (allocation, arming, deletion, and the resume re-arm) is gated on !hvf_irqchip_in_kernel(): with the Apple in-kernel vGIC, HVF owns the vtimer and delivers wake-ups itself. Note for stable backports: this commit won't apply to 11.0 as it has changes to handle the hvf in-kernel irqchip support that landed after the 11.0 release. The v3 version of this commit: https://patchew.org/QEMU/20260427195516.46256-1-scottjgo@gmail.com/ should be suitable for 11.0 backporting (it is essentially identical except that it doesn't make the changes conditional on !hvf_irqchip_in_kernel()). Cc: qemu-stable@nongnu.org Fixes: b5f8f77271 ("accel/hvf: Implement WFI without using pselect()") Signed-off-by: Scott J. Goldman <scottjgo@gmail.com> Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr> [PMM: added note about stable backports to commit message] Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/system/hvf_int.h | 1 + target/arm/hvf/hvf.c | 140 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 1 deletion(-) diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h index XXXXXXX..XXXXXXX 100644 --- a/include/system/hvf_int.h +++ b/include/system/hvf_int.h @@ -XXX,XX +XXX,XX @@ struct AccelCPUState { hv_vcpu_exit_t *exit; bool vtimer_masked; bool guest_debug_enabled; + struct QEMUTimer *wfi_timer; #endif }; diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -XXX,XX +XXX,XX @@ #include "hw/core/irq.h" #include "hw/arm/virt.h" #include "qemu/main-loop.h" +#include "qemu/timer.h" #include "system/cpus.h" #include "arm-powerctl.h" #include "target/arm/cpu.h" @@ -XXX,XX +XXX,XX @@ void hvf_arm_init_debug(void) #define TMR_CTL_IMASK (1 << 1) #define TMR_CTL_ISTATUS (1 << 2) +static void hvf_wfi_timer_cb(void *opaque); + static uint32_t chosen_ipa_bit_size; typedef struct HVFVTimer { @@ -XXX,XX +XXX,XX @@ void hvf_arch_vcpu_destroy(CPUState *cpu) { hv_return_t ret; + if (!hvf_irqchip_in_kernel()) { + timer_free(cpu->accel->wfi_timer); + cpu->accel->wfi_timer = NULL; + } + ret = hv_vcpu_destroy(cpu->accel->fd); assert_hvf_ok(ret); } @@ -XXX,XX +XXX,XX @@ int hvf_arch_init_vcpu(CPUState *cpu) arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]); assert_hvf_ok(ret); + if (!hvf_irqchip_in_kernel()) { + cpu->accel->wfi_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + hvf_wfi_timer_cb, cpu); + } + aarch64_add_sme_properties(OBJECT(cpu)); return 0; } @@ -XXX,XX +XXX,XX @@ static uint64_t hvf_vtimer_val_raw(void) return mach_absolute_time() - hvf_state->vtimer_offset; } +static void hvf_wfi_timer_cb(void *opaque) +{ + CPUState *cpu = opaque; + ARMCPU *arm_cpu = ARM_CPU(cpu); + + /* + * vtimer expired while the CPU was halted for WFI. + * Mirror HV_EXIT_REASON_VTIMER_ACTIVATED: raise the vtimer + * interrupt and mark as masked so hvf_sync_vtimer() will + * check and unmask when the guest handles it. + * + * The interrupt delivery chain (GIC -> cpu_interrupt -> + * qemu_cpu_kick) wakes the vCPU thread from halt_cond. + */ + qemu_set_irq(arm_cpu->gt_timer_outputs[GTIMER_VIRT], 1); + cpu->accel->vtimer_masked = true; +} + +/* + * Arm a host-side QEMU_CLOCK_VIRTUAL timer to fire when the guest's + * vtimer (CNTV_CVAL_EL0) is scheduled to expire. HVF only delivers + * HV_EXIT_REASON_VTIMER_ACTIVATED during hv_vcpu_run(), which we won't + * call while the vCPU is halted, so we need this to wake the vCPU. + * + * QEMU_CLOCK_VIRTUAL pauses while the VM is stopped, which keeps the + * timer in lockstep with the guest's view of vtime across pause/resume. + * + * Caller must supply the current CNTV_CTL_EL0 and CNTV_CVAL_EL0 values, + * since the appropriate source (HVF vs. env) depends on context. + * + * Returns 0 if the timer was armed (or if the vtimer is disabled/masked + * and the vCPU should still halt waiting on another event), or -1 if + * the vtimer has already expired. + */ +static int hvf_arm_wfi_timer(CPUState *cpu, uint64_t ctl, uint64_t cval) +{ + ARMCPU *arm_cpu = ARM_CPU(cpu); + uint64_t now; + int64_t delta_ns; + + if (!(ctl & TMR_CTL_ENABLE) || (ctl & TMR_CTL_IMASK)) { + return 0; + } + + now = hvf_vtimer_val_raw(); + if (cval <= now) { + return -1; + } + + delta_ns = muldiv64(cval - now, NANOSECONDS_PER_SECOND, + arm_cpu->gt_cntfrq_hz); + timer_mod(cpu->accel->wfi_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + delta_ns); + return 0; +} + static int hvf_wfi(CPUState *cpu) { if (cpu_has_work(cpu)) { @@ -XXX,XX +XXX,XX @@ static int hvf_wfi(CPUState *cpu) return 0; } + if (!hvf_irqchip_in_kernel()) { + uint64_t ctl, cval; + hv_return_t r; + + /* + * Read the vtimer state directly from HVF. We're on the vCPU + * thread, just exited from hv_vcpu_run(), so HVF holds the + * authoritative values and env may be stale. + */ + r = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CTL_EL0, + &ctl); + assert_hvf_ok(r); + r = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CVAL_EL0, + &cval); + assert_hvf_ok(r); + + if (hvf_arm_wfi_timer(cpu, ctl, cval) < 0) { + /* vtimer already expired, don't halt */ + return 0; + } + } + + cpu->halted = 1; return EXCP_HLT; } @@ -XXX,XX +XXX,XX @@ int hvf_arch_vcpu_exec(CPUState *cpu) hv_return_t r; if (cpu->halted) { - return EXCP_HLT; + if (!cpu_has_work(cpu)) { + return EXCP_HLT; + } + cpu->halted = 0; + if (!hvf_irqchip_in_kernel()) { + timer_del(cpu->accel->wfi_timer); + } } flush_cpu_state(cpu); @@ -XXX,XX +XXX,XX @@ static void hvf_vm_state_change(void *opaque, bool running, RunState state) /* Update vtimer offset on all CPUs */ hvf_state->vtimer_offset = mach_absolute_time() - s->vtimer_val; cpu_synchronize_all_states(); + + /* + * After migration restore (or any resume), the wfi_timer is not + * scheduled on this QEMU instance, so re-arm it for any halted + * vCPU with a pending vtimer. For a non-migration resume the + * QEMU_CLOCK_VIRTUAL timer was already scheduled; recomputing the + * deadline produces the same value and is a harmless no-op. + * + * cpu_synchronize_all_states() above ensures env mirrors the + * authoritative vtimer state (whether that came from HVF or from + * the migration stream), so we can safely read it here from the + * iothread. + * + * Only applies when we own the wfi_timer; with an in-kernel vGIC + * the timer is never allocated and HVF handles vtimer wake-ups. + */ + if (!hvf_irqchip_in_kernel()) { + CPUState *cpu; + + CPU_FOREACH(cpu) { + ARMCPU *arm_cpu; + uint64_t ctl, cval; + + if (!cpu->accel || !cpu->halted) { + continue; + } + + arm_cpu = ARM_CPU(cpu); + ctl = arm_cpu->env.cp15.c14_timer[GTIMER_VIRT].ctl; + cval = arm_cpu->env.cp15.c14_timer[GTIMER_VIRT].cval; + + if (hvf_arm_wfi_timer(cpu, ctl, cval) < 0) { + /* + * vtimer already expired while we were paused; raise + * the IRQ now so the halted vCPU wakes up. + */ + hvf_wfi_timer_cb(cpu); + } + } + } } else { /* Remember vtimer value on every pause */ s->vtimer_val = hvf_vtimer_val_raw(); -- 2.43.0
v3->v4: Windows headers define an INT type which clashed with an enum value name in arm_gicv3_its.c... The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5: Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913-3 for you to fetch changes up to 28e987a7e7edaa3ca7feeac65edca26145df8814: hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 21:01:08 +0100) ---------------------------------------------------------------- target-arm queue: * mark MPS2/MPS3 board-internal i2c buses as 'full' so that command line user-created devices are not plugged into them * Take an exception if PSTATE.IL is set * Support an emulated ITS in the virt board * Add support for kudo-bmc board * Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM * cadence_uart: Fix clock handling issues that prevented u-boot from running ---------------------------------------------------------------- Bin Meng (6): hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase hw/char: cadence_uart: Disable transmit when input clock is disabled hw/char: cadence_uart: Move clock/reset check to uart_can_receive() hw/char: cadence_uart: Convert to memop_with_attrs() ops hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}() hw/char: cadence_uart: Log a guest error when device is unclocked or in reset Chris Rauer (1): hw/arm: Add support for kudo-bmc board. Marc Zyngier (1): hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM Peter Maydell (5): target/arm: Take an exception if PSTATE.IL is set qdev: Support marking individual buses as 'full' hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full' hw/arm/mps2.c: Mark internal-only I2C buses as 'full' Richard Henderson (1): target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn Shashi Mallela (9): hw/intc: GICv3 ITS initial framework hw/intc: GICv3 ITS register definitions added hw/intc: GICv3 ITS command queue framework hw/intc: GICv3 ITS Command processing hw/intc: GICv3 ITS Feature enablement hw/intc: GICv3 redistributor ITS processing tests/data/acpi/virt: Add IORT files for ITS hw/arm/virt: add ITS support in virt GIC tests/data/acpi/virt: Update IORT files for ITS docs/system/arm/nuvoton.rst | 1 + hw/intc/gicv3_internal.h | 188 ++++- include/hw/arm/virt.h | 2 + include/hw/intc/arm_gicv3_common.h | 13 + include/hw/intc/arm_gicv3_its_common.h | 32 +- include/hw/qdev-core.h | 24 + target/arm/cpu.h | 1 + target/arm/kvm_arm.h | 4 +- target/arm/syndrome.h | 5 + target/arm/translate.h | 2 + hw/arm/mps2-tz.c | 92 ++- hw/arm/mps2.c | 12 +- hw/arm/npcm7xx_boards.c | 34 + hw/arm/virt.c | 29 +- hw/char/cadence_uart.c | 61 +- hw/intc/arm_gicv3.c | 14 + hw/intc/arm_gicv3_common.c | 13 + hw/intc/arm_gicv3_cpuif.c | 7 +- hw/intc/arm_gicv3_dist.c | 5 +- hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_its_common.c | 7 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/arm_gicv3_redist.c | 153 +++- hw/misc/zynq_slcr.c | 31 +- softmmu/qdev-monitor.c | 7 +- target/arm/helper-a64.c | 1 + target/arm/helper.c | 8 + target/arm/kvm.c | 7 +- target/arm/translate-a64.c | 255 +++--- target/arm/translate.c | 21 + hw/intc/meson.build | 1 + tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes 35 files changed, 2144 insertions(+), 210 deletions(-) create mode 100644 hw/intc/arm_gicv3_its.c create mode 100644 tests/data/acpi/virt/IORT create mode 100644 tests/data/acpi/virt/IORT.memhp create mode 100644 tests/data/acpi/virt/IORT.numamem create mode 100644 tests/data/acpi/virt/IORT.pxb