On Fri, Jun 19, 2026 at 9:20 AM Lazar, Lijo <[email protected]> wrote: > > <ping> > > On 17-Jun-26 3:05 PM, Lijo Lazar wrote: > > Internal US/DS switch may not be exposed in passthrough. Guard the > > upstream port reads to avoid a NULL dereference. > > > > Signed-off-by: Lijo Lazar <[email protected]>
Acked-by: Alex Deucher <[email protected]> > > --- > > drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c | 59 +++++++++++++++------- > > 1 file changed, 42 insertions(+), 17 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c > > b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c > > index 72ea37dbfea8..5f1389901504 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c > > +++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c > > @@ -589,6 +589,29 @@ static struct aqua_reg_list pcie_reg_addrs[] = { > > { smreg_0x1A380088, 6, DW_ADDR_INCR }, > > }; > > > > +/* > > + * Return the GPU's internal US switch port, or NULL if it is not visible > > + * (e.g. passthrough) or the EP is parented under an unrelated bridge. > > + */ > > +static struct pci_dev *aqua_vanjaram_get_us_pdev(struct amdgpu_device > > *adev) > > +{ > > + struct pci_dev *ds_pdev, *us_pdev; > > + > > + ds_pdev = pci_upstream_bridge(adev->pdev); > > + if (!ds_pdev || ds_pdev->vendor != PCI_VENDOR_ID_ATI || > > + pci_pcie_type(ds_pdev) != PCI_EXP_TYPE_DOWNSTREAM) > > + return NULL; > > + > > + us_pdev = pci_upstream_bridge(ds_pdev); > > + if (!us_pdev || > > + (us_pdev->vendor != PCI_VENDOR_ID_ATI && > > + us_pdev->vendor != PCI_VENDOR_ID_AMD) || > > + pci_pcie_type(us_pdev) != PCI_EXP_TYPE_UPSTREAM) > > + return NULL; > > + > > + return us_pdev; > > +} > > + > > static ssize_t aqua_vanjaram_read_pcie_state(struct amdgpu_device *adev, > > void *buf, size_t max_size) > > { > > @@ -596,7 +619,7 @@ static ssize_t aqua_vanjaram_read_pcie_state(struct > > amdgpu_device *adev, > > uint32_t start_addr, incrx, num_regs, szbuf; > > struct amdgpu_regs_pcie_v1_0 *pcie_regs; > > struct amdgpu_smn_reg_data *reg_data; > > - struct pci_dev *us_pdev, *ds_pdev; > > + struct pci_dev *us_pdev; > > int aer_cap, r, n; > > > > if (!buf || !max_size) > > @@ -628,25 +651,27 @@ static ssize_t aqua_vanjaram_read_pcie_state(struct > > amdgpu_device *adev, > > } > > } > > > > - ds_pdev = pci_upstream_bridge(adev->pdev); > > - us_pdev = pci_upstream_bridge(ds_pdev); > > + us_pdev = aqua_vanjaram_get_us_pdev(adev); > > + if (us_pdev) { > > + pcie_capability_read_word(us_pdev, PCI_EXP_DEVSTA, > > + &pcie_regs->device_status); > > + pcie_capability_read_word(us_pdev, PCI_EXP_LNKSTA, > > + &pcie_regs->link_status); > > + > > + aer_cap = pci_find_ext_capability(us_pdev, > > PCI_EXT_CAP_ID_ERR); > > + if (aer_cap) { > > + pci_read_config_dword(us_pdev, > > + aer_cap + PCI_ERR_COR_STATUS, > > + > > &pcie_regs->pcie_corr_err_status); > > + pci_read_config_dword(us_pdev, > > + aer_cap + PCI_ERR_UNCOR_STATUS, > > + > > &pcie_regs->pcie_uncorr_err_status); > > + } > > > > - pcie_capability_read_word(us_pdev, PCI_EXP_DEVSTA, > > - &pcie_regs->device_status); > > - pcie_capability_read_word(us_pdev, PCI_EXP_LNKSTA, > > - &pcie_regs->link_status); > > - > > - aer_cap = pci_find_ext_capability(us_pdev, PCI_EXT_CAP_ID_ERR); > > - if (aer_cap) { > > - pci_read_config_dword(us_pdev, aer_cap + PCI_ERR_COR_STATUS, > > - &pcie_regs->pcie_corr_err_status); > > - pci_read_config_dword(us_pdev, aer_cap + PCI_ERR_UNCOR_STATUS, > > - &pcie_regs->pcie_uncorr_err_status); > > + pci_read_config_dword(us_pdev, PCI_PRIMARY_BUS, > > + &pcie_regs->sub_bus_number_latency); > > } > > > > - pci_read_config_dword(us_pdev, PCI_PRIMARY_BUS, > > - &pcie_regs->sub_bus_number_latency); > > - > > pcie_reg_state->common_header.structure_size = szbuf; > > pcie_reg_state->common_header.format_revision = 1; > > pcie_reg_state->common_header.content_revision = 0; >
