xref: /linux/arch/arm/include/asm/switch_to.h (revision b24413180f5600bcb3bb70fbed5cf186b60864bd)
1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
29f97da78SDavid Howells #ifndef __ASM_ARM_SWITCH_TO_H
39f97da78SDavid Howells #define __ASM_ARM_SWITCH_TO_H
49f97da78SDavid Howells 
59f97da78SDavid Howells #include <linux/thread_info.h>
69f97da78SDavid Howells 
79f97da78SDavid Howells /*
873a6fdc4SWill Deacon  * For v7 SMP cores running a preemptible kernel we may be pre-empted
973a6fdc4SWill Deacon  * during a TLB maintenance operation, so execute an inner-shareable dsb
1073a6fdc4SWill Deacon  * to ensure that the maintenance completes in case we migrate to another
1173a6fdc4SWill Deacon  * CPU.
1273a6fdc4SWill Deacon  */
1373a6fdc4SWill Deacon #if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) && defined(CONFIG_CPU_V7)
147baa7aecSWill Deacon #define __complete_pending_tlbi()	dsb(ish)
157baa7aecSWill Deacon #else
167baa7aecSWill Deacon #define __complete_pending_tlbi()
1773a6fdc4SWill Deacon #endif
1873a6fdc4SWill Deacon 
1973a6fdc4SWill Deacon /*
209f97da78SDavid Howells  * switch_to(prev, next) should switch from task `prev' to `next'
219f97da78SDavid Howells  * `prev' will never be the same as `next'.  schedule() itself
229f97da78SDavid Howells  * contains the memory barrier to tell GCC not to cache `current'.
239f97da78SDavid Howells  */
249f97da78SDavid Howells extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
259f97da78SDavid Howells 
269f97da78SDavid Howells #define switch_to(prev,next,last)					\
279f97da78SDavid Howells do {									\
287baa7aecSWill Deacon 	__complete_pending_tlbi();					\
299f97da78SDavid Howells 	last = __switch_to(prev,task_thread_info(prev), task_thread_info(next));	\
309f97da78SDavid Howells } while (0)
319f97da78SDavid Howells 
329f97da78SDavid Howells #endif /* __ASM_ARM_SWITCH_TO_H */
33