public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] irqchip: gic-v3-its: avoid truncating memory addresses
@ 2026-01-19 20:15 Arnd Bergmann
  2026-01-20  8:51 ` Marc Zyngier
  0 siblings, 1 reply; 3+ messages in thread
From: Arnd Bergmann @ 2026-01-19 20:15 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner
  Cc: Arnd Bergmann, Lorenzo Pieralisi, linux-arm-kernel, linux-kernel

From: Arnd Bergmann <arnd@arndb.de>

On 32-bit machines with CONFIG_ARM_LPAE, it is possible for lowmem
allocations to be backed by addresses physical memory above the 32-bit
address limit, as I found while experimenting with larger VMSPLIT
configurations.

This caused the qemu virt model to crash in the GICv3 driver, which
allocates the 'itt' object using GFP_KERNEL. Since all memory below
the 4GB physical address limit is in ZONE_DMA in this configuration,
kmalloc defaults to higher addresses for ZONE_NORMAL, and the
its driver stores the physical address in a 32-bit 'unsigned long'
variable.

Change the itt_addr variable to the correct phys_addr_t type instead,
along with all other variables in this driver that hold a physical
address.

I checked the gicv5 driver for the same problem, and it correctly
uses u64 variables, while all other irqchip drivers don't call
virt_to_phys or similar interfaces. I expect other drivers to
have similar issues, but fixing this one is sufficient for
booting a virtio based guest.

Fixes: cc2d3216f53c ("irqchip: GICv3: ITS command queue")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/irqchip/irq-gic-v3-its.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index ada585bfa451..2988def30972 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -709,7 +709,7 @@ static struct its_collection *its_build_mapd_cmd(struct its_node *its,
 						 struct its_cmd_block *cmd,
 						 struct its_cmd_desc *desc)
 {
-	unsigned long itt_addr;
+	phys_addr_t itt_addr;
 	u8 size = ilog2(desc->its_mapd_cmd.dev->nr_ites);
 
 	itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt);
@@ -879,7 +879,7 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
 					   struct its_cmd_desc *desc)
 {
 	struct its_vpe *vpe = valid_vpe(its, desc->its_vmapp_cmd.vpe);
-	unsigned long vpt_addr, vconf_addr;
+	phys_addr_t vpt_addr, vconf_addr;
 	u64 target;
 	bool alloc;
 
@@ -2477,10 +2477,10 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 	baser->psz = psz;
 	tmp = indirect ? GITS_LVL1_ENTRY_SIZE : esz;
 
-	pr_info("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n",
+	pr_info("ITS@%pa: allocated %d %s @%llx (%s, esz %d, psz %dK, shr %d)\n",
 		&its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp),
 		its_base_type_string[type],
-		(unsigned long)virt_to_phys(base),
+		(u64)virt_to_phys(base),
 		indirect ? "indirect" : "flat", (int)esz,
 		psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT);
 
-- 
2.39.5



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

* Re: [PATCH] irqchip: gic-v3-its: avoid truncating memory addresses
  2026-01-19 20:15 [PATCH] irqchip: gic-v3-its: avoid truncating memory addresses Arnd Bergmann
@ 2026-01-20  8:51 ` Marc Zyngier
  2026-01-20  9:52   ` Arnd Bergmann
  0 siblings, 1 reply; 3+ messages in thread
From: Marc Zyngier @ 2026-01-20  8:51 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Thomas Gleixner, Arnd Bergmann, Lorenzo Pieralisi,
	linux-arm-kernel, linux-kernel

On Mon, 19 Jan 2026 20:15:12 +0000,
Arnd Bergmann <arnd@kernel.org> wrote:
> 
> From: Arnd Bergmann <arnd@arndb.de>
> 
> On 32-bit machines with CONFIG_ARM_LPAE, it is possible for lowmem
> allocations to be backed by addresses physical memory above the 32-bit
> address limit, as I found while experimenting with larger VMSPLIT
> configurations.
> 
> This caused the qemu virt model to crash in the GICv3 driver, which
> allocates the 'itt' object using GFP_KERNEL. Since all memory below
> the 4GB physical address limit is in ZONE_DMA in this configuration,
> kmalloc defaults to higher addresses for ZONE_NORMAL, and the
> its driver stores the physical address in a 32-bit 'unsigned long'
> variable.
> 
> Change the itt_addr variable to the correct phys_addr_t type instead,
> along with all other variables in this driver that hold a physical
> address.

Ah, nice catch. It's amazing that we've managed for so long with such
a glaring bug. I guess most 32bit VMs don't have much memory above the
4GB limit.

> 
> I checked the gicv5 driver for the same problem, and it correctly
> uses u64 variables,

GICv5 is strictly 64bit, and cannot be plugged on a system that
supports AArch32.

> while all other irqchip drivers don't call
> virt_to_phys or similar interfaces. I expect other drivers to
> have similar issues, but fixing this one is sufficient for
> booting a virtio based guest.
> 
> Fixes: cc2d3216f53c ("irqchip: GICv3: ITS command queue")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

Cc: stable@vger.kernel.org
Reviewed-by: Marc Zyngier <maz@kernel.org>

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


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

* Re: [PATCH] irqchip: gic-v3-its: avoid truncating memory addresses
  2026-01-20  8:51 ` Marc Zyngier
@ 2026-01-20  9:52   ` Arnd Bergmann
  0 siblings, 0 replies; 3+ messages in thread
From: Arnd Bergmann @ 2026-01-20  9:52 UTC (permalink / raw)
  To: Marc Zyngier, Arnd Bergmann
  Cc: Thomas Gleixner, Lorenzo Pieralisi, linux-arm-kernel,
	linux-kernel

On Tue, Jan 20, 2026, at 09:51, Marc Zyngier wrote:
> On Mon, 19 Jan 2026 20:15:12 +0000, Arnd Bergmann <arnd@kernel.org> wrote:
>> 
>> Change the itt_addr variable to the correct phys_addr_t type instead,
>> along with all other variables in this driver that hold a physical
>> address.
>
> Ah, nice catch. It's amazing that we've managed for so long with such
> a glaring bug. I guess most 32bit VMs don't have much memory above the
> 4GB limit.

Right, the upstream qemu model specifically has no lowmem above
the limit, as its RAM starts as 0x40000000 and the most lowmem we
support (with CONFIG_VMSPLIT_1G) is 3.75GiB, ending at 0xEFFFFFFF
physical.

There are some SoCs that start physical RAM higher up, but I suppose
these were either never tested with CONFIG_VMSPLIT_1G, or they don't
have a GICv3.

The patch I'm testing with allows lowmem to be at physically
discontinuous addresses, so this can happen on any SoC that has
its second DRAM controller mapped to a high address, potentially
even with the regular VMSPLIT_3G or VMSPLIT_2G.

>> I checked the gicv5 driver for the same problem, and it correctly
>> uses u64 variables,
>
> GICv5 is strictly 64bit, and cannot be plugged on a system that
> supports AArch32.

Right, makes sense.

   Arnd


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

end of thread, other threads:[~2026-01-20  9:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-19 20:15 [PATCH] irqchip: gic-v3-its: avoid truncating memory addresses Arnd Bergmann
2026-01-20  8:51 ` Marc Zyngier
2026-01-20  9:52   ` Arnd Bergmann

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