提交 d0cd7461 编写于 作者: J Julien Thierry 提交者: Caspar Zhang

irqdesc: Add domain handler for NMIs

task #25552995

commit 6e4933a006616343f66c4702dc4fc56bb25e7b02 upstream

NMI handling code should be executed between calls to nmi_enter and
nmi_exit.

Add a separate domain handler to properly setup NMI context when handling
an interrupt requested as NMI.
Signed-off-by: NJulien Thierry <julien.thierry@arm.com>
Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: NZou Cao <zoucao@linux.alibaba.com>
Reviewed-by: Nluanshi <zhangliguang@linux.alibaba.com>
上级 3035257e
...@@ -172,6 +172,11 @@ static inline int handle_domain_irq(struct irq_domain *domain, ...@@ -172,6 +172,11 @@ static inline int handle_domain_irq(struct irq_domain *domain,
{ {
return __handle_domain_irq(domain, hwirq, true, regs); return __handle_domain_irq(domain, hwirq, true, regs);
} }
#ifdef CONFIG_IRQ_DOMAIN
int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
struct pt_regs *regs);
#endif
#endif #endif
/* Test to see if a driver has successfully requested an irq */ /* Test to see if a driver has successfully requested an irq */
......
...@@ -680,6 +680,41 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, ...@@ -680,6 +680,41 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
set_irq_regs(old_regs); set_irq_regs(old_regs);
return ret; return ret;
} }
#ifdef CONFIG_IRQ_DOMAIN
/**
* handle_domain_nmi - Invoke the handler for a HW irq belonging to a domain
* @domain: The domain where to perform the lookup
* @hwirq: The HW irq number to convert to a logical one
* @regs: Register file coming from the low-level handling code
*
* Returns: 0 on success, or -EINVAL if conversion has failed
*/
int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
unsigned int irq;
int ret = 0;
nmi_enter();
irq = irq_find_mapping(domain, hwirq);
/*
* ack_bad_irq is not NMI-safe, just report
* an invalid interrupt.
*/
if (likely(irq))
generic_handle_irq(irq);
else
ret = -EINVAL;
nmi_exit();
set_irq_regs(old_regs);
return ret;
}
#endif
#endif #endif
/* Dynamic interrupt handling */ /* Dynamic interrupt handling */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册