:p
atchew
Login
The following changes since commit 7390b0825b8e041a961f6215a18fa68213dc4779: Merge tag 'single-binary-20260226' of https://github.com/philmd/qemu into staging (2026-02-26 09:33:12 +0000) are available in the Git repository at: https://gitlab.com/pm215/qemu.git tags/pull-target-arm-20260226 for you to fetch changes up to 907b8d56351b1ba6c97953edaca6a08f02fa2048: hw/char/pl011: Only log "data written to disabled UART" once (2026-02-26 11:27:19 +0000) ---------------------------------------------------------------- target-arm queue: * target/arm: set the correct TI bits for WFIT traps * target/arm: Refactorings preparatory to KVM SME support * target/arm/kvm: Don't free migration-blocker reason on failure * target/arm/kvm: add kvm-psci-version vcpu property * Revert "target/arm/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0" * hw/arm/virt: Add virtio-mmio-transports property * hw/arm/virt: Update error message for bad gic-version option * hw/cpu: Build a15mpcore.c once as common object * hw/misc/allwinner-cpucfg: Remove use of ARM_CPU() cast macro * hw/ssi/xilinx_spips: Reset TX FIFO in reset * hw/char/pl011: Only log "data written to disabled UART" once * tests/functional: Make sure test case .py files are executable ---------------------------------------------------------------- Alex Bennée (1): target/arm: set the correct TI bits for WFIT traps Mohamed Mediouni (1): Revert "target/arm/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0" Mohammadfaiz Bawa (1): hw/arm/virt: Add virtio-mmio-transports property Peter Maydell (4): hw/arm/virt: Update error message for bad gic-version option tests/functional: Make sure test case .py files are executable target/arm/kvm: Don't free migration-blocker reason on failure hw/char/pl011: Only log "data written to disabled UART" once Philippe Mathieu-Daudé (2): hw/cpu: Build a15mpcore.c once as common object hw/misc/allwinner-cpucfg: Remove use of ARM_CPU() cast macro Richard Henderson (9): target/arm: Remove aarch64 test for kvm target/arm: Move kvm_arm_sve_get_vls within kvm.c target/arm: Init sve_vq in kvm_arm_set_cpu_features_from_host target/arm: Move kvm test out of cpu_arm_set_sve target/arm: Drop kvm_arm_sve_supported target/arm: Remove kvm test in arm_set_pmu target/arm: Drop kvm_arm_pmu_supported target/arm: Add vq argument to kvm_arch_{get, put}_sve target/arm: Add have_ffr argument to kvm_arch_{get, put}_sve Sebastian Ott (1): target/arm/kvm: add kvm-psci-version vcpu property Weixie Cui (1): hw/ssi/xilinx_spips: Reset TX FIFO in reset docs/system/arm/cpu-features.rst | 11 +++ docs/system/arm/virt.rst | 5 + hw/arm/virt-acpi-build.c | 2 +- hw/arm/virt.c | 45 ++++++++- hw/char/pl011.c | 24 ++++- hw/cpu/a15mpcore.c | 2 +- hw/cpu/meson.build | 2 +- hw/misc/allwinner-cpucfg.c | 4 +- hw/ssi/xilinx_spips.c | 4 +- include/hw/arm/virt.h | 1 + include/hw/char/pl011.h | 1 + target/arm/cpu.c | 12 ++- target/arm/cpu64.c | 72 ++++++++------ target/arm/hvf/hvf.c | 25 ----- target/arm/kvm-stub.c | 15 --- target/arm/kvm.c | 197 ++++++++++++++++++++----------------- target/arm/kvm_arm.h | 35 ------- target/arm/tcg/cpu64.c | 2 +- target/arm/tcg/op_helper.c | 2 +- tests/functional/ppc/test_ppe42.py | 0 20 files changed, 246 insertions(+), 215 deletions(-) mode change 100644 => 100755 tests/functional/ppc/test_ppe42.py
From: Weixie Cui <cuiweixie@gmail.com> In xilinx_spips_reset() and xlnx_zynqmp_qspips_reset() a cut and paste error meant we reset the RX FIFO twice and the TX FIFO not at all. Correct this to reset both FIFOs. Cc: qemu-stable@nongnu.org Signed-off-by: Weixie Cui <cuiweixie@gmail.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260223095905.67709-1-cuiweixie@gmail.com [Rewrote commit message] Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/ssi/xilinx_spips.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c index XXXXXXX..XXXXXXX 100644 --- a/hw/ssi/xilinx_spips.c +++ b/hw/ssi/xilinx_spips.c @@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d) memset(s->regs, 0, sizeof(s->regs)); fifo8_reset(&s->rx_fifo); - fifo8_reset(&s->rx_fifo); + fifo8_reset(&s->tx_fifo); /* non zero resets */ s->regs[R_CONFIG] |= MODEFAIL_GEN_EN; s->regs[R_SLAVE_IDLE_COUNT] = 0xFF; @@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d) memset(s->regs, 0, sizeof(s->regs)); fifo8_reset(&s->rx_fifo_g); - fifo8_reset(&s->rx_fifo_g); + fifo8_reset(&s->tx_fifo_g); fifo32_reset(&s->fifo_g); s->regs[R_INTR_STATUS] = R_INTR_STATUS_RESET; s->regs[R_GPIO] = 1; -- 2.43.0
From: Alex Bennée <alex.bennee@linaro.org> The WFIT trap should be reported as 0b10. Cc: qemu-stable@nongnu.org Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org> Message-id: 20260220171945.1065102-1-alex.bennee@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/tcg/op_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/tcg/op_helper.c +++ b/target/arm/tcg/op_helper.c @@ -XXX,XX +XXX,XX @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout) if (target_el) { env->pc -= 4; - raise_exception(env, excp, syn_wfx(1, 0xe, 0, false), target_el); + raise_exception(env, excp, syn_wfx(1, 0xe, 2, false), target_el); } if (uadd64_overflow(timeout, offset, &nexttick)) { -- 2.43.0
From: Mohammadfaiz Bawa <mbawa@redhat.com> Windows ARM64 guests detect virtio-mmio devices declared in ACPI tables even when no backend is attached. This causes "Unknown devices" (ACPI\LNRO0005) to appear in Device Manager. Until Windows fixes that by supporting, add a new machine property 'virtio-mmio-transports' to control the number of virtio-mmio transports instantiated. The default remains NUM_VIRTIO_TRANSPORTS (32) for backward compatibility. Setting it to 0 allows users to disable virtio-mmio entirely. Usage: -machine virt,virtio-mmio-transports=0 Signed-off-by: Mohammadfaiz Bawa <mbawa@redhat.com> Message-id: 20260219173256.152743-1-mbawa@redhat.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- docs/system/arm/virt.rst | 5 +++++ hw/arm/virt-acpi-build.c | 2 +- hw/arm/virt.c | 43 ++++++++++++++++++++++++++++++++++++++-- include/hw/arm/virt.h | 1 + 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/virt.rst +++ b/docs/system/arm/virt.rst @@ -XXX,XX +XXX,XX @@ dtb-randomness dtb-kaslr-seed A deprecated synonym for dtb-randomness. +virtio-mmio-transports + Set the number of virtio-mmio transports to create (between 0 and 32; + the default is 32). Unused transports are harmless, but you can + use this property to avoid exposing them to the guest if you wish. + x-oem-id Set string (up to 6 bytes) to override the default value of field OEMID in ACPI table header. diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]); virtio_acpi_dsdt_add(scope, memmap[VIRT_MMIO].base, memmap[VIRT_MMIO].size, (irqmap[VIRT_MMIO] + ARM_SPI_BASE), - 0, NUM_VIRTIO_TRANSPORTS); + 0, vms->virtio_transports); acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms); if (vms->acpi_dev) { build_ged_aml(scope, "\\_SB."GED_DEVICE, diff --git a/hw/arm/virt.c b/hw/arm/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms) * between kernel versions). For reliable and stable identification * of disks users must use UUIDs or similar mechanisms. */ - for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) { + for (i = 0; i < vms->virtio_transports; i++) { int irq = vms->irqmap[VIRT_MMIO] + i; hwaddr base = vms->memmap[VIRT_MMIO].base + i * size; @@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms) * loop influences virtio device to virtio transport assignment, whereas * this loop controls how virtio transports are laid out in the dtb. */ - for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) { + for (i = vms->virtio_transports - 1; i >= 0; i--) { char *nodename; int irq = vms->irqmap[VIRT_MMIO] + i; hwaddr base = vms->memmap[VIRT_MMIO].base + i * size; @@ -XXX,XX +XXX,XX @@ static void virt_set_its(Object *obj, bool value, Error **errp) } } +static void virt_get_virtio_transports(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + uint8_t transports = vms->virtio_transports; + + visit_type_uint8(v, name, &transports, errp); +} + +static void virt_set_virtio_transports(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + uint8_t transports; + + if (!visit_type_uint8(v, name, &transports, errp)) { + return; + } + + if (transports > NUM_VIRTIO_TRANSPORTS) { + error_setg(errp, "virtio-mmio-transports must not exceed %d", + NUM_VIRTIO_TRANSPORTS); + return; + } + + vms->virtio_transports = transports; +} + static bool virt_get_dtb_randomness(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) "Set the high memory region size " "for PCI MMIO"); + object_class_property_add(oc, "virtio-mmio-transports", "uint8", + virt_get_virtio_transports, + virt_set_virtio_transports, + NULL, NULL); + object_class_property_set_description(oc, "virtio-mmio-transports", + "Set the number of virtio-mmio transports to instantiate"); + object_class_property_add_str(oc, "gic-version", virt_get_gic_version, virt_set_gic_version); object_class_property_set_description(oc, "gic-version", @@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj) vms->irqmap = a15irqmap; + vms->virtio_transports = NUM_VIRTIO_TRANSPORTS; + virt_flash_create(vms); vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -XXX,XX +XXX,XX @@ struct VirtMachineState { uint32_t msi_phandle; uint32_t iommu_phandle; int psci_conduit; + uint8_t virtio_transports; hwaddr highest_gpa; DeviceState *gic; DeviceState *acpi_dev; -- 2.43.0
As we added different valid gic-version option settings, we forgot to update the hint in the error message produced when the user specifies an invalid value: $ qemu-system-aarch64 -M virt,help | grep gic-version gic-version=<string> - Set GIC version. Valid values are 2, 3, 4, host and max $ qemu-system-aarch64 -M virt,gic-version=bang qemu-system-aarch64: Invalid gic-version value Valid values are 3, 2, host, max. Update the error string to match the one we use in the help text for the option. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20260219110228.3804482-1-peter.maydell@linaro.org --- hw/arm/virt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -XXX,XX +XXX,XX @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp) vms->gic_version = VIRT_GIC_VERSION_MAX; /* Will probe later */ } else { error_setg(errp, "Invalid gic-version value"); - error_append_hint(errp, "Valid values are 3, 2, host, max.\n"); + error_append_hint(errp, "Valid values are 2, 3, 4, host, and max.\n"); } } -- 2.43.0
The top-level test python scripts in tests/functional are supposed to be marked executable; "make check-functional" doesn't care about this, but it allows them to be run as standalone executables to exercise a single test, as docs/devel/testing/functional.rst describes. A couple of files have got into the tree without the executable bit set: fix them. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Thomas Huth <thuth@redhat.com> Message-id: 20260212151258.1750268-1-peter.maydell@linaro.org --- tests/functional/ppc/test_ppe42.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tests/functional/ppc/test_ppe42.py diff --git a/tests/functional/ppc/test_ppe42.py b/tests/functional/ppc/test_ppe42.py old mode 100644 new mode 100755 -- 2.43.0
From: Sebastian Ott <sebott@redhat.com> Provide a kvm specific vcpu property to override the default (as of kernel v6.13 that would be PSCI v1.3) PSCI version emulated by kvm. Current valid values are: 0.1, 0.2, 1.0, 1.1, 1.2, and 1.3 Note: in order to support PSCI v0.1 we need to drop vcpu initialization with KVM_CAP_ARM_PSCI_0_2 in that case. Reviewed-by: Eric Auger <eric.auger@redhat.com> Tested-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Sebastian Ott <sebott@redhat.com> Message-id: 20260220115656.4831-2-sebott@redhat.com [PMM: adjust sscanf to not permit negative numbers] Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- docs/system/arm/cpu-features.rst | 11 ++++++++ target/arm/cpu.c | 8 +++++- target/arm/kvm.c | 48 ++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/cpu-features.rst +++ b/docs/system/arm/cpu-features.rst @@ -XXX,XX +XXX,XX @@ the list of KVM VCPU features and their descriptions. the guest scheduler behavior and/or be exposed to the guest userspace. +``kvm-psci-version`` + Set the Power State Coordination Interface (PSCI) firmware ABI version + that KVM provides to the guest. By default KVM will use the newest + version that it knows about (which is PSCI v1.3 in Linux v6.13). + + You only need to set this if you want to be able to migrate this + VM to a host machine running an older kernel that does not + recognize the PSCI version that this host's kernel defaults to. + + Current valid values are: 0.1, 0.2, 1.0, 1.1, 1.2, and 1.3. + TCG VCPU Features ================= 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 @@ static void arm_cpu_initfn(Object *obj) * picky DTB consumer will also provide a helpful error message. */ cpu->dtb_compatible = "qemu,unknown"; - cpu->psci_version = QEMU_PSCI_VERSION_0_1; /* By default assume PSCI v0.1 */ + if (!kvm_enabled()) { + /* By default KVM will use the newest PSCI version that it knows about. + * This can be changed using the kvm-psci-version property. + * For others assume PSCI v0.1 by default. + */ + cpu->psci_version = QEMU_PSCI_VERSION_0_1; + } cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE; if (tcg_enabled() || hvf_enabled()) { diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ static void kvm_steal_time_set(Object *obj, bool value, Error **errp) ARM_CPU(obj)->kvm_steal_time = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; } +static char *kvm_get_psci_version(Object *obj, Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + + return g_strdup_printf("%d.%d", + (int) PSCI_VERSION_MAJOR(cpu->psci_version), + (int) PSCI_VERSION_MINOR(cpu->psci_version)); +} + +static void kvm_set_psci_version(Object *obj, const char *value, Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + uint16_t maj, min; + + if (sscanf(value, "%hu.%hu", &maj, &min) != 2) { + error_setg(errp, "Invalid PSCI version."); + return; + } + + cpu->psci_version = PSCI_VERSION(maj, min); +} + /* KVM VCPU properties should be prefixed with "kvm-". */ void kvm_arm_add_vcpu_properties(ARMCPU *cpu) { @@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(ARMCPU *cpu) kvm_steal_time_set); object_property_set_description(obj, "kvm-steal-time", "Set off to disable KVM steal time."); + + object_property_add_str(obj, "kvm-psci-version", kvm_get_psci_version, + kvm_set_psci_version); + object_property_set_description(obj, "kvm-psci-version", + "Set PSCI version. " + "Valid values are 0.1, 0.2, 1.0, 1.1, 1.2, 1.3"); } bool kvm_arm_pmu_supported(void) @@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs) if (cs->start_powered_off) { cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF; } - if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) { - cpu->psci_version = QEMU_PSCI_VERSION_0_2; + if (cpu->psci_version != QEMU_PSCI_VERSION_0_1 && + kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) { + /* + * Versions >= v0.2 are backward compatible with v0.2 + * omit the feature flag for v0.1 . + */ cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2; } if (!arm_feature(env, ARM_FEATURE_AARCH64)) { @@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs) } } + if (cpu->psci_version) { + psciver = cpu->psci_version; + ret = kvm_set_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver); + if (ret) { + error_report("KVM in this kernel does not support PSCI version %d.%d", + (int) PSCI_VERSION_MAJOR(psciver), + (int) PSCI_VERSION_MINOR(psciver)); + error_printf("Consider setting the kvm-psci-version property on the " + "migration source.\n"); + return ret; + } + } /* * KVM reports the exact PSCI version it is implementing via a * special sysreg. If it is present, use its contents to determine -- 2.43.0
From: Mohamed Mediouni <mohamed@unpredictable.fr> This reverts commit bfbea371ef2cabc47effac5a286e2644d727a8d6. This commit breaks VM save/restore: Assertion failed: (b), function hvf_arch_get_registers, file hvf.c, line 667. zsh: abort ./qemu-system-aarch64 -m 8192 -M virt,accel=hvf -cdrom -device virtio-gpu Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr> Tested-by: Zenghui Yu <zenghui.yu@linux.dev> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/hvf/hvf.c | 25 ------------------------- 1 file changed, 25 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 @@ void hvf_arm_init_debug(void) #define SYSREG_PMCEID0_EL0 SYSREG(3, 3, 9, 12, 6) #define SYSREG_PMCEID1_EL0 SYSREG(3, 3, 9, 12, 7) #define SYSREG_PMCCNTR_EL0 SYSREG(3, 3, 9, 13, 0) - -#define SYSREG_CNTV_CTL_EL0 SYSREG(3, 3, 14, 3, 1) -#define SYSREG_CNTV_CVAL_EL0 SYSREG(3, 3, 14, 3, 2) #define SYSREG_PMCCFILTR_EL0 SYSREG(3, 3, 14, 15, 7) #define SYSREG_ICC_AP0R0_EL1 SYSREG(3, 0, 12, 8, 4) @@ -XXX,XX +XXX,XX @@ int hvf_arch_get_registers(CPUState *cpu) uint64_t val; hv_simd_fp_uchar16_t fpval; int i, n; - bool b; for (i = 0; i < ARRAY_SIZE(hvf_reg_match); i++) { ret = hv_vcpu_get_reg(cpu->accel->fd, hvf_reg_match[i].reg, &val); @@ -XXX,XX +XXX,XX @@ int hvf_arch_get_registers(CPUState *cpu) aarch64_restore_sp(env, arm_current_el(env)); - ret = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CVAL_EL0, &val); - assert_hvf_ok(ret); - b = hvf_sysreg_write_cp(cpu, "VTimer", SYSREG_CNTV_CVAL_EL0, val); - assert(b); - - ret = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CTL_EL0, &val); - assert_hvf_ok(ret); - b = hvf_sysreg_write_cp(cpu, "VTimer", SYSREG_CNTV_CTL_EL0, val); - assert(b); - return 0; } @@ -XXX,XX +XXX,XX @@ int hvf_arch_put_registers(CPUState *cpu) uint64_t val; hv_simd_fp_uchar16_t fpval; int i, n; - bool b; for (i = 0; i < ARRAY_SIZE(hvf_reg_match); i++) { val = *(uint64_t *)((void *)env + hvf_reg_match[i].offset); @@ -XXX,XX +XXX,XX @@ int hvf_arch_put_registers(CPUState *cpu) ret = hv_vcpu_set_vtimer_offset(cpu->accel->fd, hvf_state->vtimer_offset); assert_hvf_ok(ret); - b = hvf_sysreg_read_cp(cpu, "VTimer", SYSREG_CNTV_CVAL_EL0, &val); - assert(b); - ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CVAL_EL0, val); - assert_hvf_ok(ret); - - b = hvf_sysreg_read_cp(cpu, "VTimer", SYSREG_CNTV_CTL_EL0, &val); - assert(b); - ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CTL_EL0, val); - assert_hvf_ok(ret); - return 0; } -- 2.43.0
From: Philippe Mathieu-Daudé <philmd@linaro.org> a15mpcore.c doesn't need to include the target-specific 'kvm_arm.h' header, it only lacks the qemu_get_cpu() declaration which comes from 'hw/core/cpu.h'. Include the latter and build as common object. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260225034451.41338-1-philmd@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/cpu/a15mpcore.c | 2 +- hw/cpu/meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c index XXXXXXX..XXXXXXX 100644 --- a/hw/cpu/a15mpcore.c +++ b/hw/cpu/a15mpcore.c @@ -XXX,XX +XXX,XX @@ #include "qapi/error.h" #include "qemu/module.h" #include "hw/cpu/a15mpcore.h" +#include "hw/core/cpu.h" #include "hw/core/irq.h" #include "hw/core/qdev-properties.h" #include "system/kvm.h" -#include "kvm_arm.h" #include "target/arm/gtimer.h" static void a15mp_priv_set_irq(void *opaque, int irq, int level) diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build index XXXXXXX..XXXXXXX 100644 --- a/hw/cpu/meson.build +++ b/hw/cpu/meson.build @@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_CPU_CLUSTER', if_true: files('cluster.c')) system_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c')) system_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c')) system_ss.add(when: 'CONFIG_A9MPCORE', if_true: files('a9mpcore.c')) -specific_ss.add(when: 'CONFIG_A15MPCORE', if_true: files('a15mpcore.c')) +system_ss.add(when: 'CONFIG_A15MPCORE', if_true: files('a15mpcore.c')) -- 2.43.0
From: Philippe Mathieu-Daudé <philmd@linaro.org> allwinner_cpucfg_cpu_reset() doesn't access ARM CPU internal fields: no need to cast, pass a generic CPU pointer along. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260225034720.41495-1-philmd@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/misc/allwinner-cpucfg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/misc/allwinner-cpucfg.c b/hw/misc/allwinner-cpucfg.c index XXXXXXX..XXXXXXX 100644 --- a/hw/misc/allwinner-cpucfg.c +++ b/hw/misc/allwinner-cpucfg.c @@ -XXX,XX +XXX,XX @@ static void allwinner_cpucfg_cpu_reset(AwCpuCfgState *s, uint8_t cpu_id) trace_allwinner_cpucfg_cpu_reset(cpu_id, s->entry_addr); - ARMCPU *target_cpu = ARM_CPU(arm_get_cpu_by_id(cpu_id)); + CPUState *target_cpu = arm_get_cpu_by_id(cpu_id); if (!target_cpu) { /* * Called with a bogus value for cpu_id. Guest error will @@ -XXX,XX +XXX,XX @@ static void allwinner_cpucfg_cpu_reset(AwCpuCfgState *s, uint8_t cpu_id) */ return; } - bool target_aa64 = arm_feature(&target_cpu->env, ARM_FEATURE_AARCH64); + bool target_aa64 = arm_feature(cpu_env(target_cpu), ARM_FEATURE_AARCH64); ret = arm_set_cpu_on(cpu_id, s->entry_addr, 0, CPU_EXCEPTION_LEVEL_ON_RESET, target_aa64); -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> We no longer support kvm for aarch32, therefore the aarch64 test is trivially true. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/cpu64.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 @@ static void aarch64_host_initfn(Object *obj) ARMCPU *cpu = ARM_CPU(obj); #if defined(CONFIG_KVM) kvm_arm_set_cpu_features_from_host(cpu); - if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - aarch64_add_sve_properties(obj); - } + aarch64_add_sve_properties(obj); #elif defined(CONFIG_HVF) hvf_arm_set_cpu_features_from_host(cpu); #elif defined(CONFIG_WHPX) -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> Prepare to adjust the invocation point and visibility. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-4-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/kvm.c | 108 +++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, return ret; } +uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu) +{ + /* Only call this function if kvm_arm_sve_supported() returns true. */ + static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS]; + static bool probed; + uint32_t vq = 0; + int i; + + /* + * KVM ensures all host CPUs support the same set of vector lengths. + * So we only need to create the scratch VCPUs once and then cache + * the results. + */ + if (!probed) { + struct kvm_vcpu_init init = { + .target = -1, + .features[0] = (1 << KVM_ARM_VCPU_SVE), + }; + struct kvm_one_reg reg = { + .id = KVM_REG_ARM64_SVE_VLS, + .addr = (uint64_t)&vls[0], + }; + int fdarray[3], ret; + + probed = true; + + if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) { + error_report("failed to create scratch VCPU with SVE enabled"); + abort(); + } + ret = ioctl(fdarray[2], KVM_GET_ONE_REG, ®); + kvm_arm_destroy_scratch_host_vcpu(fdarray); + if (ret) { + error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s", + strerror(errno)); + abort(); + } + + for (i = KVM_ARM64_SVE_VLS_WORDS - 1; i >= 0; --i) { + if (vls[i]) { + vq = 64 - clz64(vls[i]) + i * 64; + break; + } + } + if (vq > ARM_MAX_VQ) { + warn_report("KVM supports vector lengths larger than " + "QEMU can enable"); + vls[0] &= MAKE_64BIT_MASK(0, ARM_MAX_VQ); + } + } + + return vls[0]; +} + static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) { /* Identify the feature bits corresponding to the host CPU, and @@ -XXX,XX +XXX,XX @@ bool kvm_arm_mte_supported(void) QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1); -uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu) -{ - /* Only call this function if kvm_arm_sve_supported() returns true. */ - static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS]; - static bool probed; - uint32_t vq = 0; - int i; - - /* - * KVM ensures all host CPUs support the same set of vector lengths. - * So we only need to create the scratch VCPUs once and then cache - * the results. - */ - if (!probed) { - struct kvm_vcpu_init init = { - .target = -1, - .features[0] = (1 << KVM_ARM_VCPU_SVE), - }; - struct kvm_one_reg reg = { - .id = KVM_REG_ARM64_SVE_VLS, - .addr = (uint64_t)&vls[0], - }; - int fdarray[3], ret; - - probed = true; - - if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) { - error_report("failed to create scratch VCPU with SVE enabled"); - abort(); - } - ret = ioctl(fdarray[2], KVM_GET_ONE_REG, ®); - kvm_arm_destroy_scratch_host_vcpu(fdarray); - if (ret) { - error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s", - strerror(errno)); - abort(); - } - - for (i = KVM_ARM64_SVE_VLS_WORDS - 1; i >= 0; --i) { - if (vls[i]) { - vq = 64 - clz64(vls[i]) + i * 64; - break; - } - } - if (vq > ARM_MAX_VQ) { - warn_report("KVM supports vector lengths larger than " - "QEMU can enable"); - vls[0] &= MAKE_64BIT_MASK(0, ARM_MAX_VQ); - } - } - - return vls[0]; -} - static int kvm_arm_sve_set_vls(ARMCPU *cpu) { uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] = { cpu->sve_vq.map }; -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> Probe for SVE vector sizes with the same scratch vm that we use for probing other features. Remove a separate initialization path in arm_cpu_sve_finalize. Unexport kvm_arm_sve_get_vls. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-5-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/cpu64.c | 20 +----------- target/arm/kvm-stub.c | 5 --- target/arm/kvm.c | 73 ++++++++++++++++--------------------------- target/arm/kvm_arm.h | 10 ------ 4 files changed, 28 insertions(+), 80 deletions(-) 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 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) */ uint32_t vq_map = cpu->sve_vq.map; uint32_t vq_init = cpu->sve_vq.init; - uint32_t vq_supported; + uint32_t vq_supported = cpu->sve_vq.supported; uint32_t vq_mask = 0; uint32_t tmp, vq, max_vq = 0; - /* - * CPU models specify a set of supported vector lengths which are - * enabled by default. Attempting to enable any vector length not set - * in the supported bitmap results in an error. When KVM is enabled we - * fetch the supported bitmap from the host. - */ - if (kvm_enabled()) { - if (kvm_arm_sve_supported()) { - cpu->sve_vq.supported = kvm_arm_sve_get_vls(cpu); - vq_supported = cpu->sve_vq.supported; - } else { - assert(!cpu_isar_feature(aa64_sve, cpu)); - vq_supported = 0; - } - } else { - vq_supported = cpu->sve_vq.supported; - } - /* * Process explicit sve<N> properties. * From the properties, sve_vq_map<N> implies sve_vq_init<N>. diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm-stub.c +++ b/target/arm/kvm-stub.c @@ -XXX,XX +XXX,XX @@ void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp) g_assert_not_reached(); } -uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu) -{ - g_assert_not_reached(); -} - void kvm_arm_enable_mte(Object *cpuobj, Error **errp) { g_assert_not_reached(); diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ typedef struct ARMHostCPUFeatures { ARMISARegisters isar; uint64_t features; uint32_t target; + uint32_t sve_vq_supported; const char *dtb_compatible; } ARMHostCPUFeatures; @@ -XXX,XX +XXX,XX @@ static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, return ret; } -uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu) +static uint32_t kvm_arm_sve_get_vls(int fd) { /* Only call this function if kvm_arm_sve_supported() returns true. */ - static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS]; - static bool probed; + uint64_t vls[KVM_ARM64_SVE_VLS_WORDS]; + struct kvm_one_reg reg = { + .id = KVM_REG_ARM64_SVE_VLS, + .addr = (uint64_t)&vls[0], + }; uint32_t vq = 0; - int i; + int ret; - /* - * KVM ensures all host CPUs support the same set of vector lengths. - * So we only need to create the scratch VCPUs once and then cache - * the results. - */ - if (!probed) { - struct kvm_vcpu_init init = { - .target = -1, - .features[0] = (1 << KVM_ARM_VCPU_SVE), - }; - struct kvm_one_reg reg = { - .id = KVM_REG_ARM64_SVE_VLS, - .addr = (uint64_t)&vls[0], - }; - int fdarray[3], ret; - - probed = true; - - if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) { - error_report("failed to create scratch VCPU with SVE enabled"); - abort(); - } - ret = ioctl(fdarray[2], KVM_GET_ONE_REG, ®); - kvm_arm_destroy_scratch_host_vcpu(fdarray); - if (ret) { - error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s", - strerror(errno)); - abort(); - } - - for (i = KVM_ARM64_SVE_VLS_WORDS - 1; i >= 0; --i) { - if (vls[i]) { - vq = 64 - clz64(vls[i]) + i * 64; - break; - } - } - if (vq > ARM_MAX_VQ) { - warn_report("KVM supports vector lengths larger than " - "QEMU can enable"); - vls[0] &= MAKE_64BIT_MASK(0, ARM_MAX_VQ); - } + ret = ioctl(fd, KVM_GET_ONE_REG, ®); + if (ret) { + error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s", + strerror(errno)); + abort(); } - return vls[0]; + for (int i = KVM_ARM64_SVE_VLS_WORDS - 1; i >= 0; --i) { + if (vls[i]) { + vq = 64 - clz64(vls[i]) + i * 64; + break; + } + } + if (vq > ARM_MAX_VQ) { + warn_report("KVM supports vector lengths larger than QEMU can enable"); + } + return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ); } static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) @@ -XXX,XX +XXX,XX @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * So only read the register if we set KVM_ARM_VCPU_SVE above. */ err |= get_host_cpu_reg(fd, ahcf, ID_AA64ZFR0_EL1_IDX); + + /* Read the set of supported vector lengths. */ + arm_host_cpu_features.sve_vq_supported = kvm_arm_sve_get_vls(fd); } } @@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) cpu->kvm_target = arm_host_cpu_features.target; cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible; cpu->isar = arm_host_cpu_features.isar; + cpu->sve_vq.supported = arm_host_cpu_features.sve_vq_supported; env->features = arm_host_cpu_features.features; } diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray, */ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray); -/** - * kvm_arm_sve_get_vls: - * @cpu: ARMCPU - * - * Get all the SVE vector lengths supported by the KVM host, setting - * the bits corresponding to their length in quadwords minus one - * (vq - 1) up to ARM_MAX_VQ. Return the resulting map. - */ -uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu); - /** * kvm_arm_set_cpu_features_from_host: * @cpu: ARMCPU to set the features for -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> Introduce a set of stub property callbacks for when we really don't want to be able to enable SVE. Register the real or stub funtions in aarch64_add_sve_properties depending on whether or not SVE is available. Adjust aarch64_a64fx_initfn to initialize the set of supported vector sizes before calling aarch64_add_sve_properties. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/cpu64.c | 48 ++++++++++++++++++++++++++++++++++++------ target/arm/tcg/cpu64.c | 2 +- 2 files changed, 42 insertions(+), 8 deletions(-) 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 @@ static void cpu_arm_set_vq(Object *obj, Visitor *v, const char *name, vq_map->init |= 1 << (vq - 1); } +static void prop_bool_get_false(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + bool value = false; + visit_type_bool(v, name, &value, errp); +} + +static void prop_bool_set_false(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + bool value; + + if (visit_type_bool(v, name, &value, errp) && value) { + error_setg(errp, "'%s' feature not supported by %s on this host", + name, current_accel_name()); + } +} + +static void prop_add_stub_bool(Object *obj, const char *name) +{ + object_property_add(obj, name, "bool", prop_bool_get_false, + prop_bool_set_false, NULL, NULL); +} + static bool cpu_arm_get_sve(Object *obj, Error **errp) { ARMCPU *cpu = ARM_CPU(obj); @@ -XXX,XX +XXX,XX @@ static bool cpu_arm_get_sve(Object *obj, Error **errp) static void cpu_arm_set_sve(Object *obj, bool value, Error **errp) { ARMCPU *cpu = ARM_CPU(obj); - - if (value && kvm_enabled() && !kvm_arm_sve_supported()) { - error_setg(errp, "'sve' feature not supported by KVM on this host"); - return; - } - FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, SVE, value); } @@ -XXX,XX +XXX,XX @@ void aarch64_add_sve_properties(Object *obj) ARMCPU *cpu = ARM_CPU(obj); uint32_t vq; - object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve); + /* + * For hw virtualization, we have already probed the set of vector + * lengths supported. If there are none, the host doesn't support + * SVE at all. In which case we register a stub property, to allow + * -cpu max,sve=off + * to always be valid. + * + * For TCG, this function is only called for cpu models which + * support SVE. The error message in the stub is written + * assuming host virtualiation is being used. + */ + if (cpu->sve_vq.supported) { + object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve); + } else { + assert(!tcg_enabled()); + prop_add_stub_bool(obj, "sve"); + } for (vq = 1; vq <= ARM_MAX_VQ; ++vq) { char name[8]; diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj) cpu->gic_pribits = 5; /* The A64FX supports only 128, 256 and 512 bit vector lengths */ - aarch64_add_sve_properties(obj); cpu->sve_vq.supported = (1 << 0) /* 128bit */ | (1 << 1) /* 256bit */ | (1 << 3); /* 512bit */ + aarch64_add_sve_properties(obj); cpu->isar.reset_pmcr_el0 = 0x46014040; -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> This function has only one real use, so inline it and drop the stubs. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/kvm-stub.c | 5 ----- target/arm/kvm.c | 9 +-------- target/arm/kvm_arm.h | 12 ------------ 3 files changed, 1 insertion(+), 25 deletions(-) diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm-stub.c +++ b/target/arm/kvm-stub.c @@ -XXX,XX +XXX,XX @@ bool kvm_arm_pmu_supported(void) return false; } -bool kvm_arm_sve_supported(void) -{ - return false; -} - bool kvm_arm_mte_supported(void) { return false; diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, static uint32_t kvm_arm_sve_get_vls(int fd) { - /* Only call this function if kvm_arm_sve_supported() returns true. */ uint64_t vls[KVM_ARM64_SVE_VLS_WORDS]; struct kvm_one_reg reg = { .id = KVM_REG_ARM64_SVE_VLS, @@ -XXX,XX +XXX,XX @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * Ask for SVE if supported, so that we can query ID_AA64ZFR0, * which is otherwise RAZ. */ - sve_supported = kvm_arm_sve_supported(); + sve_supported = kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE); if (sve_supported) { init.features[0] |= 1 << KVM_ARM_VCPU_SVE; } @@ -XXX,XX +XXX,XX @@ bool kvm_arm_el2_supported(void) return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL2); } -bool kvm_arm_sve_supported(void) -{ - return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE); -} - bool kvm_arm_mte_supported(void) { return kvm_check_extension(kvm_state, KVM_CAP_ARM_MTE); @@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs) cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3; } if (cpu_isar_feature(aa64_sve, cpu)) { - assert(kvm_arm_sve_supported()); cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE; } if (cpu_isar_feature(aa64_pauth, cpu)) { diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -XXX,XX +XXX,XX @@ bool kvm_arm_aarch32_supported(void); */ bool kvm_arm_pmu_supported(void); -/** - * kvm_arm_sve_supported: - * - * Returns true if KVM can enable SVE and false otherwise. - */ -bool kvm_arm_sve_supported(void); - /** * kvm_arm_mte_supported: * @@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_pmu_supported(void) return false; } -static inline bool kvm_arm_sve_supported(void) -{ - return false; -} - static inline bool kvm_arm_mte_supported(void) { return false; -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> In kvm_arm_get_host_cpu_features, we only set ARM_FEATURE_PMU if kvm_arm_pmu_supported. In arm_cpu_post_init we only register the "pmu" property if ARM_FEATURE_PMU. Therefore, if kvm is enabled, we can only arrive in arm_set_pmu if kvm_arm_pmu_supported. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/cpu.c | 4 ---- 1 file changed, 4 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 @@ static void arm_set_pmu(Object *obj, bool value, Error **errp) ARMCPU *cpu = ARM_CPU(obj); if (value) { - if (kvm_enabled() && !kvm_arm_pmu_supported()) { - error_setg(errp, "'pmu' feature not supported by KVM on this host"); - return; - } set_feature(&cpu->env, ARM_FEATURE_PMU); } else { unset_feature(&cpu->env, ARM_FEATURE_PMU); -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> This function has only one use, so inline it and drop the stubs. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-9-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/kvm-stub.c | 5 ----- target/arm/kvm.c | 7 +------ target/arm/kvm_arm.h | 13 ------------- 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm-stub.c +++ b/target/arm/kvm-stub.c @@ -XXX,XX +XXX,XX @@ bool kvm_arm_aarch32_supported(void) return false; } -bool kvm_arm_pmu_supported(void) -{ - return false; -} - bool kvm_arm_mte_supported(void) { return false; diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) 1 << KVM_ARM_VCPU_PTRAUTH_GENERIC); } - if (kvm_arm_pmu_supported()) { + if (kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3)) { init.features[0] |= 1 << KVM_ARM_VCPU_PMU_V3; pmu_supported = true; features |= 1ULL << ARM_FEATURE_PMU; @@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(ARMCPU *cpu) "Valid values are 0.1, 0.2, 1.0, 1.1, 1.2, 1.3"); } -bool kvm_arm_pmu_supported(void) -{ - return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3); -} - int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa) { KVMState *s = KVM_STATE(ms->accelerator); diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -XXX,XX +XXX,XX @@ void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp); */ bool kvm_arm_aarch32_supported(void); -/** - * kvm_arm_pmu_supported: - * - * Returns: true if KVM can enable the PMU - * and false otherwise. - */ -bool kvm_arm_pmu_supported(void); - /** * kvm_arm_mte_supported: * @@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_aarch32_supported(void) return false; } -static inline bool kvm_arm_pmu_supported(void) -{ - return false; -} - static inline bool kvm_arm_mte_supported(void) { return false; -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-11-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/kvm.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_fpsimd(CPUState *cs) * code the slice index to zero for now as it's unlikely we'll need more than * one slice for quite some time. */ -static int kvm_arch_put_sve(CPUState *cs) +static int kvm_arch_put_sve(CPUState *cs, uint32_t vq) { - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; + CPUARMState *env = cpu_env(cs); uint64_t tmp[ARM_MAX_VQ * 2]; uint64_t *r; int n, ret; for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) { - r = sve_bswap64(tmp, &env->vfp.zregs[n].d[0], cpu->sve_max_vq * 2); + r = sve_bswap64(tmp, &env->vfp.zregs[n].d[0], vq * 2); ret = kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_ZREG(n, 0), r); if (ret) { return ret; @@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_sve(CPUState *cs) } for (n = 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) { - r = sve_bswap64(tmp, r = &env->vfp.pregs[n].p[0], - DIV_ROUND_UP(cpu->sve_max_vq * 2, 8)); + r = sve_bswap64(tmp, &env->vfp.pregs[n].p[0], DIV_ROUND_UP(vq * 2, 8)); ret = kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_PREG(n, 0), r); if (ret) { return ret; @@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_sve(CPUState *cs) } r = sve_bswap64(tmp, &env->vfp.pregs[FFR_PRED_NUM].p[0], - DIV_ROUND_UP(cpu->sve_max_vq * 2, 8)); + DIV_ROUND_UP(vq * 2, 8)); ret = kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_FFR(0), r); if (ret) { return ret; @@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, KvmPutState level, Error **errp) } if (cpu_isar_feature(aa64_sve, cpu)) { - ret = kvm_arch_put_sve(cs); + ret = kvm_arch_put_sve(cs, cpu->sve_max_vq); } else { ret = kvm_arch_put_fpsimd(cs); } @@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_fpsimd(CPUState *cs) * code the slice index to zero for now as it's unlikely we'll need more than * one slice for quite some time. */ -static int kvm_arch_get_sve(CPUState *cs) +static int kvm_arch_get_sve(CPUState *cs, uint32_t vq) { - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; + CPUARMState *env = cpu_env(cs); uint64_t *r; int n, ret; @@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_sve(CPUState *cs) if (ret) { return ret; } - sve_bswap64(r, r, cpu->sve_max_vq * 2); + sve_bswap64(r, r, vq * 2); } for (n = 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) { @@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_sve(CPUState *cs) if (ret) { return ret; } - sve_bswap64(r, r, DIV_ROUND_UP(cpu->sve_max_vq * 2, 8)); + sve_bswap64(r, r, DIV_ROUND_UP(vq * 2, 8)); } r = &env->vfp.pregs[FFR_PRED_NUM].p[0]; @@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_sve(CPUState *cs) if (ret) { return ret; } - sve_bswap64(r, r, DIV_ROUND_UP(cpu->sve_max_vq * 2, 8)); + sve_bswap64(r, r, DIV_ROUND_UP(vq * 2, 8)); return 0; } @@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) } if (cpu_isar_feature(aa64_sve, cpu)) { - ret = kvm_arch_get_sve(cs); + ret = kvm_arch_get_sve(cs, cpu->sve_max_vq); } else { ret = kvm_arch_get_fpsimd(cs); } -- 2.43.0
From: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20260216034432.23912-12-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/kvm.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_fpsimd(CPUState *cs) * code the slice index to zero for now as it's unlikely we'll need more than * one slice for quite some time. */ -static int kvm_arch_put_sve(CPUState *cs, uint32_t vq) +static int kvm_arch_put_sve(CPUState *cs, uint32_t vq, bool have_ffr) { CPUARMState *env = cpu_env(cs); uint64_t tmp[ARM_MAX_VQ * 2]; @@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_sve(CPUState *cs, uint32_t vq) } } - r = sve_bswap64(tmp, &env->vfp.pregs[FFR_PRED_NUM].p[0], - DIV_ROUND_UP(vq * 2, 8)); - ret = kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_FFR(0), r); - if (ret) { - return ret; + if (have_ffr) { + r = sve_bswap64(tmp, &env->vfp.pregs[FFR_PRED_NUM].p[0], + DIV_ROUND_UP(vq * 2, 8)); + ret = kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_FFR(0), r); + if (ret) { + return ret; + } } return 0; @@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, KvmPutState level, Error **errp) } if (cpu_isar_feature(aa64_sve, cpu)) { - ret = kvm_arch_put_sve(cs, cpu->sve_max_vq); + ret = kvm_arch_put_sve(cs, cpu->sve_max_vq, true); } else { ret = kvm_arch_put_fpsimd(cs); } @@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_fpsimd(CPUState *cs) * code the slice index to zero for now as it's unlikely we'll need more than * one slice for quite some time. */ -static int kvm_arch_get_sve(CPUState *cs, uint32_t vq) +static int kvm_arch_get_sve(CPUState *cs, uint32_t vq, bool have_ffr) { CPUARMState *env = cpu_env(cs); uint64_t *r; @@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_sve(CPUState *cs, uint32_t vq) sve_bswap64(r, r, DIV_ROUND_UP(vq * 2, 8)); } - r = &env->vfp.pregs[FFR_PRED_NUM].p[0]; - ret = kvm_get_one_reg(cs, KVM_REG_ARM64_SVE_FFR(0), r); - if (ret) { - return ret; + if (have_ffr) { + r = &env->vfp.pregs[FFR_PRED_NUM].p[0]; + ret = kvm_get_one_reg(cs, KVM_REG_ARM64_SVE_FFR(0), r); + if (ret) { + return ret; + } + sve_bswap64(r, r, DIV_ROUND_UP(vq * 2, 8)); } - sve_bswap64(r, r, DIV_ROUND_UP(vq * 2, 8)); return 0; } @@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) } if (cpu_isar_feature(aa64_sve, cpu)) { - ret = kvm_arch_get_sve(cs, cpu->sve_max_vq); + ret = kvm_arch_get_sve(cs, cpu->sve_max_vq, true); } else { ret = kvm_arch_get_fpsimd(cs); } -- 2.43.0
The migrate_add_blocker() function documents that if it fails it will free the Error it is passed via its reasonp argument and set reasonp to NULL. That means that in kvm_arm_enable_mte() we don't need to call error_free(mte_migration_blocker) in the failure codepath. Doing so is harmless because error_free(NULL) is permitted and does nothing, but we can remove the unnecessary code. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Message-id: 20260223173232.453165-1-peter.maydell@linaro.org --- target/arm/kvm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ void kvm_arm_enable_mte(Object *cpuobj, Error **errp) error_setg(&mte_migration_blocker, "Live migration disabled due to MTE enabled"); if (migrate_add_blocker(&mte_migration_blocker, errp)) { - error_free(mte_migration_blocker); return; } -- 2.43.0
We log a GUEST_ERROR message "PL011 data written to disabled UART" if the guest writes data to the TX FIFO when it has not set the enable bit in the UART. The idea is to note that the guest has done something dubious but let it work anyway. However, since we print this message for every output character, it floods the logs when running a guest that does this. Keep a note of whether we've printed the log message or not, so we only output it once. If the guest actively disables the UART, we re-arm the log message. Notably, the Linux kernel does not bother to enable the UART if it is used for earlycon, relying on the firmware having already done that. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr> Message-id: 20260210101702.3980804-1-peter.maydell@linaro.org --- hw/char/pl011.c | 24 ++++++++++++++++++++++-- include/hw/char/pl011.h | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/hw/char/pl011.c b/hw/char/pl011.c index XXXXXXX..XXXXXXX 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -XXX,XX +XXX,XX @@ static void pl011_loopback_tx(PL011State *s, uint32_t value) static void pl011_write_txdata(PL011State *s, uint8_t data) { if (!(s->cr & CR_UARTEN)) { - qemu_log_mask(LOG_GUEST_ERROR, - "PL011 data written to disabled UART\n"); + /* + * Only log this message once, not every time the guest outputs: + * otherwise we would flood the logs with this message, making + * harder to debug guests. (Some very popular guests like Linux + * don't actively enable the UART.) + */ + if (!s->logged_disabled_uart) { + qemu_log_mask(LOG_GUEST_ERROR, + "PL011 data written to disabled UART\n"); + s->logged_disabled_uart = true; + } } if (!(s->cr & CR_TXE)) { + /* + * We don't bother with the only-log-once machinery for this check + * because TXE is enabled by default from PL011 reset, so there + * isn't likely to be existing in-the-wild guest code that trips + * over this one. + */ qemu_log_mask(LOG_GUEST_ERROR, "PL011 data written to disabled TX UART\n"); } @@ -XXX,XX +XXX,XX @@ static void pl011_write(void *opaque, hwaddr offset, break; case 12: /* UARTCR */ /* ??? Need to implement the enable bit. */ + if ((s->cr ^ value) & CR_UARTEN) { + /* Re-arm the log warning when the guest toggles UARTEN */ + s->logged_disabled_uart = false; + } s->cr = value; pl011_loopback_mdmctrl(s); break; @@ -XXX,XX +XXX,XX @@ static void pl011_reset(DeviceState *dev) s->ifl = 0x12; s->cr = 0x300; s->flags = 0; + s->logged_disabled_uart = false; pl011_reset_rx_fifo(s); pl011_reset_tx_fifo(s); } diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/char/pl011.h +++ b/include/hw/char/pl011.h @@ -XXX,XX +XXX,XX @@ struct PL011State { qemu_irq irq[6]; Clock *clk; bool migrate_clk; + bool logged_disabled_uart; const unsigned char *id; /* * Since some users embed this struct directly, we must -- 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