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 (realistically, only the timers will work), but do not include any changes to the FDT. Therefore, any guest that requires the FDT to boot will fail, i.e., Linux. 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 e35986c0..879f956e 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; } @@ -423,7 +435,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 8490cca6..630f0bbd 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