Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Timothy Hayes <timothy.hayes@arm.com>
Signed-off-by: Timothy Hayes <timothy.hayes@arm.com>
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Reviewed-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Link: https://lore.kernel.org/r/20250627100847.1022515-3-sascha.bischoff@arm.com
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>

authored by

Sascha Bischoff
Timothy Hayes
and committed by
Oliver Upton
1ec38ce3 244e9a89

+37
+33
drivers/irqchip/irq-gic-v5.c
··· 13 13 14 14 #include <linux/irqchip.h> 15 15 #include <linux/irqchip/arm-gic-v5.h> 16 + #include <linux/irqchip/arm-vgic-info.h> 16 17 17 18 #include <asm/cpufeature.h> 18 19 #include <asm/exception.h> ··· 1059 1058 } 1060 1059 } 1061 1060 1061 + #ifdef CONFIG_KVM 1062 + static struct gic_kvm_info gic_v5_kvm_info __initdata; 1063 + 1064 + static bool __init gicv5_cpuif_has_gcie_legacy(void) 1065 + { 1066 + u64 idr0 = read_sysreg_s(SYS_ICC_IDR0_EL1); 1067 + return !!FIELD_GET(ICC_IDR0_EL1_GCIE_LEGACY, idr0); 1068 + } 1069 + 1070 + static void __init gic_of_setup_kvm_info(struct device_node *node) 1071 + { 1072 + gic_v5_kvm_info.type = GIC_V5; 1073 + gic_v5_kvm_info.has_gcie_v3_compat = gicv5_cpuif_has_gcie_legacy(); 1074 + 1075 + /* GIC Virtual CPU interface maintenance interrupt */ 1076 + gic_v5_kvm_info.no_maint_irq_mask = false; 1077 + gic_v5_kvm_info.maint_irq = irq_of_parse_and_map(node, 0); 1078 + if (!gic_v5_kvm_info.maint_irq) { 1079 + pr_warn("cannot find GICv5 virtual CPU interface maintenance interrupt\n"); 1080 + return; 1081 + } 1082 + 1083 + vgic_set_kvm_info(&gic_v5_kvm_info); 1084 + } 1085 + #else 1086 + static inline void __init gic_of_setup_kvm_info(struct device_node *node) 1087 + { 1088 + } 1089 + #endif // CONFIG_KVM 1090 + 1062 1091 static int __init gicv5_of_init(struct device_node *node, struct device_node *parent) 1063 1092 { 1064 1093 int ret = gicv5_irs_of_probe(node); ··· 1120 1089 gicv5_smp_init(); 1121 1090 1122 1091 gicv5_irs_its_probe(); 1092 + 1093 + gic_of_setup_kvm_info(node); 1123 1094 1124 1095 return 0; 1125 1096
+4
include/linux/irqchip/arm-vgic-info.h
··· 15 15 GIC_V2, 16 16 /* Full GICv3, optionally with v2 compat */ 17 17 GIC_V3, 18 + /* Full GICv5, optionally with v3 compat */ 19 + GIC_V5, 18 20 }; 19 21 20 22 struct gic_kvm_info { ··· 36 34 bool has_v4_1; 37 35 /* Deactivation impared, subpar stuff */ 38 36 bool no_hw_deactivation; 37 + /* v3 compat support (GICv5 hosts, only) */ 38 + bool has_gcie_v3_compat; 39 39 }; 40 40 41 41 #ifdef CONFIG_KVM