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

Configure Feed

Select the types of activity you want to include in your feed.

KVM: arm64: gic-v5: Detect implemented PPIs on boot

As part of booting the system and initialising KVM, create and
populate a mask of the implemented PPIs. This mask allows future PPI
operations (such as save/restore or state, or syncing back into the
shadow state) to only consider PPIs that are actually implemented on
the host.

The set of implemented virtual PPIs matches the set of implemented
physical PPIs for a GICv5 host. Therefore, this mask represents all
PPIs that could ever by used by a GICv5-based guest on a specific
host, albeit pre-filtered by what we support in KVM (see next
paragraph).

Only architected PPIs are currently supported in KVM with
GICv5. Moreover, as KVM only supports a subset of all possible PPIS
(Timers, PMU, GICv5 SW_PPI) the PPI mask only includes these PPIs, if
present. The timers are always assumed to be present; if we have KVM
we have EL2, which means that we have the EL1 & EL2 Timer PPIs. If we
have a PMU (v3), then the PMUIRQ is present. The GICv5 SW_PPI is
always assumed to be present.

Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/20260319154937.3619520-12-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier <maz@kernel.org>

authored by

Sascha Bischoff and committed by
Marc Zyngier
f6568071 da92ff15

+66
+31
arch/arm64/kvm/vgic/vgic-v5.c
··· 4 4 */ 5 5 6 6 #include <kvm/arm_vgic.h> 7 + 8 + #include <linux/bitops.h> 7 9 #include <linux/irqchip/arm-vgic-info.h> 8 10 9 11 #include "vgic.h" 12 + 13 + static struct vgic_v5_ppi_caps ppi_caps; 14 + 15 + /* 16 + * Not all PPIs are guaranteed to be implemented for GICv5. Deterermine which 17 + * ones are, and generate a mask. 18 + */ 19 + static void vgic_v5_get_implemented_ppis(void) 20 + { 21 + if (!cpus_have_final_cap(ARM64_HAS_GICV5_CPUIF)) 22 + return; 23 + 24 + /* 25 + * If we have KVM, we have EL2, which means that we have support for the 26 + * EL1 and EL2 Physical & Virtual timers. 27 + */ 28 + __assign_bit(GICV5_ARCH_PPI_CNTHP, ppi_caps.impl_ppi_mask, 1); 29 + __assign_bit(GICV5_ARCH_PPI_CNTV, ppi_caps.impl_ppi_mask, 1); 30 + __assign_bit(GICV5_ARCH_PPI_CNTHV, ppi_caps.impl_ppi_mask, 1); 31 + __assign_bit(GICV5_ARCH_PPI_CNTP, ppi_caps.impl_ppi_mask, 1); 32 + 33 + /* The SW_PPI should be available */ 34 + __assign_bit(GICV5_ARCH_PPI_SW_PPI, ppi_caps.impl_ppi_mask, 1); 35 + 36 + /* The PMUIRQ is available if we have the PMU */ 37 + __assign_bit(GICV5_ARCH_PPI_PMUIRQ, ppi_caps.impl_ppi_mask, system_supports_pmuv3()); 38 + } 10 39 11 40 /* 12 41 * Probe for a vGICv5 compatible interrupt controller, returning 0 on success. ··· 46 17 { 47 18 u64 ich_vtr_el2; 48 19 int ret; 20 + 21 + vgic_v5_get_implemented_ppis(); 49 22 50 23 if (!cpus_have_final_cap(ARM64_HAS_GICV5_LEGACY)) 51 24 return -ENODEV;
+13
include/kvm/arm_vgic.h
··· 32 32 #define VGIC_MIN_LPI 8192 33 33 #define KVM_IRQCHIP_NUM_PINS (1020 - 32) 34 34 35 + /* 36 + * GICv5 supports 128 PPIs, but only the first 64 are architected. We only 37 + * support the timers and PMU in KVM, both of which are architected. Rather than 38 + * handling twice the state, we instead opt to only support the architected set 39 + * in KVM for now. At a future stage, this can be bumped up to 128, if required. 40 + */ 41 + #define VGIC_V5_NR_PRIVATE_IRQS 64 42 + 35 43 #define is_v5_type(t, i) (FIELD_GET(GICV5_HWIRQ_TYPE, (i)) == (t)) 36 44 37 45 #define __irq_is_sgi(t, i) \ ··· 426 418 struct its_vpe its_vpe; 427 419 428 420 unsigned int used_lrs; 421 + }; 422 + 423 + /* What PPI capabilities does a GICv5 host have */ 424 + struct vgic_v5_ppi_caps { 425 + DECLARE_BITMAP(impl_ppi_mask, VGIC_V5_NR_PRIVATE_IRQS); 429 426 }; 430 427 431 428 struct vgic_cpu {
+22
include/linux/irqchip/arm-gic-v5.h
··· 25 25 #define GICV5_HWIRQ_TYPE_SPI UL(0x3) 26 26 27 27 /* 28 + * Architected PPIs 29 + */ 30 + #define GICV5_ARCH_PPI_S_DB_PPI 0x0 31 + #define GICV5_ARCH_PPI_RL_DB_PPI 0x1 32 + #define GICV5_ARCH_PPI_NS_DB_PPI 0x2 33 + #define GICV5_ARCH_PPI_SW_PPI 0x3 34 + #define GICV5_ARCH_PPI_HACDBSIRQ 0xf 35 + #define GICV5_ARCH_PPI_CNTHVS 0x13 36 + #define GICV5_ARCH_PPI_CNTHPS 0x14 37 + #define GICV5_ARCH_PPI_PMBIRQ 0x15 38 + #define GICV5_ARCH_PPI_COMMIRQ 0x16 39 + #define GICV5_ARCH_PPI_PMUIRQ 0x17 40 + #define GICV5_ARCH_PPI_CTIIRQ 0x18 41 + #define GICV5_ARCH_PPI_GICMNT 0x19 42 + #define GICV5_ARCH_PPI_CNTHP 0x1a 43 + #define GICV5_ARCH_PPI_CNTV 0x1b 44 + #define GICV5_ARCH_PPI_CNTHV 0x1c 45 + #define GICV5_ARCH_PPI_CNTPS 0x1d 46 + #define GICV5_ARCH_PPI_CNTP 0x1e 47 + #define GICV5_ARCH_PPI_TRBIRQ 0x1f 48 + 49 + /* 28 50 * Tables attributes 29 51 */ 30 52 #define GICV5_NO_READ_ALLOC 0b0