Skip to content

Commit 1ec38ce

Browse files
Sticklyman1936timothy-hayes
authored andcommitted
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 <[email protected]> Signed-off-by: Timothy Hayes <[email protected]> Signed-off-by: Sascha Bischoff <[email protected]> Reviewed-by: Lorenzo Pieralisi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 244e9a8 commit 1ec38ce

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

drivers/irqchip/irq-gic-v5.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <linux/irqchip.h>
1515
#include <linux/irqchip/arm-gic-v5.h>
16+
#include <linux/irqchip/arm-vgic-info.h>
1617

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

1062+
#ifdef CONFIG_KVM
1063+
static struct gic_kvm_info gic_v5_kvm_info __initdata;
1064+
1065+
static bool __init gicv5_cpuif_has_gcie_legacy(void)
1066+
{
1067+
u64 idr0 = read_sysreg_s(SYS_ICC_IDR0_EL1);
1068+
return !!FIELD_GET(ICC_IDR0_EL1_GCIE_LEGACY, idr0);
1069+
}
1070+
1071+
static void __init gic_of_setup_kvm_info(struct device_node *node)
1072+
{
1073+
gic_v5_kvm_info.type = GIC_V5;
1074+
gic_v5_kvm_info.has_gcie_v3_compat = gicv5_cpuif_has_gcie_legacy();
1075+
1076+
/* GIC Virtual CPU interface maintenance interrupt */
1077+
gic_v5_kvm_info.no_maint_irq_mask = false;
1078+
gic_v5_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);
1079+
if (!gic_v5_kvm_info.maint_irq) {
1080+
pr_warn("cannot find GICv5 virtual CPU interface maintenance interrupt\n");
1081+
return;
1082+
}
1083+
1084+
vgic_set_kvm_info(&gic_v5_kvm_info);
1085+
}
1086+
#else
1087+
static inline void __init gic_of_setup_kvm_info(struct device_node *node)
1088+
{
1089+
}
1090+
#endif // CONFIG_KVM
1091+
10611092
static int __init gicv5_of_init(struct device_node *node, struct device_node *parent)
10621093
{
10631094
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
10901121

10911122
gicv5_irs_its_probe();
10921123

1124+
gic_of_setup_kvm_info(node);
1125+
10931126
return 0;
10941127

10951128
out_int:

include/linux/irqchip/arm-vgic-info.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ enum gic_type {
1515
GIC_V2,
1616
/* Full GICv3, optionally with v2 compat */
1717
GIC_V3,
18+
/* Full GICv5, optionally with v3 compat */
19+
GIC_V5,
1820
};
1921

2022
struct gic_kvm_info {
@@ -34,6 +36,8 @@ struct gic_kvm_info {
3436
bool has_v4_1;
3537
/* Deactivation impared, subpar stuff */
3638
bool no_hw_deactivation;
39+
/* v3 compat support (GICv5 hosts, only) */
40+
bool has_gcie_v3_compat;
3741
};
3842

3943
#ifdef CONFIG_KVM

0 commit comments

Comments
 (0)