|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3] xen/arm: gic-v3: Introduce CONFIG_GICV3_NR_LRS
Hi,
> On 6 Jul 2026, at 15:35, Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx> wrote:
>
> Add a Kconfig option that lets an integrator hard-code the number of
> GICv3 Link Registers Xen uses. The default (0) keeps reading the count
> from ICH_VTR_EL2.ListRegs at boot. A non-zero value is validated
> against the hardware count in gicv3_hyp_init() and replaces
> gicv3_info.nr_lrs.
>
> gicv3_hyp_init() now panics if CONFIG_GICV3_NR_LRS exceeds the
> hardware count, and zeroes all hardware LRs (once per CPU) as defensive
> hardening, so any interrupt left in an LR that Xen will not manage
> cannot be picked up by the GIC.
>
> gicv3_ich_read_lr()/gicv3_ich_write_lr() now reject out-of-range
> indices with an error message, ASSERT_UNREACHABLE() and WARN() instead
> of silently returning RAZ/WI; reaching this path indicates a bug.
>
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx>
> Signed-off-by: Michal Orzel <michal.orzel@xxxxxxx>
With the typo Link/List registers fixed:
Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
Cheers
Bertrand
> ---
> Changes in
> v3:
> - Validate CONFIG_GICV3_NR_LRS against the hardware count in
> gicv3_hyp_init() and panic if it exceeds it (Julien, Luca).
> - Allow an integrator to select fewer LRs than the hardware supports;
> gicv3_info.nr_lrs is replaced with the clamped value (Julien).
> - Zero all hardware LRs in gicv3_hyp_init() as defensive hardening.
> - Replace the silent RAZ/WI out-of-range path in gicv3_ich_read_lr()/
> gicv3_ich_write_lr() with gprintk() + ASSERT_UNREACHABLE() + WARN()
> (Julien).
> - Renamed the Kconfig from LRS to NR_LRS (Julien).
> - The link-time dead-code-elimination guard is split out into a
> separate follow-up patch.
>
> v2:
> - s/lrs/LRS.
> - Implement RAZ/WI instead of panic.
>
> xen/arch/arm/Kconfig | 9 ++++++++
> xen/arch/arm/gic-v3.c | 50 ++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 58 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
> index 5fa89fcb24..798bc8e9b2 100644
> --- a/xen/arch/arm/Kconfig
> +++ b/xen/arch/arm/Kconfig
> @@ -143,6 +143,15 @@ config GICV3_ESPI
> range, from 4096 to 5119. This feature is introduced in GICv3.1
> architecture.
>
> +config GICV3_NR_LRS
> + int "Number of GICv3 Link Registers used" if EXPERT
> + depends on GICV3
> + range 0 16
> + default 0
> + help
> + Controls the number of Link registers to be used.
> + Keep it set to 0 to use a value obtained from a hardware register.
> +
> config HAS_ITS
> bool "GICv3 ITS MSI controller support (UNSUPPORTED)" if UNSUPPORTED
> depends on GICV3 && !NEW_VGIC && !ARM_32
> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
> index acdac22953..46ab0b6329 100644
> --- a/xen/arch/arm/gic-v3.c
> +++ b/xen/arch/arm/gic-v3.c
> @@ -178,6 +178,15 @@ static inline void gicv3_restore_lrs(const struct vcpu
> *v)
>
> static uint64_t gicv3_ich_read_lr(int lr)
> {
> + if ( lr < 0 || lr >= gicv3_info.nr_lrs )
> + {
> + gprintk(XENLOG_ERR, "GICv3: LR read index %d out of range (nr_lrs
> %u)\n",
> + lr, gicv3_info.nr_lrs);
> + ASSERT_UNREACHABLE();
> + WARN();
> + return 0;
> + }
> +
> switch ( lr )
> {
> case 0: return READ_SYSREG_LR(0);
> @@ -203,6 +212,15 @@ static uint64_t gicv3_ich_read_lr(int lr)
>
> static void gicv3_ich_write_lr(int lr, uint64_t val)
> {
> + if ( lr < 0 || lr >= gicv3_info.nr_lrs )
> + {
> + gprintk(XENLOG_ERR, "GICv3: LR write index %d out of range (nr_lrs
> %u)\n",
> + lr, gicv3_info.nr_lrs);
> + ASSERT_UNREACHABLE();
> + WARN();
> + return;
> + }
> +
> switch ( lr )
> {
> case 0:
> @@ -1041,9 +1059,39 @@ static void gicv3_cpu_disable(void)
> static void gicv3_hyp_init(void)
> {
> register_t vtr;
> + uint8_t hw_nr_lrs;
>
> vtr = READ_SYSREG(ICH_VTR_EL2);
> - gicv3_info.nr_lrs = (vtr & ICH_VTR_NRLRGS) + 1;
> + hw_nr_lrs = (vtr & ICH_VTR_NRLRGS) + 1;
> +
> + if ( CONFIG_GICV3_NR_LRS && CONFIG_GICV3_NR_LRS > hw_nr_lrs )
> + panic("GICv3: CONFIG_GICV3_NR_LRS (%u) exceeds hardware nr_lrs
> (%u)\n",
> + CONFIG_GICV3_NR_LRS, hw_nr_lrs);
> +
> + gicv3_info.nr_lrs = CONFIG_GICV3_NR_LRS ?: hw_nr_lrs;
> +
> + /* Zero all hardware LRs. */
> + switch ( hw_nr_lrs )
> + {
> + case 16: WRITE_SYSREG_LR(0, 15); fallthrough;
> + case 15: WRITE_SYSREG_LR(0, 14); fallthrough;
> + case 14: WRITE_SYSREG_LR(0, 13); fallthrough;
> + case 13: WRITE_SYSREG_LR(0, 12); fallthrough;
> + case 12: WRITE_SYSREG_LR(0, 11); fallthrough;
> + case 11: WRITE_SYSREG_LR(0, 10); fallthrough;
> + case 10: WRITE_SYSREG_LR(0, 9); fallthrough;
> + case 9: WRITE_SYSREG_LR(0, 8); fallthrough;
> + case 8: WRITE_SYSREG_LR(0, 7); fallthrough;
> + case 7: WRITE_SYSREG_LR(0, 6); fallthrough;
> + case 6: WRITE_SYSREG_LR(0, 5); fallthrough;
> + case 5: WRITE_SYSREG_LR(0, 4); fallthrough;
> + case 4: WRITE_SYSREG_LR(0, 3); fallthrough;
> + case 3: WRITE_SYSREG_LR(0, 2); fallthrough;
> + case 2: WRITE_SYSREG_LR(0, 1); fallthrough;
> + case 1: WRITE_SYSREG_LR(0, 0); break;
> + default: BUG();
> + }
> +
> gicv3.nr_priorities = ((vtr >> ICH_VTR_PRIBITS_SHIFT) &
> ICH_VTR_PRIBITS_MASK) + 1;
>
> --
> 2.25.1
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |