[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 08/33] hw/arm/virt: Consolidate GIC finalize logic
From: |
Peter Maydell |
Subject: |
[PULL 08/33] hw/arm/virt: Consolidate GIC finalize logic |
Date: |
Fri, 3 Feb 2023 14:29:02 +0000 |
From: Alexander Graf <agraf@csgraf.de>
Up to now, the finalize_gic_version() code open coded what is essentially
a support bitmap match between host/emulation environment and desired
target GIC type.
This open coding leads to undesirable side effects. For example, a VM with
KVM and -smp 10 will automatically choose GICv3 while the same command
line with TCG will stay on GICv2 and fail the launch.
This patch combines the TCG and KVM matching code paths by making
everything a 2 pass process. First, we determine which GIC versions the
current environment is able to support, then we go through a single
state machine to determine which target GIC mode that means for us.
After this patch, the only user noticable changes should be consolidated
error messages as well as TCG -M virt supporting -smp > 8 automatically.
Signed-off-by: Alexander Graf <agraf@csgraf.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
Message-id: 20221223090107.98888-2-agraf@csgraf.de
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/hw/arm/virt.h | 15 ++--
hw/arm/virt.c | 198 ++++++++++++++++++++++--------------------
2 files changed, 112 insertions(+), 101 deletions(-)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index c7dd59d7f1f..e1ddbea96be 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -109,14 +109,19 @@ typedef enum VirtMSIControllerType {
} VirtMSIControllerType;
typedef enum VirtGICType {
- VIRT_GIC_VERSION_MAX,
- VIRT_GIC_VERSION_HOST,
- VIRT_GIC_VERSION_2,
- VIRT_GIC_VERSION_3,
- VIRT_GIC_VERSION_4,
+ VIRT_GIC_VERSION_MAX = 0,
+ VIRT_GIC_VERSION_HOST = 1,
+ /* The concrete GIC values have to match the GIC version number */
+ VIRT_GIC_VERSION_2 = 2,
+ VIRT_GIC_VERSION_3 = 3,
+ VIRT_GIC_VERSION_4 = 4,
VIRT_GIC_VERSION_NOSEL,
} VirtGICType;
+#define VIRT_GIC_VERSION_2_MASK BIT(VIRT_GIC_VERSION_2)
+#define VIRT_GIC_VERSION_3_MASK BIT(VIRT_GIC_VERSION_3)
+#define VIRT_GIC_VERSION_4_MASK BIT(VIRT_GIC_VERSION_4)
+
struct VirtMachineClass {
MachineClass parent;
bool disallow_affinity_adjustment;
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 90a7099d3b5..28c43d59fbd 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1820,6 +1820,84 @@ static void virt_set_memmap(VirtMachineState *vms, int
pa_bits)
}
}
+static VirtGICType finalize_gic_version_do(const char *accel_name,
+ VirtGICType gic_version,
+ int gics_supported,
+ unsigned int max_cpus)
+{
+ /* Convert host/max/nosel to GIC version number */
+ switch (gic_version) {
+ case VIRT_GIC_VERSION_HOST:
+ if (!kvm_enabled()) {
+ error_report("gic-version=host requires KVM");
+ exit(1);
+ }
+
+ /* For KVM, gic-version=host means gic-version=max */
+ return finalize_gic_version_do(accel_name, VIRT_GIC_VERSION_MAX,
+ gics_supported, max_cpus);
+ case VIRT_GIC_VERSION_MAX:
+ if (gics_supported & VIRT_GIC_VERSION_4_MASK) {
+ gic_version = VIRT_GIC_VERSION_4;
+ } else if (gics_supported & VIRT_GIC_VERSION_3_MASK) {
+ gic_version = VIRT_GIC_VERSION_3;
+ } else {
+ gic_version = VIRT_GIC_VERSION_2;
+ }
+ break;
+ case VIRT_GIC_VERSION_NOSEL:
+ if ((gics_supported & VIRT_GIC_VERSION_2_MASK) &&
+ max_cpus <= GIC_NCPU) {
+ gic_version = VIRT_GIC_VERSION_2;
+ } else if (gics_supported & VIRT_GIC_VERSION_3_MASK) {
+ /*
+ * in case the host does not support v2 emulation or
+ * the end-user requested more than 8 VCPUs we now default
+ * to v3. In any case defaulting to v2 would be broken.
+ */
+ gic_version = VIRT_GIC_VERSION_3;
+ } else if (max_cpus > GIC_NCPU) {
+ error_report("%s only supports GICv2 emulation but more than 8 "
+ "vcpus are requested", accel_name);
+ exit(1);
+ }
+ break;
+ case VIRT_GIC_VERSION_2:
+ case VIRT_GIC_VERSION_3:
+ case VIRT_GIC_VERSION_4:
+ break;
+ }
+
+ /* Check chosen version is effectively supported */
+ switch (gic_version) {
+ case VIRT_GIC_VERSION_2:
+ if (!(gics_supported & VIRT_GIC_VERSION_2_MASK)) {
+ error_report("%s does not support GICv2 emulation", accel_name);
+ exit(1);
+ }
+ break;
+ case VIRT_GIC_VERSION_3:
+ if (!(gics_supported & VIRT_GIC_VERSION_3_MASK)) {
+ error_report("%s does not support GICv3 emulation", accel_name);
+ exit(1);
+ }
+ break;
+ case VIRT_GIC_VERSION_4:
+ if (!(gics_supported & VIRT_GIC_VERSION_4_MASK)) {
+ error_report("%s does not support GICv4 emulation, is
virtualization=on?",
+ accel_name);
+ exit(1);
+ }
+ break;
+ default:
+ error_report("logic error in finalize_gic_version");
+ exit(1);
+ break;
+ }
+
+ return gic_version;
+}
+
/*
* finalize_gic_version - Determines the final gic_version
* according to the gic-version property
@@ -1828,118 +1906,46 @@ static void virt_set_memmap(VirtMachineState *vms, int
pa_bits)
*/
static void finalize_gic_version(VirtMachineState *vms)
{
+ const char *accel_name = current_accel_name();
unsigned int max_cpus = MACHINE(vms)->smp.max_cpus;
+ int gics_supported = 0;
- if (kvm_enabled()) {
- int probe_bitmap;
+ /* Determine which GIC versions the current environment supports */
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
+ int probe_bitmap = kvm_arm_vgic_probe();
- if (!kvm_irqchip_in_kernel()) {
- switch (vms->gic_version) {
- case VIRT_GIC_VERSION_HOST:
- warn_report(
- "gic-version=host not relevant with kernel-irqchip=off "
- "as only userspace GICv2 is supported. Using v2 ...");
- return;
- case VIRT_GIC_VERSION_MAX:
- case VIRT_GIC_VERSION_NOSEL:
- vms->gic_version = VIRT_GIC_VERSION_2;
- return;
- case VIRT_GIC_VERSION_2:
- return;
- case VIRT_GIC_VERSION_3:
- error_report(
- "gic-version=3 is not supported with kernel-irqchip=off");
- exit(1);
- case VIRT_GIC_VERSION_4:
- error_report(
- "gic-version=4 is not supported with kernel-irqchip=off");
- exit(1);
- }
- }
-
- probe_bitmap = kvm_arm_vgic_probe();
if (!probe_bitmap) {
error_report("Unable to determine GIC version supported by host");
exit(1);
}
- switch (vms->gic_version) {
- case VIRT_GIC_VERSION_HOST:
- case VIRT_GIC_VERSION_MAX:
- if (probe_bitmap & KVM_ARM_VGIC_V3) {
- vms->gic_version = VIRT_GIC_VERSION_3;
- } else {
- vms->gic_version = VIRT_GIC_VERSION_2;
- }
- return;
- case VIRT_GIC_VERSION_NOSEL:
- if ((probe_bitmap & KVM_ARM_VGIC_V2) && max_cpus <= GIC_NCPU) {
- vms->gic_version = VIRT_GIC_VERSION_2;
- } else if (probe_bitmap & KVM_ARM_VGIC_V3) {
- /*
- * in case the host does not support v2 in-kernel emulation or
- * the end-user requested more than 8 VCPUs we now default
- * to v3. In any case defaulting to v2 would be broken.
- */
- vms->gic_version = VIRT_GIC_VERSION_3;
- } else if (max_cpus > GIC_NCPU) {
- error_report("host only supports in-kernel GICv2 emulation "
- "but more than 8 vcpus are requested");
- exit(1);
- }
- break;
- case VIRT_GIC_VERSION_2:
- case VIRT_GIC_VERSION_3:
- break;
- case VIRT_GIC_VERSION_4:
- error_report("gic-version=4 is not supported with KVM");
- exit(1);
+ if (probe_bitmap & KVM_ARM_VGIC_V2) {
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
}
-
- /* Check chosen version is effectively supported by the host */
- if (vms->gic_version == VIRT_GIC_VERSION_2 &&
- !(probe_bitmap & KVM_ARM_VGIC_V2)) {
- error_report("host does not support in-kernel GICv2 emulation");
- exit(1);
- } else if (vms->gic_version == VIRT_GIC_VERSION_3 &&
- !(probe_bitmap & KVM_ARM_VGIC_V3)) {
- error_report("host does not support in-kernel GICv3 emulation");
- exit(1);
+ if (probe_bitmap & KVM_ARM_VGIC_V3) {
+ gics_supported |= VIRT_GIC_VERSION_3_MASK;
}
- return;
- }
-
- /* TCG mode */
- switch (vms->gic_version) {
- case VIRT_GIC_VERSION_NOSEL:
- vms->gic_version = VIRT_GIC_VERSION_2;
- break;
- case VIRT_GIC_VERSION_MAX:
+ } else if (kvm_enabled() && !kvm_irqchip_in_kernel()) {
+ /* KVM w/o kernel irqchip can only deal with GICv2 */
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
+ accel_name = "KVM with kernel-irqchip=off";
+ } else {
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
if (module_object_class_by_name("arm-gicv3")) {
- /* CONFIG_ARM_GICV3_TCG was set */
+ gics_supported |= VIRT_GIC_VERSION_3_MASK;
if (vms->virt) {
/* GICv4 only makes sense if CPU has EL2 */
- vms->gic_version = VIRT_GIC_VERSION_4;
- } else {
- vms->gic_version = VIRT_GIC_VERSION_3;
+ gics_supported |= VIRT_GIC_VERSION_4_MASK;
}
- } else {
- vms->gic_version = VIRT_GIC_VERSION_2;
}
- break;
- case VIRT_GIC_VERSION_HOST:
- error_report("gic-version=host requires KVM");
- exit(1);
- case VIRT_GIC_VERSION_4:
- if (!vms->virt) {
- error_report("gic-version=4 requires virtualization enabled");
- exit(1);
- }
- break;
- case VIRT_GIC_VERSION_2:
- case VIRT_GIC_VERSION_3:
- break;
}
+
+ /*
+ * Then convert helpers like host/max to concrete GIC versions and ensure
+ * the desired version is supported
+ */
+ vms->gic_version = finalize_gic_version_do(accel_name, vms->gic_version,
+ gics_supported, max_cpus);
}
/*
--
2.34.1
- [PULL 15/33] target/arm: All UNDEF-at-EL0 traps take priority over HSTR_EL2 traps, (continued)
- [PULL 15/33] target/arm: All UNDEF-at-EL0 traps take priority over HSTR_EL2 traps, Peter Maydell, 2023/02/03
- [PULL 13/33] target/arm: Remove CP_ACCESS_TRAP_UNCATEGORIZED_{EL2, EL3}, Peter Maydell, 2023/02/03
- [PULL 12/33] target/arm: Correct syndrome for ATS12NSO* at Secure EL1, Peter Maydell, 2023/02/03
- [PULL 20/33] target/arm: Mark up sysregs for HFGRTR bits 0..11, Peter Maydell, 2023/02/03
- [PULL 18/33] target/arm: Define the FEAT_FGT registers, Peter Maydell, 2023/02/03
- [PULL 27/33] target/arm: Mark up sysregs for HFGITR bits 12..17, Peter Maydell, 2023/02/03
- [PULL 24/33] target/arm: Mark up sysregs for HDFGRTR bits 0..11, Peter Maydell, 2023/02/03
- [PULL 31/33] target/arm: Implement the HFGITR_EL2.SVC_EL0 and SVC_EL1 traps, Peter Maydell, 2023/02/03
- [PULL 32/33] target/arm: Implement MDCR_EL2.TDCC and MDCR_EL3.TDCC traps, Peter Maydell, 2023/02/03
- [PULL 10/33] sbsa-ref: remove cortex-a76 from list of supported cpus, Peter Maydell, 2023/02/03
- [PULL 08/33] hw/arm/virt: Consolidate GIC finalize logic,
Peter Maydell <=
- [PULL 14/33] target/arm: Move do_coproc_insn() syndrome calculation earlier, Peter Maydell, 2023/02/03
- [PULL 28/33] target/arm: Mark up sysregs for HFGITR bits 18..47, Peter Maydell, 2023/02/03
- [PULL 33/33] target/arm: Enable FEAT_FGT on '-cpu max', Peter Maydell, 2023/02/03
- Re: [PULL 00/33] target-arm queue, Peter Maydell, 2023/02/03