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. 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
  4. 15 2月, 2017 5 次提交
  5. 28 1月, 2017 1 次提交
  6. 09 12月, 2016 1 次提交
  7. 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
  8. 11 6月, 2016 1 次提交
  9. 04 12月, 2015 1 次提交
    • A
      PCI/ASPM: Make sysfs link_state_store() consistent with link_state_show() · 57d86a04
      Andy Lutomirski 提交于
      If CONFIG_PCIEASPM_DEBUG is set, then PCI devices have a link_state
      attribute.  Reading that attribute shows the state as a bit mask: 1
      means L0S upstream, 2 means L0S downstream, and 4 means L1.
      
      Oddly, writing to link_state is inconsistent and gets translated, leading
      to mysterious results in which the value you store isn't comparable the
      value you load back out.
      
      Fix it by making link_state_store() match link_state_show().
      
      [bhelgaas: Check "aspm_disabled" *before* validating input.  When
      "aspm_disabled" is set, this changes the error for invalid input from
      -EINVAL to -EPERM.]
      Signed-off-by: NAndy Lutomirski <luto@kernel.org>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      57d86a04
  10. 11 6月, 2015 1 次提交
  11. 27 5月, 2015 1 次提交
    • Y
      PCI/ASPM: Use dev->has_secondary_link to find downstream links · c8fc9339
      Yijing Wang 提交于
      We allocate pcie_link_state for the component at the upstream end of a
      Link.  Previously we did this by allocating pcie_link_state for Root Ports
      and Downstream Ports.  This works fine for the typical topology:
      
        00:1c.0 Root Port       [bridge to bus 02]
        02:00.0 Upstream Port   [bridge to bus 03]
        03:00.0 Downstream Port [bridge to bus 04]
        04:00.0 Endpoint or Switch Port
      
      However, it is possible to have a Root Port connected to a Downstream Port
      instead of an Upstream Port, as in Robert White's ATCA system:
      
        00:1c.0 Root Port       [bridge to bus 02]
        02:00.0 Downstream Port [bridge to bus 03]
        03:01.0 Downstream Port [bridge to bus 04]
        04:00.0 Endpoint or Switch Port
      
      In this topology, we wrongly allocated pcie_link_state for the 02:00.0
      Downstream Port, which is actually the *downstream* end of a link.  This
      led to the following NULL pointer dereference when we tried to connect this
      link into the tree of links starting at the 00:1c.0 Root Port:
      
        BUG: unable to handle kernel NULL pointer dereference at 0000000000000088
        IP: [<ffffffff81550324>] pcie_aspm_init_link_state+0x744/0x850
        Hardware name: Kontron B3001/B3001, BIOS 4.6.3 08/07/2012
        Call Trace:
         [<ffffffff8153b865>] pci_scan_slot+0xd5/0x120
         [<ffffffff8153ca1d>] pci_scan_child_bus+0x2d/0xd0
         ...
      
      Instead of relying on the component type to identify the upstream end of a
      link, use the "dev->has_secondary_link" field.
      
      This means it's now possible for an Upstream Port to have a link on its
      secondary side, so alloc_pcie_link_state() needs to connect links
      originating from both Upstream and Downstream Ports into the tree.
      
      [bhelgaas: changelog, add comment]
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=94361
      Link: http://lkml.kernel.org/r/54EB81B2.4050904@pobox.comReported-by: NRobert White <rwhite@pobox.com>
      Signed-off-by: NYijing Wang <wangyijing@huawei.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      c8fc9339
  12. 21 5月, 2015 2 次提交
  13. 10 4月, 2015 1 次提交
  14. 10 1月, 2015 1 次提交
  15. 14 1月, 2014 1 次提交
  16. 15 11月, 2013 1 次提交
  17. 29 5月, 2013 1 次提交
  18. 22 5月, 2013 1 次提交
  19. 02 2月, 2013 2 次提交
  20. 15 1月, 2013 1 次提交
  21. 08 12月, 2012 1 次提交
  22. 08 11月, 2012 1 次提交
  23. 24 8月, 2012 1 次提交
  24. 23 8月, 2012 1 次提交
  25. 01 4月, 2012 1 次提交
    • M
      ASPM: Fix pcie devices with non-pcie children · c9651e70
      Matthew Garrett 提交于
      Since 3.2.12 and 3.3, some systems are failing to boot with a BUG_ON.
      Some other systems using the pata_jmicron driver fail to boot because no
      disks are detected.  Passing pcie_aspm=force on the kernel command line
      works around it.
      
      The cause: commit 4949be16 ("PCI: ignore pre-1.1 ASPM quirking when
      ASPM is disabled") changed the behaviour of pcie_aspm_sanity_check() to
      always return 0 if aspm is disabled, in order to avoid cases where we
      changed ASPM state on pre-PCIe 1.1 devices.
      
      This skipped the secondary function of pcie_aspm_sanity_check which was
      to avoid us enabling ASPM on devices that had non-PCIe children, causing
      trouble later on.  Move the aspm_disabled check so we continue to honour
      that scenario.
      
      Addresses https://bugzilla.kernel.org/show_bug.cgi?id=42979 and
                http://bugs.debian.org/665420
      
      Reported-by: Romain Francoise <romain@orebokech.com> # kernel panic
      Reported-by: Chris Holland <bandidoirlandes@gmail.com> # disk detection trouble
      Signed-off-by: NMatthew Garrett <mjg@redhat.com>
      Cc: stable@vger.kernel.org
      Tested-by: Hatem Masmoudi <hatem.masmoudi@gmail.com> # Dell Latitude E5520
      Tested-by: janek <jan0x6c@gmail.com> # pata_jmicron with JMB362/JMB363
      [jn: with more symptoms in log message]
      Signed-off-by: NJonathan Nieder <jrnieder@gmail.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      c9651e70
  26. 08 3月, 2012 1 次提交
  27. 18 2月, 2012 1 次提交
  28. 07 1月, 2012 1 次提交
    • M
      PCI: Rework ASPM disable code · 10f6dc7e
      Matthew Garrett 提交于
      Right now we forcibly clear ASPM state on all devices if the BIOS indicates
      that the feature isn't supported. Based on the Microsoft presentation
      "PCI Express In Depth for Windows Vista and Beyond", I'm starting to think
      that this may be an error. The implication is that unless the platform
      grants full control via _OSC, Windows will not touch any PCIe features -
      including ASPM. In that case clearing ASPM state would be an error unless
      the platform has granted us that control.
      
      This patch reworks the ASPM disabling code such that the actual clearing
      of state is triggered by a successful handoff of PCIe control to the OS.
      The general ASPM code undergoes some changes in order to ensure that the
      ability to clear the bits isn't overridden by ASPM having already been
      disabled. Further, this theoretically now allows for situations where
      only a subset of PCIe roots hand over control, leaving the others in the
      BIOS state.
      
      It's difficult to know for sure that this is the right thing to do -
      there's zero public documentation on the interaction between all of these
      components. But enough vendors enable ASPM on platforms and then set this
      bit that it seems likely that they're expecting the OS to leave them alone.
      
      Measured to save around 5W on an idle Thinkpad X220.
      Signed-off-by: NMatthew Garrett <mjg@redhat.com>
      Signed-off-by: NJesse Barnes <jbarnes@virtuousgeek.org>
      10f6dc7e
  29. 06 12月, 2011 1 次提交
    • M
      PCI: Rework ASPM disable code · 3c076351
      Matthew Garrett 提交于
      Right now we forcibly clear ASPM state on all devices if the BIOS indicates
      that the feature isn't supported. Based on the Microsoft presentation
      "PCI Express In Depth for Windows Vista and Beyond", I'm starting to think
      that this may be an error. The implication is that unless the platform
      grants full control via _OSC, Windows will not touch any PCIe features -
      including ASPM. In that case clearing ASPM state would be an error unless
      the platform has granted us that control.
      
      This patch reworks the ASPM disabling code such that the actual clearing
      of state is triggered by a successful handoff of PCIe control to the OS.
      The general ASPM code undergoes some changes in order to ensure that the
      ability to clear the bits isn't overridden by ASPM having already been
      disabled. Further, this theoretically now allows for situations where
      only a subset of PCIe roots hand over control, leaving the others in the
      BIOS state.
      
      It's difficult to know for sure that this is the right thing to do -
      there's zero public documentation on the interaction between all of these
      components. But enough vendors enable ASPM on platforms and then set this
      bit that it seems likely that they're expecting the OS to leave them alone.
      
      Measured to save around 5W on an idle Thinkpad X220.
      Signed-off-by: NMatthew Garrett <mjg@redhat.com>
      Signed-off-by: NJesse Barnes <jbarnes@virtuousgeek.org>
      3c076351
  30. 29 6月, 2011 1 次提交
    • M
      PCIe ASPM: forcedly -> forcibly · 8072ba1b
      Michael Witten 提交于
      Merriam-Webster tells us that the word exists. However ...
      
        * Google suggests `forcibly' because it doesn't recognize `forcedly'.
        * Google lists 494 thousand results for `forcedly'.
        * Google lists 13.7 million results for `forcibly'.
        * Linus's repo contains  1 occurrence  of `forcedly' ( 0 after my change).
        * Linus's repo contains 60 occurrences of `forcibly' (61 after my change).
      Signed-off-by: NMichael Witten <mfwitten@gmail.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      8072ba1b
  31. 22 5月, 2011 1 次提交
    • Y
      PCI/e1000e: Add and use pci_disable_link_state_locked() · 9f728f53
      Yinghai Lu 提交于
      Need to use it in _e1000e_disable_aspm.  This routine is used for error
      recovery, where the pci_bus_sem is already held, and we don't want
      pci_disable_link_state to try to take it again.  So add a locked variant
      for use in cases like this.
      
      Found lock up:
      
      [ 2374.654557] kworker/32:1    D ffff881027f6b0f0     0  6075      2 0x00000000
      [ 2374.654816]  ffff88503f099a68 0000000000000046 ffff88503f098000 0000000000004000
      [ 2374.654837]  00000000001d1ec0 ffff88503f099fd8 00000000001d1ec0 ffff88503f099fd8
      [ 2374.654860]  0000000000004000 00000000001d1ec0 ffff88503dcc8000 ffff88503f090000
      [ 2374.654880] Call Trace:
      [ 2374.654898]  [<ffffffff810b1302>] ? __lock_acquired+0x3a/0x224
      [ 2374.654914]  [<ffffffff81c2b59c>] ? _raw_spin_unlock_irq+0x30/0x36
      [ 2374.654925]  [<ffffffff810b069d>] ? trace_hardirqs_on_caller+0x1f/0x178
      [ 2374.654936]  [<ffffffff81c2ab24>] rwsem_down_failed_common+0xd3/0x103
      [ 2374.654945]  [<ffffffff810b158f>] ? __lock_contended+0x3a/0x2a2
      [ 2374.654955]  [<ffffffff81c2ab7b>] rwsem_down_read_failed+0x12/0x14
      [ 2374.654967]  [<ffffffff813371e4>] call_rwsem_down_read_failed+0x14/0x30
      [ 2374.654981]  [<ffffffff8135df20>] ? pci_disable_link_state+0x5f/0xf5
      [ 2374.654990]  [<ffffffff81c2a0e6>] ? down_read+0x7e/0x91
      [ 2374.654999]  [<ffffffff8135df20>] ? pci_disable_link_state+0x5f/0xf5
      [ 2374.655008]  [<ffffffff8135df20>] pci_disable_link_state+0x5f/0xf5
      [ 2374.655024]  [<ffffffff81661796>] e1000e_disable_aspm+0x55/0x5a
      [ 2374.655037]  [<ffffffff816677eb>] e1000_io_slot_reset+0x59/0xea
      [ 2374.655048]  [<ffffffff8135fe0d>] ? report_mmio_enabled+0x5d/0x5d
      [ 2374.655057]  [<ffffffff8135fe3b>] report_slot_reset+0x2e/0x5d
      [ 2374.655072]  [<ffffffff8135369e>] pci_walk_bus+0x8a/0xb7
      [ 2374.655081]  [<ffffffff8135fe0d>] ? report_mmio_enabled+0x5d/0x5d
      [ 2374.655091]  [<ffffffff813603be>] broadcast_error_message+0xa4/0xb2
      [ 2374.655101]  [<ffffffff81352c71>] ? pci_bus_read_config_dword+0x72/0x80
      [ 2374.655110]  [<ffffffff813606df>] do_recovery+0x9e/0xf9
      [ 2374.655120]  [<ffffffff81360786>] handle_error_source+0x4c/0x51
      [ 2374.655129]  [<ffffffff81360974>] aer_isr_one_error+0x1e9/0x21a
      [ 2374.655138]  [<ffffffff81360a6c>] aer_isr+0xc7/0xcc
      [ 2374.655147]  [<ffffffff813609a5>] ? aer_isr_one_error+0x21a/0x21a
      [ 2374.655159]  [<ffffffff81096d9f>] process_one_work+0x237/0x3ec
      [ 2374.655168]  [<ffffffff81096d10>] ? process_one_work+0x1a8/0x3ec
      [ 2374.655178]  [<ffffffff8109728d>] worker_thread+0x17c/0x240
      [ 2374.655186]  [<ffffffff810b0803>] ? trace_hardirqs_on+0xd/0xf
      [ 2374.655196]  [<ffffffff81097111>] ? manage_workers+0xab/0xab
      [ 2374.655209]  [<ffffffff8109c8ed>] kthread+0xa0/0xa8
      [ 2374.655223]  [<ffffffff81c332d4>] kernel_thread_helper+0x4/0x10
      [ 2374.655232]  [<ffffffff81c2b880>] ? retint_restore_args+0xe/0xe
      [ 2374.655243]  [<ffffffff8109c84d>] ? __init_kthread_worker+0x5b/0x5b
      [ 2374.655252]  [<ffffffff81c332d0>] ? gs_change+0xb/0xb
      
      when aer happens,
      pci_walk_bus already have down_read(&pci_bus_sem)...
      then report_slot_reset
              ==> e1000_io_slot_reset
                      ==> e1000e_disable_aspm
                              ==> pci_disable_link_state...
      
      We can not use pci_disable_link_state, and it will try to hold pci_bus_sem again.
      
      Try to have __pci_disable_link_state that will not need to hold pci_bus_sem.
      
      -v2: change name to pci_disable_link_state_locked() according to Jesse.
      
      [jbarnes: make sure new function is exported for modules]
      Signed-off-by: NYinghai Lu <yinghai@kernel.org>
      Signed-off-by: NJesse Barnes <jbarnes@virtuousgeek.org>
      9f728f53
  32. 11 5月, 2011 1 次提交
  33. 22 3月, 2011 1 次提交
    • N
      PCI: Changing ASPM policy, via /sys, to POWERSAVE could cause NMIs · bbfa306a
      Naga Chumbalkar 提交于
      v3 -> v2: Modified the text that describes the problem
      v2 -> v1: Returned -EPERM
      v1      : http://marc.info/?l=linux-pci&m=130013194803727&w=2
      
      For servers whose hardware cannot handle ASPM the BIOS ought to set the
      FADT bit shown below:
      In Sec 5.2.9.3 (IA-PC Boot Arch. Flags) of ACPI4.0a Specification, please
      see Table 5-11:
      PCIe ASPM Controls: If set, indicates to OSPM that it must not enable
      OPSM ASPM control on this platform.
      
      However there are shipping servers whose BIOS did not set this bit. (An
      example is the HP ProLiant DL385 G6. A Maintenance BIOS will fix that).
      For such servers even if a call is made via pci_no_aspm(), based on _OSC
      support in the BIOS, it may be too late because the ASPM code may have
      already allocated and filled its "link_list".
      
      So if a user sets the ASPM "policy" to "powersave" via /sys then
      pcie_aspm_set_policy() will run through the "link_list" and re-configure
      ASPM policy on devices that advertise ASPM L0s/L1 capability:
      # echo powersave > /sys/module/pcie_aspm/parameters/policy
      # cat /sys/module/pcie_aspm/parameters/policy
      default performance [powersave]
      
      That can cause NMIs since the hardware doesn't play well with ASPM:
      [ 1651.906015] NMI: PCI system error (SERR) for reason b1 on CPU 0.
      [ 1651.906015] Dazed and confused, but trying to continue
      
      Ideally, the BIOS should have set that FADT bit in the first place but we
      could be more robust - especially given the fact that Windows doesn't
      cause NMIs in the above scenario.
      
      There should be a sanity check to not allow a user to modify ASPM policy
      when aspm_disabled is set.
      Signed-off-by: NNaga Chumbalkar <nagananda.chumbalkar@hp.com>
      Acked-by: NRafael J. Wysocki <rjw@sisk.pl>
      Cc: Matthew Garrett <mjg59@srcf.ucam.org>
      Signed-off-by: NJesse Barnes <jbarnes@virtuousgeek.org>
      bbfa306a