1. 02 9月, 2020 1 次提交
  2. 21 12月, 2019 1 次提交
    • J
      PCI/MSI: Fix incorrect MSI-X masking on resume · 8d588ce7
      Jian-Hong Pan 提交于
      commit e045fa29e89383c717e308609edd19d2fd29e1be upstream.
      
      When a driver enables MSI-X, msix_program_entries() reads the MSI-X Vector
      Control register for each vector and saves it in desc->masked.  Each
      register is 32 bits and bit 0 is the actual Mask bit.
      
      When we restored these registers during resume, we previously set the Mask
      bit if *any* bit in desc->masked was set instead of when the Mask bit
      itself was set:
      
        pci_restore_state
          pci_restore_msi_state
            __pci_restore_msix_state
              for_each_pci_msi_entry
                msix_mask_irq(entry, entry->masked)   <-- entire u32 word
                  __pci_msix_desc_mask_irq(desc, flag)
                    mask_bits = desc->masked & ~PCI_MSIX_ENTRY_CTRL_MASKBIT
                    if (flag)       <-- testing entire u32, not just bit 0
                      mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT
                    writel(mask_bits, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL)
      
      This means that after resume, MSI-X vectors were masked when they shouldn't
      be, which leads to timeouts like this:
      
        nvme nvme0: I/O 978 QID 3 timeout, completion polled
      
      On resume, set the Mask bit only when the saved Mask bit from suspend was
      set.
      
      This should remove the need for 19ea025e1d28 ("nvme: Add quirk for Kingston
      NVME SSD running FW E8FK11.T").
      
      [bhelgaas: commit log, move fix to __pci_msix_desc_mask_irq()]
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=204887
      Link: https://lore.kernel.org/r/20191008034238.2503-1-jian-hong@endlessm.com
      Fixes: f2440d9a ("PCI MSI: Refactor interrupt masking code")
      Signed-off-by: NJian-Hong Pan <jian-hong@endlessm.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8d588ce7
  3. 05 12月, 2019 1 次提交
    • M
      PCI/MSI: Return -ENOSPC from pci_alloc_irq_vectors_affinity() · 3e059545
      Ming Lei 提交于
      [ Upstream commit 77f88abd4a6f73a1a68dbdc0e3f21575fd508fc3 ]
      
      The API of pci_alloc_irq_vectors_affinity() says it returns -ENOSPC if
      fewer than @min_vecs interrupt vectors are available for @dev.
      
      However, if a device supports MSI-X but not MSI and a caller requests
      @min_vecs that can't be satisfied by MSI-X, we previously returned -EINVAL
      (from the failed attempt to enable MSI), not -ENOSPC.
      
      When -ENOSPC is returned, callers may reduce the number IRQs they request
      and try again.  Most callers can use the @min_vecs and @max_vecs
      parameters to avoid this retry loop, but that doesn't work when using IRQ
      affinity "nr_sets" because rebalancing the sets is driver-specific.
      
      This return value bug has been present since pci_alloc_irq_vectors() was
      added in v4.10 by aff17164 ("PCI: Provide sensible IRQ vector
      alloc/free routines"), but it wasn't an issue because @min_vecs/@max_vecs
      removed the need for callers to iteratively reduce the number of IRQs
      requested and retry the allocation, so they didn't need to distinguish
      -ENOSPC from -EINVAL.
      
      In v5.0, 6da4b3ab9a6e ("genirq/affinity: Add support for allocating
      interrupt sets") added IRQ sets to the interface, which reintroduced the
      need to check for -ENOSPC and possibly reduce the number of IRQs requested
      and retry the allocation.
      Signed-off-by: NMing Lei <ming.lei@redhat.com>
      [bhelgaas: changelog]
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Cc: Jens Axboe <axboe@fb.com>
      Cc: Keith Busch <keith.busch@intel.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      3e059545
  4. 14 11月, 2018 1 次提交
    • T
      PCI/MSI: Warn and return error if driver enables MSI/MSI-X twice · f17c1795
      Tonghao Zhang 提交于
      [ Upstream commit 4c1ef72e9b71a19fb405ebfcd37c0a5e16fa44ca ]
      
      It is a serious driver defect to enable MSI or MSI-X more than once.  Doing
      so may panic the kernel as in the stack trace below:
      
        Call Trace:
          sysfs_add_one+0xa5/0xd0
          create_dir+0x7c/0xe0
          sysfs_create_subdir+0x1c/0x20
          internal_create_group+0x6d/0x290
          sysfs_create_groups+0x4a/0xa0
          populate_msi_sysfs+0x1cd/0x210
          pci_enable_msix+0x31c/0x3e0
          igbuio_pci_open+0x72/0x300 [igb_uio]
          uio_open+0xcc/0x120 [uio]
          chrdev_open+0xa1/0x1e0
          [...]
          do_sys_open+0xf3/0x1f0
          SyS_open+0x1e/0x20
          system_call_fastpath+0x16/0x1b
          ---[ end trace 11042e2848880209 ]---
          Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffffa056b4fa
      
      We want to keep the WARN_ON() and stack trace so the driver can be fixed,
      but we can avoid the kernel panic by returning an error.  We may still get
      warnings like this:
      
        Call Trace:
          pci_enable_msix+0x3c9/0x3e0
          igbuio_pci_open+0x72/0x300 [igb_uio]
          uio_open+0xcc/0x120 [uio]
          chrdev_open+0xa1/0x1e0
          [...]
          do_sys_open+0xf3/0x1f0
          SyS_open+0x1e/0x20
          system_call_fastpath+0x16/0x1b
          ------------[ cut here ]------------
          WARNING: at fs/sysfs/dir.c:526 sysfs_add_one+0xa5/0xd0()
          sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:03.0/0000:01:00.1/msi_irqs'
      Signed-off-by: NTonghao Zhang <xiangxia.m.yue@gmail.com>
      [bhelgaas: changelog, fix patch whitespace, remove !!]
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f17c1795
  5. 15 8月, 2018 1 次提交
    • H
      PCI/MSI: Set IRQCHIP_ONESHOT_SAFE for PCI-MSI irqchips · 923aa4c3
      Heiner Kallweit 提交于
      If flag IRQCHIP_ONESHOT_SAFE isn't set for an irqchip and we have a
      threaded interrupt with no primary handler, flag IRQF_ONESHOT needs to be
      set for the interrupt, causing some overhead in the threaded interrupt
      handler.  For more detailed explanation also check following comment in
      __setup_irq():
      
        The interrupt was requested with handler = NULL, so we use the default
        primary handler for it. But it does not have the oneshot flag set.  In
        combination with level interrupts this is deadly, because the default
        primary handler just wakes the thread, then the irq lines is reenabled,
        but the device still has the level irq asserted.  Rinse and repeat....
      
        While this works for edge type interrupts, we play it safe and reject
        unconditionally because we can't say for sure which type this interrupt
        really has.  The type flags are unreliable as the underlying chip
        implementation can override them.
      
      Another comment in __setup_irq() gives a hint already that this
      overhead can be avoided for PCI-MSI:
      
        Some irq chips like MSI based interrupts are per se one shot safe.  Check
        the chip flags, so we can avoid the unmask dance at the end of the
        threaded handler for those.
      
      Following this let's mark all PCI-MSI irqchips as oneshot-safe.
      
      See also discussion here:
      https://lkml.kernel.org/r/alpine.DEB.2.21.1808032136490.1658@nanos.tec.linutronix.deSigned-off-by: NHeiner Kallweit <hkallweit1@gmail.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      923aa4c3
  6. 13 6月, 2018 1 次提交
    • K
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook 提交于
      The kzalloc() function has a 2-factor argument form, kcalloc(). This
      patch replaces cases of:
      
              kzalloc(a * b, gfp)
      
      with:
              kcalloc(a * b, gfp)
      
      as well as handling cases of:
      
              kzalloc(a * b * c, gfp)
      
      with:
      
              kzalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kzalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kzalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kzalloc
      + kcalloc
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(sizeof(THING) * C2, ...)
      |
        kzalloc(sizeof(TYPE) * C2, ...)
      |
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(C1 * C2, ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      6396bb22
  7. 13 5月, 2018 1 次提交
  8. 20 3月, 2018 1 次提交
  9. 27 1月, 2018 1 次提交
  10. 19 1月, 2018 1 次提交
  11. 18 10月, 2017 1 次提交
    • T
      PCI/MSI: Set MSI_FLAG_MUST_REACTIVATE in core code · 25e960ef
      Thomas Gleixner 提交于
      If interrupt reservation mode is enabled then the PCI/MSI interrupts must
      be reactivated after early activation.
      
      Make sure that all callers of pci_msi_create_irq_domain() have the
      MSI_FLAG_MUST_REACTIVATE set when reservation mode is enabled.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Josh Poulson <jopoulso@microsoft.com>
      Cc: Mihai Costache <v-micos@microsoft.com>
      Cc: Stephen Hemminger <sthemmin@microsoft.com>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: linux-pci@vger.kernel.org
      Cc: Haiyang Zhang <haiyangz@microsoft.com>
      Cc: Dexuan Cui <decui@microsoft.com>
      Cc: Simon Xiao <sixiao@microsoft.com>
      Cc: Saeed Mahameed <saeedm@mellanox.com>
      Cc: Jork Loeser <Jork.Loeser@microsoft.com>
      Cc: Bjorn Helgaas <bhelgaas@google.com>
      Cc: devel@linuxdriverproject.org
      Cc: KY Srinivasan <kys@microsoft.com>
      Link: https://lkml.kernel.org/r/20171017075600.448649905@linutronix.de
      25e960ef
  12. 26 8月, 2017 1 次提交
  13. 15 8月, 2017 1 次提交
    • R
      PCI/MSI: Assume MSIs use real Requester ID, not an alias · 235b2c77
      Robin Murphy 提交于
      Currently, we handle all DMA aliases equally when calculating MSI requester
      IDs for the generic infrastructure. This turns out to be the wrong thing to
      do in the face of pure DMA quirks like those of Marvell SATA cards, where
      in the usual case the last thing seen in the alias walk is the DMA phantom
      function: we end up configuring the MSI doorbell to expect that alias, then
      find we have no interrupts since the MSI writes still come from the 'real'
      RID, thus get filtered out and ignored.
      
      Improve the alias walk to only account for the topological aliases that
      matter, based on the logic from the Intel IRQ remapping code.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      235b2c77
  14. 23 6月, 2017 1 次提交
  15. 23 5月, 2017 1 次提交
  16. 11 4月, 2017 1 次提交
  17. 30 3月, 2017 1 次提交
  18. 24 3月, 2017 1 次提交
    • B
      PCI/MSI: Use dev_printk() when possible · 4bb66691
      Bjorn Helgaas 提交于
      Use dev_printk() when possible.  This makes messages more consistent with
      other device-related messages and, in some cases, adds useful information.
      This changes messages like this:
      
        Unable to allocate affinity masks, ignoring
      
      to this:
      
        pci 0000:01:00.0: can't allocate MSI affinity masks for 4 vectors
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      4bb66691
  19. 10 3月, 2017 1 次提交
  20. 02 3月, 2017 1 次提交
  21. 18 2月, 2017 1 次提交
    • P
      PCI/MSI: Fix msi_desc->affinity memory leak when freeing MSI IRQs · 81efbadd
      Prarit Bhargava 提交于
      During device setup, msix_setup_entries() and msi_setup_entry() allocate
      msi_desc by calling alloc_msi_entry().  alloc_msi_entry() can also allocate
      a affinity cpumask.  During device teardown free_msi_irqs() is called and
      the msi_desc is freed, but the affinity cpumask is leaked.
      
      Fix it by calling free_msi_entry() which frees both the msi_desc and the
      affinity cpumask.
      
      [bhelgaas: aa48b6f7 ("genirq/MSI: Move alloc_msi_entry() from PCI into
       generic MSI code") moved alloc_msi_entry() from drivers/pci/msi.c to
       kernel/irq/msi.c and added a new corresponding free_msi_entry() interface.
      
       After aa48b6f7, pci/msi.c used alloc_msi_entry(), but did its own
       kfree() instead of using free_msi_entry().  28f4b041 ("genirq/msi: Add
       cpumask allocation to alloc_msi_entry") added affinity to both
       alloc_msi_entry() and free_msi_entry(), but pci/msi.c didn't use
       free_msi_entry(), resulting in this leak.]
      
      Fixes: aa48b6f7 ("genirq/MSI: Move alloc_msi_entry() from PCI into generic MSI code")
      Signed-off-by: NPrarit Bhargava <prarit@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      CC: Myron Stowe <mstowe@redhat.com>
      81efbadd
  22. 11 2月, 2017 5 次提交
  23. 03 2月, 2017 1 次提交
  24. 14 1月, 2017 1 次提交
  25. 12 1月, 2017 1 次提交
  26. 09 11月, 2016 5 次提交
  27. 26 10月, 2016 1 次提交
  28. 15 9月, 2016 3 次提交
  29. 13 9月, 2016 1 次提交
  30. 18 8月, 2016 1 次提交