1. 14 11月, 2017 2 次提交
    • B
      PCI/ASPM: Use correct capability pointer to program LTR_L1.2_THRESHOLD · c00054f5
      Bjorn Helgaas 提交于
      Previously we programmed the LTR_L1.2_THRESHOLD in the parent (upstream)
      device using the capability pointer of the *child* (downstream) device,
      which corrupted some random word of the parent's config space.
      
      Use the parent's L1 SS capability pointer to program its
      LTR_L1.2_THRESHOLD.
      
      Fixes: aeda9ade ("PCI/ASPM: Configure L1 substate settings")
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NVidya Sagar <vidyas@nvidia.com>
      CC: stable@vger.kernel.org	# v4.11+
      CC: Rajat Jain <rajatja@google.com>
      c00054f5
    • B
      PCI/ASPM: Account for downstream device's Port Common_Mode_Restore_Time · 94ac327e
      Bjorn Helgaas 提交于
      Every Port that supports the L1.2 substate advertises its Port
      Common_Mode_Restore_Time, i.e., the time the Port requires to re-establish
      common mode when exiting L1.2 (see PCIe r3.1, sec 7.33.2).
      
      Per sec 5.5.3.3.1, when exiting L1.2, the Downstream Port (the device at
      the upstream end of the link) must send TS1 training sequences for at least
      T(COMMONMODE) after it detects electrical idle exit on the Link.  We want
      this to be long enough for both ends of the Link, so we should set it to
      the maximum of the Port Common_Mode_Restore_Time for the upstream and
      downstream components on the Link.
      
      Previously we only looked at the Port Common_Mode_Restore_Time of the
      upstream device, so if the downstream device required more time, we didn't
      program the upstream device's T(COMMONMODE) correctly.
      
      Fixes: f1f0366d ("PCI/ASPM: Calculate and save the L1.2 timing parameters")
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NVidya Sagar <vidyas@nvidia.com>
      Acked-by: NRajat Jain <rajatja@google.com>
      CC: stable@vger.kernel.org	# v4.11+
      94ac327e
  2. 06 10月, 2017 1 次提交
    • A
      PCI/ASPM: Deal with missing root ports in link state handling · ee8bdfb6
      Ard Biesheuvel 提交于
      Even though it is unconventional, some PCIe host implementations omit the
      root ports entirely, and simply consist of a host bridge (which is not
      modeled as a device in the PCI hierarchy) and a link.
      
      When the downstream device is an endpoint, our current code does not seem
      to mind this unusual configuration. However, when PCIe switches are
      involved, the ASPM code assumes that any downstream switch port has a
      parent, and blindly dereferences the bus->parent->self field of the pci_dev
      struct to chain the downstream link state to the link state of the root
      port. Given that the root port is missing, the link is not modeled at all,
      and nor is the link state, and attempting to access it results in a NULL
      pointer dereference and a crash.
      
      Avoid this by allowing the link state chain to terminate at the downstream
      port if no root port exists.
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      ee8bdfb6
  3. 14 9月, 2017 1 次提交
  4. 02 9月, 2017 1 次提交
  5. 25 8月, 2017 2 次提交
  6. 01 8月, 2017 1 次提交
  7. 13 7月, 2017 1 次提交
    • R
      PCI / PM: Fix native PME handling during system suspend/resume · c7b5a4e6
      Rafael J. Wysocki 提交于
      Commit 76cde7e4 (PCI / PM: Make PCIe PME interrupts wake up from
      suspend-to-idle) went too far with preventing pcie_pme_work_fn() from
      clearing the root port's PME Status and re-enabling the PME interrupt
      which should be done for PMEs to work correctly after system resume.
      
      The failing scenario is as follows:
      
       1. pcie_pme_suspend() finds that the PME IRQ should be designated
          for system wakeup, so it calls enable_irq_wake() and then sets
          data->suspend_level to PME_SUSPEND_WAKEUP.
      
       2. PME interrupt happens at this point.
      
       3. pcie_pme_irq() runs, disables the PME interrupt and queues up
          the execution of pcie_pme_work_fn().
      
       4. pcie_pme_work_fn() runs before pcie_pme_resume() and breaks out
          of the loop right away, because data->suspend_level is not
          PME_SUSPEND_NONE, and it doesn't re-enable the PME interrupt
          for the same reason.
      
       5. pcie_pme_resume() runs and simply calls disable_irq_wake()
          without re-enabling the PME interrupt (because data->suspend_level
          is not PME_SUSPEND_NONE), so the PME interrupt remains disabled
          and the PME Status remains set.
      
      To fix this notice that there is no reason why pcie_pme_work_fn()
      should behave in a special way during system resume if the PME
      interrupt is not disabled by pcie_pme_suspend() and partially revert
      commit 76cde7e4 and restore the previous (and correct) behavior
      of pcie_pme_work_fn().
      
      Fixes: 76cde7e4 (PCI / PM: Make PCIe PME interrupts wake up from suspend-to-idle)
      Reported-and-tested-by: NNaresh Solanki <naresh.solanki@intel.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NBjorn Helgaas <bhelgaas@google.com>
      c7b5a4e6
  8. 28 6月, 2017 2 次提交
    • R
      PM / core: Drop run_wake flag from struct dev_pm_info · de3ef1eb
      Rafael J. Wysocki 提交于
      The run_wake flag in struct dev_pm_info is used to indicate whether
      or not the device is capable of generating remote wakeup signals at
      run time (or in the system working state), but the distinction
      between runtime remote wakeup and system wakeup signaling has always
      been rather artificial.  The only practical reason for it to exist
      at the core level was that ACPI and PCI treated those two cases
      differently, but that's not the case any more after recent changes.
      
      For this reason, get rid of the run_wake flag and, when applicable,
      use device_set_wakeup_capable() and device_can_wakeup() instead of
      device_set_run_wake() and device_run_wake(), respectively.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Acked-by: NBjorn Helgaas <bhelgaas@google.com>
      de3ef1eb
    • R
      PCI / PM: Drop pme_interrupt flag from struct pci_dev · 8370c2dc
      Rafael J. Wysocki 提交于
      The pme_interrupt flag in struct pci_dev is set when PMEs generated
      by the device are going to be signaled via root port PME interrupts.
      
      Ironically enough, that information is only used by the code setting
      up device wakeup through ACPI which returns as soon as it sees the
      pme_interrupt flag set while setting up "remote runtime wakeup".
      That is questionable, however, because in theory there may be PCIe
      devices using out-of-band PME signaling under root ports handled
      by the native PME code or devices requiring wakeup power setup to be
      carried out by AML.  For such devices, ACPI wakeup should be invoked
      regardless of whether or not native PME signaling is used in general.
      
      For this reason, drop the pme_interrupt flag and rework the code
      using it which then allows the ACPI-based device wakeup handling
      in PCI to be consolidated to use one code path for both "runtime
      remote wakeup" and system wakeup (from sleep states).
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Acked-by: NBjorn Helgaas <bhelgaas@google.com>
      8370c2dc
  9. 17 6月, 2017 2 次提交
  10. 23 5月, 2017 2 次提交
  11. 30 3月, 2017 1 次提交
  12. 08 3月, 2017 1 次提交
    • Y
      PCI/ASPM: Always set link->downstream to avoid NULL dereference on remove · 3bd7db63
      Yinghai Lu 提交于
      We call pcie_aspm_exit_link_state() when we remove a device.  If the device
      is the last PCIe function to be removed below a bridge and the bridge has
      an ASPM link_state struct, we disable ASPM on the link.  Disabling ASPM
      requires link->downstream (used in pcie_config_aspm_link()).
      
      We previously set link->downstream in pcie_aspm_cap_init(), but only if the
      device was not blacklisted.  Removing the blacklisted device caused a NULL
      pointer dereference in the pcie_aspm_exit_link_state() ->
      pcie_config_aspm_link() path:
      
        # echo 1 > /sys/bus/pci/devices/0000\:0b\:00.0/remove
        ...
         BUG: unable to handle kernel NULL pointer dereference at 0000000000000080
         IP: pcie_config_aspm_link+0x5d/0x2b0
         Call Trace:
          pcie_aspm_exit_link_state+0x75/0x130
          pci_stop_bus_device+0xa4/0xb0
          pci_stop_and_remove_bus_device_locked+0x1a/0x30
          remove_store+0x50/0x70
          dev_attr_store+0x18/0x30
          sysfs_kf_write+0x44/0x60
          kernfs_fop_write+0x10e/0x190
          __vfs_write+0x28/0x110
          ? rcu_read_lock_sched_held+0x5d/0x80
          ? rcu_sync_lockdep_assert+0x2c/0x60
          ? __sb_start_write+0x173/0x1a0
          ? vfs_write+0xb3/0x180
          vfs_write+0xc4/0x180
          SyS_write+0x49/0xa0
          do_syscall_64+0xa6/0x1c0
          entry_SYSCALL64_slow_path+0x25/0x25
         ---[ end trace bd187ee0267df5d9 ]---
      
      To avoid this, set link->downstream in alloc_pcie_link_state(), so every
      pcie_link_state structure has a valid link->downstream pointer.
      
      [bhelgaas: changelog]
      Signed-off-by: NYinghai Lu <yinghai@kernel.org>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Acked-by: NRajat Jain <rajatja@google.com>
      CC: stable@vger.kernel.org
      3bd7db63
  13. 15 2月, 2017 6 次提交
    • Y
      PCI/PME: Restore pcie_pme_driver.remove · afe3e4d1
      Yinghai Lu 提交于
      In addition to making PME non-modular, d7def204 ("PCI/PME: Make
      explicitly non-modular") removed the pcie_pme_driver .remove() method,
      pcie_pme_remove().
      
      pcie_pme_remove() freed the PME IRQ that was requested in pci_pme_probe().
      The fact that we don't free the IRQ after d7def204 causes the following
      crash when removing a PCIe port device via /sys:
      
        ------------[ cut here ]------------
        kernel BUG at drivers/pci/msi.c:370!
        invalid opcode: 0000 [#1] SMP
        Modules linked in:
        CPU: 1 PID: 14509 Comm: sh Tainted: G    W  4.8.0-rc1-yh-00012-gd29438d6
        RIP: 0010:[<ffffffff9758bbf5>]  free_msi_irqs+0x65/0x190
        ...
        Call Trace:
         [<ffffffff9758cda4>] pci_disable_msi+0x34/0x40
         [<ffffffff97583817>] cleanup_service_irqs+0x27/0x30
         [<ffffffff97583e9a>] pcie_port_device_remove+0x2a/0x40
         [<ffffffff97584250>] pcie_portdrv_remove+0x40/0x50
         [<ffffffff97576d7b>] pci_device_remove+0x4b/0xc0
         [<ffffffff9785ebe6>] __device_release_driver+0xb6/0x150
         [<ffffffff9785eca5>] device_release_driver+0x25/0x40
         [<ffffffff975702e4>] pci_stop_bus_device+0x74/0xa0
         [<ffffffff975704ea>] pci_stop_and_remove_bus_device_locked+0x1a/0x30
         [<ffffffff97578810>] remove_store+0x50/0x70
         [<ffffffff9785a378>] dev_attr_store+0x18/0x30
         [<ffffffff97260b64>] sysfs_kf_write+0x44/0x60
         [<ffffffff9725feae>] kernfs_fop_write+0x10e/0x190
         [<ffffffff971e13f8>] __vfs_write+0x28/0x110
         [<ffffffff970b0fa4>] ? percpu_down_read+0x44/0x80
         [<ffffffff971e53a7>] ? __sb_start_write+0xa7/0xe0
         [<ffffffff971e53a7>] ? __sb_start_write+0xa7/0xe0
         [<ffffffff971e1f04>] vfs_write+0xc4/0x180
         [<ffffffff971e3089>] SyS_write+0x49/0xa0
         [<ffffffff97001a46>] do_syscall_64+0xa6/0x1b0
         [<ffffffff9819201e>] entry_SYSCALL64_slow_path+0x25/0x25
        ...
         RIP  [<ffffffff9758bbf5>] free_msi_irqs+0x65/0x190
         RSP <ffff89ad3085bc48>
        ---[ end trace f4505e1dac5b95d3 ]---
        Segmentation fault
      
      Restore pcie_pme_remove().
      
      [bhelgaas: changelog]
      Fixes: d7def204 ("PCI/PME: Make explicitly non-modular")
      Signed-off-by: NYinghai Lu <yinghai@kernel.org>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Acked-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      CC: stable@vger.kernel.org	# v4.9+
      afe3e4d1
    • R
      PCI/ASPM: Add comment about L1 substate latency · a142f4d3
      Rajat Jain 提交于
      Since the exit latencies for L1 substates are not advertised by a device,
      it is not clear in spec how to do a L1 substate exit latency check.  We
      assume that the L1 exit latencies advertised by a device include L1
      substate latencies (and hence do not do any check).  If that is not true,
      we should do some sort of check here.
      
      (I'm not clear about what that check should like currently. I'd be glad to
      take up any suggestions).
      Signed-off-by: NRajat Jain <rajatja@google.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      a142f4d3
    • R
      PCI/ASPM: Configure L1 substate settings · aeda9ade
      Rajat Jain 提交于
      Configure the L1 substate settings on the upstream and downstream devices,
      while taking care of the rules dictated by the PCIe spec.
      
      [bhelgaas: drop "inline"]
      Signed-off-by: NRajat Jain <rajatja@google.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      aeda9ade
    • R
      PCI/ASPM: Calculate and save the L1.2 timing parameters · f1f0366d
      Rajat Jain 提交于
      Calculate and save the timing parameters that need to be programmed if we
      need to enable L1.2 substates later.
      
      We use the same logic (and a constant value for 1 of the parameters) as
      used by Intel's coreboot:
      
        https://www.coreboot.org/pipermail/coreboot-gerrit/2015-March/021134.html
        https://review.coreboot.org/#/c/8832/Signed-off-by: NRajat Jain <rajatja@google.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      f1f0366d
    • R
      PCI/ASPM: Read and set up L1 substate capabilities · b5a0a9b5
      Rajat Jain 提交于
      The PCIe spec (r3.1, sec 7.33) says the L1 PM Substates Capability may be
      implemented only in function 0.
      
      Read the L1 substate capability structures of upstream and downstream
      components of the link and set it up in the device structure.
      
      [bhelgaas: add specific spec reference]
      Signed-off-by: NRajat Jain <rajatja@google.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      b5a0a9b5
    • R
      PCI/ASPM: Add support for L1 substates · b2103ccb
      Rajat Jain 提交于
      Add support for ASPM L1 substates.  For details about L1 substates, see the
      PCIe r3.1 spec, which includes the ECN below in secs 5.5 and 7.33.
      
      Add macros for the 4 new L1 substates, and add a new ASPM "POWER_SUPERSAVE"
      policy that can be used to enable L1 substates on a system if desired.  The
      new policy is in a sense, a superset of the existing POWERSAVE policy.  The
      4 policies are now:
      
        DEFAULT: Reads and uses whatever ASPM states BIOS enabled
        PERFORMANCE: Everything except L0 disabled.
        POWERSAVE: L0s and L1 enabled (but not L1 substates)
        POWER_SUPERSAVE: L0s + L1 + L1 substates also enabled
      
      [bhelgaas: add PCIe r3.1 spec reference]
      Link: https://pcisig.com/sites/default/files/specification_documents/ECN_L1_PM_Substates_with_CLKREQ_31_May_2013_Rev10a.pdfSigned-off-by: NRajat Jain <rajatja@google.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      b2103ccb
  14. 11 2月, 2017 3 次提交
  15. 28 1月, 2017 1 次提交
  16. 13 12月, 2016 6 次提交
  17. 09 12月, 2016 1 次提交
  18. 24 11月, 2016 1 次提交
  19. 18 11月, 2016 2 次提交
  20. 15 11月, 2016 1 次提交
    • J
      PCI/ASPM: Use permission-specific DEVICE_ATTR variants · fc4f57fa
      Julia Lawall 提交于
      Use DEVICE_ATTR_RW for read-write attributes.  This simplifies the source
      code, improves readability, and reduces the chance of inconsistencies.
      
      The semantic patch that makes this change is as follows:
      (http://coccinelle.lip6.fr/)
      
      // <smpl>
      @rw@
      declarer name DEVICE_ATTR;
      identifier x,x_show,x_store;
      @@
      
      DEVICE_ATTR(x, \(0644\|S_IRUGO|S_IWUSR\), x_show, x_store);
      
      @script:ocaml@
      x << rw.x;
      x_show << rw.x_show;
      x_store << rw.x_store;
      @@
      
      if not (x^"_show" = x_show && x^"_store" = x_store)
      then Coccilib.include_match false
      
      @@
      declarer name DEVICE_ATTR_RW;
      identifier rw.x,rw.x_show,rw.x_store;
      @@
      
      - DEVICE_ATTR(x, \(0644\|S_IRUGO|S_IWUSR\), x_show, x_store);
      + DEVICE_ATTR_RW(x);
      // </smpl>
      Signed-off-by: NJulia Lawall <Julia.Lawall@lip6.fr>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      fc4f57fa
  21. 30 9月, 2016 1 次提交
  22. 28 9月, 2016 1 次提交