提交 313b0d5a 编写于 作者: S Sumit Garg 提交者: Zheng Zengkai

nmi: backtrace: Allow runtime arch specific override

maillist inclusion
category: feature
bugzilla: 49593
CVE: NA
Reference: https://www.spinics.net/lists/arm-kernel/msg851005.html

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

Add a boolean return to arch_trigger_cpumask_backtrace() to support a
use-case where a particular architecture detects at runtime if it supports
NMI backtrace or it would like to fallback to default implementation using
SMP cross-calls.

Currently such an architecture example is arm64 supporting pseudo NMIs
feature which is only available on platforms which have support for GICv3
or later version.
Signed-off-by: NSumit Garg <sumit.garg@linaro.org>
Signed-off-by: NWei Li <liwei391@huawei.com>
Reviewed-by: NXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 b284ae00
...@@ -31,7 +31,7 @@ void handle_IRQ(unsigned int, struct pt_regs *); ...@@ -31,7 +31,7 @@ void handle_IRQ(unsigned int, struct pt_regs *);
void init_IRQ(void); void init_IRQ(void);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask, extern bool arch_trigger_cpumask_backtrace(const cpumask_t *mask,
bool exclude_self); bool exclude_self);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
#endif #endif
......
...@@ -856,7 +856,8 @@ static void raise_nmi(cpumask_t *mask) ...@@ -856,7 +856,8 @@ static void raise_nmi(cpumask_t *mask)
__ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask); __ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask);
} }
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) bool arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
{ {
nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_nmi); nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_nmi);
return true;
} }
...@@ -78,7 +78,7 @@ extern int cp0_fdc_irq; ...@@ -78,7 +78,7 @@ extern int cp0_fdc_irq;
extern int get_c0_fdc_int(void); extern int get_c0_fdc_int(void);
void arch_trigger_cpumask_backtrace(const struct cpumask *mask, bool arch_trigger_cpumask_backtrace(const struct cpumask *mask,
bool exclude_self); bool exclude_self);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
......
...@@ -735,9 +735,10 @@ static void raise_backtrace(cpumask_t *mask) ...@@ -735,9 +735,10 @@ static void raise_backtrace(cpumask_t *mask)
} }
} }
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) bool arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
{ {
nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_backtrace); nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_backtrace);
return true;
} }
int mips_get_process_fp_mode(struct task_struct *task) int mips_get_process_fp_mode(struct task_struct *task)
......
...@@ -9,7 +9,7 @@ static inline void arch_touch_nmi_watchdog(void) {} ...@@ -9,7 +9,7 @@ static inline void arch_touch_nmi_watchdog(void) {}
#endif #endif
#if defined(CONFIG_NMI_IPI) && defined(CONFIG_STACKTRACE) #if defined(CONFIG_NMI_IPI) && defined(CONFIG_STACKTRACE)
extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask, extern bool arch_trigger_cpumask_backtrace(const cpumask_t *mask,
bool exclude_self); bool exclude_self);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
#endif #endif
......
...@@ -264,8 +264,9 @@ static void raise_backtrace_ipi(cpumask_t *mask) ...@@ -264,8 +264,9 @@ static void raise_backtrace_ipi(cpumask_t *mask)
} }
} }
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) bool arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
{ {
nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_backtrace_ipi); nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_backtrace_ipi);
return true;
} }
#endif /* defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_NMI_IPI) */ #endif /* defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_NMI_IPI) */
...@@ -87,7 +87,7 @@ static inline unsigned long get_softint(void) ...@@ -87,7 +87,7 @@ static inline unsigned long get_softint(void)
return retval; return retval;
} }
void arch_trigger_cpumask_backtrace(const struct cpumask *mask, bool arch_trigger_cpumask_backtrace(const struct cpumask *mask,
bool exclude_self); bool exclude_self);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
......
...@@ -248,7 +248,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp) ...@@ -248,7 +248,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp)
} }
} }
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) bool arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
{ {
struct thread_info *tp = current_thread_info(); struct thread_info *tp = current_thread_info();
struct pt_regs *regs = get_irq_regs(); struct pt_regs *regs = get_irq_regs();
...@@ -303,6 +303,8 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) ...@@ -303,6 +303,8 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
spin_unlock_irqrestore(&global_cpu_snapshot_lock, flags); spin_unlock_irqrestore(&global_cpu_snapshot_lock, flags);
return true;
} }
#ifdef CONFIG_MAGIC_SYSRQ #ifdef CONFIG_MAGIC_SYSRQ
......
...@@ -47,7 +47,7 @@ extern void init_ISA_irqs(void); ...@@ -47,7 +47,7 @@ extern void init_ISA_irqs(void);
extern void __init init_IRQ(void); extern void __init init_IRQ(void);
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
void arch_trigger_cpumask_backtrace(const struct cpumask *mask, bool arch_trigger_cpumask_backtrace(const struct cpumask *mask,
bool exclude_self); bool exclude_self);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
......
...@@ -34,10 +34,11 @@ static void nmi_raise_cpu_backtrace(cpumask_t *mask) ...@@ -34,10 +34,11 @@ static void nmi_raise_cpu_backtrace(cpumask_t *mask)
apic->send_IPI_mask(mask, NMI_VECTOR); apic->send_IPI_mask(mask, NMI_VECTOR);
} }
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) bool arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
{ {
nmi_trigger_cpumask_backtrace(mask, exclude_self, nmi_trigger_cpumask_backtrace(mask, exclude_self,
nmi_raise_cpu_backtrace); nmi_raise_cpu_backtrace);
return true;
} }
static int nmi_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs) static int nmi_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs)
......
...@@ -163,26 +163,22 @@ static inline void touch_nmi_watchdog(void) ...@@ -163,26 +163,22 @@ static inline void touch_nmi_watchdog(void)
#ifdef arch_trigger_cpumask_backtrace #ifdef arch_trigger_cpumask_backtrace
static inline bool trigger_all_cpu_backtrace(void) static inline bool trigger_all_cpu_backtrace(void)
{ {
arch_trigger_cpumask_backtrace(cpu_online_mask, false); return arch_trigger_cpumask_backtrace(cpu_online_mask, false);
return true;
} }
static inline bool trigger_allbutself_cpu_backtrace(void) static inline bool trigger_allbutself_cpu_backtrace(void)
{ {
arch_trigger_cpumask_backtrace(cpu_online_mask, true); return arch_trigger_cpumask_backtrace(cpu_online_mask, true);
return true;
} }
static inline bool trigger_cpumask_backtrace(struct cpumask *mask) static inline bool trigger_cpumask_backtrace(struct cpumask *mask)
{ {
arch_trigger_cpumask_backtrace(mask, false); return arch_trigger_cpumask_backtrace(mask, false);
return true;
} }
static inline bool trigger_single_cpu_backtrace(int cpu) static inline bool trigger_single_cpu_backtrace(int cpu)
{ {
arch_trigger_cpumask_backtrace(cpumask_of(cpu), false); return arch_trigger_cpumask_backtrace(cpumask_of(cpu), false);
return true;
} }
/* generic implementation */ /* generic implementation */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册