mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 23:39:18 +00:00
irqchip/gic-v4.1: Disable vSGI upon (GIC CPUIF < v4.1) detection
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> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20210317100719.3331-2-lorenzo.pieralisi@arm.com
This commit is contained in:
parent
a6992bbe97
commit
46135d6f87
@ -86,7 +86,7 @@ static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GICD_TYPER2:
|
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;
|
value = GICD_TYPER2_nASSGIcap;
|
||||||
break;
|
break;
|
||||||
case GICD_IIDR:
|
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;
|
dist->enabled = val & GICD_CTLR_ENABLE_SS_G1;
|
||||||
|
|
||||||
/* Not a GICv4.1? No HW SGIs */
|
/* 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;
|
val &= ~GICD_CTLR_nASSGIreq;
|
||||||
|
|
||||||
/* Dist stays enabled? nASSGIreq is RO */
|
/* Dist stays enabled? nASSGIreq is RO */
|
||||||
|
@ -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 *vpe_domain_ops;
|
||||||
static const struct irq_domain_ops *sgi_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)
|
static bool has_v4_1(void)
|
||||||
{
|
{
|
||||||
return !!sgi_domain_ops;
|
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)
|
static int its_alloc_vcpu_sgis(struct its_vpe *vpe, int idx)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
int sgi_base;
|
int sgi_base;
|
||||||
|
|
||||||
if (!has_v4_1())
|
if (!has_v4_1_sgi())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
name = kasprintf(GFP_KERNEL, "GICv4-sgi-%d", task_pid_nr(current));
|
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;
|
int i;
|
||||||
|
|
||||||
if (!has_v4_1())
|
if (!has_v4_1_sgi())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < vm->nr_vpes; i++) {
|
for (i = 0; i < vm->nr_vpes; i++) {
|
||||||
|
@ -145,4 +145,6 @@ int its_init_v4(struct irq_domain *domain,
|
|||||||
const struct irq_domain_ops *vpe_ops,
|
const struct irq_domain_ops *vpe_ops,
|
||||||
const struct irq_domain_ops *sgi_ops);
|
const struct irq_domain_ops *sgi_ops);
|
||||||
|
|
||||||
|
bool gic_cpuif_has_vsgi(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user