Re: [PATCH v2 08/13] PCI/P2PDMA: Honor ACS egress control vectors
[email protected] Thu, 06 Aug 2026 11:47:42 +0000
| Newsgroups | org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] Cross-domain PCIe ACS Egress Control Vector evaluation uses meaningless port numbers when devices reside on different host bridges. -- --- Patch [8]: [PATCH v2 08/13] PCI/P2PDMA: Honor ACS egress control vectors --- commit 96de4ef43ce98491771577d7338b7224cb26b816 Author: Leon Romanovsky <[email protected]> PCI/P2PDMA: Honor ACS egress control vectors This commit updates P2PDMA to properly evaluate the ACS Egress Control Vector when determining routing between peers. It reads the vector where the paths diverge below their common upstream port, treating a clear vector bit as a direct path and a set bit (without Request Redirect) as an ACS Violation. > diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c > --- a/drivers/pci/p2pdma.c > +++ b/drivers/pci/p2pdma.c [ ... ] > @@ -770,25 +770,44 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client, > */ > no_common_upstream = true; > > -check_b_path_acs: > - bb = b; > +check_paths_acs: > + *dist = dist_a + dist_b; > + bb = provider; > > while (bb) { > + target = bb == a_child ? b_child : NULL; > + state = pci_acs_p2pdma_state(bb, target); [Severity: High] When no_common_upstream is true, the provider and client reside on different host bridges. Does this cause pci_acs_p2pdma_state() to evaluate the ACS Egress Control Vector using a target from a completely different PCIe domain? If bb == a_child, b_child is passed as the target. Down in pci_acs_egress_ctrl_set(), the link capabilities of the foreign port are used to extract a target port number: drivers/pci/pci.c:pci_acs_egress_ctrl_set() { ... target_port = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); ... ret = pci_read_config_dword(pdev, pdev->acs_cap + PCI_ACS_EGRESS_CTL_V + (target_port / 32) * sizeof(vector), &vector); ... } Since pdev and target are on different host bridges, does this use a meaningless port number as an index? If so, this could read arbitrary bits from the hardware configuration space and potentially result in incorrect ACS routing decisions or spurious violation warnings. > + if (state != PCI_ACS_P2PDMA_DIRECT) { > + seq_buf_print_bus_devfn(&acs_list, bb); > + if (state == PCI_ACS_P2PDMA_REDIRECT) > + acs_redirect_cnt++; > + else if (!acs_unsupported) > + acs_unsupported = bb; > + } > + > if (a == bb) > break; > > - if (pci_acs_p2pdma_state(bb, NULL) == > - PCI_ACS_P2PDMA_REDIRECT) { > - seq_buf_print_bus_devfn(&acs_list, bb); > - acs_cnt++; > - } > - > bb = pci_upstream_bridge(bb); > } > > - *dist = dist_a + dist_b; > - > - if (!acs_cnt) { > + bb = client; > + > + while (bb && a != bb) { > + target = bb == b_child ? a_child : NULL; > + state = pci_acs_p2pdma_state(bb, target); [Severity: High] Similarly here, if the devices are on different host bridges, a_child and b_child are on different domains. Does passing a_child as the target to b_child's ACS evaluation create the same cross-domain hardware configuration read issue? > + if (state != PCI_ACS_P2PDMA_DIRECT) { > seq_buf_print_bus_devfn(&acs_list, bb); > - acs_cnt++; > + if (state == PCI_ACS_P2PDMA_REDIRECT) > + acs_redirect_cnt++; > + else if (!acs_unsupported) > + acs_unsupported = bb; > } > > bb = pci_upstream_bridge(bb); -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=8