[RFC PATCH v4 03/16] iommu/arm-smmu-v3: Add initial pSMMU realm viommu plumbing

Jason Gunthorpe jgg at ziepe.ca
Wed Sep 2 05:17:00 PDT 2026


On Wed, Sep 02, 2026 at 02:30:00PM +0530, Aneesh Kumar K.V wrote:
> Jason Gunthorpe <jgg at ziepe.ca> writes:
> 
> > On Tue, Sep 01, 2026 at 03:36:37PM +0530, Aneesh Kumar K.V wrote:
> >
> >> @@ -463,14 +460,13 @@
> >>  	vsmmu->vmid = s2_parent->s2_cfg.vmid;
> >>  
> >>  	if (viommu->type == IOMMU_VIOMMU_TYPE_ARM_SMMUV3) {
> >> +		if (arm_smmu_is_realm_viommu(viommu))
> >> +			return arm_realm_smmu_v3_init(viommu, user_data);
> >> +
> >
> > I think the realm vsmmu is going to require a different info struct
> > than the normal psmmu case, isn't it?
> >
> > If so it needs its own enum value.
> >
> > It would be nice to see a draft patch showing how the real vsmmu works
> > on top of the RMM spec for it. If we are using a viommu object then
> > non-vsmmu case should be identical just with an option in the info
> > struct to not create the vsmmu object.
> 
> Based on feedback on other emails in this thread, I have now implemented
> this without using a vdevice or viommu. This should make the CCA and
> non-CCA cases similar.

That wasn't the feedback. The feedback was to use the viommu and not
make a bunch of new stuff..

> +int arm_smmu_realm_tsm_bind(struct device *dev, struct kvm *kvm)
> +{
> +	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> +	int ret;
> +
> +	if (!kvm_is_realm(kvm))
> +		return 0;
> +
> +	ret = arm_realm_smmu_get(master->smmu);
> +	if (ret)
> +		return ret;
> +
> +	ret = arm_realm_smmu_stream_get(master);
> +	if (ret)
> +		arm_realm_smmu_put(master->smmu);
> +	return ret;

It still makes no sense this doesn't do the VDEV_CREATE too.

> iommufd_device_tsm_op_ioctl()
> 
> 	switch (cmd->type) {
> 	case IOMMU_DEVICE_TSM_BIND:
> 		if (!idev->tsm_iommu_bound && ops->tsm_bind) {
> 			if (WARN_ON_ONCE(!ops->tsm_unbind)) {
> 				ret = -EOPNOTSUPP;
> 				break;
> 			}
> 			ret = ops->tsm_bind(idev->dev, kvm);
> 			if (ret)
> 				break;
> 			idev->tsm_iommu_bound = true;
> 			iommu_bound = true;
> 		}
> 		ret = tsm_bind(idev->dev, kvm, cmd->tdi_id);

Yuk! Now this uAPI doesn't make any sense when you have an actual
viommu involved, we can't take tdi_id from userspace, it must come
from the vdevice.

I don't want two confusingly different flows, this stuff is hard
enough to keep straight.

Your first version was better, we just need to commit to using the
viommu for everyone on every arch and drop the the tsm_bind() API and
IOMMU_DEVICE_TSM_BIND interface.

The only draw back is the VMM has to manage a litte bit more.

Jason



More information about the linux-arm-kernel mailing list