Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright IBM Corp. 1999, 2009
0004  *
0005  * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
0006  */
0007 
0008 #ifndef __ASM_SWITCH_TO_H
0009 #define __ASM_SWITCH_TO_H
0010 
0011 #include <linux/thread_info.h>
0012 #include <asm/fpu/api.h>
0013 #include <asm/ptrace.h>
0014 #include <asm/guarded_storage.h>
0015 
0016 extern struct task_struct *__switch_to(void *, void *);
0017 extern void update_cr_regs(struct task_struct *task);
0018 
0019 static inline void save_access_regs(unsigned int *acrs)
0020 {
0021     typedef struct { int _[NUM_ACRS]; } acrstype;
0022 
0023     asm volatile("stam 0,15,%0" : "=Q" (*(acrstype *)acrs));
0024 }
0025 
0026 static inline void restore_access_regs(unsigned int *acrs)
0027 {
0028     typedef struct { int _[NUM_ACRS]; } acrstype;
0029 
0030     asm volatile("lam 0,15,%0" : : "Q" (*(acrstype *)acrs));
0031 }
0032 
0033 #define switch_to(prev, next, last) do {                \
0034     /* save_fpu_regs() sets the CIF_FPU flag, which enforces    \
0035      * a restore of the floating point / vector registers as    \
0036      * soon as the next task returns to user space          \
0037      */                             \
0038     save_fpu_regs();                        \
0039     save_access_regs(&prev->thread.acrs[0]);            \
0040     save_ri_cb(prev->thread.ri_cb);                 \
0041     save_gs_cb(prev->thread.gs_cb);                 \
0042     update_cr_regs(next);                       \
0043     restore_access_regs(&next->thread.acrs[0]);         \
0044     restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb);      \
0045     restore_gs_cb(next->thread.gs_cb);              \
0046     prev = __switch_to(prev, next);                 \
0047 } while (0)
0048 
0049 #endif /* __ASM_SWITCH_TO_H */