[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging] xen/arm: gic-v3: Introduce CONFIG_GICV3_NR_LRS



commit a0b958f45fade7e43ce748e686369c85b6c3c0d4
Author:     Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx>
AuthorDate: Mon Jul 6 15:35:53 2026 +0200
Commit:     Michal Orzel <michal.orzel@xxxxxxx>
CommitDate: Mon Oct 12 08:50:11 2026 +0200

    xen/arm: gic-v3: Introduce CONFIG_GICV3_NR_LRS
    
    Add a Kconfig option that lets an integrator hard-code the number of
    GICv3 List 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>
    Reviewed-by: Luca Fancellu <luca.fancellu@xxxxxxx>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
---
 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 06289005f4..b9c5c40678 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -145,6 +145,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 List Registers used" if EXPERT
+       depends on GICV3
+       range 0 16
+       default 0
+       help
+         Controls the number of List 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 76b81bfb03..23a4497a30 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:
@@ -1043,9 +1061,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;
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.