From 5ae47f7aece19c5a6efbf99d000f389278e93c1d Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Fri, 19 Apr 2024 14:33:06 +0100 Subject: [PATCH] hw/arm/virt: Enable NMI support in the GIC if the CPU has FEAT_NMI If the CPU implements FEAT_NMI, then turn on the NMI support in the GICv3 too. It's permitted to have a configuration with FEAT_NMI in the CPU (and thus NMI support in the CPU interfaces too) but no NMI support in the distributor and redistributor, but this isn't a very useful setup as it's close to having no NMI support at all. We don't need to gate the enabling of NMI in the GIC behind a machine version property, because none of our current CPUs implement FEAT_NMI, and '-cpu max' is not something we maintain migration compatibility across versions for. So we can always enable the GIC NMI support when the CPU has it. Neither hvf nor KVM support NMI in the GIC yet, so we don't enable it unless we're using TCG. Signed-off-by: Jinjie Ruan Reviewed-by: Richard Henderson Message-id: 20240407081733.3231820-25-ruanjinjie@huawei.com [PMM: Update comment and commit message] Suggested-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/virt.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index c4b03b09c2..3c93c0c0a6 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -729,6 +729,20 @@ static void create_v2m(VirtMachineState *vms) vms->msi_controller = VIRT_MSI_CTRL_GICV2M; } +/* + * If the CPU has FEAT_NMI, then turn on the NMI support in the GICv3 too. + * It's permitted to have a configuration with NMI in the CPU (and thus the + * GICv3 CPU interface) but not in the distributor/redistributors, but it's + * not very useful. + */ +static bool gicv3_nmi_present(VirtMachineState *vms) +{ + ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0)); + + return tcg_enabled() && cpu_isar_feature(aa64_nmi, cpu) && + (vms->gic_version != VIRT_GIC_VERSION_2); +} + static void create_gic(VirtMachineState *vms, MemoryRegion *mem) { MachineState *ms = MACHINE(vms); @@ -802,6 +816,11 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem) vms->virt); } } + + if (gicv3_nmi_present(vms)) { + qdev_prop_set_bit(vms->gic, "has-nmi", true); + } + gicbusdev = SYS_BUS_DEVICE(vms->gic); sysbus_realize_and_unref(gicbusdev, &error_fatal); sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);