summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2026-07-27 09:54:23 -0700
committerGuenter Roeck <linux@roeck-us.net>2026-07-27 11:35:22 -0700
commit080bbf42faf77e6489ab30d5114c5f8f6ccbb1b8 (patch)
treec0ecf7073225a7437553bed6a040b0d430277c41
parentaa9429edf9fc0e90d6f4da19ea4b5495a54ab117 (diff)
downloadlinux-next-080bbf42faf77e6489ab30d5114c5f8f6ccbb1b8.tar.gz
linux-next-080bbf42faf77e6489ab30d5114c5f8f6ccbb1b8.zip
hwmon: (nzxt-smart2) DMA-align output buffer
Sashiko reports: When send_output_report() calls hid_hw_output_report(), the underlying USB HID core calls usb_interrupt_msg() which maps this buffer directly for DMA. When the DMA mapping flushes or invalidates the cacheline, it will corrupt the adjacent variables (mutex, update_interval) that were modified concurrently by the CPU. This causes memory corruption due to cacheline sharing on non-coherent CPU architectures (such as ARM or MIPS). The DMA API debugging tool (CONFIG_DMA_API_DEBUG) will trigger runtime warnings for this violation. Any operation that triggers send_output_report() (like setting a fan speed or updating the interval) causes the USB DMA mapping. On systems with non-coherent caches, this structural bug causes immediate and deterministic memory corruption. Align the output buffer to ARCH_DMA_MINALIGN to fix the problem. Reported-by: Sashiko <sashiko-bot@kernel.org> Fixes: 53e68c20aeb1 ("hwmon: add driver for NZXT RGB&Fan Controller/Smart Device v2.") Cc: Aleksandr Mezin <mezin.alexander@gmail.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/nzxt-smart2.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/hwmon/nzxt-smart2.c b/drivers/hwmon/nzxt-smart2.c
index e2316c46629d..ff0c0bee0e83 100644
--- a/drivers/hwmon/nzxt-smart2.c
+++ b/drivers/hwmon/nzxt-smart2.c
@@ -203,7 +203,7 @@ struct drvdata {
*/
struct mutex mutex;
long update_interval;
- u8 output_buffer[OUTPUT_REPORT_SIZE];
+ u8 output_buffer[OUTPUT_REPORT_SIZE] __aligned(ARCH_DMA_MINALIGN);
};
static long scale_pwm_value(long val, long orig_max, long new_max)