mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] irqchip/gic-v3-its: Fix the ITT pool's alignment, zeroing and growth
@ 2026-11-06  9:26 Fuad Tabba
  2026-11-06  9:26 ` [PATCH 1/3] irqchip/gic-v3-its: Align sub-page ITTs to 256 bytes Fuad Tabba
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Fuad Tabba @ 2026-11-06  9:26 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner
  Cc: Radu Rendec, Steven Price, Suzuki K Poulose, Will Deacon,
	Fuad Tabba, linux-arm-kernel, linux-kernel

Hi folks,

Three fixes to the ITT pool that took over sub-page ITTs from
kzalloc_node(). It doesn't align them to 256 bytes, though MAPD now
relies on it to. It doesn't zero the ITTs it reuses either, and it
leaks pages when it fails to grow.

The first gives the pool a 256-byte granule. With its 1-byte granule,
ITTs stay aligned only while every size is a multiple of 256, which
holds for power-of-two ITE sizes but not for QEMU's 12-byte ones. On
QEMU, two devices with 32 MSI-X vectors each are enough to put the
second device's ITT at an address MAPD truncates into the first's.

The second zeroes an ITT reused from the pool, as MAPD requires. The
third frees the page when gen_pool_add() fails.

Based on Linux 7.4-rc1 (6628e7d4c6b25).

Cheers,
/fuad

Fuad Tabba (3):
  irqchip/gic-v3-its: Align sub-page ITTs to 256 bytes
  irqchip/gic-v3-its: Zero ITTs reused from the ITT pool
  irqchip/gic-v3-its: Free the page when gen_pool_add() fails

 drivers/irqchip/irq-gic-v3-its.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)


base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
-- 
2.47.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] irqchip/gic-v3-its: Align sub-page ITTs to 256 bytes
  2026-11-06  9:26 [PATCH 0/3] irqchip/gic-v3-its: Fix the ITT pool's alignment, zeroing and growth Fuad Tabba
@ 2026-11-06  9:26 ` Fuad Tabba
  2026-11-06  9:49   ` Suzuki K Poulose
  2026-11-06  9:26 ` [PATCH 2/3] irqchip/gic-v3-its: Zero ITTs reused from the ITT pool Fuad Tabba
  2026-11-06  9:26 ` [PATCH 3/3] irqchip/gic-v3-its: Free the page when gen_pool_add() fails Fuad Tabba
  2 siblings, 1 reply; 7+ messages in thread
From: Fuad Tabba @ 2026-11-06  9:26 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner
  Cc: Radu Rendec, Steven Price, Suzuki K Poulose, Will Deacon,
	Fuad Tabba, linux-arm-kernel, linux-kernel

Commit e36d4165f0796 ("irqchip/gic-v3-its: Rely on genpool alignment")
dropped the ALIGN() of the ITT address in MAPD, on the premise that the
ITT pool returns 256-byte aligned blocks. However, the pool's minimum
allocation order is get_order(ITS_ITT_ALIGN), which is 0, so its
granule is a single byte. An ITT whose size is not a multiple of 256
leaves the next one misaligned, MAPD drops the low bits of its address,
and that device's ITEs land on the previous device's ITT. QEMU's
emulated ITS has 12-byte ITEs, so two devices with 32 vectors each are
enough to hit it.

Create the pool with a granule of ITS_ITT_ALIGN.

Fixes: e36d4165f0796 ("irqchip/gic-v3-its: Rely on genpool alignment")
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 282e4bafb084f..5613c52adf88e 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -5849,7 +5849,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
 	bool has_v4_1 = false;
 	int err;
 
-	itt_pool = gen_pool_create(get_order(ITS_ITT_ALIGN), -1);
+	itt_pool = gen_pool_create(ilog2(ITS_ITT_ALIGN), -1);
 	if (!itt_pool)
 		return -ENOMEM;
 
-- 
2.47.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/3] irqchip/gic-v3-its: Zero ITTs reused from the ITT pool
  2026-11-06  9:26 [PATCH 0/3] irqchip/gic-v3-its: Fix the ITT pool's alignment, zeroing and growth Fuad Tabba
  2026-11-06  9:26 ` [PATCH 1/3] irqchip/gic-v3-its: Align sub-page ITTs to 256 bytes Fuad Tabba
@ 2026-11-06  9:26 ` Fuad Tabba
  2026-11-06  9:56   ` Suzuki K Poulose
  2026-11-06  9:26 ` [PATCH 3/3] irqchip/gic-v3-its: Free the page when gen_pool_add() fails Fuad Tabba
  2 siblings, 1 reply; 7+ messages in thread
From: Fuad Tabba @ 2026-11-06  9:26 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner
  Cc: Radu Rendec, Steven Price, Suzuki K Poulose, Will Deacon,
	Fuad Tabba, linux-arm-kernel, linux-kernel

Commit b08e2f42e86b5 ("irqchip/gic-v3-its: Share ITS tables with a
non-trusted hypervisor") moved sub-page ITTs from kzalloc_node() to a
genpool. The pages added to the pool are zeroed, but an ITT freed back
to it goes to the next device as the previous one left it. MAPD is then
UNPREDICTABLE: "When V == 1, the specified ITT does not contain all
zeros" (IHI 0069H.b, 5.3.10).

Zero the ITT when it comes from the pool.

Fixes: b08e2f42e86b5 ("irqchip/gic-v3-its: Share ITS tables with a non-trusted hypervisor")
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
 drivers/irqchip/irq-gic-v3-its.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 5613c52adf88e..5c3ab9d30f6af 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -267,8 +267,10 @@ static void *itt_alloc_pool(int node, int size)
 
 	do {
 		addr = gen_pool_alloc(itt_pool, size);
-		if (addr)
+		if (addr) {
+			memset((void *)addr, 0, size);
 			break;
+		}
 
 		page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0);
 		if (!page)
-- 
2.47.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/3] irqchip/gic-v3-its: Free the page when gen_pool_add() fails
  2026-11-06  9:26 [PATCH 0/3] irqchip/gic-v3-its: Fix the ITT pool's alignment, zeroing and growth Fuad Tabba
  2026-11-06  9:26 ` [PATCH 1/3] irqchip/gic-v3-its: Align sub-page ITTs to 256 bytes Fuad Tabba
  2026-11-06  9:26 ` [PATCH 2/3] irqchip/gic-v3-its: Zero ITTs reused from the ITT pool Fuad Tabba
@ 2026-11-06  9:26 ` Fuad Tabba
  2026-11-06  9:59   ` Suzuki K Poulose
  2 siblings, 1 reply; 7+ messages in thread
From: Fuad Tabba @ 2026-11-06  9:26 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner
  Cc: Radu Rendec, Steven Price, Suzuki K Poulose, Will Deacon,
	Fuad Tabba, linux-arm-kernel, linux-kernel

When the ITT pool has no room, itt_alloc_pool() grows it by a page and
retries. gen_pool_add() fails when it cannot allocate its chunk
descriptor, but its return is ignored, so the page is leaked and the
retry allocates another page to leak, until an add succeeds or a page
allocation fails.

Free the page and fail the allocation instead.

Fixes: b08e2f42e86b5 ("irqchip/gic-v3-its: Share ITS tables with a non-trusted hypervisor")
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
 drivers/irqchip/irq-gic-v3-its.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 5c3ab9d30f6af..bdf7c81e60c76 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -276,7 +276,10 @@ static void *itt_alloc_pool(int node, int size)
 		if (!page)
 			break;
 
-		gen_pool_add(itt_pool, (unsigned long)page_address(page), PAGE_SIZE, node);
+		if (gen_pool_add(itt_pool, (unsigned long)page_address(page), PAGE_SIZE, node)) {
+			its_free_pages(page_address(page), 0);
+			break;
+		}
 	} while (!addr);
 
 	return (void *)addr;
-- 
2.47.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] irqchip/gic-v3-its: Align sub-page ITTs to 256 bytes
  2026-11-06  9:26 ` [PATCH 1/3] irqchip/gic-v3-its: Align sub-page ITTs to 256 bytes Fuad Tabba
@ 2026-11-06  9:49   ` Suzuki K Poulose
  0 siblings, 0 replies; 7+ messages in thread
From: Suzuki K Poulose @ 2026-11-06  9:49 UTC (permalink / raw)
  To: Fuad Tabba, Marc Zyngier, Thomas Gleixner
  Cc: Radu Rendec, Steven Price, Will Deacon, Fuad Tabba,
	linux-arm-kernel, linux-kernel

On 06/11/2026 09:26, Fuad Tabba wrote:
> Commit e36d4165f0796 ("irqchip/gic-v3-its: Rely on genpool alignment")
> dropped the ALIGN() of the ITT address in MAPD, on the premise that the
> ITT pool returns 256-byte aligned blocks. However, the pool's minimum
> allocation order is get_order(ITS_ITT_ALIGN), which is 0, so its
> granule is a single byte. An ITT whose size is not a multiple of 256
> leaves the next one misaligned, MAPD drops the low bits of its address,
> and that device's ITEs land on the previous device's ITT. QEMU's
> emulated ITS has 12-byte ITEs, so two devices with 32 vectors each are
> enough to hit it.
> 
> Create the pool with a granule of ITS_ITT_ALIGN.
> 
> Fixes: e36d4165f0796 ("irqchip/gic-v3-its: Rely on genpool alignment")
> Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
> ---
>   drivers/irqchip/irq-gic-v3-its.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 282e4bafb084f..5613c52adf88e 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -5849,7 +5849,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>   	bool has_v4_1 = false;
>   	int err;
>   
> -	itt_pool = gen_pool_create(get_order(ITS_ITT_ALIGN), -1);
> +	itt_pool = gen_pool_create(ilog2(ITS_ITT_ALIGN), -1);


gen_pool_create expects the first argument as:

min_alloc_order: log base 2 of number of bytes each bitmap bit represents

So, passing get_order() is definitely wrong and ilog2 is the correct
choice here.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>

>   	if (!itt_pool)
>   		return -ENOMEM;
>   


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] irqchip/gic-v3-its: Zero ITTs reused from the ITT pool
  2026-11-06  9:26 ` [PATCH 2/3] irqchip/gic-v3-its: Zero ITTs reused from the ITT pool Fuad Tabba
@ 2026-11-06  9:56   ` Suzuki K Poulose
  0 siblings, 0 replies; 7+ messages in thread
From: Suzuki K Poulose @ 2026-11-06  9:56 UTC (permalink / raw)
  To: Fuad Tabba, Marc Zyngier, Thomas Gleixner
  Cc: Radu Rendec, Steven Price, Will Deacon, Fuad Tabba,
	linux-arm-kernel, linux-kernel

On 06/11/2026 09:26, Fuad Tabba wrote:
> Commit b08e2f42e86b5 ("irqchip/gic-v3-its: Share ITS tables with a
> non-trusted hypervisor") moved sub-page ITTs from kzalloc_node() to a
> genpool. The pages added to the pool are zeroed, but an ITT freed back
> to it goes to the next device as the previous one left it. MAPD is then
> UNPREDICTABLE: "When V == 1, the specified ITT does not contain all
> zeros" (IHI 0069H.b, 5.3.10).
> 
> Zero the ITT when it comes from the pool.
> 
> Fixes: b08e2f42e86b5 ("irqchip/gic-v3-its: Share ITS tables with a non-trusted hypervisor")
> Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
> ---
>   drivers/irqchip/irq-gic-v3-its.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 5613c52adf88e..5c3ab9d30f6af 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -267,8 +267,10 @@ static void *itt_alloc_pool(int node, int size)
>   
>   	do {
>   		addr = gen_pool_alloc(itt_pool, size);
> -		if (addr)
> +		if (addr) {
> +			memset((void *)addr, 0, size);
>   			break;
> +		}

It is safer to do this at allocation than freeing something back to the 
gen_pool.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>

>   
>   		page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0);
>   		if (!page)


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] irqchip/gic-v3-its: Free the page when gen_pool_add() fails
  2026-11-06  9:26 ` [PATCH 3/3] irqchip/gic-v3-its: Free the page when gen_pool_add() fails Fuad Tabba
@ 2026-11-06  9:59   ` Suzuki K Poulose
  0 siblings, 0 replies; 7+ messages in thread
From: Suzuki K Poulose @ 2026-11-06  9:59 UTC (permalink / raw)
  To: Fuad Tabba, Marc Zyngier, Thomas Gleixner
  Cc: Radu Rendec, Steven Price, Will Deacon, Fuad Tabba,
	linux-arm-kernel, linux-kernel

On 06/11/2026 09:26, Fuad Tabba wrote:
> When the ITT pool has no room, itt_alloc_pool() grows it by a page and
> retries. gen_pool_add() fails when it cannot allocate its chunk
> descriptor, but its return is ignored, so the page is leaked and the
> retry allocates another page to leak, until an add succeeds or a page
> allocation fails.
> 
> Free the page and fail the allocation instead.
> 
> Fixes: b08e2f42e86b5 ("irqchip/gic-v3-its: Share ITS tables with a non-trusted hypervisor")
> Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
> ---
>   drivers/irqchip/irq-gic-v3-its.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 5c3ab9d30f6af..bdf7c81e60c76 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -276,7 +276,10 @@ static void *itt_alloc_pool(int node, int size)
>   		if (!page)
>   			break;
>   
> -		gen_pool_add(itt_pool, (unsigned long)page_address(page), PAGE_SIZE, node);
> +		if (gen_pool_add(itt_pool, (unsigned long)page_address(page), PAGE_SIZE, node)) {
> +			its_free_pages(page_address(page), 0);
> +			break;
> +		}

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>


>   	} while (!addr);
>   
>   	return (void *)addr;


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-11-06  9:59 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-06  9:26 [PATCH 0/3] irqchip/gic-v3-its: Fix the ITT pool's alignment, zeroing and growth Fuad Tabba
2026-11-06  9:26 ` [PATCH 1/3] irqchip/gic-v3-its: Align sub-page ITTs to 256 bytes Fuad Tabba
2026-11-06  9:49   ` Suzuki K Poulose
2026-11-06  9:26 ` [PATCH 2/3] irqchip/gic-v3-its: Zero ITTs reused from the ITT pool Fuad Tabba
2026-11-06  9:56   ` Suzuki K Poulose
2026-11-06  9:26 ` [PATCH 3/3] irqchip/gic-v3-its: Free the page when gen_pool_add() fails Fuad Tabba
2026-11-06  9:59   ` Suzuki K Poulose

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®