Commit 1ec38ce3 authored by Sascha Bischoff's avatar Sascha Bischoff Committed by Oliver Upton
Browse files

irqchip/gic-v5: Populate struct gic_kvm_info



Populate the gic_kvm_info struct based on support for
FEAT_GCIE_LEGACY.  The struct is used by KVM to probe for a compatible
GIC.

Co-authored-by: default avatarTimothy Hayes <timothy.hayes@arm.com>
Signed-off-by: default avatarTimothy Hayes <timothy.hayes@arm.com>
Signed-off-by: default avatarSascha Bischoff <sascha.bischoff@arm.com>
Reviewed-by: default avatarLorenzo Pieralisi <lpieralisi@kernel.org>
Link: https://lore.kernel.org/r/20250627100847.1022515-3-sascha.bischoff@arm.com


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent 244e9a89
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@

#include <linux/irqchip.h>
#include <linux/irqchip/arm-gic-v5.h>
#include <linux/irqchip/arm-vgic-info.h>

#include <asm/cpufeature.h>
#include <asm/exception.h>
@@ -1058,6 +1059,36 @@ static void gicv5_set_cpuif_idbits(void)
	}
}

#ifdef CONFIG_KVM
static struct gic_kvm_info gic_v5_kvm_info __initdata;

static bool __init gicv5_cpuif_has_gcie_legacy(void)
{
	u64 idr0 = read_sysreg_s(SYS_ICC_IDR0_EL1);
	return !!FIELD_GET(ICC_IDR0_EL1_GCIE_LEGACY, idr0);
}

static void __init gic_of_setup_kvm_info(struct device_node *node)
{
	gic_v5_kvm_info.type = GIC_V5;
	gic_v5_kvm_info.has_gcie_v3_compat = gicv5_cpuif_has_gcie_legacy();

	/* GIC Virtual CPU interface maintenance interrupt */
	gic_v5_kvm_info.no_maint_irq_mask = false;
	gic_v5_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);
	if (!gic_v5_kvm_info.maint_irq) {
		pr_warn("cannot find GICv5 virtual CPU interface maintenance interrupt\n");
		return;
	}

	vgic_set_kvm_info(&gic_v5_kvm_info);
}
#else
static inline void __init gic_of_setup_kvm_info(struct device_node *node)
{
}
#endif // CONFIG_KVM

static int __init gicv5_of_init(struct device_node *node, struct device_node *parent)
{
	int ret = gicv5_irs_of_probe(node);
@@ -1090,6 +1121,8 @@ static int __init gicv5_of_init(struct device_node *node, struct device_node *pa

	gicv5_irs_its_probe();

	gic_of_setup_kvm_info(node);

	return 0;

out_int:
+4 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ enum gic_type {
	GIC_V2,
	/* Full GICv3, optionally with v2 compat */
	GIC_V3,
	/* Full GICv5, optionally with v3 compat */
	GIC_V5,
};

struct gic_kvm_info {
@@ -34,6 +36,8 @@ struct gic_kvm_info {
	bool		has_v4_1;
	/* Deactivation impared, subpar stuff */
	bool		no_hw_deactivation;
	/* v3 compat support (GICv5 hosts, only) */
	bool		has_gcie_v3_compat;
};

#ifdef CONFIG_KVM