Bump the core arm64 GIC code to also support a GICv5 configuration - invoked with `--irqchip=gicv5`. Only the core GICv5 device is created and initialised. No other GICv5-specific configuration is taking place. These changes are sufficient to start a GICv5-based VM and use PPIs with some big limitations, but do not include any changes to the FDT. Therefore, any guest that requires the FDT to boot will fail. Signed-off-by: Sascha Bischoff --- arm64/gic.c | 23 ++++++++++++++++++----- arm64/include/kvm/gic.h | 1 + 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/arm64/gic.c b/arm64/gic.c index 7461b0f3..8e4ff846 100644 --- a/arm64/gic.c +++ b/arm64/gic.c @@ -41,6 +41,8 @@ int irqchip_parser(const struct option *opt, const char *arg, int unset) *type = IRQCHIP_GICV3; } else if (!strcmp(arg, "gicv3-its")) { *type = IRQCHIP_GICV3_ITS; + } else if (!strcmp(arg, "gicv5")) { + *type = IRQCHIP_GICV5; } else { pr_err("irqchip: unknown type \"%s\"\n", arg); return -1; @@ -182,6 +184,9 @@ static int gic__create_device(struct kvm *kvm, enum irqchip_type type) gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3; dist_attr.attr = KVM_VGIC_V3_ADDR_TYPE_DIST; break; + case IRQCHIP_GICV5: + gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V5; + break; case IRQCHIP_AUTO: return -ENODEV; } @@ -201,15 +206,20 @@ static int gic__create_device(struct kvm *kvm, enum irqchip_type type) case IRQCHIP_GICV3: err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &redist_attr); break; + case IRQCHIP_GICV5: + break; case IRQCHIP_AUTO: return -ENODEV; } if (err) goto out_err; - err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &dist_attr); - if (err) - goto out_err; + /* Only set the dist_attr for non-GICv5 */ + if (type != IRQCHIP_GICV5) { + err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &dist_attr); + if (err) + goto out_err; + } err = gic__create_msi_frame(kvm, type, gic_msi_base); if (err) @@ -258,7 +268,7 @@ int gic__create(struct kvm *kvm, enum irqchip_type type) switch (type) { case IRQCHIP_AUTO: - for (try = IRQCHIP_GICV3_ITS; try >= IRQCHIP_GICV2; try--) { + for (try = IRQCHIP_GICV5; try >= IRQCHIP_GICV2; try--) { err = gic__create(kvm, try); if (!err) break; @@ -283,6 +293,8 @@ int gic__create(struct kvm *kvm, enum irqchip_type type) gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size; gic_msi_base = gic_redists_base - gic_msi_size; break; + case IRQCHIP_GICV5: + break; default: return -ENODEV; } @@ -420,7 +432,8 @@ u32 gic__get_fdt_irq_cpumask(struct kvm *kvm) { /* Only for GICv2 */ if (kvm->cfg.arch.irqchip == IRQCHIP_GICV3 || - kvm->cfg.arch.irqchip == IRQCHIP_GICV3_ITS) + kvm->cfg.arch.irqchip == IRQCHIP_GICV3_ITS || + kvm->cfg.arch.irqchip == IRQCHIP_GICV5) return 0; if (kvm->nrcpus > 8) diff --git a/arm64/include/kvm/gic.h b/arm64/include/kvm/gic.h index 1541a582..83fbf89b 100644 --- a/arm64/include/kvm/gic.h +++ b/arm64/include/kvm/gic.h @@ -29,6 +29,7 @@ enum irqchip_type { IRQCHIP_GICV2M, IRQCHIP_GICV3, IRQCHIP_GICV3_ITS, + IRQCHIP_GICV5, }; struct kvm; -- 2.34.1