From 8673bedd76c2ae43acaeec1f78f3e4ec31088c77 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Mon, 12 Oct 2026 15:42:03 +0200 Subject: [PATCH] ARM/sysctl: Expose the supported guest GIC modes in physinfo In preparation to simplify the domain creation logic surrounding GIC version. On a GICv3 host, also report support for GICv2-compatible guests when the hardware's vGICv2 compatibility mode is enabled, rather than just the native GIC version. Signed-off-by: Andrew Cooper Signed-off-by: Julian Vetter Reviewed-by: Michal Orzel --- xen/arch/arm/include/asm/vgic.h | 6 ++++++ xen/arch/arm/sysctl.c | 29 +++++++++++++++++++++++++++++ xen/arch/arm/vgic-v2.c | 5 +++++ xen/arch/arm/vgic/vgic-v2.c | 5 +++++ xen/include/public/sysctl.h | 2 ++ 5 files changed, 47 insertions(+) diff --git a/xen/arch/arm/include/asm/vgic.h b/xen/arch/arm/include/asm/vgic.h index 6f9ab1c98c..26c53aaf3c 100644 --- a/xen/arch/arm/include/asm/vgic.h +++ b/xen/arch/arm/include/asm/vgic.h @@ -433,6 +433,12 @@ unsigned int vgic_max_vcpus(unsigned int domctl_vgic_version); void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t csize, paddr_t vbase, uint32_t aliased_offset); +#ifdef CONFIG_VGICV2 +bool vgic_v2_hw_enabled(void); +#else +static inline bool vgic_v2_hw_enabled(void) { return false; } +#endif + #ifdef CONFIG_GICV3 struct rdist_region; void vgic_v3_setup_hw(paddr_t dbase, diff --git a/xen/arch/arm/sysctl.c b/xen/arch/arm/sysctl.c index 32cab4feff..8de4027b9c 100644 --- a/xen/arch/arm/sysctl.c +++ b/xen/arch/arm/sysctl.c @@ -12,7 +12,11 @@ #include #include #include + #include +#include +#include + #include void arch_do_physinfo(struct xen_sysctl_physinfo *pi) @@ -21,6 +25,31 @@ void arch_do_physinfo(struct xen_sysctl_physinfo *pi) pi->arch_capabilities |= MASK_INSR(sve_encode_vl(get_sys_vl_len()), XEN_SYSCTL_PHYSCAP_ARM_SVE_MASK); + + switch ( gic_hw_version() ) + { + case GIC_V2: + pi->arch_capabilities |= XEN_SYSCTL_PHYSCAP_ARM_GIC_V2; + break; + + case GIC_V3: + pi->arch_capabilities |= XEN_SYSCTL_PHYSCAP_ARM_GIC_V3; + + /* GICv3 may additionally support GICv2-compatible guests. */ + if ( vgic_v2_hw_enabled() ) + pi->arch_capabilities |= XEN_SYSCTL_PHYSCAP_ARM_GIC_V2; + break; + + default: + /* + * Running a control domain without having the GIC sorted yet? + * Something's broken, but there's nothing we can do about it here. + */ + printk_once(XENLOG_ERR "Unrecognised GIC version %d\n", + gic_hw_version()); + ASSERT_UNREACHABLE(); + break; + } } long arch_do_sysctl(struct xen_sysctl *sysctl, diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index 6328ce6f7e..62666a84db 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -49,6 +49,11 @@ void __init vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t csize, vgic_v2_hw.aliased_offset = aliased_offset; } +bool vgic_v2_hw_enabled(void) +{ + return vgic_v2_hw.enabled; +} + #define NR_TARGETS_PER_ITARGETSR 4U #define NR_BITS_PER_TARGET (32U / NR_TARGETS_PER_ITARGETSR) diff --git a/xen/arch/arm/vgic/vgic-v2.c b/xen/arch/arm/vgic/vgic-v2.c index 06fa365453..f6a58ed89e 100644 --- a/xen/arch/arm/vgic/vgic-v2.c +++ b/xen/arch/arm/vgic/vgic-v2.c @@ -47,6 +47,11 @@ void __init vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t csize, printk("Using the new VGIC implementation.\n"); } +bool vgic_v2_hw_enabled(void) +{ + return gic_v2_hw_data.enabled; +} + /* * transfer the content of the LRs back into the corresponding ap_list: * - active bit is transferred as is diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index 63d0ee062b..a1216d7287 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -106,6 +106,8 @@ struct xen_sysctl_tbuf_op { #if defined(__arm__) || defined(__aarch64__) #define XEN_SYSCTL_PHYSCAP_ARM_SVE_MASK (0x1FU) +#define XEN_SYSCTL_PHYSCAP_ARM_GIC_V2 (1U << 5) +#define XEN_SYSCTL_PHYSCAP_ARM_GIC_V3 (1U << 6) #endif struct xen_sysctl_physinfo {