[RFC PATCH 4/5] iommu/arm-smmu-v3: Add stream table directory structure to debugfs

Qinxin Xia xiaqinxin at huawei.com
Mon Mar 16 19:04:17 PDT 2026



On 2026/3/17 00:01:50, Robin Murphy <robin.murphy at arm.com> wrote:
> On 2026-03-13 10:43 am, Qinxin Xia wrote:
>> Add stream table directory structure creation to debugfs
>> This organizes debugfs entries by device and stream ID:
>>
>> /sys/kernel/debug/iommu/arm_smmu_v3/smmu0/stream_table/
>> └── 0000:01:00.0:0/
>>      └─── ste
> 
> Similar to my previous comment on CDs (sorry I'm reading out of order), 
> I wonder if it might not be more useful to expose STEs by index, then 
> have the name of the associated device as an attribute/link below that. 
> Or perhaps even have whole cross-linked "by StreamID" and "by device" 
> hierarchies if you want to get really fancy. From userspace it's not 
> always easy to know exactly which StreamIDs are owned by which devices, 
> and I can say from experience that if you do have to debug things at the 
> STE level, the StreamID is often the thing you're starting from. Plus if 
> you wanted to, say, check that STEs are correctly disabled after SR-IOV 
> VF teardown, then there may not even be a device any more.
> 
> Thanks,
> Robin.
> 
To quickly obtain the mapping between SIDs and devices, I named the
directory dev_name+sid. Can we keep this naming mode and add a device
link to the directory?

According to Nicolin's suggestion, I plan to release the corresponding
debugfs in release_device in the next version. After VF teardown, users
cannot view information such as ste and cd anymore.

>> Signed-off-by: Qinxin Xia <xiaqinxin at huawei.com>
>> ---
>>   .../arm/arm-smmu-v3/arm-smmu-v3-debugfs.c     | 80 ++++++++++++++++++-
>>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  3 +
>>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  4 +
>>   3 files changed, 85 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c b/ 
>> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
>> index d7f3defd94a3..f62df02847ac 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debugfs.c
>> @@ -31,7 +31,10 @@
>>    * /sys/kernel/debug/iommu/arm_smmu_v3/
>>    * └── smmu0/
>>    *     ├── capabilities    # SMMU feature capabilities and 
>> configuration
>> - *     └── registers       # SMMU Key registers
>> + *     ├── registers       # SMMU Key registers
>> + *     └── stream_table
>> + *       └── 0000:01:00.0:0/                    # PCI device with 
>> Stream ID 0
>> + *             ├── ste                           # Stream Table Entry
>>    *
>>    * The capabilities file provides detailed information about:
>>    * - Architecture version and translation stage support (Stage1/Stage2)
>> @@ -324,5 +327,78 @@ static int smmu_debugfs_ste_show(struct seq_file 
>> *seq, void *v)
>>       smmu_debug_dump_ste(seq, dev);
>>       return 0;
>>   }
>> -
>>   DEFINE_SHOW_ATTRIBUTE(smmu_debugfs_ste);
>> +
>> +/**
>> + * smmu_debugfs_create_stream_table() - Create debugfs entries for 
>> stream table
>> + * @dev: device to create entries for
>> + * @smmu: SMMU device
>> + *
>> + * Return: 0 on success, negative error code on failure
>> + */
>> +int smmu_debugfs_create_stream_table(struct device *dev,
>> +                     struct arm_smmu_device *smmu)
>> +{
>> +    struct dentry *stream_dir, *cd_dir, *dev_dir;
>> +    struct dentry *ste_file, *all_cds_file;
>> +    struct iommu_fwspec *fwspec;
>> +    char name[64];
>> +    int i, ret = 0;
>> +
>> +    if (!smmu->debugfs->stream_dir) {
>> +        stream_dir = debugfs_create_dir("stream_table",
>> +                        smmu->debugfs->smmu_dir);
>> +        if (!stream_dir)
>> +            return -ENOMEM;
>> +        smmu->debugfs->stream_dir = stream_dir;
>> +    } else {
>> +        stream_dir = smmu->debugfs->stream_dir;
>> +    }
>> +
>> +    fwspec = dev_iommu_fwspec_get(dev);
>> +    if (!fwspec)
>> +        return -ENODEV;
>> +
>> +    for (i = 0; i < fwspec->num_ids; i++) {
>> +        u32 sid = fwspec->ids[i];
>> +
>> +        if (dev_is_pci(dev)) {
>> +            struct pci_dev *pdev = to_pci_dev(dev);
>> +
>> +            snprintf(name, sizeof(name), "%04x:%02x:%02x.%d:%u",
>> +                 pci_domain_nr(pdev->bus), pdev->bus->number,
>> +                 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
>> +                 sid);
>> +        } else {
>> +            snprintf(name, sizeof(name), "%s:%u", dev_name(dev),
>> +                 sid);
>> +        }
>> +
>> +        dev_dir = debugfs_create_dir(name, stream_dir);
>> +        if (!dev_dir) {
>> +            ret = -ENOMEM;
>> +            goto cleanup;
>> +        }
>> +
>> +        /* Create STE file */
>> +        ste_file = debugfs_create_file("ste", 0444, dev_dir, dev,
>> +                           &smmu_debugfs_ste_fops);
>> +        if (!ste_file) {
>> +            ret = -ENOMEM;
>> +            goto cleanup_dev;
>> +        }
>> +
>> +        /* Success for this stream ID, continue to next */
>> +        continue;
>> +
>> +cleanup_dev:
>> +        debugfs_remove_recursive(dev_dir);
>> +cleanup:
>> +        if (ret) {
>> +            debugfs_remove_recursive(stream_dir);
>> +            break;
>> +        }
>> +    }
>> +
>> +    return ret;
>> +}
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/ 
>> iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index 211a0c87507a..c57897e5f644 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -3133,6 +3133,9 @@ static int arm_smmu_attach_dev(struct 
>> iommu_domain *domain, struct device *dev,
>>       arm_smmu_attach_commit(&state);
>>       mutex_unlock(&arm_smmu_asid_lock);
>> +#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
>> +    smmu_debugfs_create_stream_table(dev, smmu);
>> +#endif
>>       return 0;
>>   }
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/ 
>> iommu/arm/arm-smmu-v3/arm-smmu-v3.h
>> index 247f27426f6b..e9cd24c1ab3c 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
>> @@ -737,9 +737,13 @@ struct arm_smmu_impl_ops {
>>   struct arm_smmu_debugfs {
>>       struct dentry *root_dir;
>>       struct dentry *smmu_dir;
>> +    struct dentry *stream_dir;
>>       struct arm_smmu_device *smmu;
>>   };
>> +
>>   int arm_smmu_debugfs_setup(struct arm_smmu_device *smmu, phys_addr_t 
>> ioaddr);
>> +int smmu_debugfs_create_stream_table(struct device *dev,
>> +                    struct arm_smmu_device *smmu);
>>   #endif
>>   /* An SMMUv3 instance */
> 
> 

-- 
Thanks,
Qinxin




More information about the linux-arm-kernel mailing list