Re: [RFC PATCH 09/15] virt: tdx-guest: Capture the TDI report during device lock
From: Xiaoyao Li
Date: Mon Oct 26 2026 - 01:04:55 EST
On 9/24/2026 12:10 PM, Zhenzhong Duan wrote:
> Retrieve the Trusted Device Interface report through
> TDCM_OP_GET_TDI_REPORT after binding the device.
>
> Store the report in the PCI TSM device evidence object and free it
> during device unlock.
It doesn't talk about why the report is needed, and why it needs to be stored in
the evidence object.
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx>
> ---
> drivers/virt/coco/tdx-guest/connect.c | 45 +++++++++++++++++++++++++++
> 1 file changed, 45 insertions(+)
>
> diff --git a/drivers/virt/coco/tdx-guest/connect.c b/drivers/virt/coco/tdx-guest/connect.c
> index e36515fc43ef..d5934e8c0089 100644
> --- a/drivers/virt/coco/tdx-guest/connect.c
> +++ b/drivers/virt/coco/tdx-guest/connect.c
> @@ -217,8 +217,35 @@ static int tdx_tdi_read_state(struct tdx_devsec *tdevsec, u8 *state)
> return ret;
> }
>
> +static u8 *tdx_tdi_get_report(struct tdx_devsec *tdevsec, u32 *report_sz)
> +{
> + struct pci_dev *pdev = tdevsec->pci.base_tsm.pdev;
> + u8 *report;
> + int ret;
> +
> + struct tdcm_ctx *tdcm __free(tdx_tdcm_free) =
> + tdx_tdcm_alloc(pdev, TDCM_OP_GET_TDI_REPORT, 0, MAX_TDI_REPORT_SIZE);
> + if (IS_ERR(tdcm))
> + return ERR_CAST(tdcm);
> +
> + ret = tdx_tdcm_run(tdcm);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + report = kmemdup(to_tdcm_rsp_data(tdcm), tdcm->rsp_data_sz, GFP_KERNEL);
> + if (!report)
> + return ERR_PTR(-ENOMEM);
> +
> + *report_sz = tdcm->rsp_data_sz;
> + print_hex_dump_debug("tdi_report: ", DUMP_PREFIX_OFFSET, 16, 1, report, *report_sz, false);
> + return report;
> +}
> +
> static struct pci_tsm *tdx_devsec_lock(struct tsm_dev *tsm_dev, struct pci_dev *pdev)
> {
> + struct device_evidence_object *tsm_report;
> + struct device_evidence *evidence;
> + u32 report_sz;
> u8 state;
> int ret;
>
> @@ -237,6 +264,10 @@ static struct pci_tsm *tdx_devsec_lock(struct tsm_dev *tsm_dev, struct pci_dev *
> if (IS_ERR(tdevsec_bind))
> return ERR_CAST(tdevsec_bind);
>
> + u8 *report __free(kfree) = tdx_tdi_get_report(tdevsec, &report_sz);
> + if (IS_ERR(report))
> + return ERR_CAST(report);
> +
> ret = tdx_tdi_read_state(tdevsec, &state);
> if (ret)
> return ERR_PTR(ret);
> @@ -244,6 +275,17 @@ static struct pci_tsm *tdx_devsec_lock(struct tsm_dev *tsm_dev, struct pci_dev *
> if (state != TDI_STATE_CONFIG_LOCKED)
> return ERR_PTR(-EIO);
>
> + evidence = device_evidence_create(0, HASH_ALGO_SHA384);
> +
> + if (!evidence)
> + return ERR_PTR(-ENOMEM);
> +
> + tsm_report = &evidence->obj[DEVICE_EVIDENCE_TYPE_REPORT];
> + tsm_report->data = no_free_ptr(report);
> + tsm_report->len = report_sz;
it looks better if TSM evidence sub system can provide some helper instead of
manually operating on the obj. But this is not the problem of this patch.
> +
> + tdevsec->pci.base_tsm.evidence = evidence;
> +
> retain_and_null_ptr(tdevsec_bind);
>
> return &no_free_ptr(tdevsec)->pci.base_tsm;
> @@ -252,10 +294,13 @@ static struct pci_tsm *tdx_devsec_lock(struct tsm_dev *tsm_dev, struct pci_dev *
> static void tdx_devsec_unlock(struct pci_tsm *tsm)
> {
> struct tdx_devsec *tdevsec = to_tdx_devsec(tsm);
> + struct device_evidence *evidence = tsm->evidence;
>
> if (WARN_ON(tdx_tdi_unbind_dev(tdevsec)))
> return;
>
> + kfree(evidence->obj[DEVICE_EVIDENCE_TYPE_REPORT].data);
> + kfree(evidence);
> kfree(tdevsec);
> }
>