Re: [RFC PATCH v4 09/11] coco: guest: arm64: Hook TSM accept to Realm TDISP RUN transition

Kameron Carr <[email protected]>
Newsgroups org.infradead.lists.linux-arm-kernel,dev.linux.lists.kvmarm,dev.linux.lists.linux-coco,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 4/27/2026 1:28 AM, Aneesh Kumar K.V (Arm) wrote:
> Add an accept callback in pci_tsm_ops and implement cca_device_accept() to:
> - verify evidence generation (lock_nonce)
> - allocate and register protected MMIO ranges
> - transition TDI state to RUN
> 
> Reviewed-by: Jonathan Cameron <[email protected]>
> Signed-off-by: Aneesh Kumar K.V (Arm) <[email protected]>
> ---
>  drivers/virt/coco/arm-cca-guest/arm-cca.c | 20 +++++++++++
>  drivers/virt/coco/arm-cca-guest/rsi-da.c  | 43 +++++++++++++++++++++++
>  drivers/virt/coco/arm-cca-guest/rsi-da.h  |  1 +
>  3 files changed, 64 insertions(+)
> 
> diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/arm-cca-guest/arm-cca.c
> index 320dd5aa7b9a..b29b3948a454 100644
> --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c
> +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c
> @@ -499,9 +499,29 @@ static void cca_tsm_unlock(struct pci_tsm *tsm)
>  	kfree(cca_dsc);
>  }
>  
> +static int __cca_tsm_accept(struct pci_dev *pdev, unsigned long lock_nonce)
> +{
> +	int ret;
> +
> +	ret = cca_device_accept(pdev, lock_nonce);
> +	if (ret) {
> +		pci_err(pdev, "failed to transition the device to run state (%d)\n", ret);
> +		return ret;
> +	}
> +	return 0;
> +}
> +
> +static int cca_tsm_accept(struct pci_dev *pdev)
> +{
> +	struct cca_guest_dsc *dsc = to_cca_guest_dsc(pdev);
> +
> +	return __cca_tsm_accept(pdev, dsc->dev_info.lock_nonce);
> +}
> +
>  static struct pci_tsm_ops cca_devsec_pci_ops = {
>  	.lock = cca_tsm_lock,
>  	.unlock = cca_tsm_unlock,
> +	.accept	 = cca_tsm_accept,
>  };
>  
>  static void cca_devsec_tsm_remove(void *tsm_dev)
> diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/arm-cca-guest/rsi-da.c
> index 039138768f8f..7c2b28fa43a1 100644
> --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c
> +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c
> @@ -230,3 +230,46 @@ int cca_verify_digests(u64 hash_algo,
>  	}
>  	return 0;
>  }
> +
> +int cca_device_accept(struct pci_dev *pdev, unsigned long lock_nonce)
> +{
> +	int ret;
> +	struct cca_guest_dsc *dsc = to_cca_guest_dsc(pdev);
> +
> +	if (lock_nonce != dsc->dev_info.lock_nonce) {
> +		pci_err(pdev, "Device evidence generation mismatch\n");
> +		return -EIO;
> +	}
> +
> +	/* Allocation private mmio range based on interface report. */
> +	struct pci_tsm_mmio *tsm_mmio __free(kfree) = pci_tsm_mmio_alloc(pdev);
> +	if (!tsm_mmio) {
> +		pci_err(pdev, "Protected mmio range allocation failure\n");
> +		return -ENOMEM;
> +	}
> +
> +	/*
> +	 * Present the private mmio range in the resource hierarchy.
> +	 * We don't use this for ioremap, ioremap check the RIPAS value.
> +	 */
> +	ret = pci_tsm_mmio_setup(pdev, tsm_mmio);
> +	if (ret) {
> +		pci_err(pdev, "Protected mmio setup failure\n");
> +		return ret;
> +	}
> +
> +	ret = cca_map_evidence_report_range(pdev, tsm_mmio);
> +	if (ret) {
> +		pci_err(pdev, "failed to validate the interface report\n");
> +		return ret;
> +	}
> +
> +	ret = rhi_vdev_set_tdi_state(pdev, RHI_DA_TDI_CONFIG_RUN);
> +	if (ret) {
> +		pci_err(pdev, "failed to switch the device (%u) to RUN state\n", ret);
> +		return ret;
> +	}

After calling pci_tsm_mmio_setup() we have mappings from insert_resource()
then failures from later return codes never call mmio_teardown() so
remove_resource() is never called, only kfree on the tsm_mmio.

Likewise after cca_map_evidence_report_range() the mmio entry memory ranges
have state RIPAS_DEV. Later failures never restore RIPAS_EMPTY.

Could clean up be handled better? Is there a reason these failures don't
have a rollback path?

Regards,
Kameron

> +
> +	dsc->pci.mmio = no_free_ptr(tsm_mmio);
> +	return 0;
> +}
> diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/arm-cca-guest/rsi-da.h
> index 07a044d3e335..eeb049d374c5 100644
> --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h
> +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h
> @@ -61,5 +61,6 @@ int cca_verify_digests(u64 hash_algo,
>  		uint8_t *interface_report, size_t interface_report_size,
>  		uint8_t *measurements, size_t measurements_size,
>  		struct rsi_vdevice_info *dev_info);
> +int cca_device_accept(struct pci_dev *pdev, unsigned long lock_nonce);
>  
>  #endif
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.