
From: Wei Li <liwei391@huawei.com> hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4JBQ8 ---------------------------------------- Kprobes use 'stop_machine' to modify code which could be ran in the pseudo nmi context at the same time. This patch mask pseudo nmi before running the stop_machine callback to avoid this race condition. Signed-off-by: Wei Li <liwei391@huawei.com> Reviewed-by: Yang Yingliang <yangyingliang@huawei.com> Reviewed-by: Cheng Jian <cj.chengjian@huawei.com> Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com> --- arch/arm64/include/asm/arch_gicv3.h | 11 +++++++++++ kernel/stop_machine.c | 3 +++ 2 files changed, 14 insertions(+) diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 3dd64dd18559..12aced900ada 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -184,5 +184,16 @@ static inline void gic_arch_enable_irqs(void) asm volatile ("msr daifclr, #2" : : : "memory"); } +static inline void gic_arch_disable_irqs(void) +{ + asm volatile ("msr daifset, #2" : : : "memory"); +} + +static inline void gic_arch_restore_irqs(unsigned long flags) +{ + if (gic_supports_nmi()) + asm volatile ("msr daif, %0" : : "r" (flags >> 32) + : "memory"); +} #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARCH_GICV3_H */ diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 5c80fe3562b7..dd5aeddbed5d 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -25,6 +25,7 @@ #ifdef CONFIG_ARM64 #include <linux/arm_sdei.h> +#include <asm/arch_gicv3.h> #endif /* @@ -223,6 +224,7 @@ static int multi_cpu_stop(void *data) local_irq_disable(); hard_irq_disable(); #ifdef CONFIG_ARM64 + gic_arch_disable_irqs(); sdei_mask_local_cpu(); #endif break; @@ -247,6 +249,7 @@ static int multi_cpu_stop(void *data) #ifdef CONFIG_ARM64 sdei_unmask_local_cpu(); + gic_arch_restore_irqs(flags); #endif local_irq_restore(flags); return err; -- 2.20.1