Merge branch 'pci/virtualization'
authorBjorn Helgaas <bhelgaas@google.com>
Thu, 2 Sep 2021 19:56:43 +0000 (14:56 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 2 Sep 2021 19:56:43 +0000 (14:56 -0500)
- Add ACS quirks for NXP LX2xx0 and LX2xx2 platforms (Wasim Khan)

- Add ACS quirks for Cavium multi-function devices (George Cherian)

- Enforce pci=noats with Transaction Blocking (Alex Williamson)

* pci/virtualization:
  PCI/ACS: Enforce pci=noats with Transaction Blocking
  PCI: Add ACS quirks for Cavium multi-function devices
  PCI: Add ACS quirks for NXP LX2xx0 and LX2xx2 platforms

1  2 
drivers/pci/pci.c
drivers/pci/quirks.c

diff --combined drivers/pci/pci.c
index 8e594c3a0e4d45cb0e1b5b2b1ee3f7886ae1cdc8,e0c6ceced2073f04d3eaf0dd625521a388db4494..c3f6ff3bd2af5bae1afd01019b1561b171cd970d
@@@ -31,7 -31,6 +31,7 @@@
  #include <linux/vmalloc.h>
  #include <asm/dma.h>
  #include <linux/aer.h>
 +#include <linux/bitfield.h>
  #include "pci.h"
  
  DEFINE_MUTEX(pci_slot_mutex);
@@@ -73,11 -72,6 +73,11 @@@ static void pci_dev_d3_sleep(struct pci
                msleep(delay);
  }
  
 +bool pci_reset_supported(struct pci_dev *dev)
 +{
 +      return dev->reset_methods[0] != 0;
 +}
 +
  #ifdef CONFIG_PCI_DOMAINS
  int pci_domains_supported = 1;
  #endif
@@@ -212,36 -206,32 +212,36 @@@ int pci_status_get_and_clear_errors(str
  EXPORT_SYMBOL_GPL(pci_status_get_and_clear_errors);
  
  #ifdef CONFIG_HAS_IOMEM
 -void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
 +static void __iomem *__pci_ioremap_resource(struct pci_dev *pdev, int bar,
 +                                          bool write_combine)
  {
        struct resource *res = &pdev->resource[bar];
 +      resource_size_t start = res->start;
 +      resource_size_t size = resource_size(res);
  
        /*
         * Make sure the BAR is actually a memory resource, not an IO resource
         */
        if (res->flags & IORESOURCE_UNSET || !(res->flags & IORESOURCE_MEM)) {
 -              pci_warn(pdev, "can't ioremap BAR %d: %pR\n", bar, res);
 +              pci_err(pdev, "can't ioremap BAR %d: %pR\n", bar, res);
                return NULL;
        }
 -      return ioremap(res->start, resource_size(res));
 +
 +      if (write_combine)
 +              return ioremap_wc(start, size);
 +
 +      return ioremap(start, size);
 +}
 +
 +void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
 +{
 +      return __pci_ioremap_resource(pdev, bar, false);
  }
  EXPORT_SYMBOL_GPL(pci_ioremap_bar);
  
  void __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar)
  {
 -      /*
 -       * Make sure the BAR is actually a memory resource, not an IO resource
 -       */
 -      if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
 -              WARN_ON(1);
 -              return NULL;
 -      }
 -      return ioremap_wc(pci_resource_start(pdev, bar),
 -                        pci_resource_len(pdev, bar));
 +      return __pci_ioremap_resource(pdev, bar, true);
  }
  EXPORT_SYMBOL_GPL(pci_ioremap_wc_bar);
  #endif
@@@ -925,8 -915,8 +925,8 @@@ static void pci_std_enable_acs(struct p
        /* Upstream Forwarding */
        ctrl |= (cap & PCI_ACS_UF);
  
-       /* Enable Translation Blocking for external devices */
-       if (dev->external_facing || dev->untrusted)
+       /* Enable Translation Blocking for external devices and noats */
+       if (pci_ats_disabled() || dev->external_facing || dev->untrusted)
                ctrl |= (cap & PCI_ACS_TB);
  
        pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
@@@ -4631,12 -4621,32 +4631,12 @@@ int pci_wait_for_pending_transaction(st
  }
  EXPORT_SYMBOL(pci_wait_for_pending_transaction);
  
 -/**
 - * pcie_has_flr - check if a device supports function level resets
 - * @dev: device to check
 - *
 - * Returns true if the device advertises support for PCIe function level
 - * resets.
 - */
 -bool pcie_has_flr(struct pci_dev *dev)
 -{
 -      u32 cap;
 -
 -      if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
 -              return false;
 -
 -      pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
 -      return cap & PCI_EXP_DEVCAP_FLR;
 -}
 -EXPORT_SYMBOL_GPL(pcie_has_flr);
 -
  /**
   * pcie_flr - initiate a PCIe function level reset
   * @dev: device to reset
   *
 - * Initiate a function level reset on @dev.  The caller should ensure the
 - * device supports FLR before calling this function, e.g. by using the
 - * pcie_has_flr() helper.
 + * Initiate a function level reset unconditionally on @dev without
 + * checking any flags and DEVCAP
   */
  int pcie_flr(struct pci_dev *dev)
  {
  }
  EXPORT_SYMBOL_GPL(pcie_flr);
  
 -static int pci_af_flr(struct pci_dev *dev, int probe)
 +/**
 + * pcie_reset_flr - initiate a PCIe function level reset
 + * @dev: device to reset
 + * @probe: if true, return 0 if device can be reset this way
 + *
 + * Initiate a function level reset on @dev.
 + */
 +int pcie_reset_flr(struct pci_dev *dev, bool probe)
 +{
 +      if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
 +              return -ENOTTY;
 +
 +      if (!(dev->devcap & PCI_EXP_DEVCAP_FLR))
 +              return -ENOTTY;
 +
 +      if (probe)
 +              return 0;
 +
 +      return pcie_flr(dev);
 +}
 +EXPORT_SYMBOL_GPL(pcie_reset_flr);
 +
 +static int pci_af_flr(struct pci_dev *dev, bool probe)
  {
        int pos;
        u8 cap;
  /**
   * pci_pm_reset - Put device into PCI_D3 and back into PCI_D0.
   * @dev: Device to reset.
 - * @probe: If set, only check if the device can be reset this way.
 + * @probe: if true, return 0 if the device can be reset this way.
   *
   * If @dev supports native PCI PM and its PCI_PM_CTRL_NO_SOFT_RESET flag is
   * unset, it will be reinitialized internally when going from PCI_D3hot to
   * by default (i.e. unless the @dev's d3hot_delay field has a different value).
   * Moreover, only devices in D0 can be reset by this function.
   */
 -static int pci_pm_reset(struct pci_dev *dev, int probe)
 +static int pci_pm_reset(struct pci_dev *dev, bool probe)
  {
        u16 csr;
  
@@@ -5000,7 -4988,7 +5000,7 @@@ int pci_bridge_secondary_bus_reset(stru
  }
  EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset);
  
 -static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
 +static int pci_parent_bus_reset(struct pci_dev *dev, bool probe)
  {
        struct pci_dev *pdev;
  
        return pci_bridge_secondary_bus_reset(dev->bus->self);
  }
  
 -static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, int probe)
 +static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, bool probe)
  {
        int rc = -ENOTTY;
  
        return rc;
  }
  
 -static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe)
 +static int pci_dev_reset_slot_function(struct pci_dev *dev, bool probe)
  {
        if (dev->multifunction || dev->subordinate || !dev->slot ||
            dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
        return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
  }
  
 -static int pci_reset_bus_function(struct pci_dev *dev, int probe)
 +static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
  {
        int rc;
  
@@@ -5126,139 -5114,6 +5126,139 @@@ static void pci_dev_restore(struct pci_
                err_handler->reset_done(dev);
  }
  
 +/* dev->reset_methods[] is a 0-terminated list of indices into this array */
 +static const struct pci_reset_fn_method pci_reset_fn_methods[] = {
 +      { },
 +      { pci_dev_specific_reset, .name = "device_specific" },
 +      { pci_dev_acpi_reset, .name = "acpi" },
 +      { pcie_reset_flr, .name = "flr" },
 +      { pci_af_flr, .name = "af_flr" },
 +      { pci_pm_reset, .name = "pm" },
 +      { pci_reset_bus_function, .name = "bus" },
 +};
 +
 +static ssize_t reset_method_show(struct device *dev,
 +                               struct device_attribute *attr, char *buf)
 +{
 +      struct pci_dev *pdev = to_pci_dev(dev);
 +      ssize_t len = 0;
 +      int i, m;
 +
 +      for (i = 0; i < PCI_NUM_RESET_METHODS; i++) {
 +              m = pdev->reset_methods[i];
 +              if (!m)
 +                      break;
 +
 +              len += sysfs_emit_at(buf, len, "%s%s", len ? " " : "",
 +                                   pci_reset_fn_methods[m].name);
 +      }
 +
 +      if (len)
 +              len += sysfs_emit_at(buf, len, "\n");
 +
 +      return len;
 +}
 +
 +static int reset_method_lookup(const char *name)
 +{
 +      int m;
 +
 +      for (m = 1; m < PCI_NUM_RESET_METHODS; m++) {
 +              if (sysfs_streq(name, pci_reset_fn_methods[m].name))
 +                      return m;
 +      }
 +
 +      return 0;       /* not found */
 +}
 +
 +static ssize_t reset_method_store(struct device *dev,
 +                                struct device_attribute *attr,
 +                                const char *buf, size_t count)
 +{
 +      struct pci_dev *pdev = to_pci_dev(dev);
 +      char *options, *name;
 +      int m, n;
 +      u8 reset_methods[PCI_NUM_RESET_METHODS] = { 0 };
 +
 +      if (sysfs_streq(buf, "")) {
 +              pdev->reset_methods[0] = 0;
 +              pci_warn(pdev, "All device reset methods disabled by user");
 +              return count;
 +      }
 +
 +      if (sysfs_streq(buf, "default")) {
 +              pci_init_reset_methods(pdev);
 +              return count;
 +      }
 +
 +      options = kstrndup(buf, count, GFP_KERNEL);
 +      if (!options)
 +              return -ENOMEM;
 +
 +      n = 0;
 +      while ((name = strsep(&options, " ")) != NULL) {
 +              if (sysfs_streq(name, ""))
 +                      continue;
 +
 +              name = strim(name);
 +
 +              m = reset_method_lookup(name);
 +              if (!m) {
 +                      pci_err(pdev, "Invalid reset method '%s'", name);
 +                      goto error;
 +              }
 +
 +              if (pci_reset_fn_methods[m].reset_fn(pdev, PCI_RESET_PROBE)) {
 +                      pci_err(pdev, "Unsupported reset method '%s'", name);
 +                      goto error;
 +              }
 +
 +              if (n == PCI_NUM_RESET_METHODS - 1) {
 +                      pci_err(pdev, "Too many reset methods\n");
 +                      goto error;
 +              }
 +
 +              reset_methods[n++] = m;
 +      }
 +
 +      reset_methods[n] = 0;
 +
 +      /* Warn if dev-specific supported but not highest priority */
 +      if (pci_reset_fn_methods[1].reset_fn(pdev, PCI_RESET_PROBE) == 0 &&
 +          reset_methods[0] != 1)
 +              pci_warn(pdev, "Device-specific reset disabled/de-prioritized by user");
 +      memcpy(pdev->reset_methods, reset_methods, sizeof(pdev->reset_methods));
 +      kfree(options);
 +      return count;
 +
 +error:
 +      /* Leave previous methods unchanged */
 +      kfree(options);
 +      return -EINVAL;
 +}
 +static DEVICE_ATTR_RW(reset_method);
 +
 +static struct attribute *pci_dev_reset_method_attrs[] = {
 +      &dev_attr_reset_method.attr,
 +      NULL,
 +};
 +
 +static umode_t pci_dev_reset_method_attr_is_visible(struct kobject *kobj,
 +                                                  struct attribute *a, int n)
 +{
 +      struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
 +
 +      if (!pci_reset_supported(pdev))
 +              return 0;
 +
 +      return a->mode;
 +}
 +
 +const struct attribute_group pci_dev_reset_method_attr_group = {
 +      .attrs = pci_dev_reset_method_attrs,
 +      .is_visible = pci_dev_reset_method_attr_is_visible,
 +};
 +
  /**
   * __pci_reset_function_locked - reset a PCI device function while holding
   * the @dev mutex lock.
   */
  int __pci_reset_function_locked(struct pci_dev *dev)
  {
 -      int rc;
 +      int i, m, rc = -ENOTTY;
  
        might_sleep();
  
        /*
 -       * A reset method returns -ENOTTY if it doesn't support this device
 -       * and we should try the next method.
 +       * A reset method returns -ENOTTY if it doesn't support this device and
 +       * we should try the next method.
         *
 -       * If it returns 0 (success), we're finished.  If it returns any
 -       * other error, we're also finished: this indicates that further
 -       * reset mechanisms might be broken on the device.
 +       * If it returns 0 (success), we're finished.  If it returns any other
 +       * error, we're also finished: this indicates that further reset
 +       * mechanisms might be broken on the device.
         */
 -      rc = pci_dev_specific_reset(dev, 0);
 -      if (rc != -ENOTTY)
 -              return rc;
 -      if (pcie_has_flr(dev)) {
 -              rc = pcie_flr(dev);
 +      for (i = 0; i < PCI_NUM_RESET_METHODS; i++) {
 +              m = dev->reset_methods[i];
 +              if (!m)
 +                      return -ENOTTY;
 +
 +              rc = pci_reset_fn_methods[m].reset_fn(dev, PCI_RESET_DO_RESET);
 +              if (!rc)
 +                      return 0;
                if (rc != -ENOTTY)
                        return rc;
        }
 -      rc = pci_af_flr(dev, 0);
 -      if (rc != -ENOTTY)
 -              return rc;
 -      rc = pci_pm_reset(dev, 0);
 -      if (rc != -ENOTTY)
 -              return rc;
 -      return pci_reset_bus_function(dev, 0);
 +
 +      return -ENOTTY;
  }
  EXPORT_SYMBOL_GPL(__pci_reset_function_locked);
  
  /**
 - * pci_probe_reset_function - check whether the device can be safely reset
 - * @dev: PCI device to reset
 + * pci_init_reset_methods - check whether device can be safely reset
 + * and store supported reset mechanisms.
 + * @dev: PCI device to check for reset mechanisms
   *
   * Some devices allow an individual function to be reset without affecting
 - * other functions in the same device.  The PCI device must be responsive
 - * to PCI config space in order to use this function.
 + * other functions in the same device.  The PCI device must be in D0-D3hot
 + * state.
   *
 - * Returns 0 if the device function can be reset or negative if the
 - * device doesn't support resetting a single function.
 + * Stores reset mechanisms supported by device in reset_methods byte array
 + * which is a member of struct pci_dev.
   */
 -int pci_probe_reset_function(struct pci_dev *dev)
 +void pci_init_reset_methods(struct pci_dev *dev)
  {
 -      int rc;
 +      int m, i, rc;
 +
 +      BUILD_BUG_ON(ARRAY_SIZE(pci_reset_fn_methods) != PCI_NUM_RESET_METHODS);
  
        might_sleep();
  
 -      rc = pci_dev_specific_reset(dev, 1);
 -      if (rc != -ENOTTY)
 -              return rc;
 -      if (pcie_has_flr(dev))
 -              return 0;
 -      rc = pci_af_flr(dev, 1);
 -      if (rc != -ENOTTY)
 -              return rc;
 -      rc = pci_pm_reset(dev, 1);
 -      if (rc != -ENOTTY)
 -              return rc;
 +      i = 0;
 +      for (m = 1; m < PCI_NUM_RESET_METHODS; m++) {
 +              rc = pci_reset_fn_methods[m].reset_fn(dev, PCI_RESET_PROBE);
 +              if (!rc)
 +                      dev->reset_methods[i++] = m;
 +              else if (rc != -ENOTTY)
 +                      break;
 +      }
  
 -      return pci_reset_bus_function(dev, 1);
 +      dev->reset_methods[i] = 0;
  }
  
  /**
@@@ -5361,7 -5218,7 +5361,7 @@@ int pci_reset_function(struct pci_dev *
  {
        int rc;
  
 -      if (!dev->reset_fn)
 +      if (!pci_reset_supported(dev))
                return -ENOTTY;
  
        pci_dev_lock(dev);
@@@ -5397,7 -5254,7 +5397,7 @@@ int pci_reset_function_locked(struct pc
  {
        int rc;
  
 -      if (!dev->reset_fn)
 +      if (!pci_reset_supported(dev))
                return -ENOTTY;
  
        pci_dev_save_and_disable(dev);
@@@ -5420,7 -5277,7 +5420,7 @@@ int pci_try_reset_function(struct pci_d
  {
        int rc;
  
 -      if (!dev->reset_fn)
 +      if (!pci_reset_supported(dev))
                return -ENOTTY;
  
        if (!pci_dev_trylock(dev))
@@@ -5648,7 -5505,7 +5648,7 @@@ static void pci_slot_restore_locked(str
        }
  }
  
 -static int pci_slot_reset(struct pci_slot *slot, int probe)
 +static int pci_slot_reset(struct pci_slot *slot, bool probe)
  {
        int rc;
  
   */
  int pci_probe_reset_slot(struct pci_slot *slot)
  {
 -      return pci_slot_reset(slot, 1);
 +      return pci_slot_reset(slot, PCI_RESET_PROBE);
  }
  EXPORT_SYMBOL_GPL(pci_probe_reset_slot);
  
@@@ -5699,14 -5556,14 +5699,14 @@@ static int __pci_reset_slot(struct pci_
  {
        int rc;
  
 -      rc = pci_slot_reset(slot, 1);
 +      rc = pci_slot_reset(slot, PCI_RESET_PROBE);
        if (rc)
                return rc;
  
        if (pci_slot_trylock(slot)) {
                pci_slot_save_and_disable_locked(slot);
                might_sleep();
 -              rc = pci_reset_hotplug_slot(slot->hotplug, 0);
 +              rc = pci_reset_hotplug_slot(slot->hotplug, PCI_RESET_DO_RESET);
                pci_slot_restore_locked(slot);
                pci_slot_unlock(slot);
        } else
        return rc;
  }
  
 -static int pci_bus_reset(struct pci_bus *bus, int probe)
 +static int pci_bus_reset(struct pci_bus *bus, bool probe)
  {
        int ret;
  
@@@ -5761,14 -5618,14 +5761,14 @@@ int pci_bus_error_reset(struct pci_dev 
                        goto bus_reset;
  
        list_for_each_entry(slot, &bus->slots, list)
 -              if (pci_slot_reset(slot, 0))
 +              if (pci_slot_reset(slot, PCI_RESET_DO_RESET))
                        goto bus_reset;
  
        mutex_unlock(&pci_slot_mutex);
        return 0;
  bus_reset:
        mutex_unlock(&pci_slot_mutex);
 -      return pci_bus_reset(bridge->subordinate, 0);
 +      return pci_bus_reset(bridge->subordinate, PCI_RESET_DO_RESET);
  }
  
  /**
   */
  int pci_probe_reset_bus(struct pci_bus *bus)
  {
 -      return pci_bus_reset(bus, 1);
 +      return pci_bus_reset(bus, PCI_RESET_PROBE);
  }
  EXPORT_SYMBOL_GPL(pci_probe_reset_bus);
  
@@@ -5793,7 -5650,7 +5793,7 @@@ static int __pci_reset_bus(struct pci_b
  {
        int rc;
  
 -      rc = pci_bus_reset(bus, 1);
 +      rc = pci_bus_reset(bus, PCI_RESET_PROBE);
        if (rc)
                return rc;
  
diff --combined drivers/pci/quirks.c
index e21e8d626741a7d501c2cb45f9f6d0647b1d21bf,68e47002b72cee47e489e3c6eda4d91266f51bda..d7542e01fb56720720995065cb0a209bed0dc819
@@@ -1821,45 -1821,6 +1821,45 @@@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_I
  
  DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, PCI_CLASS_BRIDGE_PCI, 8, quirk_pcie_mch);
  
 +/*
 + * HiSilicon KunPeng920 and KunPeng930 have devices appear as PCI but are
 + * actually on the AMBA bus. These fake PCI devices can support SVA via
 + * SMMU stall feature, by setting dma-can-stall for ACPI platforms.
 + *
 + * Normally stalling must not be enabled for PCI devices, since it would
 + * break the PCI requirement for free-flowing writes and may lead to
 + * deadlock.  We expect PCI devices to support ATS and PRI if they want to
 + * be fault-tolerant, so there's no ACPI binding to describe anything else,
 + * even when a "PCI" device turns out to be a regular old SoC device
 + * dressed up as a RCiEP and normal rules don't apply.
 + */
 +static void quirk_huawei_pcie_sva(struct pci_dev *pdev)
 +{
 +      struct property_entry properties[] = {
 +              PROPERTY_ENTRY_BOOL("dma-can-stall"),
 +              {},
 +      };
 +
 +      if (pdev->revision != 0x21 && pdev->revision != 0x30)
 +              return;
 +
 +      pdev->pasid_no_tlp = 1;
 +
 +      /*
 +       * Set the dma-can-stall property on ACPI platforms. Device tree
 +       * can set it directly.
 +       */
 +      if (!pdev->dev.of_node &&
 +          device_add_properties(&pdev->dev, properties))
 +              pci_warn(pdev, "could not add stall property");
 +}
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0xa250, quirk_huawei_pcie_sva);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0xa251, quirk_huawei_pcie_sva);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0xa255, quirk_huawei_pcie_sva);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0xa256, quirk_huawei_pcie_sva);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0xa258, quirk_huawei_pcie_sva);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0xa259, quirk_huawei_pcie_sva);
 +
  /*
   * It's possible for the MSI to get corrupted if SHPC and ACPI are used
   * together on certain PXH-based systems.
@@@ -3273,13 -3234,12 +3273,13 @@@ static void fixup_mpss_256(struct pci_d
  {
        dev->pcie_mpss = 1; /* 256 bytes */
  }
 -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE,
 -                       PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0, fixup_mpss_256);
 -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE,
 -                       PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256);
 -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE,
 -                       PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256);
 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE,
 +                      PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0, fixup_mpss_256);
 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE,
 +                      PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256);
 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE,
 +                      PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256);
 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ASMEDIA, 0x0612, fixup_mpss_256);
  
  /*
   * Intel 5000 and 5100 Memory controllers have an erratum with read completion
@@@ -3742,7 -3702,7 +3742,7 @@@ DECLARE_PCI_FIXUP_SUSPEND_LATE(PCI_VEND
   * reset a single function if other methods (e.g. FLR, PM D0->D3) are
   * not available.
   */
 -static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
 +static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, bool probe)
  {
        /*
         * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
  #define NSDE_PWR_STATE                0xd0100
  #define IGD_OPERATION_TIMEOUT 10000     /* set timeout 10 seconds */
  
 -static int reset_ivb_igd(struct pci_dev *dev, int probe)
 +static int reset_ivb_igd(struct pci_dev *dev, bool probe)
  {
        void __iomem *mmio_base;
        unsigned long timeout;
@@@ -3807,7 -3767,7 +3807,7 @@@ reset_complete
  }
  
  /* Device-specific reset method for Chelsio T4-based adapters */
 -static int reset_chelsio_generic_dev(struct pci_dev *dev, int probe)
 +static int reset_chelsio_generic_dev(struct pci_dev *dev, bool probe)
  {
        u16 old_command;
        u16 msix_flags;
   *    Chapter 3: NVMe control registers
   *    Chapter 7.3: Reset behavior
   */
 -static int nvme_disable_and_flr(struct pci_dev *dev, int probe)
 +static int nvme_disable_and_flr(struct pci_dev *dev, bool probe)
  {
        void __iomem *bar;
        u16 cmd;
        u32 cfg;
  
        if (dev->class != PCI_CLASS_STORAGE_EXPRESS ||
 -          !pcie_has_flr(dev) || !pci_resource_start(dev, 0))
 +          pcie_reset_flr(dev, PCI_RESET_PROBE) || !pci_resource_start(dev, 0))
                return -ENOTTY;
  
        if (probe)
   * device too soon after FLR.  A 250ms delay after FLR has heuristically
   * proven to produce reliably working results for device assignment cases.
   */
 -static int delay_250ms_after_flr(struct pci_dev *dev, int probe)
 +static int delay_250ms_after_flr(struct pci_dev *dev, bool probe)
  {
 -      if (!pcie_has_flr(dev))
 -              return -ENOTTY;
 -
        if (probe)
 -              return 0;
 +              return pcie_reset_flr(dev, PCI_RESET_PROBE);
  
 -      pcie_flr(dev);
 +      pcie_reset_flr(dev, PCI_RESET_DO_RESET);
  
        msleep(250);
  
  #define HINIC_OPERATION_TIMEOUT     15000     /* 15 seconds */
  
  /* Device-specific reset method for Huawei Intelligent NIC virtual functions */
 -static int reset_hinic_vf_dev(struct pci_dev *pdev, int probe)
 +static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
  {
        unsigned long timeout;
        void __iomem *bar;
@@@ -4056,7 -4019,7 +4056,7 @@@ static const struct pci_dev_reset_metho
   * because when a host assigns a device to a guest VM, the host may need
   * to reset the device but probably doesn't have a driver for it.
   */
 -int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 +int pci_dev_specific_reset(struct pci_dev *dev, bool probe)
  {
        const struct pci_dev_reset_methods *i;
  
@@@ -4651,6 -4614,18 +4651,18 @@@ static int pci_quirk_qcom_rp_acs(struc
                PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
  }
  
+ /*
+  * Each of these NXP Root Ports is in a Root Complex with a unique segment
+  * number and does provide isolation features to disable peer transactions
+  * and validate bus numbers in requests, but does not provide an ACS
+  * capability.
+  */
+ static int pci_quirk_nxp_rp_acs(struct pci_dev *dev, u16 acs_flags)
+ {
+       return pci_acs_ctrl_enabled(acs_flags,
+               PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
+ }
  static int pci_quirk_al_acs(struct pci_dev *dev, u16 acs_flags)
  {
        if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
@@@ -4877,6 -4852,10 +4889,10 @@@ static const struct pci_dev_acs_enable
        { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */
        /* Cavium ThunderX */
        { PCI_VENDOR_ID_CAVIUM, PCI_ANY_ID, pci_quirk_cavium_acs },
+       /* Cavium multi-function devices */
+       { PCI_VENDOR_ID_CAVIUM, 0xA026, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_CAVIUM, 0xA059, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_CAVIUM, 0xA060, pci_quirk_mf_endpoint_acs },
        /* APM X-Gene */
        { PCI_VENDOR_ID_AMCC, 0xE004, pci_quirk_xgene_acs },
        /* Ampere Computing */
        { PCI_VENDOR_ID_ZHAOXIN, 0x3038, pci_quirk_mf_endpoint_acs },
        { PCI_VENDOR_ID_ZHAOXIN, 0x3104, pci_quirk_mf_endpoint_acs },
        { PCI_VENDOR_ID_ZHAOXIN, 0x9083, pci_quirk_mf_endpoint_acs },
+       /* NXP root ports, xx=16, 12, or 08 cores */
+       /* LX2xx0A : without security features + CAN-FD */
+       { PCI_VENDOR_ID_NXP, 0x8d81, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8da1, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8d83, pci_quirk_nxp_rp_acs },
+       /* LX2xx0C : security features + CAN-FD */
+       { PCI_VENDOR_ID_NXP, 0x8d80, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8da0, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8d82, pci_quirk_nxp_rp_acs },
+       /* LX2xx0E : security features + CAN */
+       { PCI_VENDOR_ID_NXP, 0x8d90, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8db0, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8d92, pci_quirk_nxp_rp_acs },
+       /* LX2xx0N : without security features + CAN */
+       { PCI_VENDOR_ID_NXP, 0x8d91, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8db1, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8d93, pci_quirk_nxp_rp_acs },
+       /* LX2xx2A : without security features + CAN-FD */
+       { PCI_VENDOR_ID_NXP, 0x8d89, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8da9, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8d8b, pci_quirk_nxp_rp_acs },
+       /* LX2xx2C : security features + CAN-FD */
+       { PCI_VENDOR_ID_NXP, 0x8d88, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8da8, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8d8a, pci_quirk_nxp_rp_acs },
+       /* LX2xx2E : security features + CAN */
+       { PCI_VENDOR_ID_NXP, 0x8d98, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8db8, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8d9a, pci_quirk_nxp_rp_acs },
+       /* LX2xx2N : without security features + CAN */
+       { PCI_VENDOR_ID_NXP, 0x8d99, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8db9, pci_quirk_nxp_rp_acs },
+       { PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs },
        /* Zhaoxin Root/Downstream Ports */
        { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs },
        { 0 }
@@@ -5068,7 -5080,7 +5117,7 @@@ static int pci_quirk_enable_intel_spt_p
        ctrl |= (cap & PCI_ACS_CR);
        ctrl |= (cap & PCI_ACS_UF);
  
-       if (dev->external_facing || dev->untrusted)
+       if (pci_ats_disabled() || dev->external_facing || dev->untrusted)
                ctrl |= (cap & PCI_ACS_TB);
  
        pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl);
@@@ -5666,7 -5678,7 +5715,7 @@@ static void quirk_reset_lenovo_thinkpad
  
        if (pdev->subsystem_vendor != PCI_VENDOR_ID_LENOVO ||
            pdev->subsystem_device != 0x222e ||
 -          !pdev->reset_fn)
 +          !pci_reset_supported(pdev))
                return;
  
        if (pci_enable_device_mem(pdev))