From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=198.175.65.21 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794458652; b=eZoEENXnu7/zmElG0sC33s2iGujE7Zc0vOhbT6SEEGoKTHb+AbVem8WMhTmSQ/Rr2JME kV0hwHNy66SwWcb9CNqvlWg1HZfPpR/47wZSviCgcKNylaQ6eYxIodtENjpCCGnCRN5dy cjNAYhqnKPFq1i2xzSPP3YZ4LIaOhxm0N2cNhbtUxp0h/d1bUvkdOVxe/P6JGPWaCQ9HA TR40EJKukLd5kDFqY4sTGteshh6ONZJyL8sQHibFGiZiRUAe+h5/lGyIrOjZ8LaDHakGq LFaA4s+am5g+wbb9LexVMtX/TEV6fbLiLITIq3dLVVsEWJUGCh+n6ZO35n/VsYPSOHg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794458652; h=DMARC-Filter:DKIM-Signature:X-CSE-ConnectionGUID:X-CSE-MsgGUID: X-IronPort-AV:X-IronPort-AV:Received:X-CSE-ConnectionGUID: X-CSE-MsgGUID:X-ExtLoop1:X-IronPort-AV:Received:From:To:Cc:Subject: Date:Message-ID:X-Mailer:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=OJZB/KWGVqc2T1AsmUrF/xg+bbNeF2TYlPgy84jekk8=; b=2uY8dVnCrFYYxymyKpCjbbWcCA2d0NqhZ0cCrvHMshn7Sz62HrPp3irSK7I4LTRX2b8X qcKFiBIQERTbWGxZ2Fwy8D+KaTXXsPkuhJBo4cfvyZUpVpFx96KB4hl9FfiRt7soEX3Qa cfCqItINEli17DgYhDy0BEPiUUf+n3j/q012xp8hhaYhslXaPTBcnBVyDLSaiUaD+qOm1 YRs3lTTli38Ph4DBi9E5uMwf+4fMGU5UmN74gp3rlRpn+mPDrUGaT9f8pv0IR00AfaQ4e v1DPUyg+ZeOfNRzqEkCFtykRpYYwZAofD0t2v3Aael2ef5PtvHI5Y3QGVHbmgdx7zWA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=D1kuSpqc; arc=none smtp.remote-ip=198.175.65.21 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.21]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28E76606A891; Thu, 12 Nov 2026 04:44:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 28E76606A891 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=D1kuSpqc DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1794458652; x=1825994652; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hcsXVEn81AeXzJnd7PHsl4rkkzcb2igGpk9RZpo0Rdg=; b=D1kuSpqcnl+0Doe4U3dDCNzP1HpeDC42i9scqm3MklNBNsDMoqTzuBrc DOG2IqiUO+kjhK7iecowRcxaBzcpOGy8Sk0JjcHp/CucNH/gCS7XGWLUz IKWknayCS1Rzi/g4YvHYQEAYv/NNVeunT/8fT9Ez0pDuznBe4C/sLt/AR DtPoGLQ8aJ0sqpfp49mjRWyt/cqEphDakfLlvD+15gF2PfMSOh2lX/UFJ jnKYpZ1wQurpbxGHkuz70VVEUMufSmccfpXlxqAPPwifmeed7nItNBcXg kJY9SzXnL4oNd39pOcGAVhO89xNRBSqnvmackSUzZ2o0+V032ndCgtTHV Q==; X-CSE-ConnectionGUID: T2JC0cx0SoqrBWZ/vH4Zpw== X-CSE-MsgGUID: rkwISmJrQbifJf3hX3Ao5Q== X-IronPort-AV: E=McAfee;i="6800,10657,11963"; a="3318370" X-IronPort-AV: E=Sophos;i="6.27,209,1787036400"; d="scan'208";a="3318370" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Nov 2026 20:44:12 -0800 X-CSE-ConnectionGUID: 2EU4aIJTRKSLsU32oCEL5g== X-CSE-MsgGUID: AermUxDiTtO68FmVorFxJw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,209,1787036400"; d="scan'208";a="8728667" Received: from allen-box.sh.intel.com ([10.239.48.101]) by fmviesa002.fm.intel.com with ESMTP; 11 Nov 2026 20:44:08 -0800 From: Lu Baolu To: iommu@lists.linux.dev, x86@kernel.org, linux-coco@lists.linux.dev, kvm@vger.kernel.org Cc: Jason Gunthorpe , Kevin Tian , Kiryl Shutsemau , Rick Edgecombe , yilun.xu@linux.intel.com, xiaoyao.li@intel.com, Chao Gao , Binbin Wu , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v3 7/9] coco/tdx-host: Add skeleton to support PCI link encryption Date: Thu, 12 Nov 2026 12:30:52 +0800 Message-ID: <20261112043054.2664857-8-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261112043054.2664857-1-baolu.lu@linux.intel.com> References: <20261112043054.2664857-1-baolu.lu@linux.intel.com> 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 Register a Link TSM instance to support host side TSM operations for TDISP, when the TDX Connect support bit is set by TDX Module in tdx_feature0. This is the main purpose of an independent tdx-host module out of TDX core. Recall that a TEE Security Manager (TSM) is a platform agent that speaks the TEE Device Interface Security Protocol (TDISP) to PCIe devices and manages private memory resources for the platform. An independent tdx-host module allows for device-security enumeration and initialization flows to be deferred from other TDX Module initialization requirements. Crucially, when / if TDX Module init moves earlier in x86 initialization flow this driver is still guaranteed to run after IOMMU and PCI init (i.e. subsys_initcall() vs device_initcall()). The ability to unload the module, or unbind the driver is also useful for debug and coarse grained transitioning between PCI TSM operation and PCI CMA operation (native kernel PCI device authentication). For now only check for TDX Connect support in the TDX Module and register the Link TSM. The TSM support is basic boilerplate with operation flows to be added later. Based on work by Yilun and Dan. Signed-off-by: Lu Baolu --- drivers/virt/coco/tdx-host/Kconfig | 2 + arch/x86/include/asm/tdx.h | 8 ++ drivers/virt/coco/tdx-host/tdx-host.c | 118 +++++++++++++++++++++++++- 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/drivers/virt/coco/tdx-host/Kconfig b/drivers/virt/coco/tdx-host/Kconfig index 57d0c01a4357..f8c8cc29d46c 100644 --- a/drivers/virt/coco/tdx-host/Kconfig +++ b/drivers/virt/coco/tdx-host/Kconfig @@ -1,6 +1,8 @@ config TDX_HOST_SERVICES tristate depends on INTEL_TDX_HOST + depends on PCI select FW_LOADER select FW_UPLOAD + select PCI_TSM default m diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 0ed0062c9b0a..fc284a555984 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -142,6 +142,14 @@ int tdx_topup_pamt_cache(struct tdx_pamt_cache *cache, unsigned long npages); int tdx_pamt_get(kvm_pfn_t pfn, struct tdx_pamt_cache *cache); void tdx_pamt_put(kvm_pfn_t pfn); +static inline bool tdx_supports_tdisp(const struct tdx_sys_info *sysinfo) +{ + if (!(sysinfo->features.tdx_features0 & TDX_FEATURES0_TDXCONNECT)) + return false; + + return false; /* To be enabled when kernel is ready */ +} + int tdx_guest_keyid_alloc(void); u32 tdx_get_nr_guest_keyids(void); void tdx_guest_keyid_free(unsigned int keyid); diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-host/tdx-host.c index e8ed8dfa526e..0908aaaa28ac 100644 --- a/drivers/virt/coco/tdx-host/tdx-host.c +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -9,10 +9,14 @@ #include #include #include +#include +#include +#include #include #include #include +#include static const struct x86_cpu_id tdx_host_ids[] = { X86_MATCH_FEATURE(X86_FEATURE_TDX_HOST_PLATFORM, NULL), @@ -20,6 +24,112 @@ static const struct x86_cpu_id tdx_host_ids[] = { }; MODULE_DEVICE_TABLE(x86cpu, tdx_host_ids); +struct tdx_tsm_link { + struct pci_tsm_pf0 pci; +}; + +static struct tdx_tsm_link *to_tdx_tsm_link(struct pci_tsm *tsm) +{ + return container_of(tsm, struct tdx_tsm_link, pci.base_tsm); +} + +static int tdx_tsm_link_connect(struct pci_dev *pdev) +{ + return -ENXIO; +} + +static void tdx_tsm_link_disconnect(struct pci_dev *pdev) +{ +} + +static struct pci_tsm *tdx_tsm_link_pf0_probe(struct tsm_dev *tsm_dev, + struct pci_dev *pdev) +{ + int rc; + + struct tdx_tsm_link *tlink __free(kfree) = kzalloc_obj(*tlink); + if (!tlink) + return NULL; + + rc = pci_tsm_pf0_constructor(pdev, &tlink->pci, tsm_dev); + if (rc) + return NULL; + + return &no_free_ptr(tlink)->pci.base_tsm; +} + +static void tdx_tsm_link_pf0_remove(struct pci_tsm *tsm) +{ + struct tdx_tsm_link *tlink = to_tdx_tsm_link(tsm); + + pci_tsm_pf0_destructor(&tlink->pci); + kfree(tlink); +} + +static struct pci_tsm *tdx_tsm_link_fn_probe(struct tsm_dev *tsm_dev, + struct pci_dev *pdev) +{ + int rc; + + struct pci_tsm *pci_tsm __free(kfree) = kzalloc_obj(*pci_tsm); + if (!pci_tsm) + return NULL; + + rc = pci_tsm_link_constructor(pdev, pci_tsm, tsm_dev); + if (rc) + return NULL; + + return no_free_ptr(pci_tsm); +} + +static struct pci_tsm *tdx_tsm_link_probe(struct tsm_dev *tsm_dev, + struct pci_dev *pdev) +{ + if (is_pci_tsm_pf0(pdev)) + return tdx_tsm_link_pf0_probe(tsm_dev, pdev); + + return tdx_tsm_link_fn_probe(tsm_dev, pdev); +} + +static void tdx_tsm_link_remove(struct pci_tsm *tsm) +{ + if (is_pci_tsm_pf0(tsm->pdev)) { + tdx_tsm_link_pf0_remove(tsm); + return; + } + + /* for sub-functions */ + kfree(tsm); +} + +static struct pci_tsm_ops tdx_tsm_link_ops = { + .probe = tdx_tsm_link_probe, + .remove = tdx_tsm_link_remove, + .connect = tdx_tsm_link_connect, + .disconnect = tdx_tsm_link_disconnect, +}; + +static void unregister_link_tsm(void *link) +{ + tsm_unregister(link); +} + +static int tdx_tdisp_init(struct device *dev) +{ + const struct tdx_sys_info *sysinfo = tdx_get_sysinfo(); + struct tsm_dev *link; + + if (!sysinfo || !tdx_supports_tdisp(sysinfo)) + return 0; + + link = tsm_register(dev, &tdx_tsm_link_ops); + if (IS_ERR(link)) + return dev_err_probe(dev, PTR_ERR(link), + "failed to register TSM\n"); + + return devm_add_action_or_reset(dev, unregister_link_tsm, link); +} + static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -204,7 +314,13 @@ static int seamldr_init(struct device *dev) static int tdx_host_probe(struct faux_device *fdev) { - return seamldr_init(&fdev->dev); + int ret; + + ret = seamldr_init(&fdev->dev); + if (ret) + return ret; + + return tdx_tdisp_init(&fdev->dev); } static const struct faux_device_ops tdx_host_ops = { -- 2.43.0