* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-22 3:09 ` Guo Ren
0 siblings, 0 replies; 27+ messages in thread
From: Guo Ren @ 2026-04-22 3:09 UTC (permalink / raw)
To: fangyu.yu, cp0613, inochiama, me, gaohan, anup, atish.patra, pjw,
palmer, alex, tglx, Albert Ou
Cc: kvm-riscv, kvm, linux-kernel, linux-riscv
Hi all,
This patch simply removed `nr_guest_files`, which is suboptimal. For
v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
(per-HART) and compute the effective HGEI count in
`kvm_riscv_aia_enable()` as:
min(hgctrl->nr_hgei, lc->nr_guest_files)
This provides a more accurate and robust per-HART configuration.
Here are the updated two patches for your review:
irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
With the recent KVM AIA per-HART HGEI conversion, the global
nr_guest_files is no longer appropriate. Different HARTs in
heterogeneous SoCs may have different numbers of guest interrupt
files.
Move `nr_guest_files` from `struct imsic_global_config` to
`struct imsic_local_config`, and compute it per-CPU in
imsic_setup_state() based on the actual MMIO guest file region size.
Update the related comment to reflect that KVM now uses the
per-HART value.
This eliminates the last global assumption about guest files and
completes the per-HART conversion series for RISC-V AIA/IMSIC.
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
b/drivers/irqchip/irq-riscv-imsic-state.c
index e3ed874d89e7..3d455ef43298 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
fwnode_handle *fwnode,
int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
{
- u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
nr_handlers = 0;
+ u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
struct imsic_global_config *global;
struct imsic_local_config *local;
void __iomem **mmios_va = NULL;
@@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
*fwnode, void *opaque)
}
/* Configure handlers for target CPUs */
- global->nr_guest_files = BIT(global->guest_index_bits) - 1;
for (i = 0; i < nr_parent_irqs; i++) {
rc = imsic_get_parent_hartid(fwnode, i, &hartid);
if (rc) {
@@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
fwnode_handle *fwnode, void *opaque)
local->msi_va = mmios_va[index] + reloff;
/*
- * KVM uses global->nr_guest_files to determine the
available guest
+ * KVM uses local->nr_guest_files to determine the
available guest
* interrupt files on each CPU. Take the minimum number of guest
* interrupt files across all CPUs to avoid KVM
incorrectly allocating
* an unexisted or unmapped guest interrupt file on some CPUs.
*/
- nr_guest_files = (resource_size(&mmios[index]) -
reloff) / IMSIC_MMIO_PAGE_SZ - 1;
- global->nr_guest_files = min(global->nr_guest_files,
nr_guest_files);
+ local->nr_guest_files =
+ (resource_size(&mmios[index]) - reloff) /
IMSIC_MMIO_PAGE_SZ - 1;
nr_handlers++;
}
diff --git a/include/linux/irqchip/riscv-imsic.h
b/include/linux/irqchip/riscv-imsic.h
index 4b348836de7a..13e8bd7ff4b4 100644
--- a/include/linux/irqchip/riscv-imsic.h
+++ b/include/linux/irqchip/riscv-imsic.h
@@ -40,6 +40,9 @@
struct imsic_local_config {
phys_addr_t msi_pa;
void __iomem *msi_va;
+
+ /* Number of guest interrupt files per core */
+ u32 nr_guest_files;
};
struct imsic_global_config {
@@ -68,9 +71,6 @@ struct imsic_global_config {
/* Number of guest interrupt identities */
u32 nr_guest_ids;
- /* Number of guest interrupt files per core */
- u32 nr_guest_files;
-
/* Per-CPU IMSIC addresses */
struct imsic_local_config __percpu *local;
};
------------------------
The other one:
RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
Now that `nr_guest_files` has been moved to `struct imsic_local_config`
and is computed per-HART, KVM must respect the actual number of guest
interrupt files available on each HART when setting up HGEI.
In `kvm_riscv_aia_enable()`:
- Retrieve the per-CPU IMSIC local config
- Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
HGEI count for this HART
- Use the result to initialize `free_bitmap`
This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
where different cores may have different IMSIC guest file counts, and
completes the per-HART conversion series.
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
index 70ff1d25dd99..a5f4b7fe1dce 100644
--- a/arch/riscv/kvm/aia.c
+++ b/arch/riscv/kvm/aia.c
@@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
void kvm_riscv_aia_enable(void)
{
struct aia_hgei_control *hgctrl;
+ const struct imsic_global_config *gc;
+ const struct imsic_local_config *lc;
+ unsigned int nr_hgei;
if (!kvm_riscv_aia_available())
return;
@@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
if (hgctrl->nr_hgei)
hgctrl->nr_hgei--;
- if (hgctrl->nr_hgei) {
- hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
+ gc = imsic_get_global_config();
+ lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
+ if (lc)
+ nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
+
+ if (nr_hgei) {
+ hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
hgctrl->free_bitmap &= ~BIT(0);
} else {
hgctrl->free_bitmap = 0;
On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
>
> From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
>
> With the recent KVM AIA changes, HGEI line management is now fully
> per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> The IMSIC driver no longer needs to compute and enforce a global
> minimum number of guest interrupt files across all HARTs.
>
> Remove:
> - `u32 nr_guest_files` from `struct imsic_global_config`
> - the initial `BIT(global->guest_index_bits) - 1` assignment
> - the entire per-CPU MMIO-based min() calculation and its comment
> (which was specifically there to protect old KVM)
>
> The per-HART guest file count is already handled locally in
> `imsic_local_config` during the parent IRQ loop, so this global
> field was redundant.
>
> This completes the cleanup series, eliminates the last global
> assumption about guest files, and improves support for heterogeneous
> (big.LITTLE / multi-vendor) RISC-V platforms.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> ---
> drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> include/linux/irqchip/riscv-imsic.h | 3 ---
> 2 files changed, 1 insertion(+), 14 deletions(-)
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d89e7..fef27247a34f 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
>
> int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> {
> - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> struct imsic_global_config *global;
> struct imsic_local_config *local;
> void __iomem **mmios_va = NULL;
> @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> }
>
> /* Configure handlers for target CPUs */
> - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> for (i = 0; i < nr_parent_irqs; i++) {
> rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> if (rc) {
> @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> local->msi_pa = mmios[index].start + reloff;
> local->msi_va = mmios_va[index] + reloff;
>
> - /*
> - * KVM uses global->nr_guest_files to determine the available guest
> - * interrupt files on each CPU. Take the minimum number of guest
> - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> - * an unexisted or unmapped guest interrupt file on some CPUs.
> - */
> - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> -
> nr_handlers++;
> }
>
> diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> index 4b348836de7a..7f3ff5c5ea53 100644
> --- a/include/linux/irqchip/riscv-imsic.h
> +++ b/include/linux/irqchip/riscv-imsic.h
> @@ -68,9 +68,6 @@ struct imsic_global_config {
> /* Number of guest interrupt identities */
> u32 nr_guest_ids;
>
> - /* Number of guest interrupt files per core */
> - u32 nr_guest_files;
> -
> /* Per-CPU IMSIC addresses */
> struct imsic_local_config __percpu *local;
> };
> --
> 2.40.1
>
--
Best Regards
Guo Ren
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-22 3:09 ` Guo Ren
0 siblings, 0 replies; 27+ messages in thread
From: Guo Ren @ 2026-04-22 3:09 UTC (permalink / raw)
To: fangyu.yu, cp0613, inochiama, me, gaohan, anup, atish.patra, pjw,
palmer, alex, tglx, Albert Ou
Cc: kvm-riscv, kvm, linux-kernel, linux-riscv
Hi all,
This patch simply removed `nr_guest_files`, which is suboptimal. For
v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
(per-HART) and compute the effective HGEI count in
`kvm_riscv_aia_enable()` as:
min(hgctrl->nr_hgei, lc->nr_guest_files)
This provides a more accurate and robust per-HART configuration.
Here are the updated two patches for your review:
irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
With the recent KVM AIA per-HART HGEI conversion, the global
nr_guest_files is no longer appropriate. Different HARTs in
heterogeneous SoCs may have different numbers of guest interrupt
files.
Move `nr_guest_files` from `struct imsic_global_config` to
`struct imsic_local_config`, and compute it per-CPU in
imsic_setup_state() based on the actual MMIO guest file region size.
Update the related comment to reflect that KVM now uses the
per-HART value.
This eliminates the last global assumption about guest files and
completes the per-HART conversion series for RISC-V AIA/IMSIC.
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
b/drivers/irqchip/irq-riscv-imsic-state.c
index e3ed874d89e7..3d455ef43298 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
fwnode_handle *fwnode,
int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
{
- u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
nr_handlers = 0;
+ u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
struct imsic_global_config *global;
struct imsic_local_config *local;
void __iomem **mmios_va = NULL;
@@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
*fwnode, void *opaque)
}
/* Configure handlers for target CPUs */
- global->nr_guest_files = BIT(global->guest_index_bits) - 1;
for (i = 0; i < nr_parent_irqs; i++) {
rc = imsic_get_parent_hartid(fwnode, i, &hartid);
if (rc) {
@@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
fwnode_handle *fwnode, void *opaque)
local->msi_va = mmios_va[index] + reloff;
/*
- * KVM uses global->nr_guest_files to determine the
available guest
+ * KVM uses local->nr_guest_files to determine the
available guest
* interrupt files on each CPU. Take the minimum number of guest
* interrupt files across all CPUs to avoid KVM
incorrectly allocating
* an unexisted or unmapped guest interrupt file on some CPUs.
*/
- nr_guest_files = (resource_size(&mmios[index]) -
reloff) / IMSIC_MMIO_PAGE_SZ - 1;
- global->nr_guest_files = min(global->nr_guest_files,
nr_guest_files);
+ local->nr_guest_files =
+ (resource_size(&mmios[index]) - reloff) /
IMSIC_MMIO_PAGE_SZ - 1;
nr_handlers++;
}
diff --git a/include/linux/irqchip/riscv-imsic.h
b/include/linux/irqchip/riscv-imsic.h
index 4b348836de7a..13e8bd7ff4b4 100644
--- a/include/linux/irqchip/riscv-imsic.h
+++ b/include/linux/irqchip/riscv-imsic.h
@@ -40,6 +40,9 @@
struct imsic_local_config {
phys_addr_t msi_pa;
void __iomem *msi_va;
+
+ /* Number of guest interrupt files per core */
+ u32 nr_guest_files;
};
struct imsic_global_config {
@@ -68,9 +71,6 @@ struct imsic_global_config {
/* Number of guest interrupt identities */
u32 nr_guest_ids;
- /* Number of guest interrupt files per core */
- u32 nr_guest_files;
-
/* Per-CPU IMSIC addresses */
struct imsic_local_config __percpu *local;
};
------------------------
The other one:
RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
Now that `nr_guest_files` has been moved to `struct imsic_local_config`
and is computed per-HART, KVM must respect the actual number of guest
interrupt files available on each HART when setting up HGEI.
In `kvm_riscv_aia_enable()`:
- Retrieve the per-CPU IMSIC local config
- Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
HGEI count for this HART
- Use the result to initialize `free_bitmap`
This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
where different cores may have different IMSIC guest file counts, and
completes the per-HART conversion series.
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
index 70ff1d25dd99..a5f4b7fe1dce 100644
--- a/arch/riscv/kvm/aia.c
+++ b/arch/riscv/kvm/aia.c
@@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
void kvm_riscv_aia_enable(void)
{
struct aia_hgei_control *hgctrl;
+ const struct imsic_global_config *gc;
+ const struct imsic_local_config *lc;
+ unsigned int nr_hgei;
if (!kvm_riscv_aia_available())
return;
@@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
if (hgctrl->nr_hgei)
hgctrl->nr_hgei--;
- if (hgctrl->nr_hgei) {
- hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
+ gc = imsic_get_global_config();
+ lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
+ if (lc)
+ nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
+
+ if (nr_hgei) {
+ hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
hgctrl->free_bitmap &= ~BIT(0);
} else {
hgctrl->free_bitmap = 0;
On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
>
> From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
>
> With the recent KVM AIA changes, HGEI line management is now fully
> per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> The IMSIC driver no longer needs to compute and enforce a global
> minimum number of guest interrupt files across all HARTs.
>
> Remove:
> - `u32 nr_guest_files` from `struct imsic_global_config`
> - the initial `BIT(global->guest_index_bits) - 1` assignment
> - the entire per-CPU MMIO-based min() calculation and its comment
> (which was specifically there to protect old KVM)
>
> The per-HART guest file count is already handled locally in
> `imsic_local_config` during the parent IRQ loop, so this global
> field was redundant.
>
> This completes the cleanup series, eliminates the last global
> assumption about guest files, and improves support for heterogeneous
> (big.LITTLE / multi-vendor) RISC-V platforms.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> ---
> drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> include/linux/irqchip/riscv-imsic.h | 3 ---
> 2 files changed, 1 insertion(+), 14 deletions(-)
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d89e7..fef27247a34f 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
>
> int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> {
> - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> struct imsic_global_config *global;
> struct imsic_local_config *local;
> void __iomem **mmios_va = NULL;
> @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> }
>
> /* Configure handlers for target CPUs */
> - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> for (i = 0; i < nr_parent_irqs; i++) {
> rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> if (rc) {
> @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> local->msi_pa = mmios[index].start + reloff;
> local->msi_va = mmios_va[index] + reloff;
>
> - /*
> - * KVM uses global->nr_guest_files to determine the available guest
> - * interrupt files on each CPU. Take the minimum number of guest
> - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> - * an unexisted or unmapped guest interrupt file on some CPUs.
> - */
> - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> -
> nr_handlers++;
> }
>
> diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> index 4b348836de7a..7f3ff5c5ea53 100644
> --- a/include/linux/irqchip/riscv-imsic.h
> +++ b/include/linux/irqchip/riscv-imsic.h
> @@ -68,9 +68,6 @@ struct imsic_global_config {
> /* Number of guest interrupt identities */
> u32 nr_guest_ids;
>
> - /* Number of guest interrupt files per core */
> - u32 nr_guest_files;
> -
> /* Per-CPU IMSIC addresses */
> struct imsic_local_config __percpu *local;
> };
> --
> 2.40.1
>
--
Best Regards
Guo Ren
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
2026-04-22 3:09 ` Guo Ren
(?)
@ 2026-04-22 9:44 ` Anup Patel
-1 siblings, 0 replies; 27+ messages in thread
From: Anup Patel @ 2026-04-22 9:44 UTC (permalink / raw)
To: Guo Ren
Cc: fangyu.yu, cp0613, inochiama, me, gaohan, atish.patra, pjw,
palmer, alex, tglx, Albert Ou, kvm-riscv, kvm, linux-kernel,
linux-riscv
On Wed, Apr 22, 2026 at 8:39 AM Guo Ren <guoren@kernel.org> wrote:
>
> Hi all,
>
> This patch simply removed `nr_guest_files`, which is suboptimal. For
> v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> (per-HART) and compute the effective HGEI count in
> `kvm_riscv_aia_enable()` as:
>
> min(hgctrl->nr_hgei, lc->nr_guest_files)
Yes, I was going to comment the exact same thing. Good that you
realized it early.
Regards,
Anup
>
> This provides a more accurate and robust per-HART configuration.
>
> Here are the updated two patches for your review:
>
> irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
>
> With the recent KVM AIA per-HART HGEI conversion, the global
> nr_guest_files is no longer appropriate. Different HARTs in
> heterogeneous SoCs may have different numbers of guest interrupt
> files.
>
> Move `nr_guest_files` from `struct imsic_global_config` to
> `struct imsic_local_config`, and compute it per-CPU in
> imsic_setup_state() based on the actual MMIO guest file region size.
>
> Update the related comment to reflect that KVM now uses the
> per-HART value.
>
> This eliminates the last global assumption about guest files and
> completes the per-HART conversion series for RISC-V AIA/IMSIC.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d89e7..3d455ef43298 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> fwnode_handle *fwnode,
>
> int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> {
> - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> nr_handlers = 0;
> + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> struct imsic_global_config *global;
> struct imsic_local_config *local;
> void __iomem **mmios_va = NULL;
> @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> *fwnode, void *opaque)
> }
>
> /* Configure handlers for target CPUs */
> - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> for (i = 0; i < nr_parent_irqs; i++) {
> rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> if (rc) {
> @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> fwnode_handle *fwnode, void *opaque)
> local->msi_va = mmios_va[index] + reloff;
>
> /*
> - * KVM uses global->nr_guest_files to determine the
> available guest
> + * KVM uses local->nr_guest_files to determine the
> available guest
> * interrupt files on each CPU. Take the minimum number of guest
> * interrupt files across all CPUs to avoid KVM
> incorrectly allocating
> * an unexisted or unmapped guest interrupt file on some CPUs.
> */
> - nr_guest_files = (resource_size(&mmios[index]) -
> reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> - global->nr_guest_files = min(global->nr_guest_files,
> nr_guest_files);
> + local->nr_guest_files =
> + (resource_size(&mmios[index]) - reloff) /
> IMSIC_MMIO_PAGE_SZ - 1;
>
> nr_handlers++;
> }
> diff --git a/include/linux/irqchip/riscv-imsic.h
> b/include/linux/irqchip/riscv-imsic.h
> index 4b348836de7a..13e8bd7ff4b4 100644
> --- a/include/linux/irqchip/riscv-imsic.h
> +++ b/include/linux/irqchip/riscv-imsic.h
> @@ -40,6 +40,9 @@
> struct imsic_local_config {
> phys_addr_t msi_pa;
> void __iomem *msi_va;
> +
> + /* Number of guest interrupt files per core */
> + u32 nr_guest_files;
> };
>
> struct imsic_global_config {
> @@ -68,9 +71,6 @@ struct imsic_global_config {
> /* Number of guest interrupt identities */
> u32 nr_guest_ids;
>
> - /* Number of guest interrupt files per core */
> - u32 nr_guest_files;
> -
> /* Per-CPU IMSIC addresses */
> struct imsic_local_config __percpu *local;
> };
>
> ------------------------
> The other one:
>
> RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
>
> Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> and is computed per-HART, KVM must respect the actual number of guest
> interrupt files available on each HART when setting up HGEI.
>
> In `kvm_riscv_aia_enable()`:
>
> - Retrieve the per-CPU IMSIC local config
> - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> HGEI count for this HART
> - Use the result to initialize `free_bitmap`
>
> This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> where different cores may have different IMSIC guest file counts, and
> completes the per-HART conversion series.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> index 70ff1d25dd99..a5f4b7fe1dce 100644
> --- a/arch/riscv/kvm/aia.c
> +++ b/arch/riscv/kvm/aia.c
> @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> void kvm_riscv_aia_enable(void)
> {
> struct aia_hgei_control *hgctrl;
> + const struct imsic_global_config *gc;
> + const struct imsic_local_config *lc;
> + unsigned int nr_hgei;
>
> if (!kvm_riscv_aia_available())
> return;
> @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> if (hgctrl->nr_hgei)
> hgctrl->nr_hgei--;
>
> - if (hgctrl->nr_hgei) {
> - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> + gc = imsic_get_global_config();
> + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> + if (lc)
> + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> +
> + if (nr_hgei) {
> + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> hgctrl->free_bitmap &= ~BIT(0);
> } else {
> hgctrl->free_bitmap = 0;
>
>
> On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> >
> > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> >
> > With the recent KVM AIA changes, HGEI line management is now fully
> > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > The IMSIC driver no longer needs to compute and enforce a global
> > minimum number of guest interrupt files across all HARTs.
> >
> > Remove:
> > - `u32 nr_guest_files` from `struct imsic_global_config`
> > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > - the entire per-CPU MMIO-based min() calculation and its comment
> > (which was specifically there to protect old KVM)
> >
> > The per-HART guest file count is already handled locally in
> > `imsic_local_config` during the parent IRQ loop, so this global
> > field was redundant.
> >
> > This completes the cleanup series, eliminates the last global
> > assumption about guest files, and improves support for heterogeneous
> > (big.LITTLE / multi-vendor) RISC-V platforms.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > ---
> > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > include/linux/irqchip/riscv-imsic.h | 3 ---
> > 2 files changed, 1 insertion(+), 14 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..fef27247a34f 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > local->msi_pa = mmios[index].start + reloff;
> > local->msi_va = mmios_va[index] + reloff;
> >
> > - /*
> > - * KVM uses global->nr_guest_files to determine the available guest
> > - * interrupt files on each CPU. Take the minimum number of guest
> > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > - */
> > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > -
> > nr_handlers++;
> > }
> >
> > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..7f3ff5c5ea53 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> > --
> > 2.40.1
> >
>
>
> --
> Best Regards
> Guo Ren
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-22 9:44 ` Anup Patel
0 siblings, 0 replies; 27+ messages in thread
From: Anup Patel @ 2026-04-22 9:44 UTC (permalink / raw)
To: Guo Ren
Cc: fangyu.yu, cp0613, inochiama, me, gaohan, atish.patra, pjw,
palmer, alex, tglx, Albert Ou, kvm-riscv, kvm, linux-kernel,
linux-riscv
On Wed, Apr 22, 2026 at 8:39 AM Guo Ren <guoren@kernel.org> wrote:
>
> Hi all,
>
> This patch simply removed `nr_guest_files`, which is suboptimal. For
> v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> (per-HART) and compute the effective HGEI count in
> `kvm_riscv_aia_enable()` as:
>
> min(hgctrl->nr_hgei, lc->nr_guest_files)
Yes, I was going to comment the exact same thing. Good that you
realized it early.
Regards,
Anup
>
> This provides a more accurate and robust per-HART configuration.
>
> Here are the updated two patches for your review:
>
> irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
>
> With the recent KVM AIA per-HART HGEI conversion, the global
> nr_guest_files is no longer appropriate. Different HARTs in
> heterogeneous SoCs may have different numbers of guest interrupt
> files.
>
> Move `nr_guest_files` from `struct imsic_global_config` to
> `struct imsic_local_config`, and compute it per-CPU in
> imsic_setup_state() based on the actual MMIO guest file region size.
>
> Update the related comment to reflect that KVM now uses the
> per-HART value.
>
> This eliminates the last global assumption about guest files and
> completes the per-HART conversion series for RISC-V AIA/IMSIC.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d89e7..3d455ef43298 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> fwnode_handle *fwnode,
>
> int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> {
> - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> nr_handlers = 0;
> + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> struct imsic_global_config *global;
> struct imsic_local_config *local;
> void __iomem **mmios_va = NULL;
> @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> *fwnode, void *opaque)
> }
>
> /* Configure handlers for target CPUs */
> - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> for (i = 0; i < nr_parent_irqs; i++) {
> rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> if (rc) {
> @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> fwnode_handle *fwnode, void *opaque)
> local->msi_va = mmios_va[index] + reloff;
>
> /*
> - * KVM uses global->nr_guest_files to determine the
> available guest
> + * KVM uses local->nr_guest_files to determine the
> available guest
> * interrupt files on each CPU. Take the minimum number of guest
> * interrupt files across all CPUs to avoid KVM
> incorrectly allocating
> * an unexisted or unmapped guest interrupt file on some CPUs.
> */
> - nr_guest_files = (resource_size(&mmios[index]) -
> reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> - global->nr_guest_files = min(global->nr_guest_files,
> nr_guest_files);
> + local->nr_guest_files =
> + (resource_size(&mmios[index]) - reloff) /
> IMSIC_MMIO_PAGE_SZ - 1;
>
> nr_handlers++;
> }
> diff --git a/include/linux/irqchip/riscv-imsic.h
> b/include/linux/irqchip/riscv-imsic.h
> index 4b348836de7a..13e8bd7ff4b4 100644
> --- a/include/linux/irqchip/riscv-imsic.h
> +++ b/include/linux/irqchip/riscv-imsic.h
> @@ -40,6 +40,9 @@
> struct imsic_local_config {
> phys_addr_t msi_pa;
> void __iomem *msi_va;
> +
> + /* Number of guest interrupt files per core */
> + u32 nr_guest_files;
> };
>
> struct imsic_global_config {
> @@ -68,9 +71,6 @@ struct imsic_global_config {
> /* Number of guest interrupt identities */
> u32 nr_guest_ids;
>
> - /* Number of guest interrupt files per core */
> - u32 nr_guest_files;
> -
> /* Per-CPU IMSIC addresses */
> struct imsic_local_config __percpu *local;
> };
>
> ------------------------
> The other one:
>
> RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
>
> Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> and is computed per-HART, KVM must respect the actual number of guest
> interrupt files available on each HART when setting up HGEI.
>
> In `kvm_riscv_aia_enable()`:
>
> - Retrieve the per-CPU IMSIC local config
> - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> HGEI count for this HART
> - Use the result to initialize `free_bitmap`
>
> This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> where different cores may have different IMSIC guest file counts, and
> completes the per-HART conversion series.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> index 70ff1d25dd99..a5f4b7fe1dce 100644
> --- a/arch/riscv/kvm/aia.c
> +++ b/arch/riscv/kvm/aia.c
> @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> void kvm_riscv_aia_enable(void)
> {
> struct aia_hgei_control *hgctrl;
> + const struct imsic_global_config *gc;
> + const struct imsic_local_config *lc;
> + unsigned int nr_hgei;
>
> if (!kvm_riscv_aia_available())
> return;
> @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> if (hgctrl->nr_hgei)
> hgctrl->nr_hgei--;
>
> - if (hgctrl->nr_hgei) {
> - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> + gc = imsic_get_global_config();
> + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> + if (lc)
> + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> +
> + if (nr_hgei) {
> + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> hgctrl->free_bitmap &= ~BIT(0);
> } else {
> hgctrl->free_bitmap = 0;
>
>
> On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> >
> > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> >
> > With the recent KVM AIA changes, HGEI line management is now fully
> > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > The IMSIC driver no longer needs to compute and enforce a global
> > minimum number of guest interrupt files across all HARTs.
> >
> > Remove:
> > - `u32 nr_guest_files` from `struct imsic_global_config`
> > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > - the entire per-CPU MMIO-based min() calculation and its comment
> > (which was specifically there to protect old KVM)
> >
> > The per-HART guest file count is already handled locally in
> > `imsic_local_config` during the parent IRQ loop, so this global
> > field was redundant.
> >
> > This completes the cleanup series, eliminates the last global
> > assumption about guest files, and improves support for heterogeneous
> > (big.LITTLE / multi-vendor) RISC-V platforms.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > ---
> > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > include/linux/irqchip/riscv-imsic.h | 3 ---
> > 2 files changed, 1 insertion(+), 14 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..fef27247a34f 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > local->msi_pa = mmios[index].start + reloff;
> > local->msi_va = mmios_va[index] + reloff;
> >
> > - /*
> > - * KVM uses global->nr_guest_files to determine the available guest
> > - * interrupt files on each CPU. Take the minimum number of guest
> > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > - */
> > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > -
> > nr_handlers++;
> > }
> >
> > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..7f3ff5c5ea53 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> > --
> > 2.40.1
> >
>
>
> --
> Best Regards
> Guo Ren
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-22 9:44 ` Anup Patel
0 siblings, 0 replies; 27+ messages in thread
From: Anup Patel @ 2026-04-22 9:44 UTC (permalink / raw)
To: Guo Ren
Cc: fangyu.yu, cp0613, inochiama, me, gaohan, atish.patra, pjw,
palmer, alex, tglx, Albert Ou, kvm-riscv, kvm, linux-kernel,
linux-riscv
On Wed, Apr 22, 2026 at 8:39 AM Guo Ren <guoren@kernel.org> wrote:
>
> Hi all,
>
> This patch simply removed `nr_guest_files`, which is suboptimal. For
> v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> (per-HART) and compute the effective HGEI count in
> `kvm_riscv_aia_enable()` as:
>
> min(hgctrl->nr_hgei, lc->nr_guest_files)
Yes, I was going to comment the exact same thing. Good that you
realized it early.
Regards,
Anup
>
> This provides a more accurate and robust per-HART configuration.
>
> Here are the updated two patches for your review:
>
> irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
>
> With the recent KVM AIA per-HART HGEI conversion, the global
> nr_guest_files is no longer appropriate. Different HARTs in
> heterogeneous SoCs may have different numbers of guest interrupt
> files.
>
> Move `nr_guest_files` from `struct imsic_global_config` to
> `struct imsic_local_config`, and compute it per-CPU in
> imsic_setup_state() based on the actual MMIO guest file region size.
>
> Update the related comment to reflect that KVM now uses the
> per-HART value.
>
> This eliminates the last global assumption about guest files and
> completes the per-HART conversion series for RISC-V AIA/IMSIC.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d89e7..3d455ef43298 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> fwnode_handle *fwnode,
>
> int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> {
> - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> nr_handlers = 0;
> + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> struct imsic_global_config *global;
> struct imsic_local_config *local;
> void __iomem **mmios_va = NULL;
> @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> *fwnode, void *opaque)
> }
>
> /* Configure handlers for target CPUs */
> - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> for (i = 0; i < nr_parent_irqs; i++) {
> rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> if (rc) {
> @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> fwnode_handle *fwnode, void *opaque)
> local->msi_va = mmios_va[index] + reloff;
>
> /*
> - * KVM uses global->nr_guest_files to determine the
> available guest
> + * KVM uses local->nr_guest_files to determine the
> available guest
> * interrupt files on each CPU. Take the minimum number of guest
> * interrupt files across all CPUs to avoid KVM
> incorrectly allocating
> * an unexisted or unmapped guest interrupt file on some CPUs.
> */
> - nr_guest_files = (resource_size(&mmios[index]) -
> reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> - global->nr_guest_files = min(global->nr_guest_files,
> nr_guest_files);
> + local->nr_guest_files =
> + (resource_size(&mmios[index]) - reloff) /
> IMSIC_MMIO_PAGE_SZ - 1;
>
> nr_handlers++;
> }
> diff --git a/include/linux/irqchip/riscv-imsic.h
> b/include/linux/irqchip/riscv-imsic.h
> index 4b348836de7a..13e8bd7ff4b4 100644
> --- a/include/linux/irqchip/riscv-imsic.h
> +++ b/include/linux/irqchip/riscv-imsic.h
> @@ -40,6 +40,9 @@
> struct imsic_local_config {
> phys_addr_t msi_pa;
> void __iomem *msi_va;
> +
> + /* Number of guest interrupt files per core */
> + u32 nr_guest_files;
> };
>
> struct imsic_global_config {
> @@ -68,9 +71,6 @@ struct imsic_global_config {
> /* Number of guest interrupt identities */
> u32 nr_guest_ids;
>
> - /* Number of guest interrupt files per core */
> - u32 nr_guest_files;
> -
> /* Per-CPU IMSIC addresses */
> struct imsic_local_config __percpu *local;
> };
>
> ------------------------
> The other one:
>
> RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
>
> Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> and is computed per-HART, KVM must respect the actual number of guest
> interrupt files available on each HART when setting up HGEI.
>
> In `kvm_riscv_aia_enable()`:
>
> - Retrieve the per-CPU IMSIC local config
> - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> HGEI count for this HART
> - Use the result to initialize `free_bitmap`
>
> This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> where different cores may have different IMSIC guest file counts, and
> completes the per-HART conversion series.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> index 70ff1d25dd99..a5f4b7fe1dce 100644
> --- a/arch/riscv/kvm/aia.c
> +++ b/arch/riscv/kvm/aia.c
> @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> void kvm_riscv_aia_enable(void)
> {
> struct aia_hgei_control *hgctrl;
> + const struct imsic_global_config *gc;
> + const struct imsic_local_config *lc;
> + unsigned int nr_hgei;
>
> if (!kvm_riscv_aia_available())
> return;
> @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> if (hgctrl->nr_hgei)
> hgctrl->nr_hgei--;
>
> - if (hgctrl->nr_hgei) {
> - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> + gc = imsic_get_global_config();
> + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> + if (lc)
> + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> +
> + if (nr_hgei) {
> + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> hgctrl->free_bitmap &= ~BIT(0);
> } else {
> hgctrl->free_bitmap = 0;
>
>
> On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> >
> > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> >
> > With the recent KVM AIA changes, HGEI line management is now fully
> > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > The IMSIC driver no longer needs to compute and enforce a global
> > minimum number of guest interrupt files across all HARTs.
> >
> > Remove:
> > - `u32 nr_guest_files` from `struct imsic_global_config`
> > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > - the entire per-CPU MMIO-based min() calculation and its comment
> > (which was specifically there to protect old KVM)
> >
> > The per-HART guest file count is already handled locally in
> > `imsic_local_config` during the parent IRQ loop, so this global
> > field was redundant.
> >
> > This completes the cleanup series, eliminates the last global
> > assumption about guest files, and improves support for heterogeneous
> > (big.LITTLE / multi-vendor) RISC-V platforms.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > ---
> > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > include/linux/irqchip/riscv-imsic.h | 3 ---
> > 2 files changed, 1 insertion(+), 14 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..fef27247a34f 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > local->msi_pa = mmios[index].start + reloff;
> > local->msi_va = mmios_va[index] + reloff;
> >
> > - /*
> > - * KVM uses global->nr_guest_files to determine the available guest
> > - * interrupt files on each CPU. Take the minimum number of guest
> > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > - */
> > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > -
> > nr_handlers++;
> > }
> >
> > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..7f3ff5c5ea53 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> > --
> > 2.40.1
> >
>
>
> --
> Best Regards
> Guo Ren
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
2026-04-22 9:44 ` Anup Patel
(?)
@ 2026-04-25 1:07 ` guoren
-1 siblings, 0 replies; 27+ messages in thread
From: guoren @ 2026-04-25 1:07 UTC (permalink / raw)
To: anup
Cc: alex, aou, atish.patra, cp0613, fangyu.yu, gaohan, guoren,
inochiama, kvm-riscv, kvm, linux-kernel, linux-riscv, me, palmer,
pjw, tglx
Hi Anup,
> On Wed, Apr 22, 2026 at 8:39 AM Guo Ren <guoren@kernel.org> wrote:
> >
> > Hi all,
> >
> > This patch simply removed `nr_guest_files`, which is suboptimal. For
> > v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> > (per-HART) and compute the effective HGEI count in
> > `kvm_riscv_aia_enable()` as:
> >
> > min(hgctrl->nr_hgei, lc->nr_guest_files)
>
> Yes, I was going to comment the exact same thing. Good that you
> realized it early.
Thank you for the feedback. This is V2:
https://lore.kernel.org/kvm-riscv/20260425005916.3321811-1-guoren@kernel.org/
Best Regards
GUO Ren
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-25 1:07 ` guoren
0 siblings, 0 replies; 27+ messages in thread
From: guoren @ 2026-04-25 1:07 UTC (permalink / raw)
To: anup
Cc: alex, aou, atish.patra, cp0613, fangyu.yu, gaohan, guoren,
inochiama, kvm-riscv, kvm, linux-kernel, linux-riscv, me, palmer,
pjw, tglx
Hi Anup,
> On Wed, Apr 22, 2026 at 8:39 AM Guo Ren <guoren@kernel.org> wrote:
> >
> > Hi all,
> >
> > This patch simply removed `nr_guest_files`, which is suboptimal. For
> > v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> > (per-HART) and compute the effective HGEI count in
> > `kvm_riscv_aia_enable()` as:
> >
> > min(hgctrl->nr_hgei, lc->nr_guest_files)
>
> Yes, I was going to comment the exact same thing. Good that you
> realized it early.
Thank you for the feedback. This is V2:
https://lore.kernel.org/kvm-riscv/20260425005916.3321811-1-guoren@kernel.org/
Best Regards
GUO Ren
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-25 1:07 ` guoren
0 siblings, 0 replies; 27+ messages in thread
From: guoren @ 2026-04-25 1:07 UTC (permalink / raw)
To: anup
Cc: alex, aou, atish.patra, cp0613, fangyu.yu, gaohan, guoren,
inochiama, kvm-riscv, kvm, linux-kernel, linux-riscv, me, palmer,
pjw, tglx
Hi Anup,
> On Wed, Apr 22, 2026 at 8:39 AM Guo Ren <guoren@kernel.org> wrote:
> >
> > Hi all,
> >
> > This patch simply removed `nr_guest_files`, which is suboptimal. For
> > v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> > (per-HART) and compute the effective HGEI count in
> > `kvm_riscv_aia_enable()` as:
> >
> > min(hgctrl->nr_hgei, lc->nr_guest_files)
>
> Yes, I was going to comment the exact same thing. Good that you
> realized it early.
Thank you for the feedback. This is V2:
https://lore.kernel.org/kvm-riscv/20260425005916.3321811-1-guoren@kernel.org/
Best Regards
GUO Ren
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
2026-04-22 3:09 ` Guo Ren
(?)
@ 2026-04-23 4:20 ` Inochi Amaoto
-1 siblings, 0 replies; 27+ messages in thread
From: Inochi Amaoto @ 2026-04-23 4:20 UTC (permalink / raw)
To: Guo Ren, fangyu.yu, cp0613, inochiama, me, gaohan, anup,
atish.patra, pjw, palmer, alex, tglx, Albert Ou
Cc: kvm-riscv, kvm, linux-kernel, linux-riscv
On Wed, Apr 22, 2026 at 11:09:30AM +0800, Guo Ren wrote:
> Hi all,
>
> This patch simply removed `nr_guest_files`, which is suboptimal. For
> v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> (per-HART) and compute the effective HGEI count in
> `kvm_riscv_aia_enable()` as:
>
> min(hgctrl->nr_hgei, lc->nr_guest_files)
>
> This provides a more accurate and robust per-HART configuration.
>
> Here are the updated two patches for your review:
>
> irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
>
> With the recent KVM AIA per-HART HGEI conversion, the global
> nr_guest_files is no longer appropriate. Different HARTs in
> heterogeneous SoCs may have different numbers of guest interrupt
> files.
>
> Move `nr_guest_files` from `struct imsic_global_config` to
> `struct imsic_local_config`, and compute it per-CPU in
> imsic_setup_state() based on the actual MMIO guest file region size.
>
> Update the related comment to reflect that KVM now uses the
> per-HART value.
>
> This eliminates the last global assumption about guest files and
> completes the per-HART conversion series for RISC-V AIA/IMSIC.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d89e7..3d455ef43298 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> fwnode_handle *fwnode,
>
> int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> {
> - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> nr_handlers = 0;
> + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> struct imsic_global_config *global;
> struct imsic_local_config *local;
> void __iomem **mmios_va = NULL;
> @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> *fwnode, void *opaque)
> }
>
> /* Configure handlers for target CPUs */
> - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> for (i = 0; i < nr_parent_irqs; i++) {
> rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> if (rc) {
> @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> fwnode_handle *fwnode, void *opaque)
> local->msi_va = mmios_va[index] + reloff;
>
> /*
> - * KVM uses global->nr_guest_files to determine the
> available guest
> + * KVM uses local->nr_guest_files to determine the
> available guest
> * interrupt files on each CPU. Take the minimum number of guest
> * interrupt files across all CPUs to avoid KVM
> incorrectly allocating
> * an unexisted or unmapped guest interrupt file on some CPUs.
> */
> - nr_guest_files = (resource_size(&mmios[index]) -
> reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> - global->nr_guest_files = min(global->nr_guest_files,
> nr_guest_files);
> + local->nr_guest_files =
> + (resource_size(&mmios[index]) - reloff) /
> IMSIC_MMIO_PAGE_SZ - 1;
>
The min is still required, otherwise the local->nr_guest_files can be
bigger than BIT(global->guest_index_bits) - 1, which is the max number
of the guest interrupt files that a hart can have. This condition is
true if the IMSIC group has more than one harts.
Regards,
Inochi
> nr_handlers++;
> }
> diff --git a/include/linux/irqchip/riscv-imsic.h
> b/include/linux/irqchip/riscv-imsic.h
> index 4b348836de7a..13e8bd7ff4b4 100644
> --- a/include/linux/irqchip/riscv-imsic.h
> +++ b/include/linux/irqchip/riscv-imsic.h
> @@ -40,6 +40,9 @@
> struct imsic_local_config {
> phys_addr_t msi_pa;
> void __iomem *msi_va;
> +
> + /* Number of guest interrupt files per core */
> + u32 nr_guest_files;
> };
>
> struct imsic_global_config {
> @@ -68,9 +71,6 @@ struct imsic_global_config {
> /* Number of guest interrupt identities */
> u32 nr_guest_ids;
>
> - /* Number of guest interrupt files per core */
> - u32 nr_guest_files;
> -
> /* Per-CPU IMSIC addresses */
> struct imsic_local_config __percpu *local;
> };
>
> ------------------------
> The other one:
>
> RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
>
> Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> and is computed per-HART, KVM must respect the actual number of guest
> interrupt files available on each HART when setting up HGEI.
>
> In `kvm_riscv_aia_enable()`:
>
> - Retrieve the per-CPU IMSIC local config
> - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> HGEI count for this HART
> - Use the result to initialize `free_bitmap`
>
> This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> where different cores may have different IMSIC guest file counts, and
> completes the per-HART conversion series.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> index 70ff1d25dd99..a5f4b7fe1dce 100644
> --- a/arch/riscv/kvm/aia.c
> +++ b/arch/riscv/kvm/aia.c
> @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> void kvm_riscv_aia_enable(void)
> {
> struct aia_hgei_control *hgctrl;
> + const struct imsic_global_config *gc;
> + const struct imsic_local_config *lc;
> + unsigned int nr_hgei;
>
> if (!kvm_riscv_aia_available())
> return;
> @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> if (hgctrl->nr_hgei)
> hgctrl->nr_hgei--;
>
> - if (hgctrl->nr_hgei) {
> - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> + gc = imsic_get_global_config();
> + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> + if (lc)
> + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> +
> + if (nr_hgei) {
> + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> hgctrl->free_bitmap &= ~BIT(0);
> } else {
> hgctrl->free_bitmap = 0;
>
>
> On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> >
> > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> >
> > With the recent KVM AIA changes, HGEI line management is now fully
> > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > The IMSIC driver no longer needs to compute and enforce a global
> > minimum number of guest interrupt files across all HARTs.
> >
> > Remove:
> > - `u32 nr_guest_files` from `struct imsic_global_config`
> > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > - the entire per-CPU MMIO-based min() calculation and its comment
> > (which was specifically there to protect old KVM)
> >
> > The per-HART guest file count is already handled locally in
> > `imsic_local_config` during the parent IRQ loop, so this global
> > field was redundant.
> >
> > This completes the cleanup series, eliminates the last global
> > assumption about guest files, and improves support for heterogeneous
> > (big.LITTLE / multi-vendor) RISC-V platforms.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > ---
> > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > include/linux/irqchip/riscv-imsic.h | 3 ---
> > 2 files changed, 1 insertion(+), 14 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..fef27247a34f 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > local->msi_pa = mmios[index].start + reloff;
> > local->msi_va = mmios_va[index] + reloff;
> >
> > - /*
> > - * KVM uses global->nr_guest_files to determine the available guest
> > - * interrupt files on each CPU. Take the minimum number of guest
> > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > - */
> > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > -
> > nr_handlers++;
> > }
> >
> > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..7f3ff5c5ea53 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> > --
> > 2.40.1
> >
>
>
> --
> Best Regards
> Guo Ren
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-23 4:20 ` Inochi Amaoto
0 siblings, 0 replies; 27+ messages in thread
From: Inochi Amaoto @ 2026-04-23 4:20 UTC (permalink / raw)
To: Guo Ren, fangyu.yu, cp0613, inochiama, me, gaohan, anup,
atish.patra, pjw, palmer, alex, tglx, Albert Ou
Cc: kvm-riscv, kvm, linux-kernel, linux-riscv
On Wed, Apr 22, 2026 at 11:09:30AM +0800, Guo Ren wrote:
> Hi all,
>
> This patch simply removed `nr_guest_files`, which is suboptimal. For
> v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> (per-HART) and compute the effective HGEI count in
> `kvm_riscv_aia_enable()` as:
>
> min(hgctrl->nr_hgei, lc->nr_guest_files)
>
> This provides a more accurate and robust per-HART configuration.
>
> Here are the updated two patches for your review:
>
> irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
>
> With the recent KVM AIA per-HART HGEI conversion, the global
> nr_guest_files is no longer appropriate. Different HARTs in
> heterogeneous SoCs may have different numbers of guest interrupt
> files.
>
> Move `nr_guest_files` from `struct imsic_global_config` to
> `struct imsic_local_config`, and compute it per-CPU in
> imsic_setup_state() based on the actual MMIO guest file region size.
>
> Update the related comment to reflect that KVM now uses the
> per-HART value.
>
> This eliminates the last global assumption about guest files and
> completes the per-HART conversion series for RISC-V AIA/IMSIC.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d89e7..3d455ef43298 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> fwnode_handle *fwnode,
>
> int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> {
> - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> nr_handlers = 0;
> + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> struct imsic_global_config *global;
> struct imsic_local_config *local;
> void __iomem **mmios_va = NULL;
> @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> *fwnode, void *opaque)
> }
>
> /* Configure handlers for target CPUs */
> - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> for (i = 0; i < nr_parent_irqs; i++) {
> rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> if (rc) {
> @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> fwnode_handle *fwnode, void *opaque)
> local->msi_va = mmios_va[index] + reloff;
>
> /*
> - * KVM uses global->nr_guest_files to determine the
> available guest
> + * KVM uses local->nr_guest_files to determine the
> available guest
> * interrupt files on each CPU. Take the minimum number of guest
> * interrupt files across all CPUs to avoid KVM
> incorrectly allocating
> * an unexisted or unmapped guest interrupt file on some CPUs.
> */
> - nr_guest_files = (resource_size(&mmios[index]) -
> reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> - global->nr_guest_files = min(global->nr_guest_files,
> nr_guest_files);
> + local->nr_guest_files =
> + (resource_size(&mmios[index]) - reloff) /
> IMSIC_MMIO_PAGE_SZ - 1;
>
The min is still required, otherwise the local->nr_guest_files can be
bigger than BIT(global->guest_index_bits) - 1, which is the max number
of the guest interrupt files that a hart can have. This condition is
true if the IMSIC group has more than one harts.
Regards,
Inochi
> nr_handlers++;
> }
> diff --git a/include/linux/irqchip/riscv-imsic.h
> b/include/linux/irqchip/riscv-imsic.h
> index 4b348836de7a..13e8bd7ff4b4 100644
> --- a/include/linux/irqchip/riscv-imsic.h
> +++ b/include/linux/irqchip/riscv-imsic.h
> @@ -40,6 +40,9 @@
> struct imsic_local_config {
> phys_addr_t msi_pa;
> void __iomem *msi_va;
> +
> + /* Number of guest interrupt files per core */
> + u32 nr_guest_files;
> };
>
> struct imsic_global_config {
> @@ -68,9 +71,6 @@ struct imsic_global_config {
> /* Number of guest interrupt identities */
> u32 nr_guest_ids;
>
> - /* Number of guest interrupt files per core */
> - u32 nr_guest_files;
> -
> /* Per-CPU IMSIC addresses */
> struct imsic_local_config __percpu *local;
> };
>
> ------------------------
> The other one:
>
> RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
>
> Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> and is computed per-HART, KVM must respect the actual number of guest
> interrupt files available on each HART when setting up HGEI.
>
> In `kvm_riscv_aia_enable()`:
>
> - Retrieve the per-CPU IMSIC local config
> - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> HGEI count for this HART
> - Use the result to initialize `free_bitmap`
>
> This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> where different cores may have different IMSIC guest file counts, and
> completes the per-HART conversion series.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> index 70ff1d25dd99..a5f4b7fe1dce 100644
> --- a/arch/riscv/kvm/aia.c
> +++ b/arch/riscv/kvm/aia.c
> @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> void kvm_riscv_aia_enable(void)
> {
> struct aia_hgei_control *hgctrl;
> + const struct imsic_global_config *gc;
> + const struct imsic_local_config *lc;
> + unsigned int nr_hgei;
>
> if (!kvm_riscv_aia_available())
> return;
> @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> if (hgctrl->nr_hgei)
> hgctrl->nr_hgei--;
>
> - if (hgctrl->nr_hgei) {
> - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> + gc = imsic_get_global_config();
> + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> + if (lc)
> + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> +
> + if (nr_hgei) {
> + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> hgctrl->free_bitmap &= ~BIT(0);
> } else {
> hgctrl->free_bitmap = 0;
>
>
> On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> >
> > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> >
> > With the recent KVM AIA changes, HGEI line management is now fully
> > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > The IMSIC driver no longer needs to compute and enforce a global
> > minimum number of guest interrupt files across all HARTs.
> >
> > Remove:
> > - `u32 nr_guest_files` from `struct imsic_global_config`
> > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > - the entire per-CPU MMIO-based min() calculation and its comment
> > (which was specifically there to protect old KVM)
> >
> > The per-HART guest file count is already handled locally in
> > `imsic_local_config` during the parent IRQ loop, so this global
> > field was redundant.
> >
> > This completes the cleanup series, eliminates the last global
> > assumption about guest files, and improves support for heterogeneous
> > (big.LITTLE / multi-vendor) RISC-V platforms.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > ---
> > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > include/linux/irqchip/riscv-imsic.h | 3 ---
> > 2 files changed, 1 insertion(+), 14 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..fef27247a34f 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > local->msi_pa = mmios[index].start + reloff;
> > local->msi_va = mmios_va[index] + reloff;
> >
> > - /*
> > - * KVM uses global->nr_guest_files to determine the available guest
> > - * interrupt files on each CPU. Take the minimum number of guest
> > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > - */
> > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > -
> > nr_handlers++;
> > }
> >
> > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..7f3ff5c5ea53 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> > --
> > 2.40.1
> >
>
>
> --
> Best Regards
> Guo Ren
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-23 4:20 ` Inochi Amaoto
0 siblings, 0 replies; 27+ messages in thread
From: Inochi Amaoto @ 2026-04-23 4:20 UTC (permalink / raw)
To: Guo Ren, fangyu.yu, cp0613, inochiama, me, gaohan, anup,
atish.patra, pjw, palmer, alex, tglx, Albert Ou
Cc: kvm-riscv, kvm, linux-kernel, linux-riscv
On Wed, Apr 22, 2026 at 11:09:30AM +0800, Guo Ren wrote:
> Hi all,
>
> This patch simply removed `nr_guest_files`, which is suboptimal. For
> v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> (per-HART) and compute the effective HGEI count in
> `kvm_riscv_aia_enable()` as:
>
> min(hgctrl->nr_hgei, lc->nr_guest_files)
>
> This provides a more accurate and robust per-HART configuration.
>
> Here are the updated two patches for your review:
>
> irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
>
> With the recent KVM AIA per-HART HGEI conversion, the global
> nr_guest_files is no longer appropriate. Different HARTs in
> heterogeneous SoCs may have different numbers of guest interrupt
> files.
>
> Move `nr_guest_files` from `struct imsic_global_config` to
> `struct imsic_local_config`, and compute it per-CPU in
> imsic_setup_state() based on the actual MMIO guest file region size.
>
> Update the related comment to reflect that KVM now uses the
> per-HART value.
>
> This eliminates the last global assumption about guest files and
> completes the per-HART conversion series for RISC-V AIA/IMSIC.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d89e7..3d455ef43298 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> fwnode_handle *fwnode,
>
> int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> {
> - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> nr_handlers = 0;
> + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> struct imsic_global_config *global;
> struct imsic_local_config *local;
> void __iomem **mmios_va = NULL;
> @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> *fwnode, void *opaque)
> }
>
> /* Configure handlers for target CPUs */
> - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> for (i = 0; i < nr_parent_irqs; i++) {
> rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> if (rc) {
> @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> fwnode_handle *fwnode, void *opaque)
> local->msi_va = mmios_va[index] + reloff;
>
> /*
> - * KVM uses global->nr_guest_files to determine the
> available guest
> + * KVM uses local->nr_guest_files to determine the
> available guest
> * interrupt files on each CPU. Take the minimum number of guest
> * interrupt files across all CPUs to avoid KVM
> incorrectly allocating
> * an unexisted or unmapped guest interrupt file on some CPUs.
> */
> - nr_guest_files = (resource_size(&mmios[index]) -
> reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> - global->nr_guest_files = min(global->nr_guest_files,
> nr_guest_files);
> + local->nr_guest_files =
> + (resource_size(&mmios[index]) - reloff) /
> IMSIC_MMIO_PAGE_SZ - 1;
>
The min is still required, otherwise the local->nr_guest_files can be
bigger than BIT(global->guest_index_bits) - 1, which is the max number
of the guest interrupt files that a hart can have. This condition is
true if the IMSIC group has more than one harts.
Regards,
Inochi
> nr_handlers++;
> }
> diff --git a/include/linux/irqchip/riscv-imsic.h
> b/include/linux/irqchip/riscv-imsic.h
> index 4b348836de7a..13e8bd7ff4b4 100644
> --- a/include/linux/irqchip/riscv-imsic.h
> +++ b/include/linux/irqchip/riscv-imsic.h
> @@ -40,6 +40,9 @@
> struct imsic_local_config {
> phys_addr_t msi_pa;
> void __iomem *msi_va;
> +
> + /* Number of guest interrupt files per core */
> + u32 nr_guest_files;
> };
>
> struct imsic_global_config {
> @@ -68,9 +71,6 @@ struct imsic_global_config {
> /* Number of guest interrupt identities */
> u32 nr_guest_ids;
>
> - /* Number of guest interrupt files per core */
> - u32 nr_guest_files;
> -
> /* Per-CPU IMSIC addresses */
> struct imsic_local_config __percpu *local;
> };
>
> ------------------------
> The other one:
>
> RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
>
> Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> and is computed per-HART, KVM must respect the actual number of guest
> interrupt files available on each HART when setting up HGEI.
>
> In `kvm_riscv_aia_enable()`:
>
> - Retrieve the per-CPU IMSIC local config
> - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> HGEI count for this HART
> - Use the result to initialize `free_bitmap`
>
> This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> where different cores may have different IMSIC guest file counts, and
> completes the per-HART conversion series.
>
> Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
>
> diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> index 70ff1d25dd99..a5f4b7fe1dce 100644
> --- a/arch/riscv/kvm/aia.c
> +++ b/arch/riscv/kvm/aia.c
> @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> void kvm_riscv_aia_enable(void)
> {
> struct aia_hgei_control *hgctrl;
> + const struct imsic_global_config *gc;
> + const struct imsic_local_config *lc;
> + unsigned int nr_hgei;
>
> if (!kvm_riscv_aia_available())
> return;
> @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> if (hgctrl->nr_hgei)
> hgctrl->nr_hgei--;
>
> - if (hgctrl->nr_hgei) {
> - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> + gc = imsic_get_global_config();
> + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> + if (lc)
> + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> +
> + if (nr_hgei) {
> + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> hgctrl->free_bitmap &= ~BIT(0);
> } else {
> hgctrl->free_bitmap = 0;
>
>
> On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> >
> > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> >
> > With the recent KVM AIA changes, HGEI line management is now fully
> > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > The IMSIC driver no longer needs to compute and enforce a global
> > minimum number of guest interrupt files across all HARTs.
> >
> > Remove:
> > - `u32 nr_guest_files` from `struct imsic_global_config`
> > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > - the entire per-CPU MMIO-based min() calculation and its comment
> > (which was specifically there to protect old KVM)
> >
> > The per-HART guest file count is already handled locally in
> > `imsic_local_config` during the parent IRQ loop, so this global
> > field was redundant.
> >
> > This completes the cleanup series, eliminates the last global
> > assumption about guest files, and improves support for heterogeneous
> > (big.LITTLE / multi-vendor) RISC-V platforms.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > ---
> > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > include/linux/irqchip/riscv-imsic.h | 3 ---
> > 2 files changed, 1 insertion(+), 14 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..fef27247a34f 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > local->msi_pa = mmios[index].start + reloff;
> > local->msi_va = mmios_va[index] + reloff;
> >
> > - /*
> > - * KVM uses global->nr_guest_files to determine the available guest
> > - * interrupt files on each CPU. Take the minimum number of guest
> > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > - */
> > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > -
> > nr_handlers++;
> > }
> >
> > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..7f3ff5c5ea53 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> > --
> > 2.40.1
> >
>
>
> --
> Best Regards
> Guo Ren
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
2026-04-23 4:20 ` Inochi Amaoto
(?)
@ 2026-04-23 9:07 ` Guo Ren
-1 siblings, 0 replies; 27+ messages in thread
From: Guo Ren @ 2026-04-23 9:07 UTC (permalink / raw)
To: Inochi Amaoto
Cc: fangyu.yu, cp0613, me, gaohan, anup, atish.patra, pjw, palmer,
alex, tglx, Albert Ou, kvm-riscv, kvm, linux-kernel, linux-riscv
On Thu, Apr 23, 2026 at 12:20 PM Inochi Amaoto <inochiama@gmail.com> wrote:
>
> On Wed, Apr 22, 2026 at 11:09:30AM +0800, Guo Ren wrote:
> > Hi all,
> >
> > This patch simply removed `nr_guest_files`, which is suboptimal. For
> > v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> > (per-HART) and compute the effective HGEI count in
> > `kvm_riscv_aia_enable()` as:
> >
> > min(hgctrl->nr_hgei, lc->nr_guest_files)
> >
> > This provides a more accurate and robust per-HART configuration.
> >
> > Here are the updated two patches for your review:
> >
> > irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
> >
> > With the recent KVM AIA per-HART HGEI conversion, the global
> > nr_guest_files is no longer appropriate. Different HARTs in
> > heterogeneous SoCs may have different numbers of guest interrupt
> > files.
> >
> > Move `nr_guest_files` from `struct imsic_global_config` to
> > `struct imsic_local_config`, and compute it per-CPU in
> > imsic_setup_state() based on the actual MMIO guest file region size.
> >
> > Update the related comment to reflect that KVM now uses the
> > per-HART value.
> >
> > This eliminates the last global assumption about guest files and
> > completes the per-HART conversion series for RISC-V AIA/IMSIC.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> > b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..3d455ef43298 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> > fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> > nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> > *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> > fwnode_handle *fwnode, void *opaque)
> > local->msi_va = mmios_va[index] + reloff;
> >
> > /*
> > - * KVM uses global->nr_guest_files to determine the
> > available guest
> > + * KVM uses local->nr_guest_files to determine the
> > available guest
> > * interrupt files on each CPU. Take the minimum number of guest
> > * interrupt files across all CPUs to avoid KVM
> > incorrectly allocating
> > * an unexisted or unmapped guest interrupt file on some CPUs.
> > */
>
> > - nr_guest_files = (resource_size(&mmios[index]) -
> > reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files,
> > nr_guest_files);
> > + local->nr_guest_files =
> > + (resource_size(&mmios[index]) - reloff) /
> > IMSIC_MMIO_PAGE_SZ - 1;
> >
>
> The min is still required, otherwise the local->nr_guest_files can be
> bigger than BIT(global->guest_index_bits) - 1, which is the max number
> of the guest interrupt files that a hart can have. This condition is
> true if the IMSIC group has more than one harts.
Yes, you are correct. Thanks for pointing it out.
>
> Regards,
> Inochi
>
> > nr_handlers++;
> > }
> > diff --git a/include/linux/irqchip/riscv-imsic.h
> > b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..13e8bd7ff4b4 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -40,6 +40,9 @@
> > struct imsic_local_config {
> > phys_addr_t msi_pa;
> > void __iomem *msi_va;
> > +
> > + /* Number of guest interrupt files per core */
> > + u32 nr_guest_files;
> > };
> >
> > struct imsic_global_config {
> > @@ -68,9 +71,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> >
> > ------------------------
> > The other one:
> >
> > RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
> >
> > Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> > and is computed per-HART, KVM must respect the actual number of guest
> > interrupt files available on each HART when setting up HGEI.
> >
> > In `kvm_riscv_aia_enable()`:
> >
> > - Retrieve the per-CPU IMSIC local config
> > - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> > HGEI count for this HART
> > - Use the result to initialize `free_bitmap`
> >
> > This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> > where different cores may have different IMSIC guest file counts, and
> > completes the per-HART conversion series.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> >
> > diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> > index 70ff1d25dd99..a5f4b7fe1dce 100644
> > --- a/arch/riscv/kvm/aia.c
> > +++ b/arch/riscv/kvm/aia.c
> > @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> > void kvm_riscv_aia_enable(void)
> > {
> > struct aia_hgei_control *hgctrl;
> > + const struct imsic_global_config *gc;
> > + const struct imsic_local_config *lc;
> > + unsigned int nr_hgei;
> >
> > if (!kvm_riscv_aia_available())
> > return;
> > @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> > if (hgctrl->nr_hgei)
> > hgctrl->nr_hgei--;
> >
> > - if (hgctrl->nr_hgei) {
> > - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> > + gc = imsic_get_global_config();
> > + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> > + if (lc)
> > + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> > +
> > + if (nr_hgei) {
> > + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> > hgctrl->free_bitmap &= ~BIT(0);
> > } else {
> > hgctrl->free_bitmap = 0;
> >
> >
> > On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> > >
> > > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> > >
> > > With the recent KVM AIA changes, HGEI line management is now fully
> > > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > > The IMSIC driver no longer needs to compute and enforce a global
> > > minimum number of guest interrupt files across all HARTs.
> > >
> > > Remove:
> > > - `u32 nr_guest_files` from `struct imsic_global_config`
> > > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > > - the entire per-CPU MMIO-based min() calculation and its comment
> > > (which was specifically there to protect old KVM)
> > >
> > > The per-HART guest file count is already handled locally in
> > > `imsic_local_config` during the parent IRQ loop, so this global
> > > field was redundant.
> > >
> > > This completes the cleanup series, eliminates the last global
> > > assumption about guest files, and improves support for heterogeneous
> > > (big.LITTLE / multi-vendor) RISC-V platforms.
> > >
> > > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > > ---
> > > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > > include/linux/irqchip/riscv-imsic.h | 3 ---
> > > 2 files changed, 1 insertion(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > > index e3ed874d89e7..fef27247a34f 100644
> > > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> > >
> > > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > {
> > > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > > struct imsic_global_config *global;
> > > struct imsic_local_config *local;
> > > void __iomem **mmios_va = NULL;
> > > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > }
> > >
> > > /* Configure handlers for target CPUs */
> > > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > > for (i = 0; i < nr_parent_irqs; i++) {
> > > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > > if (rc) {
> > > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > local->msi_pa = mmios[index].start + reloff;
> > > local->msi_va = mmios_va[index] + reloff;
> > >
> > > - /*
> > > - * KVM uses global->nr_guest_files to determine the available guest
> > > - * interrupt files on each CPU. Take the minimum number of guest
> > > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > > - */
> > > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > > -
> > > nr_handlers++;
> > > }
> > >
> > > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > > index 4b348836de7a..7f3ff5c5ea53 100644
> > > --- a/include/linux/irqchip/riscv-imsic.h
> > > +++ b/include/linux/irqchip/riscv-imsic.h
> > > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > > /* Number of guest interrupt identities */
> > > u32 nr_guest_ids;
> > >
> > > - /* Number of guest interrupt files per core */
> > > - u32 nr_guest_files;
> > > -
> > > /* Per-CPU IMSIC addresses */
> > > struct imsic_local_config __percpu *local;
> > > };
> > > --
> > > 2.40.1
> > >
> >
> >
> > --
> > Best Regards
> > Guo Ren
> >
> > --
> > kvm-riscv mailing list
> > kvm-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kvm-riscv
--
Best Regards
Guo Ren
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-23 9:07 ` Guo Ren
0 siblings, 0 replies; 27+ messages in thread
From: Guo Ren @ 2026-04-23 9:07 UTC (permalink / raw)
To: Inochi Amaoto
Cc: fangyu.yu, cp0613, me, gaohan, anup, atish.patra, pjw, palmer,
alex, tglx, Albert Ou, kvm-riscv, kvm, linux-kernel, linux-riscv
On Thu, Apr 23, 2026 at 12:20 PM Inochi Amaoto <inochiama@gmail.com> wrote:
>
> On Wed, Apr 22, 2026 at 11:09:30AM +0800, Guo Ren wrote:
> > Hi all,
> >
> > This patch simply removed `nr_guest_files`, which is suboptimal. For
> > v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> > (per-HART) and compute the effective HGEI count in
> > `kvm_riscv_aia_enable()` as:
> >
> > min(hgctrl->nr_hgei, lc->nr_guest_files)
> >
> > This provides a more accurate and robust per-HART configuration.
> >
> > Here are the updated two patches for your review:
> >
> > irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
> >
> > With the recent KVM AIA per-HART HGEI conversion, the global
> > nr_guest_files is no longer appropriate. Different HARTs in
> > heterogeneous SoCs may have different numbers of guest interrupt
> > files.
> >
> > Move `nr_guest_files` from `struct imsic_global_config` to
> > `struct imsic_local_config`, and compute it per-CPU in
> > imsic_setup_state() based on the actual MMIO guest file region size.
> >
> > Update the related comment to reflect that KVM now uses the
> > per-HART value.
> >
> > This eliminates the last global assumption about guest files and
> > completes the per-HART conversion series for RISC-V AIA/IMSIC.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> > b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..3d455ef43298 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> > fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> > nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> > *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> > fwnode_handle *fwnode, void *opaque)
> > local->msi_va = mmios_va[index] + reloff;
> >
> > /*
> > - * KVM uses global->nr_guest_files to determine the
> > available guest
> > + * KVM uses local->nr_guest_files to determine the
> > available guest
> > * interrupt files on each CPU. Take the minimum number of guest
> > * interrupt files across all CPUs to avoid KVM
> > incorrectly allocating
> > * an unexisted or unmapped guest interrupt file on some CPUs.
> > */
>
> > - nr_guest_files = (resource_size(&mmios[index]) -
> > reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files,
> > nr_guest_files);
> > + local->nr_guest_files =
> > + (resource_size(&mmios[index]) - reloff) /
> > IMSIC_MMIO_PAGE_SZ - 1;
> >
>
> The min is still required, otherwise the local->nr_guest_files can be
> bigger than BIT(global->guest_index_bits) - 1, which is the max number
> of the guest interrupt files that a hart can have. This condition is
> true if the IMSIC group has more than one harts.
Yes, you are correct. Thanks for pointing it out.
>
> Regards,
> Inochi
>
> > nr_handlers++;
> > }
> > diff --git a/include/linux/irqchip/riscv-imsic.h
> > b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..13e8bd7ff4b4 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -40,6 +40,9 @@
> > struct imsic_local_config {
> > phys_addr_t msi_pa;
> > void __iomem *msi_va;
> > +
> > + /* Number of guest interrupt files per core */
> > + u32 nr_guest_files;
> > };
> >
> > struct imsic_global_config {
> > @@ -68,9 +71,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> >
> > ------------------------
> > The other one:
> >
> > RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
> >
> > Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> > and is computed per-HART, KVM must respect the actual number of guest
> > interrupt files available on each HART when setting up HGEI.
> >
> > In `kvm_riscv_aia_enable()`:
> >
> > - Retrieve the per-CPU IMSIC local config
> > - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> > HGEI count for this HART
> > - Use the result to initialize `free_bitmap`
> >
> > This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> > where different cores may have different IMSIC guest file counts, and
> > completes the per-HART conversion series.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> >
> > diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> > index 70ff1d25dd99..a5f4b7fe1dce 100644
> > --- a/arch/riscv/kvm/aia.c
> > +++ b/arch/riscv/kvm/aia.c
> > @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> > void kvm_riscv_aia_enable(void)
> > {
> > struct aia_hgei_control *hgctrl;
> > + const struct imsic_global_config *gc;
> > + const struct imsic_local_config *lc;
> > + unsigned int nr_hgei;
> >
> > if (!kvm_riscv_aia_available())
> > return;
> > @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> > if (hgctrl->nr_hgei)
> > hgctrl->nr_hgei--;
> >
> > - if (hgctrl->nr_hgei) {
> > - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> > + gc = imsic_get_global_config();
> > + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> > + if (lc)
> > + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> > +
> > + if (nr_hgei) {
> > + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> > hgctrl->free_bitmap &= ~BIT(0);
> > } else {
> > hgctrl->free_bitmap = 0;
> >
> >
> > On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> > >
> > > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> > >
> > > With the recent KVM AIA changes, HGEI line management is now fully
> > > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > > The IMSIC driver no longer needs to compute and enforce a global
> > > minimum number of guest interrupt files across all HARTs.
> > >
> > > Remove:
> > > - `u32 nr_guest_files` from `struct imsic_global_config`
> > > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > > - the entire per-CPU MMIO-based min() calculation and its comment
> > > (which was specifically there to protect old KVM)
> > >
> > > The per-HART guest file count is already handled locally in
> > > `imsic_local_config` during the parent IRQ loop, so this global
> > > field was redundant.
> > >
> > > This completes the cleanup series, eliminates the last global
> > > assumption about guest files, and improves support for heterogeneous
> > > (big.LITTLE / multi-vendor) RISC-V platforms.
> > >
> > > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > > ---
> > > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > > include/linux/irqchip/riscv-imsic.h | 3 ---
> > > 2 files changed, 1 insertion(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > > index e3ed874d89e7..fef27247a34f 100644
> > > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> > >
> > > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > {
> > > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > > struct imsic_global_config *global;
> > > struct imsic_local_config *local;
> > > void __iomem **mmios_va = NULL;
> > > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > }
> > >
> > > /* Configure handlers for target CPUs */
> > > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > > for (i = 0; i < nr_parent_irqs; i++) {
> > > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > > if (rc) {
> > > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > local->msi_pa = mmios[index].start + reloff;
> > > local->msi_va = mmios_va[index] + reloff;
> > >
> > > - /*
> > > - * KVM uses global->nr_guest_files to determine the available guest
> > > - * interrupt files on each CPU. Take the minimum number of guest
> > > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > > - */
> > > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > > -
> > > nr_handlers++;
> > > }
> > >
> > > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > > index 4b348836de7a..7f3ff5c5ea53 100644
> > > --- a/include/linux/irqchip/riscv-imsic.h
> > > +++ b/include/linux/irqchip/riscv-imsic.h
> > > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > > /* Number of guest interrupt identities */
> > > u32 nr_guest_ids;
> > >
> > > - /* Number of guest interrupt files per core */
> > > - u32 nr_guest_files;
> > > -
> > > /* Per-CPU IMSIC addresses */
> > > struct imsic_local_config __percpu *local;
> > > };
> > > --
> > > 2.40.1
> > >
> >
> >
> > --
> > Best Regards
> > Guo Ren
> >
> > --
> > kvm-riscv mailing list
> > kvm-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kvm-riscv
--
Best Regards
Guo Ren
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 3/3] irqchip/riscv-imsic: Remove global nr_guest_files after KVM AIA per-HART conversion
@ 2026-04-23 9:07 ` Guo Ren
0 siblings, 0 replies; 27+ messages in thread
From: Guo Ren @ 2026-04-23 9:07 UTC (permalink / raw)
To: Inochi Amaoto
Cc: fangyu.yu, cp0613, me, gaohan, anup, atish.patra, pjw, palmer,
alex, tglx, Albert Ou, kvm-riscv, kvm, linux-kernel, linux-riscv
On Thu, Apr 23, 2026 at 12:20 PM Inochi Amaoto <inochiama@gmail.com> wrote:
>
> On Wed, Apr 22, 2026 at 11:09:30AM +0800, Guo Ren wrote:
> > Hi all,
> >
> > This patch simply removed `nr_guest_files`, which is suboptimal. For
> > v2, I will keep `nr_guest_files` inside `struct imsic_local_config`
> > (per-HART) and compute the effective HGEI count in
> > `kvm_riscv_aia_enable()` as:
> >
> > min(hgctrl->nr_hgei, lc->nr_guest_files)
> >
> > This provides a more accurate and robust per-HART configuration.
> >
> > Here are the updated two patches for your review:
> >
> > irqchip/riscv-imsic: Move nr_guest_files to per-HART local config
> >
> > With the recent KVM AIA per-HART HGEI conversion, the global
> > nr_guest_files is no longer appropriate. Different HARTs in
> > heterogeneous SoCs may have different numbers of guest interrupt
> > files.
> >
> > Move `nr_guest_files` from `struct imsic_global_config` to
> > `struct imsic_local_config`, and compute it per-CPU in
> > imsic_setup_state() based on the actual MMIO guest file region size.
> >
> > Update the related comment to reflect that KVM now uses the
> > per-HART value.
> >
> > This eliminates the last global assumption about guest files and
> > completes the per-HART conversion series for RISC-V AIA/IMSIC.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> >
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c
> > b/drivers/irqchip/irq-riscv-imsic-state.c
> > index e3ed874d89e7..3d455ef43298 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct
> > fwnode_handle *fwnode,
> >
> > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > {
> > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files,
> > nr_handlers = 0;
> > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > struct imsic_global_config *global;
> > struct imsic_local_config *local;
> > void __iomem **mmios_va = NULL;
> > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle
> > *fwnode, void *opaque)
> > }
> >
> > /* Configure handlers for target CPUs */
> > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > for (i = 0; i < nr_parent_irqs; i++) {
> > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > if (rc) {
> > @@ -920,13 +919,13 @@ int __init imsic_setup_state(struct
> > fwnode_handle *fwnode, void *opaque)
> > local->msi_va = mmios_va[index] + reloff;
> >
> > /*
> > - * KVM uses global->nr_guest_files to determine the
> > available guest
> > + * KVM uses local->nr_guest_files to determine the
> > available guest
> > * interrupt files on each CPU. Take the minimum number of guest
> > * interrupt files across all CPUs to avoid KVM
> > incorrectly allocating
> > * an unexisted or unmapped guest interrupt file on some CPUs.
> > */
>
> > - nr_guest_files = (resource_size(&mmios[index]) -
> > reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > - global->nr_guest_files = min(global->nr_guest_files,
> > nr_guest_files);
> > + local->nr_guest_files =
> > + (resource_size(&mmios[index]) - reloff) /
> > IMSIC_MMIO_PAGE_SZ - 1;
> >
>
> The min is still required, otherwise the local->nr_guest_files can be
> bigger than BIT(global->guest_index_bits) - 1, which is the max number
> of the guest interrupt files that a hart can have. This condition is
> true if the IMSIC group has more than one harts.
Yes, you are correct. Thanks for pointing it out.
>
> Regards,
> Inochi
>
> > nr_handlers++;
> > }
> > diff --git a/include/linux/irqchip/riscv-imsic.h
> > b/include/linux/irqchip/riscv-imsic.h
> > index 4b348836de7a..13e8bd7ff4b4 100644
> > --- a/include/linux/irqchip/riscv-imsic.h
> > +++ b/include/linux/irqchip/riscv-imsic.h
> > @@ -40,6 +40,9 @@
> > struct imsic_local_config {
> > phys_addr_t msi_pa;
> > void __iomem *msi_va;
> > +
> > + /* Number of guest interrupt files per core */
> > + u32 nr_guest_files;
> > };
> >
> > struct imsic_global_config {
> > @@ -68,9 +71,6 @@ struct imsic_global_config {
> > /* Number of guest interrupt identities */
> > u32 nr_guest_ids;
> >
> > - /* Number of guest interrupt files per core */
> > - u32 nr_guest_files;
> > -
> > /* Per-CPU IMSIC addresses */
> > struct imsic_local_config __percpu *local;
> > };
> >
> > ------------------------
> > The other one:
> >
> > RISC-V: KVM: AIA: Use per-HART IMSIC guest files to compute final HGEI count
> >
> > Now that `nr_guest_files` has been moved to `struct imsic_local_config`
> > and is computed per-HART, KVM must respect the actual number of guest
> > interrupt files available on each HART when setting up HGEI.
> >
> > In `kvm_riscv_aia_enable()`:
> >
> > - Retrieve the per-CPU IMSIC local config
> > - Take `min(hgctrl->nr_hgei, lc->nr_guest_files)` as the final usable
> > HGEI count for this HART
> > - Use the result to initialize `free_bitmap`
> >
> > This ensures correct HGEI allocation on heterogeneous RISC-V SoCs
> > where different cores may have different IMSIC guest file counts, and
> > completes the per-HART conversion series.
> >
> > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> >
> > diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> > index 70ff1d25dd99..a5f4b7fe1dce 100644
> > --- a/arch/riscv/kvm/aia.c
> > +++ b/arch/riscv/kvm/aia.c
> > @@ -534,6 +534,9 @@ static void aia_hgei_exit(void)
> > void kvm_riscv_aia_enable(void)
> > {
> > struct aia_hgei_control *hgctrl;
> > + const struct imsic_global_config *gc;
> > + const struct imsic_local_config *lc;
> > + unsigned int nr_hgei;
> >
> > if (!kvm_riscv_aia_available())
> > return;
> > @@ -547,8 +550,13 @@ void kvm_riscv_aia_enable(void)
> > if (hgctrl->nr_hgei)
> > hgctrl->nr_hgei--;
> >
> > - if (hgctrl->nr_hgei) {
> > - hgctrl->free_bitmap = BIT(hgctrl->nr_hgei + 1) - 1;
> > + gc = imsic_get_global_config();
> > + lc = (gc) ? this_cpu_ptr(gc->local) : NULL;
> > + if (lc)
> > + nr_hgei = min(hgctrl->nr_hgei, lc->nr_guest_files);
> > +
> > + if (nr_hgei) {
> > + hgctrl->free_bitmap = BIT(nr_hgei + 1) - 1;
> > hgctrl->free_bitmap &= ~BIT(0);
> > } else {
> > hgctrl->free_bitmap = 0;
> >
> >
> > On Tue, Apr 21, 2026 at 10:55 PM <guoren@kernel.org> wrote:
> > >
> > > From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
> > >
> > > With the recent KVM AIA changes, HGEI line management is now fully
> > > per-CPU (via struct aia_hgei_control::nr_hgei) and the global
> > > kvm_riscv_aia_nr_hgei has been replaced by a simple enabled flag.
> > > The IMSIC driver no longer needs to compute and enforce a global
> > > minimum number of guest interrupt files across all HARTs.
> > >
> > > Remove:
> > > - `u32 nr_guest_files` from `struct imsic_global_config`
> > > - the initial `BIT(global->guest_index_bits) - 1` assignment
> > > - the entire per-CPU MMIO-based min() calculation and its comment
> > > (which was specifically there to protect old KVM)
> > >
> > > The per-HART guest file count is already handled locally in
> > > `imsic_local_config` during the parent IRQ loop, so this global
> > > field was redundant.
> > >
> > > This completes the cleanup series, eliminates the last global
> > > assumption about guest files, and improves support for heterogeneous
> > > (big.LITTLE / multi-vendor) RISC-V platforms.
> > >
> > > Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
> > > ---
> > > drivers/irqchip/irq-riscv-imsic-state.c | 12 +-----------
> > > include/linux/irqchip/riscv-imsic.h | 3 ---
> > > 2 files changed, 1 insertion(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > > index e3ed874d89e7..fef27247a34f 100644
> > > --- a/drivers/irqchip/irq-riscv-imsic-state.c
> > > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > > @@ -784,7 +784,7 @@ static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> > >
> > > int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > {
> > > - u32 i, j, index, nr_parent_irqs, nr_mmios, nr_guest_files, nr_handlers = 0;
> > > + u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > > struct imsic_global_config *global;
> > > struct imsic_local_config *local;
> > > void __iomem **mmios_va = NULL;
> > > @@ -878,7 +878,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > }
> > >
> > > /* Configure handlers for target CPUs */
> > > - global->nr_guest_files = BIT(global->guest_index_bits) - 1;
> > > for (i = 0; i < nr_parent_irqs; i++) {
> > > rc = imsic_get_parent_hartid(fwnode, i, &hartid);
> > > if (rc) {
> > > @@ -919,15 +918,6 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
> > > local->msi_pa = mmios[index].start + reloff;
> > > local->msi_va = mmios_va[index] + reloff;
> > >
> > > - /*
> > > - * KVM uses global->nr_guest_files to determine the available guest
> > > - * interrupt files on each CPU. Take the minimum number of guest
> > > - * interrupt files across all CPUs to avoid KVM incorrectly allocating
> > > - * an unexisted or unmapped guest interrupt file on some CPUs.
> > > - */
> > > - nr_guest_files = (resource_size(&mmios[index]) - reloff) / IMSIC_MMIO_PAGE_SZ - 1;
> > > - global->nr_guest_files = min(global->nr_guest_files, nr_guest_files);
> > > -
> > > nr_handlers++;
> > > }
> > >
> > > diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
> > > index 4b348836de7a..7f3ff5c5ea53 100644
> > > --- a/include/linux/irqchip/riscv-imsic.h
> > > +++ b/include/linux/irqchip/riscv-imsic.h
> > > @@ -68,9 +68,6 @@ struct imsic_global_config {
> > > /* Number of guest interrupt identities */
> > > u32 nr_guest_ids;
> > >
> > > - /* Number of guest interrupt files per core */
> > > - u32 nr_guest_files;
> > > -
> > > /* Per-CPU IMSIC addresses */
> > > struct imsic_local_config __percpu *local;
> > > };
> > > --
> > > 2.40.1
> > >
> >
> >
> > --
> > Best Regards
> > Guo Ren
> >
> > --
> > kvm-riscv mailing list
> > kvm-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kvm-riscv
--
Best Regards
Guo Ren
^ permalink raw reply [flat|nested] 27+ messages in thread