From: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
To: Dan Williams <dan.j.williams@intel.com>,
linux-coco@lists.linux.dev, linux-pci@vger.kernel.org
Cc: gregkh@linuxfoundation.org, bhelgaas@google.com,
yilun.xu@linux.intel.com, aik@amd.com
Subject: Re: [PATCH 1/7] PCI/TSM: Add pci_tsm_{bind,unbind}() methods for instantiating TDIs
Date: Tue, 02 Sep 2025 20:35:50 +0530 [thread overview]
Message-ID: <yq5a7byg3ne9.fsf@kernel.org> (raw)
In-Reply-To: <20250827035259.1356758-2-dan.j.williams@intel.com>
Dan Williams <dan.j.williams@intel.com> writes:
> After a PCIe device has established a secure link and session between a TEE
> Security Manager (TSM) and its local Device Security Manager (DSM), the
> device or its subfunctions are candidates to be bound to a private memory
> context, a TVM. A PCIe device function interface assigned to a TVM is a TEE
> Device Interface (TDI).
>
> The pci_tsm_bind() requests the low-level TSM driver to associate the
> device with private MMIO and private IOMMU context resources of a given TVM
> represented by a @kvm argument. A device in the bound state corresponds to
> the TDISP protocol LOCKED state and awaits validation by the TVM. It is a
> 'struct pci_tsm_link_ops' operation because, similar to IDE establishment,
> it involves host side resource establishment and context setup on behalf of
> the guest. It is also expected to be performed lazily to allow for
> operation of the device in non-confidential "shared" context for pre-lock
> configuration.
>
> Co-developed-by: Xu Yilun <yilun.xu@linux.intel.com>
> Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/pci/tsm.c | 95 +++++++++++++++++++++++++++++++++++++++++
> include/linux/pci-tsm.h | 30 +++++++++++++
> 2 files changed, 125 insertions(+)
>
> diff --git a/drivers/pci/tsm.c b/drivers/pci/tsm.c
> index 092e81c5208c..302a974f3632 100644
> --- a/drivers/pci/tsm.c
> +++ b/drivers/pci/tsm.c
> @@ -251,6 +251,99 @@ static int remove_fn(struct pci_dev *pdev, void *data)
> return 0;
> }
>
> +/*
> + * Note, this helper only returns an error code and takes an argument for
> + * compatibility with the pci_walk_bus() callback prototype. pci_tsm_unbind()
> + * always succeeds.
> + */
> +static int __pci_tsm_unbind(struct pci_dev *pdev, void *data)
> +{
> + struct pci_tdi *tdi;
> + struct pci_tsm_pf0 *tsm_pf0;
> +
> + lockdep_assert_held(&pci_tsm_rwsem);
> +
> + if (!pdev->tsm)
> + return 0;
> +
> + tsm_pf0 = to_pci_tsm_pf0(pdev->tsm);
> + guard(mutex)(&tsm_pf0->lock);
> +
> + tdi = pdev->tsm->tdi;
> + if (!tdi)
> + return 0;
> +
> + pdev->tsm->ops->unbind(tdi);
> + pdev->tsm->tdi = NULL;
> +
> + return 0;
> +}
> +
> +void pci_tsm_unbind(struct pci_dev *pdev)
> +{
> + guard(rwsem_read)(&pci_tsm_rwsem);
> + __pci_tsm_unbind(pdev, NULL);
> +}
> +EXPORT_SYMBOL_GPL(pci_tsm_unbind);
> +
> +/**
> + * pci_tsm_bind() - Bind @pdev as a TDI for @kvm
> + * @pdev: PCI device function to bind
> + * @kvm: Private memory attach context
> + * @tdi_id: Identifier (virtual BDF) for the TDI as referenced by the TSM and DSM
> + *
> + * Returns 0 on success, or a negative error code on failure.
> + *
> + * Context: Caller is responsible for constraining the bind lifetime to the
> + * registered state of the device. For example, pci_tsm_bind() /
> + * pci_tsm_unbind() limited to the VFIO driver bound state of the device.
> + */
> +int pci_tsm_bind(struct pci_dev *pdev, struct kvm *kvm, u32 tdi_id)
> +{
> + const struct pci_tsm_ops *ops;
> + struct pci_tsm_pf0 *tsm_pf0;
> + struct pci_tdi *tdi;
> +
> + if (!kvm)
> + return -EINVAL;
> +
> + guard(rwsem_read)(&pci_tsm_rwsem);
> +
> + if (!pdev->tsm)
> + return -EINVAL;
> +
> + ops = pdev->tsm->ops;
> +
> + if (!is_link_tsm(ops->owner))
> + return -ENXIO;
> +
> + tsm_pf0 = to_pci_tsm_pf0(pdev->tsm);
> + guard(mutex)(&tsm_pf0->lock);
> +
> + /* Resolve races to bind a TDI */
> + if (pdev->tsm->tdi) {
> + if (pdev->tsm->tdi->kvm == kvm)
> + return 0;
> + else
> + return -EBUSY;
> + }
> +
> + tdi = ops->bind(pdev, kvm, tdi_id);
> + if (IS_ERR(tdi))
> + return PTR_ERR(tdi);
> +
> + pdev->tsm->tdi = tdi;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(pci_tsm_bind);
> +
> +static void pci_tsm_unbind_all(struct pci_dev *pdev)
> +{
> + pci_tsm_walk_fns_reverse(pdev, __pci_tsm_unbind, NULL);
> + __pci_tsm_unbind(pdev, NULL);
> +}
> +
> static void __pci_tsm_disconnect(struct pci_dev *pdev)
> {
> struct pci_tsm_pf0 *tsm_pf0 = to_pci_tsm_pf0(pdev->tsm);
> @@ -259,6 +352,8 @@ static void __pci_tsm_disconnect(struct pci_dev *pdev)
> /* disconnect() mutually exclusive with subfunction pci_tsm_init() */
> lockdep_assert_held_write(&pci_tsm_rwsem);
>
> + pci_tsm_unbind_all(pdev);
> +
> /*
> * disconnect() is uninterruptible as it may be called for device
> * teardown
> diff --git a/include/linux/pci-tsm.h b/include/linux/pci-tsm.h
> index e4f9ea4a54a9..337b566adfc5 100644
> --- a/include/linux/pci-tsm.h
> +++ b/include/linux/pci-tsm.h
> @@ -5,6 +5,8 @@
> #include <linux/pci.h>
>
> struct pci_tsm;
> +struct kvm;
> +enum pci_tsm_req_scope;
>
> /*
> * struct pci_tsm_ops - manage confidential links and security state
> @@ -29,18 +31,25 @@ struct pci_tsm_ops {
> * @connect: establish / validate a secure connection (e.g. IDE)
> * with the device
> * @disconnect: teardown the secure link
> + * @bind: bind a TDI in preparation for it to be accepted by a TVM
> + * @unbind: remove a TDI from secure operation with a TVM
> *
> * Context: @probe, @remove, @connect, and @disconnect run under
> * pci_tsm_rwsem held for write to sync with TSM unregistration and
> * mutual exclusion of @connect and @disconnect. @connect and
> * @disconnect additionally run under the DSM lock (struct
> * pci_tsm_pf0::lock) as well as @probe and @remove of the subfunctions.
> + * @bind and @unbind run under pci_tsm_rwsem held for read and the DSM
> + * lock.
> */
> struct_group_tagged(pci_tsm_link_ops, link_ops,
> struct pci_tsm *(*probe)(struct pci_dev *pdev);
> void (*remove)(struct pci_tsm *tsm);
> int (*connect)(struct pci_dev *pdev);
> void (*disconnect)(struct pci_dev *pdev);
> + struct pci_tdi *(*bind)(struct pci_dev *pdev,
> + struct kvm *kvm, u32 tdi_id);
> + void (*unbind)(struct pci_tdi *tdi);
> );
>
> /*
> @@ -58,10 +67,21 @@ struct pci_tsm_ops {
> struct tsm_dev *owner;
> };
>
> +/**
> + * struct pci_tdi - Core TEE I/O Device Interface (TDI) context
> + * @pdev: host side representation of guest-side TDI
> + * @kvm: TEE VM context of bound TDI
> + */
> +struct pci_tdi {
> + struct pci_dev *pdev;
> + struct kvm *kvm;
> +};
> +
> /**
> * struct pci_tsm - Core TSM context for a given PCIe endpoint
> * @pdev: Back ref to device function, distinguishes type of pci_tsm context
> * @dsm: PCI Device Security Manager for link operations on @pdev
> + * @tdi: TDI context established by the @bind link operation
> * @ops: Link Confidentiality or Device Function Security operations
> *
> * This structure is wrapped by low level TSM driver data and returned by
> @@ -77,6 +97,7 @@ struct pci_tsm_ops {
> struct pci_tsm {
> struct pci_dev *pdev;
> struct pci_dev *dsm;
> + struct pci_tdi *tdi;
> const struct pci_tsm_ops *ops;
> };
>
> @@ -131,6 +152,8 @@ int pci_tsm_link_constructor(struct pci_dev *pdev, struct pci_tsm *tsm,
> int pci_tsm_pf0_constructor(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm,
> const struct pci_tsm_ops *ops);
> void pci_tsm_pf0_destructor(struct pci_tsm_pf0 *tsm);
> +int pci_tsm_bind(struct pci_dev *pdev, struct kvm *kvm, u32 tdi_id);
> +void pci_tsm_unbind(struct pci_dev *pdev);
> #else
> static inline int pci_tsm_register(struct tsm_dev *tsm_dev)
> {
> @@ -139,5 +162,12 @@ static inline int pci_tsm_register(struct tsm_dev *tsm_dev)
> static inline void pci_tsm_unregister(struct tsm_dev *tsm_dev)
> {
> }
> +static inline int pci_tsm_bind(struct pci_dev *pdev, struct kvm *kvm, u64 tdi_id)
> +{
> + return -ENXIO;
> +}
> +static inline void pci_tsm_unbind(struct pci_dev *pdev)
> +{
> +}
> #endif
> #endif /*__PCI_TSM_H */
>
> base-commit: 4de43c0eb5d83004edf891b974371572e3815126
> --
> 2.50.1
Can we add tsm_bind/unbind so that we can call tsm function from iommufd instead of
pci specific functions like pci_tsm_bind()?
modified drivers/virt/coco/tsm-core.c
@@ -193,6 +193,24 @@ void tsm_ide_stream_unregister(struct pci_ide *ide)
}
EXPORT_SYMBOL_GPL(tsm_ide_stream_unregister);
+int tsm_bind(struct device *dev, struct kvm *kvm, u64 tdi_id)
+{
+ if (!dev_is_pci(dev))
+ return -EINVAL;
+
+ return pci_tsm_bind(to_pci_dev(dev), kvm, tdi_id);
+}
+EXPORT_SYMBOL_GPL(tsm_bind);
+
+int tsm_unbind(struct device *dev)
+{
+ if (!dev_is_pci(dev))
+ return -EINVAL;
+
+ return pci_tsm_unbind(to_pci_dev(dev));
+}
+EXPORT_SYMBOL_GPL(tsm_unbind);
+
static void tsm_release(struct device *dev)
{
struct tsm_dev *tsm_dev = container_of(dev, typeof(*tsm_dev), dev);
modified include/linux/tsm.h
@@ -118,6 +118,9 @@ const char *tsm_name(const struct tsm_dev *tsm_dev);
struct tsm_dev *find_tsm_dev(int id);
const struct pci_tsm_ops *tsm_pci_ops(const struct tsm_dev *tsm_dev);
struct pci_ide;
+struct kvm;
int tsm_ide_stream_register(struct pci_ide *ide);
void tsm_ide_stream_unregister(struct pci_ide *ide);
+int tsm_bind(struct device *dev, struct kvm *kvm, u64 tdi_id);
+int tsm_unbind(struct device *dev);
#endif /* __TSM_H */
next prev parent reply other threads:[~2025-09-02 15:06 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-27 3:52 [PATCH 0/7] PCI/TSM: TEE I/O infrastructure Dan Williams
2025-08-27 3:52 ` [PATCH 1/7] PCI/TSM: Add pci_tsm_{bind,unbind}() methods for instantiating TDIs Dan Williams
2025-09-02 0:12 ` Alexey Kardashevskiy
2025-09-02 15:04 ` Aneesh Kumar K.V
2025-09-10 4:47 ` dan.j.williams
2025-09-10 4:46 ` dan.j.williams
2025-09-02 15:05 ` Aneesh Kumar K.V [this message]
2025-09-10 4:50 ` dan.j.williams
2025-09-03 15:17 ` Aneesh Kumar K.V
2025-09-04 10:38 ` Alexey Kardashevskiy
2025-09-04 12:56 ` Aneesh Kumar K.V
2025-09-05 2:32 ` Alexey Kardashevskiy
2025-09-10 5:09 ` dan.j.williams
2025-08-27 3:52 ` [PATCH 2/7] PCI/TSM: Add pci_tsm_guest_req() for managing TDIs Dan Williams
2025-08-28 9:53 ` Alexey Kardashevskiy
2025-08-28 22:07 ` dan.j.williams
2025-08-29 2:21 ` Alexey Kardashevskiy
2025-08-30 2:37 ` dan.j.williams
2025-09-01 23:49 ` Alexey Kardashevskiy
2025-09-08 11:09 ` Alexey Kardashevskiy
2025-09-10 5:35 ` dan.j.williams
2025-10-10 4:48 ` Xu Yilun
2025-08-28 13:02 ` Aneesh Kumar K.V
2025-08-28 22:14 ` dan.j.williams
2025-08-27 3:52 ` [PATCH 3/7] device core: Introduce confidential device acceptance Dan Williams
2025-08-27 6:14 ` Greg KH
2025-08-28 20:07 ` dan.j.williams
2025-09-16 16:58 ` Jonathan Cameron
2025-08-27 3:52 ` [PATCH 4/7] x86/ioremap, resource: Introduce IORES_DESC_ENCRYPTED for encrypted PCI MMIO Dan Williams
2025-09-17 21:30 ` Jason Gunthorpe
2025-10-07 8:23 ` Alexey Kardashevskiy
2025-10-07 21:31 ` Alexey Kardashevskiy
2025-08-27 3:52 ` [PATCH 5/7] PCI/TSM: Add Device Security (TVM Guest) operations support Dan Williams
2025-09-03 15:22 ` Aneesh Kumar K.V
2025-09-10 5:15 ` dan.j.williams
2025-09-11 8:31 ` Aneesh Kumar K.V
2025-09-04 15:02 ` Aneesh Kumar K.V
2025-09-10 5:31 ` dan.j.williams
2025-09-16 17:10 ` Jonathan Cameron
2025-08-27 3:52 ` [PATCH 6/7] samples/devsec: Introduce a "Device Security TSM" sample driver Dan Williams
2025-08-27 12:39 ` Jason Gunthorpe
2025-08-27 23:47 ` Alexey Kardashevskiy
2025-08-28 21:38 ` dan.j.williams
2025-08-29 16:02 ` Jason Gunthorpe
2025-08-29 20:00 ` dan.j.williams
2025-08-29 23:34 ` Jason Gunthorpe
2025-08-27 3:52 ` [PATCH 7/7] tools/testing/devsec: Add a script to exercise samples/devsec/ Dan Williams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=yq5a7byg3ne9.fsf@kernel.org \
--to=aneesh.kumar@kernel.org \
--cc=aik@amd.com \
--cc=bhelgaas@google.com \
--cc=dan.j.williams@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-pci@vger.kernel.org \
--cc=yilun.xu@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.