From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D180377AA0 for ; Fri, 21 Aug 2026 03:35:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283343; cv=none; b=J0W1W8f3XWgsMawO6v3xflmDE62cJSnPZ5kUUcGR56dJuW43omIQB6nof2Or1CWmVNXNCJ45LBdq1zmF+vIhc0sDMq5hmdBqJFirISh1PstS90DMxz0f1b3WxQsrSdooEWEC3g8l3foTctRd1o+y/VP3oIH9GCGK3XEY+7hj/Gs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283343; c=relaxed/simple; bh=dh6ypal0eP9TY0RyxbOZW37QBS/0wHMrW1fkKLXmnZQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=grCmWvoS95EuI7BBYatUlsMSP5K2o3BF3bzs2SWDAcbq4rh35JJhLGbuAyVmsjrPBaYd/mQD8Zs4mFswKBsX/Jp88gNlsXTdOuaf8zSZfXIM7vyuB1aG91KjvCWGkWobPfO/IS5ED6K6dRbim3BSMv9eF8eV3sjmU0dqeh7+JfE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=J04DKAv0; arc=none smtp.client-ip=209.85.210.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="J04DKAv0" Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-848643382fcso492540b3a.1 for ; Thu, 20 Aug 2026 20:35:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283339; x=1787888139; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=akgiGKYdVb/X1Q1qbgoX9eIBpnqoztnG/F+moLn7cbc=; b=J04DKAv0JsBSwy9GT1+MtuldkRbIwJAY6oF7JrHZ/VcbR/nVBBtcNqdi25BIqVIs92 gVOTVDa5WDRklHbRb4VsSV0QUkjHuMm1vbzVbEQyzKbed7dYRxFZUqnNZtWerl4xPv+r Nz5yg9f7bIp4X52AJWpDqROGy0IZlT6o2QjRRM4qQyjJW3Mf9rf/0WuTzdoVK9sKo6DU j3L5Z6Cn4yjsIH2Wm9AEqxbI9qRBI9msRGPQfdfxYuhQ9X6LVU9UdeOu5vKXdLlf/EvQ gpuYhkNEnjVRqJ+g9m1HX68Gj/cTIYg2hyoa4uMU5NtzzOcjrP7vlPQxSYDJ8OTCPvra oI5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283339; x=1787888139; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=akgiGKYdVb/X1Q1qbgoX9eIBpnqoztnG/F+moLn7cbc=; b=iXwTGd/jfM3Y6qBQvwf1ItNfbzVh6M9XqZhbSEfZb3BRMzRhxXr+vPLs9Zpi+iE/AS e0ctJy5Hra/n7NJAZmgrTIb3qwg2WyS/WMc9Fqq3gpFjpCPkiAUpGB/s2diISEcCxwr6 fOUW+VKOjmmKCady4U4wtWuEZo3dsiQPeOIbWkhLksmPctd+YmZ4kSOXfY+ArRLNh5P5 7QgeZtFYWgrCr0LEEdQiROstXASCwagXw4CzOWuz+xCSiBGA3xO313weJIc17zHRJ9Qt I1jGJApCXuXYmQWIZgs2xUx+azkx83ipNrAuwtyI1FvET9pLybw4FI25OvbgWsBfkyQk JmXA== X-Gm-Message-State: AOJu0YyMFPWmJAEoR6rT/oANnIF5A0XTzSTbyA8jqfz0rVljPWBpFWbb Qrx6vO5NljPZsNzRnEUf55MhUsSS3+hUhE3shaCs4oHXp+g24/mYzexET/W4vQ== X-Gm-Gg: AR+sD13j6ONPRnIRYWmhXVBEcx3ijGuRt/YYbST3ood5tC003pAL5jq952U2LbZTMI+ Yg+5qZeIvQZy8nI8x4y0HFYSef827aciokGVUeW/IyRg/gGfmc6N7vRlVHF/6zrkRtZmrCm72NB tTuJs4EhBBnYkoYiTYnGJW7N9S1AhdHRxzaV351fkAiQ/03pF/LAFRMQwRbqaS96IjYxQkP7zTK Lskb5Z51/C1cm/rT4QjRAfPKgD35JvVNfUyAYGyHoUDgeLjplhBZ0s2hLJFI5vfBd49LxM9Q0D8 sVoiFuuHcgDtp0/otY365W+kYaMAwnsz4RF9xjj5iEYXO1EFlwqN5ghUeqyWJ4Y44USGsAm1Cab 2JwtigHL4tARO33WFnlJnxEMQtsjzySQGwGB5rqKRHELh4XYW2A50e+ZtNM6BXoKF1o3//DjM8h SrsNZ3MqaefA39Psc+RUzmWtV0ZvPeCnvmZxoLAMu5Eg0NfajVktEfPlL/oJX9KIp9m/Hy08l1f J6LZnRgTodY7VAlY7zASpvwnBVHRen9 X-Received: by 2002:a05:6a20:3d94:b0:3b3:26aa:5455 with SMTP id adf61e73a8af0-3cd300f9e23mr6147186637.13.1787283338691; Thu, 20 Aug 2026 20:35:38 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:38 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 06/10] mfd: nct6694: Transfer command payloads via a dedicated DMA buffer Date: Fri, 21 Aug 2026 11:35:01 +0800 Message-Id: <20260821033505.4017901-7-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Ming Yu The transport hands the caller's payload buffer straight to usb_bulk_msg(). Sub-device drivers embed those buffers in their private data structures, so they are neither cacheline aligned nor exclusively owned by the transfer. On non-coherent architectures, mapping such a buffer for DMA can corrupt the unrelated fields sharing its cachelines. Transfer the payload through a buffer owned by the transport instead, and reject commands exceeding the maximum firmware packet size. Fixes: 51dad33ede63 ("mfd: Add core driver for Nuvoton NCT6694") Signed-off-by: Ming Yu --- Changes in v7: - New patch. Fixes the DMA-unsafe use of caller-owned payload buffers reported on v6 patch 6/7. drivers/mfd/nct6694-usb.c | 38 +++++++++++++++++++++++++++---------- include/linux/mfd/nct6694.h | 3 +++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/mfd/nct6694-usb.c b/drivers/mfd/nct6694-usb.c index 2289ebfde7fa..793ce54c02aa 100644 --- a/drivers/mfd/nct6694-usb.c +++ b/drivers/mfd/nct6694-usb.c @@ -38,6 +38,7 @@ struct nct6694_usb_data { struct urb *int_in_urb; struct usb_device *udev; union nct6694_usb_msg *usb_msg; + void *xfer_buf; __le32 *int_buffer; }; @@ -120,8 +121,12 @@ int nct6694_usb_read_msg(struct nct6694 *nct6694, struct nct6694_usb_data *udata = nct6694->priv; union nct6694_usb_msg *msg = udata->usb_msg; struct usb_device *udev = udata->udev; + u16 len = le16_to_cpu(cmd_hd->len); int tx_len, rx_len, ret; + if (len > NCT6694_MAX_PACKET_SIZE) + return -EINVAL; + guard(mutex)(&udata->access_lock); memcpy(&msg->cmd_header, cmd_hd, sizeof(*cmd_hd)); @@ -140,17 +145,19 @@ int nct6694_usb_read_msg(struct nct6694 *nct6694, return ret; /* Receive data packet from USB device */ - ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), buf, - le16_to_cpu(cmd_hd->len), &rx_len, NCT6694_URB_TIMEOUT); + ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), udata->xfer_buf, + len, &rx_len, NCT6694_URB_TIMEOUT); if (ret) return ret; - if (rx_len != le16_to_cpu(cmd_hd->len)) { + if (rx_len != len) { dev_err(nct6694->dev, "Expected received length %d, but got %d\n", - le16_to_cpu(cmd_hd->len), rx_len); + len, rx_len); return -EIO; } + memcpy(buf, udata->xfer_buf, len); + return nct6694_usb_err_handling(nct6694, msg->response_header.sts); } EXPORT_SYMBOL_GPL(nct6694_usb_read_msg); @@ -173,12 +180,17 @@ int nct6694_usb_write_msg(struct nct6694 *nct6694, struct nct6694_usb_data *udata = nct6694->priv; union nct6694_usb_msg *msg = udata->usb_msg; struct usb_device *udev = udata->udev; + u16 len = le16_to_cpu(cmd_hd->len); int tx_len, rx_len, ret; + if (len > NCT6694_MAX_PACKET_SIZE) + return -EINVAL; + guard(mutex)(&udata->access_lock); memcpy(&msg->cmd_header, cmd_hd, sizeof(*cmd_hd)); msg->cmd_header.hctrl = NCT6694_HCTRL_SET; + memcpy(udata->xfer_buf, buf, len); /* Send command packet to USB device */ ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, NCT6694_BULK_OUT_EP), &msg->cmd_header, @@ -187,8 +199,8 @@ int nct6694_usb_write_msg(struct nct6694 *nct6694, return ret; /* Send data packet to USB device */ - ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, NCT6694_BULK_OUT_EP), buf, - le16_to_cpu(cmd_hd->len), &tx_len, NCT6694_URB_TIMEOUT); + ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, NCT6694_BULK_OUT_EP), udata->xfer_buf, + len, &tx_len, NCT6694_URB_TIMEOUT); if (ret) return ret; @@ -199,17 +211,19 @@ int nct6694_usb_write_msg(struct nct6694 *nct6694, return ret; /* Receive data packet from USB device */ - ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), buf, - le16_to_cpu(cmd_hd->len), &rx_len, NCT6694_URB_TIMEOUT); + ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), udata->xfer_buf, + len, &rx_len, NCT6694_URB_TIMEOUT); if (ret) return ret; - if (rx_len != le16_to_cpu(cmd_hd->len)) { + if (rx_len != len) { dev_err(nct6694->dev, "Expected transmitted length %d, but got %d\n", - le16_to_cpu(cmd_hd->len), rx_len); + len, rx_len); return -EIO; } + memcpy(buf, udata->xfer_buf, len); + return nct6694_usb_err_handling(nct6694, msg->response_header.sts); } EXPORT_SYMBOL_GPL(nct6694_usb_write_msg); @@ -270,6 +284,10 @@ static int nct6694_usb_probe(struct usb_interface *iface, if (!udata->usb_msg) return -ENOMEM; + udata->xfer_buf = devm_kzalloc(dev, NCT6694_MAX_PACKET_SIZE, GFP_KERNEL); + if (!udata->xfer_buf) + return -ENOMEM; + udata->int_buffer = devm_kzalloc(dev, sizeof(*udata->int_buffer), GFP_KERNEL); if (!udata->int_buffer) return -ENOMEM; diff --git a/include/linux/mfd/nct6694.h b/include/linux/mfd/nct6694.h index 853b1530755d..cb311e58a437 100644 --- a/include/linux/mfd/nct6694.h +++ b/include/linux/mfd/nct6694.h @@ -29,6 +29,9 @@ struct mfd_cell; #define NCT6694_HCTRL_SET 0x40 #define NCT6694_HCTRL_GET 0x80 +/* Maximum payload length the firmware accepts in a single command */ +#define NCT6694_MAX_PACKET_SIZE 0x3F0 + enum nct6694_irq_id { NCT6694_IRQ_GPIO0 = 0, NCT6694_IRQ_GPIO1, -- 2.34.1