Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2217120/?format=api
{ "id": 2217120, "url": "http://patchwork.ozlabs.org/api/patches/2217120/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260327160132.2946114-28-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-28-yilun.xu@linux.intel.com>", "list_archive_url": null, "date": "2026-03-27T16:01:28", "name": "[v2,27/31] coco/tdx-host: Implement SPDM session setup", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "4a391efc465769f2418335060ec8cb88052d5b89", "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-28-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/2217120/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2217120/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-pci+bounces-51313-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=Cqt+bNOT;\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-51313-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=\"Cqt+bNOT\"", "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 4fj6MX0fxhz1y1P\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 28 Mar 2026 04:00:08 +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 E6F5E31355EB\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 27 Mar 2026 16:30:15 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 9B6C43624BC;\n\tFri, 27 Mar 2026 16:24:15 +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 838E2405ABE;\n\tFri, 27 Mar 2026 16:24:13 +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:12 -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:09 -0700" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1774628655; cv=none;\n b=ukJZE3i8JTuDt0oKSsS4RgS2QgWxP7+ukpHBtXfvgPWDXXUjYZxoDD9hbAjjs/k/F2zmP4T3z+3kVgNl81pnPq4hQ6+G/VF7ktdg1Bl5X8uJ8a4wh/Kl8cGga2RSRQKj3r+whEw1h3YS6w8HHxDkse4aaElgbEhoY7wmDARVnjc=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1774628655; c=relaxed/simple;\n\tbh=n7uly1FuTt8IxbLUfNOG+D/wp07voqj2pWsdTiSpJ38=;\n\th=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:\n\t MIME-Version;\n b=vGvW6Opv2tSMN35PZRAi+up6U0640X0PcakMh53L4ZtG/Sl0lgnHpo8ESwaHg0M9YYTb/7LTLizxLIraKbFANVTuUYWu+afjvnN48T0T3WLXziTkHV5FAeGb+Ds6n4dzRPkJSr1ReuXkkrxqt9deDoI4MjF4AWxt/AFwof8yOps=", "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=Cqt+bNOT; 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=1774628653; x=1806164653;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=n7uly1FuTt8IxbLUfNOG+D/wp07voqj2pWsdTiSpJ38=;\n b=Cqt+bNOTRnnd9Tmk6I4IHxc35+37bRkkCWR+qHzOYRan/KR1w7l01Y2m\n QYJ28Vn0xQ3iBZq57MOGAZn1EwYrIYPcvbYVRc/fkKLhKEUAyleECqN1F\n HOQhwa43wrPtugV0OE+SMWySgL2sgGH+edz7I80bi5gmB0I7O7CxXDF8U\n 0oSHBhxTbKTowLxS1Ahems2rce0fIID5R9TAivjNnbwIgKJKv1yS5Ik+W\n +NtFC6bZr80jjjlm6ZlBdmH9HK+XXlGe6HD38WG0zlgCzwsB3MMJSB3su\n HOA4BPG8qXctniHEQAwO1s1AqjejiYDawNjeePUPnyk+4889bgHwAXkK8\n A==;", "X-CSE-ConnectionGUID": [ "rBlps5x2RVSQHXnMs+FDhw==", "JhFbTS2tRxmk9oNzW6AjMw==" ], "X-CSE-MsgGUID": [ "m653rxfnQrClpkfIVIHPzg==", "NooGNMkyRXiFbdm7LziO3w==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6800,10657,11741\"; a=\"79565678\"", "E=Sophos;i=\"6.23,144,1770624000\";\n d=\"scan'208\";a=\"79565678\"", "E=Sophos;i=\"6.23,144,1770624000\";\n d=\"scan'208\";a=\"220516373\"" ], "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 27/31] coco/tdx-host: Implement SPDM session setup", "Date": "Sat, 28 Mar 2026 00:01:28 +0800", "Message-Id": "<20260327160132.2946114-28-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": "From: Zhenzhong Duan <zhenzhong.duan@intel.com>\n\nImplementation for a most straightforward SPDM session setup, using all\ndefault session options. Retrieve device info data from TDX Module which\ncontains the SPDM negotiation results.\n\nTDH.SPDM.CONNECT/DISCONNECT are TDX Module Extension introduced\nSEAMCALLs which can run for longer periods and interruptible. But there\nis resource constraints that limit how many SEAMCALLs of this kind can\nrun simultaneously. The current situation is One SEAMCALL at a time.\nOtherwise TDX_OPERAND_BUSY is returned. To avoid \"broken indefinite\"\nretry, a tdx_ext_lock is used to guard these SEAMCALLs.\n\nCo-developed-by: Xu Yilun <yilun.xu@linux.intel.com>\nSigned-off-by: Xu Yilun <yilun.xu@linux.intel.com>\nSigned-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>\n---\n arch/x86/include/asm/shared/tdx_errno.h | 2 +\n drivers/virt/coco/tdx-host/tdx-host.c | 301 +++++++++++++++++++++++-\n 2 files changed, 299 insertions(+), 4 deletions(-)", "diff": "diff --git a/arch/x86/include/asm/shared/tdx_errno.h b/arch/x86/include/asm/shared/tdx_errno.h\nindex 8bf6765cf082..7db04fe30378 100644\n--- a/arch/x86/include/asm/shared/tdx_errno.h\n+++ b/arch/x86/include/asm/shared/tdx_errno.h\n@@ -29,6 +29,8 @@\n #define TDX_EPT_WALK_FAILED\t\t\t0xC0000B0000000000ULL\n #define TDX_EPT_ENTRY_STATE_INCORRECT\t\t0xC0000B0D00000000ULL\n #define TDX_METADATA_FIELD_NOT_READABLE\t\t0xC0000C0200000000ULL\n+#define TDX_SPDM_SESSION_KEY_REQUIRE_REFRESH\t0xC0000F4500000000ULL\n+#define TDX_SPDM_REQUEST\t\t\t0xC0000F5700000000ULL\n \n /*\n * SW-defined error codes.\ndiff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-host/tdx-host.c\nindex 06f3d194e0a8..4d127b7c2591 100644\n--- a/drivers/virt/coco/tdx-host/tdx-host.c\n+++ b/drivers/virt/coco/tdx-host/tdx-host.c\n@@ -14,6 +14,7 @@\n #include <linux/pci-doe.h>\n #include <linux/pci-tsm.h>\n #include <linux/tsm.h>\n+#include <linux/vmalloc.h>\n \n #include <asm/cpu_device_id.h>\n #include <asm/tdx.h>\n@@ -32,8 +33,43 @@ MODULE_DEVICE_TABLE(x86cpu, tdx_host_ids);\n */\n static const struct tdx_sys_info *tdx_sysinfo;\n \n+#define TDISP_FUNC_ID\t\tGENMASK(15, 0)\n+#define TDISP_FUNC_ID_SEGMENT\t\tGENMASK(23, 16)\n+#define TDISP_FUNC_ID_SEG_VALID\t\tBIT(24)\n+\n+static inline u32 tdisp_func_id(struct pci_dev *pdev)\n+{\n+\tu32 func_id;\n+\n+\tfunc_id = FIELD_PREP(TDISP_FUNC_ID_SEGMENT, pci_domain_nr(pdev->bus));\n+\tif (func_id)\n+\t\tfunc_id |= TDISP_FUNC_ID_SEG_VALID;\n+\tfunc_id |= FIELD_PREP(TDISP_FUNC_ID,\n+\t\t\t PCI_DEVID(pdev->bus->number, pdev->devfn));\n+\n+\treturn func_id;\n+}\n+\n+struct spdm_config_info_t {\n+\tu32 vmm_spdm_cap;\n+#define SPDM_CAP_HBEAT BIT(13)\n+#define SPDM_CAP_KEY_UPD BIT(14)\n+\tu8 spdm_session_policy;\n+\tu8 certificate_slot_mask;\n+\tu8 raw_bitstream_requested;\n+} __packed;\n+\n struct tdx_tsm_link {\n \tstruct pci_tsm_pf0 pci;\n+\tu32 func_id;\n+\tstruct page *in_msg;\n+\tstruct page *out_msg;\n+\n+\tu64 spdm_id;\n+\tstruct page *spdm_conf;\n+\tstruct tdx_page_array *spdm_mt;\n+\tunsigned int dev_info_size;\n+\tvoid *dev_info_data;\n };\n \n static struct tdx_tsm_link *to_tdx_tsm_link(struct pci_tsm *tsm)\n@@ -48,9 +84,9 @@ static struct tdx_tsm_link *to_tdx_tsm_link(struct pci_tsm *tsm)\n \n #define PCI_DOE_PROTOCOL_SECURE_SPDM\t\t2\n \n-static int __maybe_unused tdx_spdm_msg_exchange(struct tdx_tsm_link *tlink,\n-\t\t\t\t\t\tvoid *request, size_t request_sz,\n-\t\t\t\t\t\tvoid *response, size_t response_sz)\n+static int tdx_spdm_msg_exchange(struct tdx_tsm_link *tlink,\n+\t\t\t\t void *request, size_t request_sz,\n+\t\t\t\t void *response, size_t response_sz)\n {\n \tstruct pci_dev *pdev = tlink->pci.base_tsm.pdev;\n \tvoid *req_pl_addr, *resp_pl_addr;\n@@ -100,18 +136,246 @@ static int __maybe_unused tdx_spdm_msg_exchange(struct tdx_tsm_link *tlink,\n \treturn ret;\n }\n \n+static int tdx_spdm_session_keyupdate(struct tdx_tsm_link *tlink);\n+\n+static int tdx_tsm_link_event_handler(struct tdx_tsm_link *tlink,\n+\t\t\t\t u64 tdx_ret, u64 out_msg_sz)\n+{\n+\tint ret;\n+\n+\tif (tdx_ret == TDX_SUCCESS)\n+\t\treturn 0;\n+\n+\tif (tdx_ret == TDX_SPDM_REQUEST) {\n+\t\tret = tdx_spdm_msg_exchange(tlink,\n+\t\t\t\t\t page_address(tlink->out_msg),\n+\t\t\t\t\t out_msg_sz,\n+\t\t\t\t\t page_address(tlink->in_msg),\n+\t\t\t\t\t PAGE_SIZE);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\n+\t\treturn -EAGAIN;\n+\t}\n+\n+\tif (tdx_ret == TDX_SPDM_SESSION_KEY_REQUIRE_REFRESH) {\n+\t\t/* keyupdate won't trigger this error again, no recursion risk */\n+\t\tret = tdx_spdm_session_keyupdate(tlink);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\treturn -EAGAIN;\n+\t}\n+\n+\treturn -EFAULT;\n+}\n+\n+/*\n+ * TDX Module extension introduced SEAMCALLs work like a request queue.\n+ * The caller is responsible for grabbing a queue slot before SEAMCALL,\n+ * otherwise will fail with TDX_OPERAND_BUSY. Currently the queue depth is 1.\n+ * So a mutex could work for simplicity.\n+ */\n+static DEFINE_MUTEX(tdx_ext_lock);\n+\n+enum tdx_spdm_mng_op {\n+\tTDX_SPDM_MNG_HEARTBEAT = 0,\n+\tTDX_SPDM_MNG_KEY_UPDATE = 1,\n+\tTDX_SPDM_MNG_RECOLLECT = 2,\n+};\n+\n+static int tdx_spdm_session_mng(struct tdx_tsm_link *tlink,\n+\t\t\t\tenum tdx_spdm_mng_op op)\n+{\n+\tu64 r, out_msg_sz;\n+\tint ret;\n+\n+\tguard(mutex)(&tdx_ext_lock);\n+\tdo {\n+\t\tr = tdh_exec_spdm_mng(tlink->spdm_id, op, NULL, tlink->in_msg,\n+\t\t\t\t tlink->out_msg, NULL, &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 int tdx_spdm_session_keyupdate(struct tdx_tsm_link *tlink)\n+{\n+\treturn tdx_spdm_session_mng(tlink, TDX_SPDM_MNG_KEY_UPDATE);\n+}\n+\n+static void *tdx_dup_array_data(struct tdx_page_array *array,\n+\t\t\t\tunsigned int data_size)\n+{\n+\tunsigned int npages = (data_size + PAGE_SIZE - 1) / PAGE_SIZE;\n+\tvoid *data, *dup_data;\n+\n+\tif (npages > array->nr_pages)\n+\t\treturn NULL;\n+\n+\tdata = vm_map_ram(array->pages, npages, -1);\n+\tif (!data)\n+\t\treturn NULL;\n+\n+\tdup_data = kmemdup(data, data_size, GFP_KERNEL);\n+\tvm_unmap_ram(data, npages);\n+\n+\treturn dup_data;\n+}\n+\n+static struct tdx_tsm_link *\n+tdx_spdm_session_connect(struct tdx_tsm_link *tlink,\n+\t\t\t struct tdx_page_array *dev_info)\n+{\n+\tu64 r, out_msg_sz;\n+\tint ret;\n+\n+\tguard(mutex)(&tdx_ext_lock);\n+\tdo {\n+\t\tr = tdh_exec_spdm_connect(tlink->spdm_id, tlink->spdm_conf,\n+\t\t\t\t\t tlink->in_msg, tlink->out_msg,\n+\t\t\t\t\t dev_info, &out_msg_sz);\n+\t\tret = tdx_tsm_link_event_handler(tlink, r, out_msg_sz);\n+\t} while (ret == -EAGAIN);\n+\n+\tif (ret)\n+\t\treturn ERR_PTR(ret);\n+\n+\ttlink->dev_info_size = out_msg_sz;\n+\treturn tlink;\n+}\n+\n+static void tdx_spdm_session_disconnect(struct tdx_tsm_link *tlink)\n+{\n+\tu64 r, out_msg_sz;\n+\tint ret;\n+\n+\tguard(mutex)(&tdx_ext_lock);\n+\tdo {\n+\t\tr = tdh_exec_spdm_disconnect(tlink->spdm_id, tlink->in_msg,\n+\t\t\t\t\t tlink->out_msg, &out_msg_sz);\n+\t\tret = tdx_tsm_link_event_handler(tlink, r, out_msg_sz);\n+\t} while (ret == -EAGAIN);\n+\n+\tWARN_ON(ret);\n+}\n+\n+DEFINE_FREE(tdx_spdm_session_disconnect, struct tdx_tsm_link *,\n+\t if (!IS_ERR_OR_NULL(_T)) tdx_spdm_session_disconnect(_T))\n+\n+static struct tdx_tsm_link *tdx_spdm_create(struct tdx_tsm_link *tlink)\n+{\n+\tunsigned int nr_pages = tdx_sysinfo->connect.spdm_mt_page_count;\n+\tu64 spdm_id, r;\n+\n+\tstruct tdx_page_array *spdm_mt __free(tdx_page_array_free) =\n+\t\ttdx_page_array_create(nr_pages);\n+\tif (!spdm_mt)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\tr = tdh_spdm_create(tlink->func_id, spdm_mt, &spdm_id);\n+\tif (r)\n+\t\treturn ERR_PTR(-EFAULT);\n+\n+\ttlink->spdm_id = spdm_id;\n+\ttlink->spdm_mt = no_free_ptr(spdm_mt);\n+\treturn tlink;\n+}\n+\n+static void tdx_spdm_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_spdm_delete(tlink->spdm_id, tlink->spdm_mt, &nr_released, &released_hpa);\n+\tif (r) {\n+\t\tpci_err(pdev, \"fail to delete spdm 0x%llx\\n\", r);\n+\t\tgoto leak;\n+\t}\n+\n+\tif (tdx_page_array_ctrl_release(tlink->spdm_mt, nr_released, released_hpa)) {\n+\t\tpci_err(pdev, \"fail to release spdm_mt pages\\n\");\n+\t\tgoto leak;\n+\t}\n+\n+\treturn;\n+\n+leak:\n+\ttdx_page_array_ctrl_leak(tlink->spdm_mt);\n+}\n+\n+DEFINE_FREE(tdx_spdm_delete, struct tdx_tsm_link *, if (!IS_ERR_OR_NULL(_T)) tdx_spdm_delete(_T))\n+\n+static struct tdx_tsm_link *tdx_spdm_session_setup(struct tdx_tsm_link *tlink)\n+{\n+\tunsigned int nr_pages = tdx_sysinfo->connect.spdm_max_dev_info_pages;\n+\n+\tstruct tdx_tsm_link *tlink_create __free(tdx_spdm_delete) =\n+\t\ttdx_spdm_create(tlink);\n+\tif (IS_ERR(tlink_create))\n+\t\treturn tlink_create;\n+\n+\tstruct tdx_page_array *dev_info __free(tdx_page_array_free) =\n+\t\ttdx_page_array_create(nr_pages);\n+\tif (!dev_info)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\tstruct tdx_tsm_link *tlink_connect __free(tdx_spdm_session_disconnect) =\n+\t\ttdx_spdm_session_connect(tlink, dev_info);\n+\tif (IS_ERR(tlink_connect))\n+\t\treturn tlink_connect;\n+\n+\ttlink->dev_info_data = tdx_dup_array_data(dev_info,\n+\t\t\t\t\t\t tlink->dev_info_size);\n+\tif (!tlink->dev_info_data)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\tretain_and_null_ptr(tlink_create);\n+\tretain_and_null_ptr(tlink_connect);\n+\n+\treturn tlink;\n+}\n+\n+static void tdx_spdm_session_teardown(struct tdx_tsm_link *tlink)\n+{\n+\tkfree(tlink->dev_info_data);\n+\n+\ttdx_spdm_session_disconnect(tlink);\n+\ttdx_spdm_delete(tlink);\n+}\n+\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 static int tdx_tsm_link_connect(struct pci_dev *pdev)\n {\n-\treturn -ENXIO;\n+\tstruct tdx_tsm_link *tlink = to_tdx_tsm_link(pdev->tsm);\n+\n+\tstruct tdx_tsm_link *tlink_spdm __free(tdx_spdm_session_teardown) =\n+\t\ttdx_spdm_session_setup(tlink);\n+\tif (IS_ERR(tlink_spdm)) {\n+\t\tpci_err(pdev, \"fail to setup spdm session\\n\");\n+\t\treturn PTR_ERR(tlink_spdm);\n+\t}\n+\n+\tretain_and_null_ptr(tlink_spdm);\n+\n+\treturn 0;\n }\n \n 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_spdm_session_teardown(tlink);\n }\n \n static struct pci_tsm *tdx_tsm_link_pf0_probe(struct tsm_dev *tsm_dev,\n \t\t\t\t\t struct pci_dev *pdev)\n {\n+\tstruct spdm_config_info_t *spdm_conf;\n \tint rc;\n \n \tstruct tdx_tsm_link *tlink __free(kfree) = kzalloc_obj(*tlink);\n@@ -122,6 +386,32 @@ static struct pci_tsm *tdx_tsm_link_pf0_probe(struct tsm_dev *tsm_dev,\n \tif (rc)\n \t\treturn NULL;\n \n+\ttlink->func_id = tdisp_func_id(pdev);\n+\n+\tstruct page *in_msg_page __free(__free_page) =\n+\t\talloc_page(GFP_KERNEL | __GFP_ZERO);\n+\tif (!in_msg_page)\n+\t\treturn NULL;\n+\n+\tstruct page *out_msg_page __free(__free_page) =\n+\t\talloc_page(GFP_KERNEL | __GFP_ZERO);\n+\tif (!out_msg_page)\n+\t\treturn NULL;\n+\n+\tstruct page *spdm_conf_page __free(kfree) =\n+\t\talloc_page(GFP_KERNEL | __GFP_ZERO);\n+\tif (!spdm_conf_page)\n+\t\treturn NULL;\n+\n+\t/* use a default configuration, may require user input later */\n+\tspdm_conf = page_address(spdm_conf_page);\n+\tspdm_conf->vmm_spdm_cap = SPDM_CAP_KEY_UPD;\n+\tspdm_conf->certificate_slot_mask = 0xff;\n+\n+\ttlink->in_msg = no_free_ptr(in_msg_page);\n+\ttlink->out_msg = no_free_ptr(out_msg_page);\n+\ttlink->spdm_conf = no_free_ptr(spdm_conf_page);\n+\n \treturn &no_free_ptr(tlink)->pci.base_tsm;\n }\n \n@@ -129,6 +419,9 @@ static void tdx_tsm_link_pf0_remove(struct pci_tsm *tsm)\n {\n \tstruct tdx_tsm_link *tlink = to_tdx_tsm_link(tsm);\n \n+\t__free_page(tlink->spdm_conf);\n+\t__free_page(tlink->out_msg);\n+\t__free_page(tlink->in_msg);\n \tpci_tsm_pf0_destructor(&tlink->pci);\n \tkfree(tlink);\n }\n", "prefixes": [ "v2", "27/31" ] }