diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 3dd64dd18559503dc70e47ab14010b537f90d85b..12aced900ada4ef79609fb8062285e093c8a69a3 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 5c80fe3562b7de2436087d433b14c2e9760e4873..dd5aeddbed5d30864f98100a8b454ea76421f313 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -25,6 +25,7 @@ #ifdef CONFIG_ARM64 #include +#include #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;