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;
>

Reply via email to