Message ID | 20210317100719.3331-2-lorenzo.pieralisi@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v3,1/1] irqchip/gic-v4.1: Disable vSGI upon (GIC CPUIF < v4.1) detection | expand |
Hi Lorenzo, Wed, 17 Mar 2021 10:07:19 +0000, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote: > > GIC CPU interfaces versions predating GIC v4.1 were not built to > accommodate vINTID within the vSGI range; as reported in the GIC > specifications (8.2 "Changes to the CPU interface"), it is > CONSTRAINED UNPREDICTABLE to deliver a vSGI to a PE with > ID_AA64PFR0_EL1.GIC < b0011. > > Check the GIC CPUIF version by reading the SYS_ID_AA64_PFR0_EL1. > > Disable vSGIs if a CPUIF version < 4.1 is detected to prevent using > vSGIs on systems where they may misbehave. > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> > Cc: Marc Zyngier <maz@kernel.org> Does it need to go in as a fix? or can it just be pushed into 5.13? Given that there is no such HW in the wild just yet, I'm inclined to do the latter... Thanks, M.
On Wed, Mar 17, 2021 at 02:04:36PM +0000, Marc Zyngier wrote: > Hi Lorenzo, > > Wed, 17 Mar 2021 10:07:19 +0000, > Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote: > > > > GIC CPU interfaces versions predating GIC v4.1 were not built to > > accommodate vINTID within the vSGI range; as reported in the GIC > > specifications (8.2 "Changes to the CPU interface"), it is > > CONSTRAINED UNPREDICTABLE to deliver a vSGI to a PE with > > ID_AA64PFR0_EL1.GIC < b0011. > > > > Check the GIC CPUIF version by reading the SYS_ID_AA64_PFR0_EL1. > > > > Disable vSGIs if a CPUIF version < 4.1 is detected to prevent using > > vSGIs on systems where they may misbehave. > > > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> > > Cc: Marc Zyngier <maz@kernel.org> > > Does it need to go in as a fix? or can it just be pushed into 5.13? > Given that there is no such HW in the wild just yet, I'm inclined to > do the latter... I agree with you; it is to make the driver/vgic robust against HW misconfigurations (because that's what they are and I am not aware of any _existing_ HW with such a misconfiguration - yet), 5.13 will perfectly do. Thanks a lot. Lorenzo
diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c index 15a6c98ee92f..2f1b156021a6 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -86,7 +86,7 @@ static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu, } break; case GICD_TYPER2: - if (kvm_vgic_global_state.has_gicv4_1) + if (kvm_vgic_global_state.has_gicv4_1 && gic_cpuif_has_vsgi()) value = GICD_TYPER2_nASSGIcap; break; case GICD_IIDR: @@ -119,7 +119,7 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu, dist->enabled = val & GICD_CTLR_ENABLE_SS_G1; /* Not a GICv4.1? No HW SGIs */ - if (!kvm_vgic_global_state.has_gicv4_1) + if (!kvm_vgic_global_state.has_gicv4_1 || !gic_cpuif_has_vsgi()) val &= ~GICD_CTLR_nASSGIreq; /* Dist stays enabled? nASSGIreq is RO */ diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c index 5d1dc9915272..4ea71b28f9f5 100644 --- a/drivers/irqchip/irq-gic-v4.c +++ b/drivers/irqchip/irq-gic-v4.c @@ -87,17 +87,40 @@ static struct irq_domain *gic_domain; static const struct irq_domain_ops *vpe_domain_ops; static const struct irq_domain_ops *sgi_domain_ops; +#ifdef CONFIG_ARM64 +#include <asm/cpufeature.h> + +bool gic_cpuif_has_vsgi(void) +{ + unsigned long fld, reg = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1); + + fld = cpuid_feature_extract_unsigned_field(reg, ID_AA64PFR0_GIC_SHIFT); + + return fld >= 0x3; +} +#else +bool gic_cpuif_has_vsgi(void) +{ + return false; +} +#endif + static bool has_v4_1(void) { return !!sgi_domain_ops; } +static bool has_v4_1_sgi(void) +{ + return has_v4_1() && gic_cpuif_has_vsgi(); +} + static int its_alloc_vcpu_sgis(struct its_vpe *vpe, int idx) { char *name; int sgi_base; - if (!has_v4_1()) + if (!has_v4_1_sgi()) return 0; name = kasprintf(GFP_KERNEL, "GICv4-sgi-%d", task_pid_nr(current)); @@ -182,7 +205,7 @@ static void its_free_sgi_irqs(struct its_vm *vm) { int i; - if (!has_v4_1()) + if (!has_v4_1_sgi()) return; for (i = 0; i < vm->nr_vpes; i++) { diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h index 943c3411ca10..2c63375bbd43 100644 --- a/include/linux/irqchip/arm-gic-v4.h +++ b/include/linux/irqchip/arm-gic-v4.h @@ -145,4 +145,6 @@ int its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *vpe_ops, const struct irq_domain_ops *sgi_ops); +bool gic_cpuif_has_vsgi(void); + #endif
GIC CPU interfaces versions predating GIC v4.1 were not built to accommodate vINTID within the vSGI range; as reported in the GIC specifications (8.2 "Changes to the CPU interface"), it is CONSTRAINED UNPREDICTABLE to deliver a vSGI to a PE with ID_AA64PFR0_EL1.GIC < b0011. Check the GIC CPUIF version by reading the SYS_ID_AA64_PFR0_EL1. Disable vSGIs if a CPUIF version < 4.1 is detected to prevent using vSGIs on systems where they may misbehave. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Marc Zyngier <maz@kernel.org> --- arch/arm64/kvm/vgic/vgic-mmio-v3.c | 4 ++-- drivers/irqchip/irq-gic-v4.c | 27 +++++++++++++++++++++++++-- include/linux/irqchip/arm-gic-v4.h | 2 ++ 3 files changed, 29 insertions(+), 4 deletions(-)