0001
0002
0003
0004
0005
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
0035
0036
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