1. 09 3月, 2016 1 次提交
    • C
      x86/ACPI/PCI: Recognize that Interrupt Line 255 means "not connected" · e237a551
      Chen Fan 提交于
      Per the x86-specific footnote to PCI spec r3.0, sec 6.2.4, the value 255 in
      the Interrupt Line register means "unknown" or "no connection."
      Previously, when we couldn't derive an IRQ from the _PRT, we fell back to
      using the value from Interrupt Line as an IRQ.  It's questionable whether
      we should do that at all, but the spec clearly suggests we shouldn't do it
      for the value 255 on x86.
      
      Calling request_irq() with IRQ 255 may succeed, but the driver won't
      receive any interrupts.  Or, if IRQ 255 is shared with another device, it
      may succeed, and the driver's ISR will be called at random times when the
      *other* device interrupts.  Or it may fail if another device is using IRQ
      255 with incompatible flags.  What we *want* is for request_irq() to fail
      predictably so the driver can fall back to polling.
      
      On x86, assume 255 in the Interrupt Line means the INTx line is not
      connected.  In that case, set dev->irq to IRQ_NOTCONNECTED so request_irq()
      will fail gracefully with -ENOTCONN.
      
      We found this problem on a system where Secure Boot firmware assigned
      Interrupt Line 255 to an i801_smbus device and another device was already
      using MSI-X IRQ 255.  This was in v3.10, where i801_probe() fails if
      request_irq() fails:
      
        i801_smbus 0000:00:1f.3: enabling device (0140 -> 0143)
        i801_smbus 0000:00:1f.3: can't derive routing for PCI INT C
        i801_smbus 0000:00:1f.3: PCI INT C: no GSI
        genirq: Flags mismatch irq 255. 00000080 (i801_smbus) vs. 00000000 (megasa)
        CPU: 0 PID: 2487 Comm: kworker/0:1 Not tainted 3.10.0-229.el7.x86_64 #1
        Hardware name: FUJITSU PRIMEQUEST 2800E2/D3736, BIOS PRIMEQUEST 2000 Serie5
        Call Trace:
          dump_stack+0x19/0x1b
          __setup_irq+0x54a/0x570
          request_threaded_irq+0xcc/0x170
          i801_probe+0x32f/0x508 [i2c_i801]
          local_pci_probe+0x45/0xa0
        i801_smbus 0000:00:1f.3: Failed to allocate irq 255: -16
        i801_smbus: probe of 0000:00:1f.3 failed with error -16
      
      After aeb8a3d1 ("i2c: i801: Check if interrupts are disabled"),
      i801_probe() will fall back to polling if request_irq() fails.  But we
      still need this patch because request_irq() may succeed or fail depending
      on other devices in the system.  If request_irq() fails, i801_smbus will
      work by falling back to polling, but if it succeeds, i801_smbus won't work
      because it expects interrupts that it may not receive.
      Signed-off-by: NChen Fan <chen.fan.fnst@cn.fujitsu.com>
      Acked-by: NThomas Gleixner <tglx@linutronix.de>
      Acked-by: NBjorn Helgaas <bhelgaas@google.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      e237a551
  2. 26 1月, 2016 1 次提交
    • M
      irqdomain: Allow domain lookup with DOMAIN_BUS_WIRED token · 530cbe10
      Marc Zyngier 提交于
      Let's take the (outlandish) example of an interrupt controller
      capable of handling both wired interrupts and PCI MSIs.
      
      With the current code, the PCI MSI domain is going to be tagged
      with DOMAIN_BUS_PCI_MSI, and the wired domain with DOMAIN_BUS_ANY.
      
      Things get hairy when we start looking up the domain for a wired
      interrupt (typically when creating it based on some firmware
      information - DT or ACPI).
      
      In irq_create_fwspec_mapping(), we perform the lookup using
      DOMAIN_BUS_ANY, which is actually used as a wildcard. This gives
      us one chance out of two to end up with the wrong domain, and
      we try to configure a wired interrupt with the MSI domain.
      Everything grinds to a halt pretty quickly.
      
      What we really need to do is to start looking for a domain that
      would uniquely identify a wired interrupt domain, and only use
      DOMAIN_BUS_ANY as a fallback.
      
      In order to solve this, let's introduce a new DOMAIN_BUS_WIRED
      token, which is going to be used exactly as described above.
      Of course, this depends on the irqchip to setup the domain
      bus_token, and nobody had to implement this so far.
      
      Only so far.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Rob Herring <robh+dt@kernel.org>
      Cc: Frank Rowand <frowand.list@gmail.com>
      Cc: Grant Likely <grant.likely@linaro.org>
      Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
      Cc: Jiang Liu <jiang.liu@linux.intel.com>
      Link: http://lkml.kernel.org/r/1453816347-32720-2-git-send-email-marc.zyngier@arm.comSigned-off-by: NThomas Gleixner <tglx@linutronix.de>
      530cbe10
  3. 16 1月, 2016 1 次提交
  4. 15 1月, 2016 2 次提交
    • L
      genirq/MSI: Relax msi_domain_alloc() to support parentless MSI irqdomains · bf6f869f
      Liu Jiang 提交于
      Previously msi_domain_alloc() assumed MSI irqdomains always had parent
      irqdomains, but that's not true for the new Intel VMD devices.  Relax
      msi_domain_alloc() to support parentless MSI irqdomains.
      Signed-off-by: NJiang Liu <jiang.liu@linux.intel.com>
      Signed-off-by: NKeith Busch <keith.busch@intel.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Acked-by: NThomas Gleixner <tglx@linutronix.de>
      bf6f869f
    • T
      genirq: Validate action before dereferencing it in handle_irq_event_percpu() · 570540d5
      Thomas Gleixner 提交于
      commit 71f64340 changed the handling of irq_desc->action from
      
      CPU 0                   CPU 1
      free_irq()              lock(desc)
        lock(desc)            handle_edge_irq()
                              if (desc->action) {
                                handle_irq_event()
                                  action = desc->action
                                  unlock(desc)
        desc->action = NULL       handle_irq_event_percpu(desc, action)
                                    action->xxx
      to
      
      CPU 0                   CPU 1
      free_irq()              lock(desc)
        lock(desc)            handle_edge_irq()
                              if (desc->action) {
                                handle_irq_event()
                                  unlock(desc)
        desc->action = NULL       handle_irq_event_percpu(desc, action)
                                    action = desc->action
                                    action->xxx
      
      So if free_irq manages to set the action to NULL between the unlock and before
      the readout, we happily dereference a null pointer.
      
      We could simply revert 71f64340, but we want to preserve the better code
      generation. A simple solution is to change the action loop from a do {} while
      to a while {} loop.
      
      This is safe because we either see a valid desc->action or NULL. If the action
      is about to be removed it is still valid as free_irq() is blocked on
      synchronize_irq().
      
      CPU 0                   CPU 1
      free_irq()              lock(desc)
        lock(desc)            handle_edge_irq()
                                handle_irq_event(desc)
                                  set(INPROGRESS)
                                  unlock(desc)
                                  handle_irq_event_percpu(desc)
                                  action = desc->action
        desc->action = NULL           while (action) {
                                        action->xxx
                                        ...
                                        action = action->next;
        sychronize_irq()
          while(INPROGRESS);      lock(desc)
                                  clr(INPROGRESS)
      free(action)
      
      That's basically the same mechanism as we have for shared
      interrupts. action->next can become NULL while handle_irq_event_percpu()
      runs. Either it sees the action or NULL. It does not matter, because action
      itself cannot go away before the interrupt in progress flag has been cleared.
      
      Fixes: commit 71f64340 "genirq: Remove the second parameter from handle_irq_event_percpu()"
      Reported-by: zyjzyj2000@gmail.com
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Huang Shijie <shijie.huang@arm.com>
      Cc: Jiang Liu <jiang.liu@linux.intel.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: stable@vger.kernel.org
      Link: http://lkml.kernel.org/r/alpine.DEB.2.11.1601131224190.3575@nanos
      570540d5
  5. 21 12月, 2015 1 次提交
  6. 20 12月, 2015 1 次提交
  7. 16 12月, 2015 3 次提交
  8. 14 12月, 2015 2 次提交
    • T
      genirq: Free irq_desc with rcu · 425a5072
      Thomas Gleixner 提交于
      The new VMD device driver needs to iterate over a list of
      "demultiplexing" interrupts. Protecting that list with a lock is not
      possible because the list is also required in code pathes which hold
      irq descriptor lock. Therefor the demultiplexing interrupt handler
      would create a lock inversion scenario if it calls a demux handler
      with the list protection lock held.
      
      A solution for this is to free the irq descriptor via RCU, so the
      list can be walked with rcu read lock held.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Keith Busch <keith.busch@intel.com>
      425a5072
    • T
      genirq: Prevent chip buslock deadlock · abc7e40c
      Thomas Gleixner 提交于
      If a interrupt chip utilizes chip->buslock then free_irq() can
      deadlock in the following way:
      
      CPU0				CPU1
      				interrupt(X) (Shared or spurious)
      free_irq(X)			interrupt_thread(X)
      chip_bus_lock(X)
      				   irq_finalize_oneshot(X)
      				     chip_bus_lock(X)
      synchronize_irq(X)
      	
      synchronize_irq() waits for the interrupt thread to complete,
      i.e. forever.
      
      Solution is simple: Drop chip_bus_lock() before calling
      synchronize_irq() as we do with the irq_desc lock. There is nothing to
      be protected after the point where irq_desc lock has been released.
      
      This adds chip_bus_lock/unlock() to the remove_irq() code path, but
      that's actually correct in the case where remove_irq() is called on
      such an interrupt. The current users of remove_irq() are not affected
      as none of those interrupts is on a chip which requires buslock.
      Reported-by: NFredrik Markström <fredrik.markstrom@gmail.com>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: stable@vger.kernel.org
      abc7e40c
  9. 08 12月, 2015 1 次提交
    • T
      genirq: Implement irq_percpu_is_enabled() · f0cb3220
      Thomas Petazzoni 提交于
      Certain interrupt controller drivers have a register set that does not
      make it easy to save/restore the mask of enabled/disabled interrupts
      at suspend/resume time. At resume time, such drivers rely on the core
      kernel irq subsystem to tell whether such or such interrupt is enabled
      or not, in order to restore the proper state in the interrupt
      controller register.
      
      While the irqd_irq_disabled() provides the relevant information for
      global interrupts, there is no similar function to query the
      enabled/disabled state of a per-CPU interrupt.
      
      Therefore, this commit complements the percpu_irq API with an
      irq_percpu_is_enabled() function.
      
      [ tglx: Simplified the implementation and added kerneldoc ]
      Signed-off-by: NThomas Petazzoni <thomas.petazzoni@free-electrons.com>
      Cc: linux-arm-kernel@lists.infradead.org
      Cc: Tawfik Bayouk <tawfik@marvell.com>
      Cc: Nadav Haklai <nadavh@marvell.com>
      Cc: Lior Amsalem <alior@marvell.com>
      Cc: Andrew Lunn <andrew@lunn.ch>
      Cc: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
      Cc: Gregory Clement <gregory.clement@free-electrons.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Link: http://lkml.kernel.org/r/1445347435-2333-2-git-send-email-thomas.petazzoni@free-electrons.comSigned-off-by: NThomas Gleixner <tglx@linutronix.de>
      f0cb3220
  10. 17 11月, 2015 1 次提交
  11. 10 11月, 2015 1 次提交
    • G
      genirq/PM: Restore system wake up from chained interrupts · 4717f133
      Grygorii Strashko 提交于
      Commit e509bd7d ("genirq: Allow migration of chained interrupts
      by installing default action") breaks PCS wake up IRQ behaviour on
      TI OMAP based platforms (dra7-evm).
      
      TI OMAP IRQ wake up configuration:
      GIC-irqchip->PCM_IRQ
        |- omap_prcm_register_chain_handler
           |- PRCM-irqchip -> PRCM_IO_IRQ
              |- pcs_irq_chain_handler
                 |- pinctrl-irqchip -> PCS_uart1_wakeup_irq
      
      This happens because IRQ PM code (irq/pm.c) is expected to ignore
      chained interrupts by default:
        static bool suspend_device_irq(struct irq_desc *desc)
        {
      	if (!desc->action || desc->no_suspend_depth)
      		return false;
       - it's expected !desc->action = true for chained interrupts;
      
      but, after above change, all chained interrupt descriptors will
      have default action handler installed - chained_action.
      As result, chained interrupts will be silently disabled during system
      suspend.
      
      Hence, fix it by introducing helper function irq_desc_is_chained() and
      use it in suspend_device_irq() for chained interrupts identification
      and skip them, once detected.
      
      Fixes: e509bd7d ("genirq: Allow migration of chained interrupts..")
      Signed-off-by: NGrygorii Strashko <grygorii.strashko@ti.com>
      Reviewed-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Cc: Tony Lindgren <tony@atomide.com>
      Cc: <nsekhar@ti.com>
      Cc: <linux-arm-kernel@lists.infradead.org>
      Cc: Tony Lindgren <tony@atomide.com>
      Link: http://lkml.kernel.org/r/1447149492-20699-1-git-send-email-grygorii.strashko@ti.comSigned-off-by: NThomas Gleixner <tglx@linutronix.de>
      4717f133
  12. 22 10月, 2015 1 次提交
  13. 16 10月, 2015 1 次提交
  14. 14 10月, 2015 9 次提交
  15. 11 10月, 2015 1 次提交
    • T
      genirq: Add flag to force mask in disable_irq[_nosync]() · e9849777
      Thomas Gleixner 提交于
      If an irq chip does not implement the irq_disable callback, then we
      use a lazy approach for disabling the interrupt. That means that the
      interrupt is marked disabled, but the interrupt line is not
      immediately masked in the interrupt chip. It only becomes masked if
      the interrupt is raised while it's marked disabled. We use this to avoid
      possibly expensive mask/unmask operations for common case operations.
      
      Unfortunately there are devices which do not allow the interrupt to be
      disabled easily at the device level. They are forced to use
      disable_irq_nosync(). This can result in taking each interrupt twice.
      
      Instead of enforcing the non lazy mode on all interrupts of a irq
      chip, provide a settings flag, which can be set by the driver for that
      particular interrupt line.
      Reported-and-tested-by: NDuc Dang <dhdang@apm.com>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Link: http://lkml.kernel.org/r/alpine.DEB.2.11.1510092348370.6097@nanos
      e9849777
  16. 10 10月, 2015 2 次提交
  17. 09 10月, 2015 2 次提交
  18. 01 10月, 2015 2 次提交
  19. 30 9月, 2015 2 次提交
  20. 22 9月, 2015 2 次提交
  21. 16 9月, 2015 3 次提交