1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef __ASM_ARM_SWITCH_TO_H 3*4882a593Smuzhiyun #define __ASM_ARM_SWITCH_TO_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #include <linux/thread_info.h> 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun /* 8*4882a593Smuzhiyun * For v7 SMP cores running a preemptible kernel we may be pre-empted 9*4882a593Smuzhiyun * during a TLB maintenance operation, so execute an inner-shareable dsb 10*4882a593Smuzhiyun * to ensure that the maintenance completes in case we migrate to another 11*4882a593Smuzhiyun * CPU. 12*4882a593Smuzhiyun */ 13*4882a593Smuzhiyun #if defined(CONFIG_PREEMPTION) && defined(CONFIG_SMP) && defined(CONFIG_CPU_V7) 14*4882a593Smuzhiyun #define __complete_pending_tlbi() dsb(ish) 15*4882a593Smuzhiyun #else 16*4882a593Smuzhiyun #define __complete_pending_tlbi() 17*4882a593Smuzhiyun #endif 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun /* 20*4882a593Smuzhiyun * switch_to(prev, next) should switch from task `prev' to `next' 21*4882a593Smuzhiyun * `prev' will never be the same as `next'. schedule() itself 22*4882a593Smuzhiyun * contains the memory barrier to tell GCC not to cache `current'. 23*4882a593Smuzhiyun */ 24*4882a593Smuzhiyun extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #define switch_to(prev,next,last) \ 27*4882a593Smuzhiyun do { \ 28*4882a593Smuzhiyun __complete_pending_tlbi(); \ 29*4882a593Smuzhiyun last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ 30*4882a593Smuzhiyun } while (0) 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun #endif /* __ASM_ARM_SWITCH_TO_H */ 33