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.

irqchip/riscv-imsic: Adjust the number of available guest irq files

Currently, KVM assumes the minimum of implemented HGEIE bits and
"BIT(gc->guest_index_bits) - 1" as the number of guest files available
across all CPUs. This will not work when CPUs have different number
of guest files because KVM may incorrectly allocate a guest file on a
CPU with fewer guest files.

To address above, during initialization, calculate the number of
available guest interrupt files according to MMIO resources and
constrain the number of guest interrupt files that can be allocated
by KVM.

Signed-off-by: Xu Lu <luxu.kernel@bytedance.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Acked-by: Thomas Gleixner <tglx@kernel.org>
Link: https://lore.kernel.org/r/20260104133457.57742-1-luxu.kernel@bytedance.com
Signed-off-by: Anup Patel <anup@brainfault.org>

authored by

Xu Lu and committed by
Anup Patel
376e2f8c ed7ae7a3

+15 -2
+1 -1
arch/riscv/kvm/aia.c
··· 630 630 */ 631 631 if (gc) 632 632 kvm_riscv_aia_nr_hgei = min((ulong)kvm_riscv_aia_nr_hgei, 633 - BIT(gc->guest_index_bits) - 1); 633 + gc->nr_guest_files); 634 634 else 635 635 kvm_riscv_aia_nr_hgei = 0; 636 636
+11 -1
drivers/irqchip/irq-riscv-imsic-state.c
··· 784 784 785 785 int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque) 786 786 { 787 - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0; 787 + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0; 788 788 struct imsic_global_config *global; 789 789 struct imsic_local_config *local; 790 790 void __iomem **mmios_va = NULL; ··· 878 878 } 879 879 880 880 /* Configure handlers for target CPUs */ 881 + global->nr_guest_files = BIT(global->guest_index_bits) - 1; 881 882 for (i = 0; i < nr_parent_irqs; i++) { 882 883 rc = imsic_get_parent_hartid(fwnode, i, &hartid); 883 884 if (rc) { ··· 918 917 local = per_cpu_ptr(global->local, cpu); 919 918 local->msi_pa = mmios[index].start + reloff; 920 919 local->msi_va = mmios_va[index] + reloff; 920 + 921 + /* 922 + * KVM uses global->nr_guest_files to determine the available guest 923 + * interrupt files on each CPU. Take the minimum number of guest 924 + * interrupt files across all CPUs to avoid KVM incorrectly allocating 925 + * an unexisted or unmapped guest interrupt file on some CPUs. 926 + */ 927 + nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1; 928 + global->nr_guest_files = min(global->nr_guest_files, nr_guest_files); 921 929 922 930 nr_handlers++; 923 931 }
+3
include/linux/irqchip/riscv-imsic.h
··· 68 68 /* Number of guest interrupt identities */ 69 69 u32 nr_guest_ids; 70 70 71 + /* Number of guest interrupt files per core */ 72 + u32 nr_guest_files; 73 + 71 74 /* Per-CPU IMSIC addresses */ 72 75 struct imsic_local_config __percpu *local; 73 76 };