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

[xen master] xen/riscv: fix out-of-range indexing of the IMSIC per-CPU MSI array



commit f8b21e5a5ee62931a1c40882ad0bbc00e31a3499
Author:     Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
AuthorDate: Mon Sep 7 10:41:51 2026 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Sep 7 10:41:51 2026 +0200

    xen/riscv: fix out-of-range indexing of the IMSIC per-CPU MSI array
    
    imsic_init() indexes msi[] by the Xen CPU id hartid_to_cpuid() returns,
    but that array is allocated with one entry per parent IRQ of the IMSIC
    node, and the only range check compares the index against
    num_possible_cpus(). Neither matches the array, and the check comes
    after the first access:
    
    - hartid_to_cpuid() returns NR_CPUS when the hart isn't one Xen brought
      up, and msi[NR_CPUS].base_addr is read before that is noticed;
    - an IMSIC node listing fewer parents than Xen has CPUs makes every
      index past nr_parent_irqs go past the end of the allocation, which the
      num_possible_cpus() check lets through.
    
    Size the array by nr_cpu_ids, which is what it is indexed by,
    and move the range check ahead of the first msi[] access.
    
    Fixes: c9bd8b322ecb ("xen/riscv: imsic_init() implementation")
    Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/riscv/imsic.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/xen/arch/riscv/imsic.c b/xen/arch/riscv/imsic.c
index f7b70a8da0..8da72c0072 100644
--- a/xen/arch/riscv/imsic.c
+++ b/xen/arch/riscv/imsic.c
@@ -346,7 +346,7 @@ int __init imsic_init(const struct dt_device_node *node)
         goto imsic_init_err;
     }
 
-    msi = xvzalloc_array(struct imsic_msi, nr_parent_irqs);
+    msi = xvzalloc_array(struct imsic_msi, nr_cpu_ids);
     if ( !msi )
     {
         rc = -ENOMEM;
@@ -405,7 +405,18 @@ int __init imsic_init(const struct dt_device_node *node)
             continue;
         }
 
+        /*
+         * hartid_to_cpuid() returns NR_CPUS for a hart Xen doesn't know, so
+         * the range has to be checked before msi[] is indexed at all.
+         */
         cpu = hartid_to_cpuid(hartid);
+        if ( cpu >= nr_cpu_ids )
+        {
+            printk(XENLOG_WARNING
+                   "%s: unsupported hart ID=%#lx for parent irq%u\n",
+                   node->name, hartid, i);
+            continue;
+        }
 
         /*
          * If .base_addr is not 0, it indicates that the CPU has already been
@@ -421,13 +432,6 @@ int __init imsic_init(const struct dt_device_node *node)
             continue;
         }
 
-        if ( cpu >= num_possible_cpus() )
-        {
-            printk(XENLOG_WARNING "%s: unsupported hart ID=%#lx for parent 
irq%u\n",
-                   node->name, hartid, i);
-            continue;
-        }
-
         /* Find MMIO location of MSI page */
         reloff = i * IMSIC_HART_SIZE(imsic_cfg.guest_index_bits);
         for ( index = 0; index < nr_mmios; index++ )
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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