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