From 975cc1cf47920730b02c18fa4000dae3397b54ee Mon Sep 17 00:00:00 2001 From: Wei Li Date: Thu, 21 Dec 2023 12:36:58 +0000 Subject: [PATCH] stop_machine: mask pseudo nmi before running the callback hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8QBLL ---------------------------------------- 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 Reviewed-by: Yang Yingliang Reviewed-by: Cheng Jian Signed-off-by: Zheng Zengkai Signed-off-by: Yuntao Liu --- arch/arm64/include/asm/arch_gicv3.h | 12 ++++++++++++ kernel/stop_machine.c | 3 +++ 2 files changed, 15 insertions(+) diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 01281a5336cf..1582900e94f8 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -190,6 +190,18 @@ static inline void gic_arch_enable_irqs(void) asm volatile ("msr daifclr, #3" : : : "memory"); } +static inline void gic_arch_disable_irqs(void) +{ + asm volatile ("msr daifset, #3" : : : "memory"); +} + +static inline void gic_arch_restore_irqs(unsigned long flags) +{ + if (gic_supports_nmi()) + asm volatile ("msr daif, %0" : : "r" (flags >> 32) + : "memory"); +} + static inline bool gic_has_relaxed_pmr_sync(void) { return cpus_have_cap(ARM64_HAS_GIC_PRIO_RELAXED_SYNC); diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 9466d61d21c9..320ce5b18511 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -25,6 +25,7 @@ #ifdef CONFIG_ARM64 #include +#include #endif /* @@ -239,6 +240,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; @@ -263,6 +265,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; -- Gitee