提交 7dd4c081 编写于 作者: J Julien Thierry 提交者: Xie XiuQi

irqchip/gic-v3: Handle pseudo-NMIs

hulk inclusion
category: feature
bugzilla: 9291
CVE: NA

ported from https://lore.kernel.org/patchwork/patch/1037482/

--------------------------------

Provide a higher priority to be used for pseudo-NMIs. When such an
interrupt is received, keep interrupts fully disabled at CPU level to
prevent receiving other pseudo-NMIs while handling the current one.
Signed-off-by: NJulien Thierry <julien.thierry@arm.com>
Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: NWei Li <liwei391@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 66b1732e
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include "irq-gic-common.h" #include "irq-gic-common.h"
#define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80)
struct redist_region { struct redist_region {
void __iomem *redist_base; void __iomem *redist_base;
phys_addr_t phys_base; phys_addr_t phys_base;
...@@ -375,12 +377,45 @@ static u64 gic_mpidr_to_affinity(unsigned long mpidr) ...@@ -375,12 +377,45 @@ static u64 gic_mpidr_to_affinity(unsigned long mpidr)
return aff; return aff;
} }
static void gic_deactivate_unhandled(u32 irqnr)
{
if (static_branch_likely(&supports_deactivate_key)) {
if (irqnr < 8192)
gic_write_dir(irqnr);
} else {
gic_write_eoir(irqnr);
}
}
static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
{
int err;
if (static_branch_likely(&supports_deactivate_key))
gic_write_eoir(irqnr);
/*
* Leave the PSR.I bit set to prevent other NMIs to be
* received while handling this one.
* PSR.I will be restored when we ERET to the
* interrupted context.
*/
err = handle_domain_nmi(gic_data.domain, irqnr, regs);
if (err)
gic_deactivate_unhandled(irqnr);
}
static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
{ {
u32 irqnr; u32 irqnr;
irqnr = gic_read_iar(); irqnr = gic_read_iar();
if (gic_supports_nmi() &&
unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) {
gic_handle_nmi(irqnr, regs);
return;
}
if (gic_prio_masking_enabled()) { if (gic_prio_masking_enabled()) {
gic_pmr_mask_irqs(); gic_pmr_mask_irqs();
gic_arch_enable_irqs(); gic_arch_enable_irqs();
...@@ -397,12 +432,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs ...@@ -397,12 +432,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
err = handle_domain_irq(gic_data.domain, irqnr, regs); err = handle_domain_irq(gic_data.domain, irqnr, regs);
if (err) { if (err) {
WARN_ONCE(true, "Unexpected interrupt received!\n"); WARN_ONCE(true, "Unexpected interrupt received!\n");
if (static_branch_likely(&supports_deactivate_key)) { gic_deactivate_unhandled(irqnr);
if (irqnr < 8192)
gic_write_dir(irqnr);
} else {
gic_write_eoir(irqnr);
}
} }
return; return;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册