[PATCH 01/28] mfd: nct6694: Allocate USB DMA buffers with kzalloc_obj()
From: Lee Jones
Date: Wed Oct 21 2026 - 08:14:22 EST
nct6694_usb_probe() allocates the USB transfer buffers usb_msg and
int_buffer using devm_kzalloc(). Because devm_kzalloc() prepends
internal devres metadata to the allocation, the returned buffer pointers
are not guaranteed to be ARCH_DMA_MINALIGN cacheline-aligned. Mapping
these unaligned buffers for USB bulk and interrupt DMA transfers risks
cacheline sharing and memory corruption on non-cache-coherent
architectures.
Allocate usb_msg and int_buffer using kzalloc_obj() to guarantee
DMA-safe alignment, and free them on probe failure and in
nct6694_usb_disconnect().
Fixes: 51dad33ede63 ("mfd: Add core driver for Nuvoton NCT6694")
Closes: https://sashiko.dev/#/bug/linux-6f9e5ba3-714e-41ad-b6cd-3a17c665b87f
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
---
drivers/mfd/nct6694.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/mfd/nct6694.c b/drivers/mfd/nct6694.c
index 308b2fda3055..e2957e587d1b 100644
--- a/drivers/mfd/nct6694.c
+++ b/drivers/mfd/nct6694.c
@@ -284,17 +284,21 @@ static int nct6694_usb_probe(struct usb_interface *iface,
if (!nct6694)
return -ENOMEM;
- nct6694->usb_msg = devm_kzalloc(dev, sizeof(union nct6694_usb_msg), GFP_KERNEL);
+ nct6694->usb_msg = kzalloc_obj(*nct6694->usb_msg);
if (!nct6694->usb_msg)
return -ENOMEM;
- nct6694->int_buffer = devm_kzalloc(dev, sizeof(*nct6694->int_buffer), GFP_KERNEL);
- if (!nct6694->int_buffer)
- return -ENOMEM;
+ nct6694->int_buffer = kzalloc_obj(*nct6694->int_buffer);
+ if (!nct6694->int_buffer) {
+ ret = -ENOMEM;
+ goto err_usb_msg;
+ }
nct6694->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!nct6694->int_in_urb)
- return -ENOMEM;
+ if (!nct6694->int_in_urb) {
+ ret = -ENOMEM;
+ goto err_int_buffer;
+ }
nct6694->domain = irq_domain_create_simple(NULL, NCT6694_NR_IRQS, 0,
&nct6694_irq_domain_ops,
@@ -352,6 +356,10 @@ static int nct6694_usb_probe(struct usb_interface *iface,
irq_domain_remove(nct6694->domain);
err_urb:
usb_free_urb(nct6694->int_in_urb);
+err_int_buffer:
+ kfree(nct6694->int_buffer);
+err_usb_msg:
+ kfree(nct6694->usb_msg);
return ret;
}
@@ -367,6 +375,8 @@ static void nct6694_usb_disconnect(struct usb_interface *iface)
ida_destroy(&nct6694->gpio_ida);
irq_domain_remove(nct6694->domain);
usb_free_urb(nct6694->int_in_urb);
+ kfree(nct6694->int_buffer);
+ kfree(nct6694->usb_msg);
}
static const struct usb_device_id nct6694_ids[] = {
--
2.56.0.218.g1ec904b173-goog