1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #ifndef _ASM_RISCV_MEMBARRIER_H
3 #define _ASM_RISCV_MEMBARRIER_H
4 
5 static inline void membarrier_arch_switch_mm(struct mm_struct *prev,
6 					     struct mm_struct *next,
7 					     struct task_struct *tsk)
8 {
9 	/*
10 	 * Only need the full barrier when switching between processes.
11 	 * Barrier when switching from kernel to userspace is not
12 	 * required here, given that it is implied by mmdrop(). Barrier
13 	 * when switching from userspace to kernel is not needed after
14 	 * store to rq->curr.
15 	 */
16 	if (IS_ENABLED(CONFIG_SMP) &&
17 	    likely(!(atomic_read(&next->membarrier_state) &
18 		     (MEMBARRIER_STATE_PRIVATE_EXPEDITED |
19 		      MEMBARRIER_STATE_GLOBAL_EXPEDITED)) || !prev))
20 		return;
21 
22 	/*
23 	 * The membarrier system call requires a full memory barrier
24 	 * after storing to rq->curr, before going back to user-space.
25 	 * Matches a full barrier in the proximity of the membarrier
26 	 * system call entry.
27 	 */
28 	smp_mb();
29 }
30 
31 #endif /* _ASM_RISCV_MEMBARRIER_H */
32