[RFC PATCH v4 03/16] iommu/arm-smmu-v3: Add initial pSMMU realm viommu plumbing
Aneesh Kumar K.V
aneesh.kumar at kernel.org
Wed Sep 2 02:00:00 PDT 2026
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.
This ends up adding:
modified drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4324,6 +4324,8 @@ static const struct iommu_ops arm_smmu_ops = {
.def_domain_type = arm_smmu_def_domain_type,
.get_viommu_size = arm_smmu_get_viommu_size,
.viommu_init = arm_vsmmu_init,
+ .tsm_bind = arm_smmu_realm_tsm_bind,
+ .tsm_unbind = arm_smmu_realm_tsm_unbind,
.user_pasid_table = 1,
.owner = THIS_MODULE,
.default_domain_ops = &(const struct iommu_domain_ops) {
and
+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;
+}
+
+void arm_smmu_realm_tsm_unbind(struct device *dev, struct kvm *kvm)
+{
+ struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+
+ if (!kvm_is_realm(kvm))
+ return;
+
+ arm_realm_smmu_stream_put(master);
+ arm_realm_smmu_put(master->smmu);
+}
and tsm op iotcl now becomes
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);
if (ret && iommu_bound) {
ops->tsm_unbind(idev->dev, kvm);
idev->tsm_iommu_bound = false;
}
break;
case IOMMU_DEVICE_TSM_UNBIND:
__iommufd_device_tsm_unbind(idev);
ret = 0;
break;
default:
ret = -EINVAL;
break;
}
I am yet to clean up the changes. I just wanted to share that we can
possibly drop the vdevice/viommu requirement.
-aneesh
More information about the linux-arm-kernel
mailing list