From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=74.125.82.178 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793408826; b=xgM5O/J14PQGaGs273eBMRyv5g2EcVM682z61AyxEv6tnLMGGehugG3s6EvFGfHoMYw3 1DS1TDMeUiYCXgwqc9dJuH2eR7CJ/Rgp4M5fl179aR7bAWRWeZZNtKoxAKKB80vxfI9o1 rX0hPCcXf614lBxJk2KOeaQE5XRkI1ocFiSs5Dn4EKwAAVpQhZgO7EzQl4EW0YzRZgRmh 4S/Ig9l6NqzM8yHgUGIHXiybaq8oa0LJUCoca//L+fzyi0m3ppREuHXU8X+jskjq0u/cm ScL7RxRdp3leiMG4UcqYwLUe6NP9ziESM0Do0xexyfLt/vkd74wPRxQ74PQ4YWU+sQw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793408826; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: From:To:Cc:Subject:Date:Message-Id:X-Mailer:MIME-Version: Content-Transfer-Encoding; bh=xT9iMK/3RSde+zBTAQleC9VvYEhHkZyaWiIqI8wE2FM=; b=SzuNN3zZtLUnPY1z4WVTz7dwwz/E51Tz9gr97+iYR+HxQPn47l5079mz56ZkAcIOWtxC yVK/sYwQP4MOIw7ie/UPM4H1nyC44W4RRhMep1MMoLjysDT6Y7DUr+jzRlXp2RRqIWle9 keveowRZGWzBBOGE2x4KY/FQKx2pN/efCO4A3YmsjsvQcEOXwsxFAQg52MIia1HD9NRJU MR8dG2iSld9d8pFCEKVoI8RBKZLITRrixwSG+t+6LDiDBYHOeMIolDMQL5vo+o49q+fDw Xfw3svbu2b4rI1gukJRTyFT+18c4ti4LpMoSU0vBPFItHEhycIqI13+gAxo0D8pfgzw== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=cOAbD30s; arc=none smtp.remote-ip=74.125.82.178 Received: from mail-dy1-f178.google.com (mail-dy1-f178.google.com [74.125.82.178]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B46D5606A31C for ; Sat, 31 Oct 2026 01:07:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org B46D5606A31C 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, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=cOAbD30s Received: by mail-dy1-f178.google.com with SMTP id 5a478bee46e88-33fb4680717so546715eec.1 for ; Fri, 30 Oct 2026 18:07:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793408825; x=1794013625; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=xT9iMK/3RSde+zBTAQleC9VvYEhHkZyaWiIqI8wE2FM=; b=cOAbD30sbP8coqbY7WR55KoVfEL18HRW3wWa9x6tJnKxqfOtVa5AlUoIhAH75tardk +job3cpt7i2RGlW5se1Jlprl9fWpfuaO0gXJkLo8IvbKGye6jDkY2FRHovToyi8f/B1O T5O7lSxK7tpgYN8UQLf5ox55xEuZBYQ3FwIxBHI60SP55rP9WNfMp16GkAia+Df0EOi9 1Izd9bJzG4h89Y+HqYy+v1Tq7UPqkR6xYJS3hDTFfhfqSafuMEylCM0cV0lvCJNO1SVv FBNIV8/5DPJ28eZBntCWlMSdSpn4Egef1z5vHmFReH9CjMXfHYXZAdnDAwe7NY+LAzh6 VJww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793408825; x=1794013625; h=content-transfer-encoding:mime-version: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=xT9iMK/3RSde+zBTAQleC9VvYEhHkZyaWiIqI8wE2FM=; b=q4l9wzTycgnflmAQ+5iBdU/QICCZHp9HsGUOu4R6DS8EWgAzB7I6esEVfrvEwdJDuH f3Ubjv2kB3R6gRUjvmrZMwqKKEHVV/QzC8auBMYsaPY+oQcoI6urqcVBnp4ygImUwsQ1 zBv5O58MSWAiAfO52t/LmOPrx0Hw76Y/3vRZcWw9LNCPplj0DSvuLS60Twfb/TQrSq4m mHqjY+LOWZRA76VbcMwkm4RKaaAtQWNzhWbfQCgYgvrZFswfG71wpKaC4VoiOuqfu1sx hB2YD78bPOMpZ94DUIZlREEldBH+wfDEYJ8CvQJmxl3Hmxreg/LFhmMnPv/F8Md7FfoD w+7w== X-Forwarded-Encrypted: i=1; AKwUvBxeKVgiMDXNyUJvl3G3mBOmKHeJY/Ifa8jYhfzmNCRBfITm3idGQDsyRiSEBWMJwkyruWcicXSimEWnrJw=@vger.kernel.org X-Gm-Message-State: AFq9FYJgHJr3BWxpMhURQ2kyDUOLvos9jhVVztP0yDeb92K6fqCF27OW jL9pSIQTpFlHKVNUUK3GG1yYjaa68u0nIKMy6pfGgQCdMipcr73xMcKM X-Gm-Gg: AYBFou25kVUgdN/wharFspvuWTNRd6xPRkW0+CXvPl+1InCm4wD6cK1vhEQJDzDWBEa 4uu4xiyoWrJkhuIKKcGHytK2n6FgfuRpzexwzuPlwcncAupJAgQK4E0nHhw4Z86rKZNRt7YnSd4 /JGbFdGvJkPCnQGGOZ/aNqXZC47dK+q/6rfMKHk0JvN9kLbqeq3T3MBgmm52wmzo1JG3/SrDkCC FFH5RURKjs3w2dPrKNup7sJEISbsQ+SWvu84VQK9hLTv27NpkpG+T9nwV7EbhM0qIcUP6lfHaeJ 6NN8d0ICQ5aXck6D49UnpKfSo5hk510VnbFGcscfcPSkBmkcrIGNwQdL0Lg96Q17FIewJSuayoB XVE2VKpk82olBEkMxHyDxEQ6bWo4OsjZiQm/GLaFVi4uXawzqjNfhNHGd1bib/8jSRwk8dd/zp+ 4TLkc+rExx3c11d0BgXDOvxR7IXqwGIQGPqKEnIMWYFuTVEJoxDcT5s8geqkQ2Un5GC9ETZ7tRp xwFupyqvP+NlMNILwJ7ZryV3bDwkPj6zMO+aFBqtqGzyZXoKJlrZrf1rOI8DJqB0+nlDgxtiSHH +taPQmmpdhMzEIewXC8NZQlxXUNrsff0cltIpX+tPlP5sXfQhUbtc1jfURJP6X1PtdGUd1s3LKP 707AAHFkEWvaYssFvG075g2baLmuI+RAL56TeK4uN9ypsbPlnjp6sqBIYaLw/WL++9aVBrWxj6H +Bc5PZnabavG0/fWP4 X-Received: by 2002:a05:7300:4353:b0:369:fc93:eda5 with SMTP id 5a478bee46e88-36a42434630mr8230258eec.39.1793408824646; Fri, 30 Oct 2026 18:07:04 -0700 (PDT) Received: from brev-9gdpyq8lp.ap-south-1.compute.internal (ec2-3-110-210-194.ap-south-1.compute.amazonaws.com. [3.110.210.194]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-36a429018casm9876477eec.14.2026.10.30.18.07.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Oct 2026 18:07:04 -0700 (PDT) From: Samarth Narang To: Pierre-Yves MORDRET , Alain Volmat , Andi Shyti Cc: Maxime Coquelin , Alexandre Torgue , linux-i2c@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Samarth Narang Subject: [PATCH] i2c: stm32f7: synchronize DMA termination before releasing the buffer Date: Sat, 31 Oct 2026 01:06:58 +0000 Message-Id: <20261031010658.3366395-1-samarth.colleges@gmail.com> X-Mailer: git-send-email 2.34.1 X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit stm32f7_i2c_dma_callback() is used both as the DMA completion callback and as a cleanup helper by the threaded IRQ handlers for bus errors, arbitration loss, PEC errors, NACKs, and DMA completion timeouts. The helper calls dmaengine_terminate_async() and then immediately unmaps the DMA buffer and releases the DMA-safe message buffer through i2c_put_dma_safe_msg_buf(). On the error paths, DMA completion has not been established. dmaengine_terminate_async() only requests termination; it does not guarantee that the transfer and its callback have finished when the call returns. The DMAengine API requires synchronization before memory accessible to the descriptor is released. Although the driver calls dmaengine_synchronize() from stm32f7_i2c_xfer_core() and stm32f7_i2c_smbus_xfer(), these calls occur after the IRQ thread has already unmapped and released the buffer. They therefore cannot establish retirement before that release. If the DMA operation retains access after cleanup, a late RX write could modify freed or reused memory, while a late TX read could access data belonging to a subsequent owner. Introduce stm32f7_i2c_dma_abort() for the threaded IRQ error paths. The helper disables further peripheral DMA requests and calls dmaengine_terminate_sync() before invoking the common buffer cleanup. Since these paths execute in threaded IRQ context, synchronous termination is permitted. Remove the redundant termination request from the genuine DMA completion callback, where the descriptor has already completed. This establishes the intended ordering between DMA termination and buffer release under the DMAengine synchronous-termination contract. Fixes: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer") Fixes: ffdd20555cc6 ("i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs") Assisted-by: LLM Signed-off-by: Samarth Narang --- The issue was identified using a research static analyzer for DMA lifecycle ordering and subsequently reviewed against the driver source. It has not been reproduced on hardware. The patch has been compile-tested on arm64 with W=1. The practical exposure with the in-tree DMA providers may be narrower than the API-level ordering violation suggests. stm32-dma clears the stream enable bit and polls for it to clear, while stm32-dma3 suspends and resets the channel. However, neither behavior alone establishes that a concurrent completion callback has finished. The stm32-dma polling operation can also time out without propagating a failure through device_terminate_all(). Consequently, this change primarily corrects the driver's reliance on an asynchronous termination request as a final-retirement guarantee. A physical late write would require an outstanding access to survive the provider's shutdown behavior; that has not been demonstrated. Remaining concurrency issue: this patch does not resolve a separate, pre-existing race between genuine DMA completion and threaded IRQ error handling. If both paths invoke stm32f7_i2c_dma_callback() for the same transfer, they may both attempt to unmap and release the same buffer. Establishing a single owner for cleanup would require an additional change. drivers/i2c/busses/i2c-stm32f7.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 6bd281a9e..891b0eebe 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -736,7 +736,6 @@ static void stm32f7_i2c_dma_callback(void *arg) struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; stm32f7_i2c_disable_dma_req(i2c_dev); - dmaengine_terminate_async(dma->chan_using); dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len, dma->dma_data_dir); if (!f7_msg->smbus) @@ -744,6 +743,16 @@ static void stm32f7_i2c_dma_callback(void *arg) complete(&dma->dma_complete); } +/* Threaded IRQ context only: terminate_sync() may sleep. */ +static void stm32f7_i2c_dma_abort(struct stm32f7_i2c_dev *i2c_dev) +{ + struct stm32_i2c_dma *dma = i2c_dev->dma; + + stm32f7_i2c_disable_dma_req(i2c_dev); + dmaengine_terminate_sync(dma->chan_using); + stm32f7_i2c_dma_callback(i2c_dev); +} + static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev *i2c_dev) { struct stm32f7_i2c_timings *t = &i2c_dev->timing; @@ -1552,7 +1561,7 @@ static irqreturn_t stm32f7_i2c_handle_isr_errs(struct stm32f7_i2c_dev *i2c_dev, /* Disable dma */ if (i2c_dev->use_dma) - stm32f7_i2c_dma_callback(i2c_dev); + stm32f7_i2c_dma_abort(i2c_dev); i2c_dev->master_mode = false; complete(&i2c_dev->complete); @@ -1617,7 +1626,7 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data) __func__, f7_msg->addr); writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR); if (i2c_dev->use_dma) - stm32f7_i2c_dma_callback(i2c_dev); + stm32f7_i2c_dma_abort(i2c_dev); f7_msg->result = -ENXIO; } @@ -1635,7 +1644,7 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data) ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ); if (!ret) { dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); - stm32f7_i2c_dma_callback(i2c_dev); + stm32f7_i2c_dma_abort(i2c_dev); f7_msg->result = -ETIMEDOUT; } } base-commit: 83f32c773255720a661aa45d83e36278135f23f5 -- 2.34.1