Re: [PATCH] iommu/arm-smmu-v3: Allow stream table to have nodes with the same ID

Robin Murphy
2025-04-11T15:15:13Z

On 11/04/2025 5:47 am, Nicolin Chen wrote:
> From: Jason Gunthorpe <jgg@nvidia.com>
>
> ASPEED VGA card has two built-in devices:
> 0008:06:00.0 PCI bridge: ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge (rev 06)
> 0008:07:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics Family (rev 52)
>
> Its toplogy looks like this:
> +-[0008:00]---00.0-[01-09]--+-00.0-[02-09]--+-00.0-[03]----00.0 Sandisk Corp Device 5017
> | +-01.0-[04]--
> | +-02.0-[05]----00.0 NVIDIA Corporation Device
> | +-03.0-[06-07]----00.0-[07]----00.0 ASPEED Technology, Inc. ASPEED Graphics Family
> | +-04.0-[08]----00.0 Renesas Technology Corp. uPD720201 USB 3.0 Host Controller
> | \-05.0-[09]----00.0 Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
> \-00.1 PMC-Sierra Inc. Device 4028
>
> Being a legacy PCI device that does not have RID on the wire, the system
> does not preserve a RID for that PCI bridge (0008:06), so the IORT code
> has to dma alias for iort_pci_iommu_init() via pci_for_each_dma_alias(),
> resulting in both of them getting the same Stream ID.

Hmm, actually, this doesn't even make a whole heap of sense, and it's
not what's happening here at all.

The bridge *does* claim its own RID, and per the aliasing rules the
devices behind it claim both their own RID and the alias to function
00.0 on the bridge's secondary bus, like so in action:

[ 1.040905] pci 0000:04:00.0: arm_smmu_insert_master: SID 0x400
[ 1.046988] pci 0000:04:00.0: Adding to iommu group 0
[ 1.046995] pci 0000:05:04.0: arm_smmu_insert_master: SID 0x520
[ 1.053750] pci 0000:05:04.0: arm_smmu_insert_master: SID 0x500
[ 1.053759] pci 0000:05:04.0: Adding to iommu group 0
[ 1.053765] pci 0000:05:05.0: arm_smmu_insert_master: SID 0x528
[ 1.053767] pci 0000:05:05.0: arm_smmu_insert_master: SID 0x500
[ 1.053768] pci 0000:05:05.0: Aliasing StreamID 0x500 unsupported,
expect DMA to be broken

Which is a snippet from this topology:

-+-[0001:00]---00.0-[01]----00.0 Samsung Electronics Co Ltd NVMe SSD
Controller SM981/PM981/PM983
\-[0000:00]---00.0-[01-09]--+-00.0-[02-09]--+-08.0-[03]----00.0 VIA
Technologies, Inc. VL805/806 xHCI USB 3.0 Controller
|
+-10.0-[04-05]----00.0-[05]--+-04.0 Intel Corporation 82557/8/9/0/1
Ethernet Pro 100
| |
\-05.0 Broadcom Inc. and subsidiaries BCM4306 802.11b/g Wireless LAN
Controller
| +-11.0-[06]--
| +-12.0-[07]----00.0
Marvell Technology Group Ltd. Device 9170

(yes, I have a physical PCIe-to-PCI bridge board with random ancient
cards plugged into it specifically for griefing the SMMU drivers :D)

> On a kernel prior to v6.15-rc1, there has been an overlooked warning:
> pci 0008:07:00.0: vgaarb: setting as boot VGA device
> pci 0008:07:00.0: vgaarb: bridge control possible
> pci 0008:07:00.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none
> pcieport 0008:06:00.0: Adding to iommu group 14
> ast 0008:07:00.0: stream 67328 already in tree <===== WARNING

However in the ASpeed VGA case, we get a single device aliasing with
*itself*, because the physical RID is already function 00.0 - this is
more obvious on our CI's Ampere Altra system where the SID mappings have
no additional upper bits:

[ 22.953940] pci 0004:01:00.0: PCI bridge to [bus 02]
...
[ 23.037980] pci 0004:02:00.0: [1a03:2000] type 00 class 0x030000
conventional PCI endpoint
...
[ 27.383602] pci 0004:01:00.0: Adding to iommu group 28
[ 27.394562] pci 0004:02:00.0: stream 512 already in tree

512 == 0x200 == 02:00.0

Now that's supposed to have been supported since forever ago with
563b5cbe334e ("iommu/arm-smmu-v3: Cope with duplicated Stream IDs"),
however from a quick look I'm guessing cdf315f907d4 ("iommu/arm-smmu-v3:
Maintain a SID->device structure") might have broken it...

Thanks,
Robin.