[RFC PATCH v4 13/14] PCI/TSM: Move CMA DOE mailbox discovery out of pci_tsm_pf0_constructor()

Aneesh Kumar K.V (Arm)
2026-04-27T06:52:47Z

pci_tsm_pf0_constructor() currently looks up a CMA DOE mailbox and
fails PF0 initialization when one is not present. That is too strict
for all link TSM drivers.

Move CMA DOE mailbox discovery into the low-level PF0 probe callbacks
so each driver can decide whether a mailbox is mandatory.

Keep SEV-TIO and TDX requiring a CMA mailbox, while allowing the
arm-cca host path to proceed on PF0 devices that do not support IDE
and therefore have no DOE-based SPDM path.

Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/crypto/ccp/sev-dev-tsm.c | 13 +++++++++++++
drivers/pci/tsm/core.c | 14 ++++++++------
drivers/virt/coco/arm-cca-host/arm-cca.c | 16 +++++++++++++---
drivers/virt/coco/tdx-host/tdx-host.c | 13 +++++++++++++
4 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/ccp/sev-dev-tsm.c b/drivers/crypto/ccp/sev-dev-tsm.c
index b07ae529b591..a7506cbbe392 100644
--- a/drivers/crypto/ccp/sev-dev-tsm.c
+++ b/drivers/crypto/ccp/sev-dev-tsm.c
@@ -217,6 +217,19 @@ static struct pci_tsm *tio_pf0_probe(struct pci_dev *pdev, struct sev_device *se
if (rc)
return NULL;

+ /* if device have ide cap, setup doe mailbox */
+ if (pdev->ide_cap) {
+ struct pci_doe_mb *doe_mb;
+
+ doe_mb = pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG,
+ PCI_DOE_FEATURE_CMA);
+ if (!doe_mb)
+ return NULL;
+ dsm->tsm.doe_mb = doe_mb;
+ } else {
+ return NULL;
+ }
+
pci_dbg(pdev, "TSM enabled\n");
dsm->sev = sev;
return &no_free_ptr(dsm)->tsm.base_tsm;
diff --git a/drivers/pci/tsm/core.c b/drivers/pci/tsm/core.c
index bb440135b8f7..900306a43161 100644
--- a/drivers/pci/tsm/core.c
+++ b/drivers/pci/tsm/core.c
@@ -1236,12 +1236,14 @@ int pci_tsm_pf0_constructor(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm,
struct tsm_dev *tsm_dev)
{
mutex_init(&tsm->lock);
- tsm->doe_mb = pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG,
- PCI_DOE_FEATURE_CMA);
- if (!tsm->doe_mb) {
- pci_warn(pdev, "TSM init failure, no CMA mailbox\n");
- return -ENODEV;
- }
+
+ /*
+ * Note, low-level TSM driver responsible for determining if it wants to
+ * proceed with a device that has no DOE mailbox. TSM may have an
+ * alternate method for coordinating TDISP.
+ */
+ if (!tsm->doe_mb)
+ pci_dbg(pdev, "no CMA mailbox\n");

return pci_tsm_link_constructor(pdev, &tsm->base_tsm, tsm_dev);
}
diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/arm-cca-host/arm-cca.c
index 0b1200f591ab..265aa0cb612a 100644
--- a/drivers/virt/coco/arm-cca-host/arm-cca.c
+++ b/drivers/virt/coco/arm-cca-host/arm-cca.c
@@ -11,6 +11,8 @@
#include <linux/tsm.h>
#include <linux/vmalloc.h>
#include <linux/cleanup.h>
+#include <linux/pci-doe.h>
+

#include "rmi-da.h"

@@ -35,14 +37,22 @@ static struct pci_tsm *cca_tsm_pci_probe(struct tsm_dev *tsm_dev, struct pci_dev
return &no_free_ptr(fn_dsc)->pci;
}

- if (!pdev->ide_cap)
- return NULL;
-
struct cca_host_pf0_ep_dsc *pf0_ep_dsc __free(kfree) =
kzalloc(sizeof(*pf0_ep_dsc), GFP_KERNEL);
if (!pf0_ep_dsc)
return NULL;

+ /* if device have ide cap, setup doe mailbox */
+ if (pdev->ide_cap) {
+ struct pci_doe_mb *doe_mb;
+
+ doe_mb = pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG,
+ PCI_DOE_FEATURE_CMA);
+ if (!doe_mb)
+ return NULL;
+ pf0_ep_dsc->pci.doe_mb = doe_mb;
+ }
+
ret = pci_tsm_pf0_constructor(pdev, &pf0_ep_dsc->pci, tsm_dev);
if (ret)
return NULL;
diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-host/tdx-host.c
index ea7c2167660f..4947b9bc2359 100644
--- a/drivers/virt/coco/tdx-host/tdx-host.c
+++ b/drivers/virt/coco/tdx-host/tdx-host.c
@@ -634,6 +634,19 @@ static struct pci_tsm *tdx_link_pf0_probe(struct tsm_dev *tsm_dev,
spdm_conf->vmm_spdm_cap = SPDM_CAP_KEY_UPD;
spdm_conf->certificate_slot_mask = 0xff;

+ /* if device have ide cap, setup doe mailbox */
+ if (pdev->ide_cap) {
+ struct pci_doe_mb *doe_mb;
+
+ doe_mb = pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG,
+ PCI_DOE_FEATURE_CMA);
+ if (!doe_mb)
+ return NULL;
+ tlink->pci.doe_mb = doe_mb;
+ } else {
+ return NULL;
+ }
+
tlink->in_msg = no_free_ptr(in_msg);
tlink->out_msg = no_free_ptr(out_msg);
tlink->spdm_conf = no_free_ptr(spdm_conf);
--
2.43.0