Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2217093/?format=api
{ "id": 2217093, "url": "http://patchwork.ozlabs.org/api/patches/2217093/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260327160132.2946114-31-yilun.xu@linux.intel.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260327160132.2946114-31-yilun.xu@linux.intel.com>", "list_archive_url": null, "date": "2026-03-27T16:01:31", "name": "[v2,30/31] coco/tdx-host: Implement IDE stream setup/teardown", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "b5f56f53d42b96d0f038635706c23da7df28a153", "submitter": { "id": 87470, "url": "http://patchwork.ozlabs.org/api/people/87470/?format=api", "name": "Xu Yilun", "email": "yilun.xu@linux.intel.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260327160132.2946114-31-yilun.xu@linux.intel.com/mbox/", "series": [ { "id": 497793, "url": "http://patchwork.ozlabs.org/api/series/497793/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=497793", "date": "2026-03-27T16:01:02", "name": "PCI/TSM: PCIe Link Encryption Establishment via TDX platform services", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/497793/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2217093/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2217093/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-pci+bounces-51316-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pci@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256\n header.s=Intel header.b=e4qgqw3f;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c15:e001:75::12fc:5321; helo=sin.lore.kernel.org;\n envelope-from=linux-pci+bounces-51316-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com\n header.b=\"e4qgqw3f\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=198.175.65.14", "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.intel.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=linux.intel.com" ], "Received": [ "from sin.lore.kernel.org (sin.lore.kernel.org\n [IPv6:2600:3c15:e001:75::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fj67F0Ml1z1y1P\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 28 Mar 2026 03:49:29 +1100 (AEDT)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id 83B3D3145E05\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 27 Mar 2026 16:31:00 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id DD19140822B;\n\tFri, 27 Mar 2026 16:24:25 +0000 (UTC)", "from mgamail.intel.com (mgamail.intel.com [198.175.65.14])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 62985408251;\n\tFri, 27 Mar 2026 16:24:24 +0000 (UTC)", "from fmviesa006.fm.intel.com ([10.60.135.146])\n by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 27 Mar 2026 09:24:23 -0700", "from yilunxu-optiplex-7050.sh.intel.com ([10.239.159.165])\n by fmviesa006.fm.intel.com with ESMTP; 27 Mar 2026 09:24:20 -0700" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1774628665; cv=none;\n b=jnqOxb1SJ3+qh+wY51yqHCtNAtpfOh5IVwahxPq0zE2Atb9Xbje2T93QH76ZFGGt4BLH2mXh4vSbTeudxHQCSAFMZIi8COi8LUlfDx0p23YUZbkyDLAp9esSi1bNb3OLFszYViQg/+fk9ZsZChswAktCWGjMFuJkVPjz/uM+Lqw=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1774628665; c=relaxed/simple;\n\tbh=xIsA7BZZ8qFNyEF3mVWscDtKnNs9xK0BAxYPPzQTAOk=;\n\th=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:\n\t MIME-Version;\n b=tWmNJWiQstL7yYO+/SRfGt/KqKPurn/n3+UY5D7qECzGtjp5cy8yG16JBKQIVkpBX1Pqvz3grdknPuDj6VnIRtM785EkkzoQmgLutwffd7U3gJ9UGw59qBJ0IcOTppejP9p2sNlFboGuAUtvlZTsX5PmdgcyXiRJbR1/3oEXb7g=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.intel.com;\n spf=pass smtp.mailfrom=linux.intel.com;\n dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com\n header.b=e4qgqw3f; arc=none smtp.client-ip=198.175.65.14", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1774628664; x=1806164664;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=xIsA7BZZ8qFNyEF3mVWscDtKnNs9xK0BAxYPPzQTAOk=;\n b=e4qgqw3fgNk9Nby2XC28kcadNGS46KqHuCWWVPN5xL0j3QQNI59fO9Dk\n d2cKKs9WP4IGGDuxZc/De/Pd1rEP1VgousD3OT7o7Vk9esS6Ev6M/gK2r\n SensE02Gj2cQdliFl8G0BFQLMQwdnzaEo5g9Sl2zJO3KhsWFpojnKM0VI\n b6zuVWBU4sXVC9IktH7faaTjvP8F0wuz2i3KAXjUK62rnLrMbv/ukLEG/\n tZ9e34LbVpPzn6Wt42U5qxhAeK1hEiUaI1ogwLvSmgeq09sOl7KVL1p+w\n ctMFC32U5qz1cIQb6IgDD4074lB9njjmaX/rfHA3PU05Jv6+02+lY7sqn\n A==;", "X-CSE-ConnectionGUID": [ "BRANar8lR0eWJhuCacxqZA==", "GkiPIhJKReKCyJCqLIzbsg==" ], "X-CSE-MsgGUID": [ "WOFf8RlCTf+QK1ccYTbFBg==", "D819/3SzQf23uFLusEu/Fw==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6800,10657,11741\"; a=\"79565707\"", "E=Sophos;i=\"6.23,144,1770624000\";\n d=\"scan'208\";a=\"79565707\"", "E=Sophos;i=\"6.23,144,1770624000\";\n d=\"scan'208\";a=\"220516395\"" ], "X-ExtLoop1": "1", "From": "Xu Yilun <yilun.xu@linux.intel.com>", "To": "linux-coco@lists.linux.dev,\n\tlinux-pci@vger.kernel.org,\n\tdan.j.williams@intel.com,\n\tx86@kernel.org", "Cc": "chao.gao@intel.com,\n\tdave.jiang@intel.com,\n\tbaolu.lu@linux.intel.com,\n\tyilun.xu@linux.intel.com,\n\tyilun.xu@intel.com,\n\tzhenzhong.duan@intel.com,\n\tkvm@vger.kernel.org,\n\trick.p.edgecombe@intel.com,\n\tdave.hansen@linux.intel.com,\n\tkas@kernel.org,\n\txiaoyao.li@intel.com,\n\tvishal.l.verma@intel.com,\n\tlinux-kernel@vger.kernel.org", "Subject": "[PATCH v2 30/31] coco/tdx-host: Implement IDE stream setup/teardown", "Date": "Sat, 28 Mar 2026 00:01:31 +0800", "Message-Id": "<20260327160132.2946114-31-yilun.xu@linux.intel.com>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20260327160132.2946114-1-yilun.xu@linux.intel.com>", "References": "<20260327160132.2946114-1-yilun.xu@linux.intel.com>", "Precedence": "bulk", "X-Mailing-List": "linux-pci@vger.kernel.org", "List-Id": "<linux-pci.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit" }, "content": "Implementation for a most straightforward Selective IDE stream setup.\nHard code all parameters for Stream Control Register. And no IDE Key\nRefresh support.\n\nSigned-off-by: Xu Yilun <yilun.xu@linux.intel.com>\n---\n include/linux/pci-ide.h | 2 +\n drivers/pci/ide.c | 5 +-\n drivers/virt/coco/tdx-host/tdx-host.c | 226 ++++++++++++++++++++++++++\n 3 files changed, 231 insertions(+), 2 deletions(-)", "diff": "diff --git a/include/linux/pci-ide.h b/include/linux/pci-ide.h\nindex 381a1bf22a95..f0c6975fd429 100644\n--- a/include/linux/pci-ide.h\n+++ b/include/linux/pci-ide.h\n@@ -106,6 +106,8 @@ struct pci_ide {\n void pci_ide_set_nr_streams(struct pci_host_bridge *hb, u16 nr);\n struct pci_ide_partner *pci_ide_to_settings(struct pci_dev *pdev,\n \t\t\t\t\t struct pci_ide *ide);\n+void pci_ide_stream_to_regs(struct pci_dev *pdev, struct pci_ide *ide,\n+\t\t\t struct pci_ide_regs *regs);\n struct pci_ide *pci_ide_stream_alloc(struct pci_dev *pdev);\n void pci_ide_stream_free(struct pci_ide *ide);\n int pci_ide_stream_register(struct pci_ide *ide);\ndiff --git a/drivers/pci/ide.c b/drivers/pci/ide.c\nindex b35e8aba7ecb..1337608448c2 100644\n--- a/drivers/pci/ide.c\n+++ b/drivers/pci/ide.c\n@@ -556,8 +556,8 @@ static void mem_assoc_to_regs(struct pci_bus_region *region,\n * @ide: registered IDE settings descriptor\n * @regs: output register values\n */\n-static void pci_ide_stream_to_regs(struct pci_dev *pdev, struct pci_ide *ide,\n-\t\t\t\t struct pci_ide_regs *regs)\n+void pci_ide_stream_to_regs(struct pci_dev *pdev, struct pci_ide *ide,\n+\t\t\t struct pci_ide_regs *regs)\n {\n \tstruct pci_ide_partner *settings = pci_ide_to_settings(pdev, ide);\n \tint assoc_idx = 0;\n@@ -586,6 +586,7 @@ static void pci_ide_stream_to_regs(struct pci_dev *pdev, struct pci_ide *ide,\n \n \tregs->nr_addr = assoc_idx;\n }\n+EXPORT_SYMBOL_GPL(pci_ide_stream_to_regs);\n \n /**\n * pci_ide_stream_setup() - program settings to Selective IDE Stream registers\ndiff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-host/tdx-host.c\nindex d5072a68b81a..0f6056945788 100644\n--- a/drivers/virt/coco/tdx-host/tdx-host.c\n+++ b/drivers/virt/coco/tdx-host/tdx-host.c\n@@ -72,6 +72,10 @@ struct tdx_tsm_link {\n \tstruct tdx_page_array *spdm_mt;\n \tunsigned int dev_info_size;\n \tvoid *dev_info_data;\n+\n+\tstruct pci_ide *ide;\n+\tstruct tdx_page_array *stream_mt;\n+\tunsigned int stream_id;\n };\n \n static struct tdx_tsm_link *to_tdx_tsm_link(struct pci_tsm *tsm)\n@@ -351,6 +355,219 @@ static void tdx_spdm_session_teardown(struct tdx_tsm_link *tlink)\n DEFINE_FREE(tdx_spdm_session_teardown, struct tdx_tsm_link *,\n \t if (!IS_ERR_OR_NULL(_T)) tdx_spdm_session_teardown(_T))\n \n+enum tdx_ide_stream_km_op {\n+\tTDX_IDE_STREAM_KM_SETUP = 0,\n+\tTDX_IDE_STREAM_KM_REFRESH = 1,\n+\tTDX_IDE_STREAM_KM_STOP = 2,\n+};\n+\n+static int tdx_ide_stream_km(struct tdx_tsm_link *tlink,\n+\t\t\t enum tdx_ide_stream_km_op op)\n+{\n+\tu64 r, out_msg_sz;\n+\tint ret;\n+\n+\tdo {\n+\t\tr = tdh_ide_stream_km(tlink->spdm_id, tlink->stream_id, op,\n+\t\t\t\t tlink->in_msg, tlink->out_msg,\n+\t\t\t\t &out_msg_sz);\n+\t\tret = tdx_tsm_link_event_handler(tlink, r, out_msg_sz);\n+\t} while (ret == -EAGAIN);\n+\n+\treturn ret;\n+}\n+\n+static struct tdx_tsm_link *\n+tdx_ide_stream_key_program(struct tdx_tsm_link *tlink)\n+{\n+\tint ret;\n+\n+\tret = tdx_ide_stream_km(tlink, TDX_IDE_STREAM_KM_SETUP);\n+\tif (ret)\n+\t\treturn ERR_PTR(ret);\n+\n+\treturn tlink;\n+}\n+\n+static void tdx_ide_stream_key_stop(struct tdx_tsm_link *tlink)\n+{\n+\ttdx_ide_stream_km(tlink, TDX_IDE_STREAM_KM_STOP);\n+}\n+\n+DEFINE_FREE(tdx_ide_stream_key_stop, struct tdx_tsm_link *,\n+\t if (!IS_ERR_OR_NULL(_T)) tdx_ide_stream_key_stop(_T))\n+\n+static void sel_stream_block_regs(struct pci_dev *pdev, struct pci_ide *ide,\n+\t\t\t\t struct pci_ide_regs *regs)\n+{\n+\tstruct pci_dev *rp = pcie_find_root_port(pdev);\n+\tstruct pci_ide_partner *setting = pci_ide_to_settings(rp, ide);\n+\n+\t/* only support address association for prefetchable memory */\n+\tsetting->mem_assoc = (struct pci_bus_region) { 0, -1 };\n+\tpci_ide_stream_to_regs(rp, ide, regs);\n+}\n+\n+#define STREAM_INFO_RP_DEVFN\t\tGENMASK_ULL(7, 0)\n+#define STREAM_INFO_TYPE\t\tBIT_ULL(8)\n+#define STREAM_INFO_TYPE_LINK\t\t0\n+#define STREAM_INFO_TYPE_SEL\t\t1\n+\n+static struct tdx_tsm_link *tdx_ide_stream_create(struct tdx_tsm_link *tlink,\n+\t\t\t\t\t\t struct pci_ide *ide)\n+{\n+\tu64 stream_info, stream_ctrl;\n+\tu64 stream_id, rp_ide_id;\n+\tunsigned int nr_pages = tdx_sysinfo->connect.ide_mt_page_count;\n+\tstruct pci_dev *pdev = tlink->pci.base_tsm.pdev;\n+\tstruct pci_dev *rp = pcie_find_root_port(pdev);\n+\tstruct pci_ide_regs regs;\n+\tu64 r;\n+\n+\tstruct tdx_page_array *stream_mt __free(tdx_page_array_free) =\n+\t\ttdx_page_array_create(nr_pages);\n+\tif (!stream_mt)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\tstream_info = FIELD_PREP(STREAM_INFO_RP_DEVFN, rp->devfn);\n+\tstream_info |= FIELD_PREP(STREAM_INFO_TYPE, STREAM_INFO_TYPE_SEL);\n+\n+\t/*\n+\t * For Selective IDE stream, below values must be 0:\n+\t * NPR_AGG/PR_AGG/CPL_AGG/CONF_REQ/ALGO/DEFAULT/STREAM_ID\n+\t *\n+\t * below values are configurable but now hardcode to 0:\n+\t * PCRC/TC\n+\t */\n+\tstream_ctrl = FIELD_PREP(PCI_IDE_SEL_CTL_EN, 0) |\n+\t\t FIELD_PREP(PCI_IDE_SEL_CTL_TX_AGGR_NPR, 0) |\n+\t\t FIELD_PREP(PCI_IDE_SEL_CTL_TX_AGGR_PR, 0) |\n+\t\t FIELD_PREP(PCI_IDE_SEL_CTL_TX_AGGR_CPL, 0) |\n+\t\t FIELD_PREP(PCI_IDE_SEL_CTL_PCRC_EN, 0) |\n+\t\t FIELD_PREP(PCI_IDE_SEL_CTL_CFG_EN, 0) |\n+\t\t FIELD_PREP(PCI_IDE_SEL_CTL_ALG, 0) |\n+\t\t FIELD_PREP(PCI_IDE_SEL_CTL_TC, 0) |\n+\t\t FIELD_PREP(PCI_IDE_SEL_CTL_ID, 0);\n+\n+\tsel_stream_block_regs(pdev, ide, ®s);\n+\tif (regs.nr_addr != 1)\n+\t\treturn ERR_PTR(-EFAULT);\n+\n+\tr = tdh_ide_stream_create(stream_info, tlink->spdm_id,\n+\t\t\t\t stream_mt, stream_ctrl,\n+\t\t\t\t regs.rid1, regs.rid2, regs.addr[0].assoc1,\n+\t\t\t\t regs.addr[0].assoc2, regs.addr[0].assoc3,\n+\t\t\t\t &stream_id, &rp_ide_id);\n+\tif (r)\n+\t\treturn ERR_PTR(-EFAULT);\n+\n+\ttlink->stream_id = stream_id;\n+\ttlink->stream_mt = no_free_ptr(stream_mt);\n+\n+\tpci_dbg(pdev, \"%s stream id 0x%x rp ide_id 0x%llx\\n\", __func__,\n+\t\ttlink->stream_id, rp_ide_id);\n+\treturn tlink;\n+}\n+\n+static void tdx_ide_stream_delete(struct tdx_tsm_link *tlink)\n+{\n+\tstruct pci_dev *pdev = tlink->pci.base_tsm.pdev;\n+\tunsigned int nr_released;\n+\tu64 released_hpa, r;\n+\n+\tr = tdh_ide_stream_block(tlink->spdm_id, tlink->stream_id);\n+\tif (r) {\n+\t\tpci_err(pdev, \"ide stream block fail 0x%llx\\n\", r);\n+\t\tgoto leak;\n+\t}\n+\n+\tr = tdh_ide_stream_delete(tlink->spdm_id, tlink->stream_id,\n+\t\t\t\t tlink->stream_mt, &nr_released,\n+\t\t\t\t &released_hpa);\n+\tif (r) {\n+\t\tpci_err(pdev, \"ide stream delete fail 0x%llx\\n\", r);\n+\t\tgoto leak;\n+\t}\n+\n+\tif (tdx_page_array_ctrl_release(tlink->stream_mt, nr_released,\n+\t\t\t\t\treleased_hpa)) {\n+\t\tpci_err(pdev, \"fail to release IDE stream_mt pages\\n\");\n+\t\tgoto leak;\n+\t}\n+\n+\treturn;\n+\n+leak:\n+\ttdx_page_array_ctrl_leak(tlink->stream_mt);\n+}\n+\n+DEFINE_FREE(tdx_ide_stream_delete, struct tdx_tsm_link *,\n+\t if (!IS_ERR_OR_NULL(_T)) tdx_ide_stream_delete(_T))\n+\n+static struct tdx_tsm_link *tdx_ide_stream_setup(struct tdx_tsm_link *tlink)\n+{\n+\tstruct pci_dev *pdev = tlink->pci.base_tsm.pdev;\n+\tint ret;\n+\n+\tstruct pci_ide *ide __free(pci_ide_stream_release) =\n+\t\tpci_ide_stream_alloc(pdev);\n+\tif (!ide)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\t/* Configure IDE capability for RP & get stream_id */\n+\tstruct tdx_tsm_link *tlink_create __free(tdx_ide_stream_delete) =\n+\t\ttdx_ide_stream_create(tlink, ide);\n+\tif (IS_ERR(tlink_create))\n+\t\treturn tlink_create;\n+\n+\tide->stream_id = tlink->stream_id;\n+\tret = pci_ide_stream_register(ide);\n+\tif (ret)\n+\t\treturn ERR_PTR(ret);\n+\n+\t/*\n+\t * Configure IDE capability for target device\n+\t *\n+\t * Some test devices work only with DEFAULT_STREAM enabled. For\n+\t * simplicity, enable DEFAULT_STREAM for all devices. A future decent\n+\t * solution may be to have a quirk table to specify which devices need\n+\t * DEFAULT_STREAM.\n+\t */\n+\tide->partner[PCI_IDE_EP].default_stream = 1;\n+\tpci_ide_stream_setup(pdev, ide);\n+\n+\t/* Key Programming for RP & target device, enable IDE stream for RP */\n+\tstruct tdx_tsm_link *tlink_program __free(tdx_ide_stream_key_stop) =\n+\t\ttdx_ide_stream_key_program(tlink);\n+\tif (IS_ERR(tlink_program))\n+\t\treturn tlink_program;\n+\n+\tret = tsm_ide_stream_register(ide);\n+\tif (ret)\n+\t\treturn ERR_PTR(ret);\n+\n+\t/* Enable IDE stream for target device */\n+\tret = pci_ide_stream_enable(pdev, ide);\n+\tif (ret)\n+\t\treturn ERR_PTR(ret);\n+\n+\tretain_and_null_ptr(tlink_create);\n+\tretain_and_null_ptr(tlink_program);\n+\ttlink->ide = no_free_ptr(ide);\n+\n+\treturn tlink;\n+}\n+\n+static void tdx_ide_stream_teardown(struct tdx_tsm_link *tlink)\n+{\n+\ttdx_ide_stream_key_stop(tlink);\n+\ttdx_ide_stream_delete(tlink);\n+\tpci_ide_stream_release(tlink->ide);\n+}\n+\n+DEFINE_FREE(tdx_ide_stream_teardown, struct tdx_tsm_link *,\n+\t if (!IS_ERR_OR_NULL(_T)) tdx_ide_stream_teardown(_T))\n+\n static int tdx_tsm_link_connect(struct pci_dev *pdev)\n {\n \tstruct tdx_tsm_link *tlink = to_tdx_tsm_link(pdev->tsm);\n@@ -362,7 +579,15 @@ static int tdx_tsm_link_connect(struct pci_dev *pdev)\n \t\treturn PTR_ERR(tlink_spdm);\n \t}\n \n+\tstruct tdx_tsm_link *tlink_ide __free(tdx_ide_stream_teardown) =\n+\t\ttdx_ide_stream_setup(tlink);\n+\tif (IS_ERR(tlink_ide)) {\n+\t\tpci_err(pdev, \"fail to setup ide stream\\n\");\n+\t\treturn PTR_ERR(tlink_ide);\n+\t}\n+\n \tretain_and_null_ptr(tlink_spdm);\n+\tretain_and_null_ptr(tlink_ide);\n \n \treturn 0;\n }\n@@ -371,6 +596,7 @@ static void tdx_tsm_link_disconnect(struct pci_dev *pdev)\n {\n \tstruct tdx_tsm_link *tlink = to_tdx_tsm_link(pdev->tsm);\n \n+\ttdx_ide_stream_teardown(tlink);\n \ttdx_spdm_session_teardown(tlink);\n }\n \n", "prefixes": [ "v2", "30/31" ] }