Re: [PATCH v4 4/4] PCI/ACS: Enable PCI_ACS_TB for untrusted/external-facing devices

From: Rajat Jain
Date: Sat Jul 11 2020 - 20:35:20 EST


On Sat, Jul 11, 2020 at 12:53 PM Bjorn Helgaas <helgaas@xxxxxxxxxx> wrote:
>
> On Fri, Jul 10, 2020 at 03:53:59PM -0700, Rajat Jain wrote:
> > On Fri, Jul 10, 2020 at 2:29 PM Raj, Ashok <ashok.raj@xxxxxxxxx> wrote:
> > > On Fri, Jul 10, 2020 at 03:29:22PM -0500, Bjorn Helgaas wrote:
> > > > On Tue, Jul 07, 2020 at 03:46:04PM -0700, Rajat Jain wrote:
> > > > > When enabling ACS, enable translation blocking for external facing ports
> > > > > and untrusted devices.
> > > > >
> > > > > Signed-off-by: Rajat Jain <rajatja@xxxxxxxxxx>
> > > > > ---
> > > > > v4: Add braces to avoid warning from kernel robot
> > > > > print warning for only external-facing devices.
> > > > > v3: print warning if ACS_TB not supported on external-facing/untrusted ports.
> > > > > Minor code comments fixes.
> > > > > v2: Commit log change
> > > > >
> > > > > drivers/pci/pci.c | 8 ++++++++
> > > > > drivers/pci/quirks.c | 15 +++++++++++++++
> > > > > 2 files changed, 23 insertions(+)
> > > > >
> > > > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > > > > index 73a8627822140..a5a6bea7af7ce 100644
> > > > > --- a/drivers/pci/pci.c
> > > > > +++ b/drivers/pci/pci.c
> > > > > @@ -876,6 +876,14 @@ static void pci_std_enable_acs(struct pci_dev *dev)
> > > > > /* Upstream Forwarding */
> > > > > ctrl |= (cap & PCI_ACS_UF);
> > > > >
> > > > > + /* Enable Translation Blocking for external devices */
> > > > > + if (dev->external_facing || dev->untrusted) {
> > > > > + if (cap & PCI_ACS_TB)
> > > > > + ctrl |= PCI_ACS_TB;
> > > > > + else if (dev->external_facing)
> > > > > + pci_warn(dev, "ACS: No Translation Blocking on external-facing dev\n");
> > > > > + }
> > > >
> > > > IIUC, this means that external devices can *never* use ATS and
> > > > can never cache translations.
> >
> > Yes, but it already exists today (and this patch doesn't change that):
> > 521376741b2c2 "PCI/ATS: Only enable ATS for trusted devices"
> >
> > IMHO any external device trying to send ATS traffic despite having ATS
> > disabled should count as a bad intent. And this patch is trying to
> > plug that loophole, by blocking the AT traffic from devices that we do
> > not expect to see AT from anyway.
>
> Thinking about this some more, I wonder if Linux should:
>
> - Explicitly disable ATS for every device at enumeration-time, e.g.,
> in pci_init_capabilities(),
>
> - Enable PCI_ACS_TB for every device (not just external-facing or
> untrusted ones),
>
> - Disable PCI_ACS_TB for the relevant devices along the path only
> when enabling ATS.
>
> One nice thing about doing that is that the "untrusted" test would be
> only in pci_enable_ats(), and we wouldn't need one in
> pci_std_enable_acs().

Yes, this could work.

I think I had thought about this but I'm blanking out on why I had
given it up. I think it was because of the possibility that some
bridges may have "Translation blocking" disabled, even if not all
their descendents were trusted enough to enable ATS on them. But now
thinking about this again, as long as we retain the policy of not
enabling ATS on external devices (and thus enable TB for sure on
them), this should not be a problem. WDYT?

>
> It's possible BIOS gives us devices with ATS enabled, and this might
> break them, but that seems like something we'd want to find out about.
>

Why would they break? We'd disable ATS on each device as we enumerate
them, so they'd be functional, just with ATS disabled until it is
enabled again on internal devices as needed. Which would be WAI
behavior?

Thanks,
,
Rajat




> Bjorn