get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2195070/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2195070,
    "url": "http://patchwork.ozlabs.org/api/patches/2195070/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260210121526.68598-7-mjt@tls.msk.ru/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260210121526.68598-7-mjt@tls.msk.ru>",
    "list_archive_url": null,
    "date": "2026-02-10T12:15:03",
    "name": "[Stable-10.1.4,81/95] hw/i2c/aspeed_i2c: Fix DMA moving data into incorrect address",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "279b42a24d0e1a375ee84eaf8db678677ca6cbd5",
    "submitter": {
        "id": 183,
        "url": "http://patchwork.ozlabs.org/api/people/183/?format=api",
        "name": "Michael Tokarev",
        "email": "mjt@tls.msk.ru"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260210121526.68598-7-mjt@tls.msk.ru/mbox/",
    "series": [
        {
            "id": 491662,
            "url": "http://patchwork.ozlabs.org/api/series/491662/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=491662",
            "date": "2026-02-10T12:14:58",
            "name": "Patch Round-up for stable 10.1.4, freeze on 2026-02-10 (frozen)",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/491662/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2195070/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2195070/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)",
        "Received": [
            "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4f9LL74cHzz1xtr\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Feb 2026 23:22:39 +1100 (AEDT)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vpmhl-0006Xj-VV; Tue, 10 Feb 2026 07:18:59 -0500",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <mjt@tls.msk.ru>)\n id 1vpmgF-00034r-63; Tue, 10 Feb 2026 07:17:25 -0500",
            "from isrv.corpit.ru ([212.248.84.144])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <mjt@tls.msk.ru>)\n id 1vpmg6-0000ju-Tg; Tue, 10 Feb 2026 07:17:18 -0500",
            "from tsrv.corpit.ru (tsrv.tls.msk.ru [192.168.177.2])\n by isrv.corpit.ru (Postfix) with ESMTP id 8CF6F187DB9;\n Tue, 10 Feb 2026 15:14:46 +0300 (MSK)",
            "from think4mjt.tls.msk.ru (mjtthink.wg.tls.msk.ru [192.168.177.146])\n by tsrv.corpit.ru (Postfix) with ESMTP id 2A7AD360CDE;\n Tue, 10 Feb 2026 15:15:42 +0300 (MSK)"
        ],
        "From": "Michael Tokarev <mjt@tls.msk.ru>",
        "To": "qemu-devel@nongnu.org",
        "Cc": "qemu-stable@nongnu.org, Jamin Lin <jamin_lin@aspeedtech.com>,\n\t=?utf-8?q?C=C3=A9dric_Le_Goater?= <clg@redhat.com>,\n Michael Tokarev <mjt@tls.msk.ru>",
        "Subject": "[Stable-10.1.4 81/95] hw/i2c/aspeed_i2c: Fix DMA moving data into\n incorrect address",
        "Date": "Tue, 10 Feb 2026 15:15:03 +0300",
        "Message-ID": "<20260210121526.68598-7-mjt@tls.msk.ru>",
        "X-Mailer": "git-send-email 2.47.3",
        "In-Reply-To": "<qemu-stable-10.1.4-20260210151454@cover.tls.msk.ru>",
        "References": "<qemu-stable-10.1.4-20260210151454@cover.tls.msk.ru>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Received-SPF": "pass client-ip=212.248.84.144; envelope-from=mjt@tls.msk.ru;\n helo=isrv.corpit.ru",
        "X-Spam_score_int": "-18",
        "X-Spam_score": "-1.9",
        "X-Spam_bar": "-",
        "X-Spam_report": "(-1.9 / 5.0 requ) BAYES_00=-1.9,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no",
        "X-Spam_action": "no action",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "qemu development <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "From: Jamin Lin <jamin_lin@aspeedtech.com>\n\nIn the previous design, the I2C model updated dma_dram_offset only when\nfirmware programmed the RX/TX DMA buffer address registers. The firmware\nused to rewrite these registers before issuing each DMA command.\n\nThe firmware driver behavior has changed to program the DMA address\nregisters only once during I2C initialization. As a result, the I2C model\nno longer refreshes dma_dram_offset, causing DMA to move data into an\nincorrect DRAM address.\n\nFix this by introducing helper functions to update dma_dram_offset from\nthe DMA address registers, and invoke them right before handling TX/RX\nDMA operations. This guarantees DMA always uses the correct buffer\naddress even if the registers are programmed only once.\n\nSigned-off-by: Jamin Lin <jamin_lin@aspeedtech.com>\nFixes: c400c38854017eeccda63115814eba4c3ef2b51f (\"hw/i2c/aspeed: Introduce a new dma_dram_offset attribute in AspeedI2Cbus\")\nReviewed-by: Cédric Le Goater <clg@redhat.com>\nLink: https://lore.kernel.org/qemu-devel/20260203020855.1642884-5-jamin_lin@aspeedtech.com\nSigned-off-by: Cédric Le Goater <clg@redhat.com>\n(cherry picked from commit efea7ddb4689a1ac4bce63a9ddb32887c7f3ac50)\nSigned-off-by: Michael Tokarev <mjt@tls.msk.ru>",
    "diff": "diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c\nindex 93b8fd1661..c48fa2050b 100644\n--- a/hw/i2c/aspeed_i2c.c\n+++ b/hw/i2c/aspeed_i2c.c\n@@ -116,8 +116,6 @@ static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,\n             value = -1;\n             break;\n         }\n-\n-        value = extract64(bus->dma_dram_offset, 0, 32);\n         break;\n     case A_I2CD_DMA_LEN:\n         if (!aic->has_dma) {\n@@ -221,6 +219,64 @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)\n     return SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CD_CMD, TX_STATE);\n }\n \n+/*\n+ * The AST2700 support the maximum DRAM size is 8 GB.\n+ * The DRAM offset range is from 0x0_0000_0000 to\n+ * 0x1_FFFF_FFFF and it is enough to use bits [33:0]\n+ * saving the dram offset.\n+ * Therefore, save the high part physical address bit[1:0]\n+ * of Tx/Rx buffer address as dma_dram_offset bit[33:32].\n+ */\n+static void aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus)\n+{\n+    AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);\n+    uint32_t value;\n+\n+    assert(aic->has_dma);\n+\n+    if (aspeed_i2c_is_new_mode(bus->controller)) {\n+        value = bus->regs[R_I2CM_DMA_TX_ADDR];\n+        bus->dma_dram_offset =\n+            deposit64(bus->dma_dram_offset, 0, 32,\n+                      FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR));\n+        if (!aic->has_dma64) {\n+            value = bus->regs[R_I2CM_DMA_TX_ADDR_HI];\n+            bus->dma_dram_offset =\n+                deposit64(bus->dma_dram_offset, 32, 32,\n+                          extract32(value, 0, 2));\n+        }\n+    } else {\n+        value = bus->regs[R_I2CD_DMA_ADDR];\n+        bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32,\n+                                         value & 0x3ffffffc);\n+    }\n+}\n+\n+static void aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus)\n+{\n+    AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);\n+    uint32_t value;\n+\n+    assert(aic->has_dma);\n+\n+    if (aspeed_i2c_is_new_mode(bus->controller)) {\n+        value = bus->regs[R_I2CM_DMA_RX_ADDR];\n+        bus->dma_dram_offset =\n+            deposit64(bus->dma_dram_offset, 0, 32,\n+                      FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR));\n+        if (!aic->has_dma64) {\n+            value = bus->regs[R_I2CM_DMA_RX_ADDR_HI];\n+            bus->dma_dram_offset =\n+                deposit64(bus->dma_dram_offset, 32, 32,\n+                          extract32(value, 0, 2));\n+        }\n+    } else {\n+        value = bus->regs[R_I2CD_DMA_ADDR];\n+        bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32,\n+                                         value & 0x3ffffffc);\n+    }\n+}\n+\n static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)\n {\n     MemTxResult result;\n@@ -270,6 +326,7 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus)\n         if (aspeed_i2c_is_new_mode(bus->controller)) {\n             ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN_STS, TX_LEN, 0);\n         }\n+        aspeed_i2c_set_tx_dma_dram_offset(bus);\n         while (bus->regs[reg_dma_len]) {\n             uint8_t data;\n             ret = aspeed_i2c_dma_read(bus, &data);\n@@ -335,6 +392,7 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)\n             ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN_STS, RX_LEN, 0);\n         }\n \n+        aspeed_i2c_set_rx_dma_dram_offset(bus);\n         while (bus->regs[reg_dma_len]) {\n             MemTxResult result;\n \n@@ -401,6 +459,7 @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)\n     } else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) {\n         uint8_t data;\n \n+        aspeed_i2c_set_tx_dma_dram_offset(bus);\n         aspeed_i2c_dma_read(bus, &data);\n         return data;\n     } else {\n@@ -657,16 +716,10 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,\n     case A_I2CM_DMA_TX_ADDR:\n         bus->regs[R_I2CM_DMA_TX_ADDR] = FIELD_EX32(value, I2CM_DMA_TX_ADDR,\n                                                    ADDR);\n-        bus->dma_dram_offset =\n-            deposit64(bus->dma_dram_offset, 0, 32,\n-                      FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR));\n         break;\n     case A_I2CM_DMA_RX_ADDR:\n         bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value, I2CM_DMA_RX_ADDR,\n                                                    ADDR);\n-        bus->dma_dram_offset =\n-            deposit64(bus->dma_dram_offset, 0, 32,\n-                      FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR));\n         break;\n     case A_I2CM_DMA_LEN:\n         w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T) ||\n@@ -748,15 +801,6 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,\n         qemu_log_mask(LOG_UNIMP, \"%s: Slave mode DMA TX is not implemented\\n\",\n                       __func__);\n         break;\n-\n-    /*\n-     * The AST2700 support the maximum DRAM size is 8 GB.\n-     * The DRAM offset range is from 0x0_0000_0000 to\n-     * 0x1_FFFF_FFFF and it is enough to use bits [33:0]\n-     * saving the dram offset.\n-     * Therefore, save the high part physical address bit[1:0]\n-     * of Tx/Rx buffer address as dma_dram_offset bit[33:32].\n-     */\n     case A_I2CM_DMA_TX_ADDR_HI:\n         if (!aic->has_dma64) {\n             qemu_log_mask(LOG_GUEST_ERROR, \"%s: No DMA 64 bits support\\n\",\n@@ -766,8 +810,6 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,\n         bus->regs[R_I2CM_DMA_TX_ADDR_HI] = FIELD_EX32(value,\n                                                       I2CM_DMA_TX_ADDR_HI,\n                                                       ADDR_HI);\n-        bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32,\n-                                         extract32(value, 0, 2));\n         break;\n     case A_I2CM_DMA_RX_ADDR_HI:\n         if (!aic->has_dma64) {\n@@ -778,8 +820,6 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,\n         bus->regs[R_I2CM_DMA_RX_ADDR_HI] = FIELD_EX32(value,\n                                                       I2CM_DMA_RX_ADDR_HI,\n                                                       ADDR_HI);\n-        bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32,\n-                                         extract32(value, 0, 2));\n         break;\n     case A_I2CS_DMA_TX_ADDR_HI:\n         qemu_log_mask(LOG_UNIMP,\n@@ -795,8 +835,6 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,\n         bus->regs[R_I2CS_DMA_RX_ADDR_HI] = FIELD_EX32(value,\n                                                       I2CS_DMA_RX_ADDR_HI,\n                                                       ADDR_HI);\n-        bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32,\n-                                         extract32(value, 0, 2));\n         break;\n     default:\n         qemu_log_mask(LOG_GUEST_ERROR, \"%s: Bad offset 0x%\" HWADDR_PRIx \"\\n\",\n@@ -887,9 +925,6 @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus *bus, hwaddr offset,\n             qemu_log_mask(LOG_GUEST_ERROR, \"%s: No DMA support\\n\",  __func__);\n             break;\n         }\n-\n-        bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32,\n-                                         value & 0x3ffffffc);\n         break;\n \n     case A_I2CD_DMA_LEN:\n",
    "prefixes": [
        "Stable-10.1.4",
        "81/95"
    ]
}