u-boot.lists.denx.de archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Fix dma_addr_t for R5 SPL
@ 2025-09-02  9:40 Anshul Dalal
  2025-09-02  9:40 ` [PATCH v2 1/2] dma: ti: k3-udma: fix dma_addr_t typecasts Anshul Dalal
  2025-09-02  9:40 ` [PATCH v2 2/2] config: arch: k3: enable DMA_ADDR_T_64BIT Anshul Dalal
  0 siblings, 2 replies; 4+ messages in thread
From: Anshul Dalal @ 2025-09-02  9:40 UTC (permalink / raw)
  To: u-boot; +Cc: Anshul Dalal, vigneshr, trini, u-kumar1, p-mantena

Hi all,

On various TI's K3 platforms boot failure was observed on SPI NOR since the
commit 5609f200d062 ("arm: Kconfig: enable LTO for ARCH_K3"). This issue was
root caused to stack corruption by the 'udma_transfer' function. Where the local
variable 'paddr' of type 'dma_addr_t' was being written to as a 64-bit value
which overwrote the stack frame of the caller (dma_memcpy) as only 32-bits had
been reserved for paddr on the stack, specifically the r4 register in the frame
of dma_memcpy was being overwritten with a 0.

drivers/dma/ti/k3-udma.c:2192:

	int udma_transfer(...)
	{
		...
		dma_addr_t paddr = 0;

		...
		/* paddr was written to as 64-bit value here */
		udma_poll_completion(uc, &paddr);
	}

drivers/dma/dma-uclass.c:234:

	int dma_memcpy(...)
	{
		dma_addr_t destination;
		dma_addr_t source;
		int ret;

		...

		/* This call resolves to udma_transfer */
		ret = ops->transfer(...);

		...

		dma_unmap_single(destination, ...);
		dma_unmap_single(...);
		return ret;
	}

Enabling LTO changed how gcc mapped local variables of dma_memcpy to CPU
registers, where earlier the bug was hidden since the overwritten register
'r4' was allotted to 'ret' but was allotted to 'destination' once LTO was
enabled. And since the overwritten value was 0, the bug remained undetected
as it just meant ret was 0, but having 'destination' set to 0 caused
dma_unmap_single to fail silently leading to boot failures.

The fix entails enabling DMA_ADDR_T_64BIT which changes dma_addr_t from u32 to
u64 for the R5 SPL thus reserving enough space for 'paddr' to prevent the
overflow.

Regards,
Anshul
---
Changes for v2:
 - Add missing typecasts for usb driver
 - Reword commit description
v1: https://lore.kernel.org/u-boot/20250825133233.2475300-1-anshuld@ti.com/
---
Anshul Dalal (2):
  dma: ti: k3-udma: fix dma_addr_t typecasts
  config: arch: k3: enable DMA_ADDR_T_64BIT

 arch/arm/Kconfig         | 1 +
 drivers/dma/ti/k3-udma.c | 6 +++---
 drivers/usb/dwc3/ep0.c   | 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

-- 
2.50.1


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

* [PATCH v2 1/2] dma: ti: k3-udma: fix dma_addr_t typecasts
  2025-09-02  9:40 [PATCH v2 0/2] Fix dma_addr_t for R5 SPL Anshul Dalal
@ 2025-09-02  9:40 ` Anshul Dalal
  2025-09-02 10:53   ` Prasanth Mantena
  2025-09-02  9:40 ` [PATCH v2 2/2] config: arch: k3: enable DMA_ADDR_T_64BIT Anshul Dalal
  1 sibling, 1 reply; 4+ messages in thread
From: Anshul Dalal @ 2025-09-02  9:40 UTC (permalink / raw)
  To: u-boot; +Cc: Anshul Dalal, vigneshr, trini, u-kumar1, p-mantena

With the change to dma_addr_t from u32 to u64 in the next patch, the
existing typecasts from void* to int or vice-versa will cause the
compiler to throw a "cast from pointer to integer of different size".

Therefore this patch changes the casts to a uintptr_t which is
guaranteed to hold a pointer value on the given arch, thus preventing
the compiler warning when enabling DMA_ADDR_T_64BIT for the R5 SPL.

Signed-off-by: Anshul Dalal <anshuld@ti.com>
---
 drivers/dma/ti/k3-udma.c | 6 +++---
 drivers/usb/dwc3/ep0.c   | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 723265ab2e5..01824310995 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -2327,7 +2327,7 @@ static int udma_send(struct dma *dma, void *src, size_t len, void *metadata)
 {
 	struct udma_dev *ud = dev_get_priv(dma->dev);
 	struct cppi5_host_desc_t *desc_tx;
-	dma_addr_t dma_src = (dma_addr_t)src;
+	dma_addr_t dma_src = (uintptr_t)src;
 	struct ti_udma_drv_packet_data packet_data = { 0 };
 	dma_addr_t paddr;
 	struct udma_chan *uc;
@@ -2426,7 +2426,7 @@ static int udma_receive(struct dma *dma, void **dst, void *metadata)
 
 	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
 
-	*dst = (void *)buf_dma;
+	*dst = (void *)(uintptr_t)buf_dma;
 	uc->num_rx_bufs--;
 
 	return pkt_len;
@@ -2518,7 +2518,7 @@ int udma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
 
 	desc_num = uc->desc_rx_cur % UDMA_RX_DESC_NUM;
 	desc_rx = uc->desc_rx + (desc_num * uc->config.hdesc_size);
-	dma_dst = (dma_addr_t)dst;
+	dma_dst = (uintptr_t)dst;
 
 	cppi5_hdesc_reset_hbdesc(desc_rx);
 
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 531f0b522af..c656cbe25ce 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -380,7 +380,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
 	dep = dwc->eps[0];
 	dwc->ep0_usb_req.dep = dep;
 	dwc->ep0_usb_req.request.length = sizeof(*response_pkt);
-	dwc->ep0_usb_req.request.buf = (void *)dwc->setup_buf_addr;
+	dwc->ep0_usb_req.request.buf = (void *)(uintptr_t)dwc->setup_buf_addr;
 	dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl;
 
 	return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
@@ -662,7 +662,7 @@ static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 	dep = dwc->eps[0];
 	dwc->ep0_usb_req.dep = dep;
 	dwc->ep0_usb_req.request.length = dep->endpoint.maxpacket;
-	dwc->ep0_usb_req.request.buf = (void *)dwc->setup_buf_addr;
+	dwc->ep0_usb_req.request.buf = (void *)(uintptr_t)dwc->setup_buf_addr;
 	dwc->ep0_usb_req.request.complete = dwc3_ep0_set_sel_cmpl;
 
 	return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
-- 
2.50.1


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

* [PATCH v2 2/2] config: arch: k3: enable DMA_ADDR_T_64BIT
  2025-09-02  9:40 [PATCH v2 0/2] Fix dma_addr_t for R5 SPL Anshul Dalal
  2025-09-02  9:40 ` [PATCH v2 1/2] dma: ti: k3-udma: fix dma_addr_t typecasts Anshul Dalal
@ 2025-09-02  9:40 ` Anshul Dalal
  1 sibling, 0 replies; 4+ messages in thread
From: Anshul Dalal @ 2025-09-02  9:40 UTC (permalink / raw)
  To: u-boot; +Cc: Anshul Dalal, vigneshr, trini, u-kumar1, p-mantena

ARCH_K3 encompasses both 32 and 64-bit cores on the same SoC, though the
DMA addresses are always 64-bit in size.

With the current implementation, the R5 SPL uses a u32 for dma_addr_t
which leads to data overflow when functions such as k3_nav_*_pop_mem try
to write a 64-bit address to dma_addr_t variable.

In certain cases it leads to stack corruption which manifest as boot
failures on certain compilers, such as SPI boot on GCC 14.2 or 13.3.

Therefore this patch selects CONFIG_DMA_ADDR_T_64BIT for all ARCH_K3.

Fixes: ffcc66e8fec5 ("dma: ti: add driver to K3 UDMA")
Signed-off-by: Anshul Dalal <anshuld@ti.com>
---
 arch/arm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 40368abc297..16db046f4b8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -833,6 +833,7 @@ config ARCH_K3
 	select FIT
 	select REGEX
 	select FIT_SIGNATURE if ARM64
+	select DMA_ADDR_T_64BIT
 	select LTO
 	imply TI_SECURE_DEVICE
 	imply DM_RNG if ARM64
-- 
2.50.1


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

* Re: [PATCH v2 1/2] dma: ti: k3-udma: fix dma_addr_t typecasts
  2025-09-02  9:40 ` [PATCH v2 1/2] dma: ti: k3-udma: fix dma_addr_t typecasts Anshul Dalal
@ 2025-09-02 10:53   ` Prasanth Mantena
  0 siblings, 0 replies; 4+ messages in thread
From: Prasanth Mantena @ 2025-09-02 10:53 UTC (permalink / raw)
  To: Anshul Dalal; +Cc: u-boot, vigneshr, trini, u-kumar1

Hi Anshul,
On 15:10, Anshul Dalal wrote:
> With the change to dma_addr_t from u32 to u64 in the next patch, the

This feels little odd honestly. Can we make the commit description in a
generic way instead of using "next patch" terms in the description.
And, still this patch fixes something that comes from applying the next
patch. Not really sure, if this is ok this way.

Regards,
Prasanth

> existing typecasts from void* to int or vice-versa will cause the
> compiler to throw a "cast from pointer to integer of different size".
> 
> Therefore this patch changes the casts to a uintptr_t which is
> guaranteed to hold a pointer value on the given arch, thus preventing
> the compiler warning when enabling DMA_ADDR_T_64BIT for the R5 SPL.
> 
> Signed-off-by: Anshul Dalal <anshuld@ti.com>
> ---
>  drivers/dma/ti/k3-udma.c | 6 +++---
>  drivers/usb/dwc3/ep0.c   | 4 ++--
>  2 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
> index 723265ab2e5..01824310995 100644
> --- a/drivers/dma/ti/k3-udma.c
> +++ b/drivers/dma/ti/k3-udma.c
> @@ -2327,7 +2327,7 @@ static int udma_send(struct dma *dma, void *src, size_t len, void *metadata)
>  {
>  	struct udma_dev *ud = dev_get_priv(dma->dev);
>  	struct cppi5_host_desc_t *desc_tx;
> -	dma_addr_t dma_src = (dma_addr_t)src;
> +	dma_addr_t dma_src = (uintptr_t)src;
>  	struct ti_udma_drv_packet_data packet_data = { 0 };
>  	dma_addr_t paddr;
>  	struct udma_chan *uc;
> @@ -2426,7 +2426,7 @@ static int udma_receive(struct dma *dma, void **dst, void *metadata)
>  
>  	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
>  
> -	*dst = (void *)buf_dma;
> +	*dst = (void *)(uintptr_t)buf_dma;
>  	uc->num_rx_bufs--;
>  
>  	return pkt_len;
> @@ -2518,7 +2518,7 @@ int udma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
>  
>  	desc_num = uc->desc_rx_cur % UDMA_RX_DESC_NUM;
>  	desc_rx = uc->desc_rx + (desc_num * uc->config.hdesc_size);
> -	dma_dst = (dma_addr_t)dst;
> +	dma_dst = (uintptr_t)dst;
>  
>  	cppi5_hdesc_reset_hbdesc(desc_rx);
>  
> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
> index 531f0b522af..c656cbe25ce 100644
> --- a/drivers/usb/dwc3/ep0.c
> +++ b/drivers/usb/dwc3/ep0.c
> @@ -380,7 +380,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
>  	dep = dwc->eps[0];
>  	dwc->ep0_usb_req.dep = dep;
>  	dwc->ep0_usb_req.request.length = sizeof(*response_pkt);
> -	dwc->ep0_usb_req.request.buf = (void *)dwc->setup_buf_addr;
> +	dwc->ep0_usb_req.request.buf = (void *)(uintptr_t)dwc->setup_buf_addr;
>  	dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl;
>  
>  	return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
> @@ -662,7 +662,7 @@ static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
>  	dep = dwc->eps[0];
>  	dwc->ep0_usb_req.dep = dep;
>  	dwc->ep0_usb_req.request.length = dep->endpoint.maxpacket;
> -	dwc->ep0_usb_req.request.buf = (void *)dwc->setup_buf_addr;
> +	dwc->ep0_usb_req.request.buf = (void *)(uintptr_t)dwc->setup_buf_addr;
>  	dwc->ep0_usb_req.request.complete = dwc3_ep0_set_sel_cmpl;
>  
>  	return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
> -- 
> 2.50.1
> 

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

end of thread, other threads:[~2025-09-02 10:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-02  9:40 [PATCH v2 0/2] Fix dma_addr_t for R5 SPL Anshul Dalal
2025-09-02  9:40 ` [PATCH v2 1/2] dma: ti: k3-udma: fix dma_addr_t typecasts Anshul Dalal
2025-09-02 10:53   ` Prasanth Mantena
2025-09-02  9:40 ` [PATCH v2 2/2] config: arch: k3: enable DMA_ADDR_T_64BIT Anshul Dalal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).