1. 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
  2. 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
  3. 15 2月, 2017 5 次提交
  4. 28 1月, 2017 1 次提交
  5. 09 12月, 2016 1 次提交
  6. 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
  7. 11 6月, 2016 1 次提交
  8. 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
  9. 11 6月, 2015 1 次提交
  10. 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
  11. 21 5月, 2015 2 次提交
  12. 10 4月, 2015 1 次提交
  13. 10 1月, 2015 1 次提交
  14. 14 1月, 2014 1 次提交
  15. 15 11月, 2013 1 次提交
  16. 29 5月, 2013 1 次提交
  17. 22 5月, 2013 1 次提交
  18. 02 2月, 2013 2 次提交
  19. 15 1月, 2013 1 次提交
  20. 08 12月, 2012 1 次提交
  21. 08 11月, 2012 1 次提交
  22. 24 8月, 2012 1 次提交
  23. 23 8月, 2012 1 次提交
  24. 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
  25. 08 3月, 2012 1 次提交
  26. 18 2月, 2012 1 次提交
  27. 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
  28. 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
  29. 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
  30. 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
  31. 11 5月, 2011 1 次提交
  32. 22 3月, 2011 3 次提交