 bee5c2863e
			
		
	
	
	bee5c2863e
	
	
	
		
			
			Fix broken contraints for both save_access_regs() and restore_access_regs(). The constraints are incorrect since they tell the compiler that the inline assemblies only access the first element of an array of 16 elements. Therefore the compiler could generate incorrect code. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
		
			
				
	
	
		
			103 lines
		
	
	
	
		
			2.4 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
	
		
			2.4 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright IBM Corp. 1999, 2009
 | |
|  *
 | |
|  * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
 | |
|  */
 | |
| 
 | |
| #ifndef __ASM_SWITCH_TO_H
 | |
| #define __ASM_SWITCH_TO_H
 | |
| 
 | |
| #include <linux/thread_info.h>
 | |
| #include <asm/ptrace.h>
 | |
| 
 | |
| extern struct task_struct *__switch_to(void *, void *);
 | |
| extern void update_cr_regs(struct task_struct *task);
 | |
| 
 | |
| static inline void save_fp_regs(s390_fp_regs *fpregs)
 | |
| {
 | |
| 	asm volatile(
 | |
| 		"	std	0,%O0+8(%R0)\n"
 | |
| 		"	std	2,%O0+24(%R0)\n"
 | |
| 		"	std	4,%O0+40(%R0)\n"
 | |
| 		"	std	6,%O0+56(%R0)"
 | |
| 		: "=Q" (*fpregs) : "Q" (*fpregs));
 | |
| 	if (!MACHINE_HAS_IEEE)
 | |
| 		return;
 | |
| 	asm volatile(
 | |
| 		"	stfpc	%0\n"
 | |
| 		"	std	1,%O0+16(%R0)\n"
 | |
| 		"	std	3,%O0+32(%R0)\n"
 | |
| 		"	std	5,%O0+48(%R0)\n"
 | |
| 		"	std	7,%O0+64(%R0)\n"
 | |
| 		"	std	8,%O0+72(%R0)\n"
 | |
| 		"	std	9,%O0+80(%R0)\n"
 | |
| 		"	std	10,%O0+88(%R0)\n"
 | |
| 		"	std	11,%O0+96(%R0)\n"
 | |
| 		"	std	12,%O0+104(%R0)\n"
 | |
| 		"	std	13,%O0+112(%R0)\n"
 | |
| 		"	std	14,%O0+120(%R0)\n"
 | |
| 		"	std	15,%O0+128(%R0)\n"
 | |
| 		: "=Q" (*fpregs) : "Q" (*fpregs));
 | |
| }
 | |
| 
 | |
| static inline void restore_fp_regs(s390_fp_regs *fpregs)
 | |
| {
 | |
| 	asm volatile(
 | |
| 		"	ld	0,%O0+8(%R0)\n"
 | |
| 		"	ld	2,%O0+24(%R0)\n"
 | |
| 		"	ld	4,%O0+40(%R0)\n"
 | |
| 		"	ld	6,%O0+56(%R0)"
 | |
| 		: : "Q" (*fpregs));
 | |
| 	if (!MACHINE_HAS_IEEE)
 | |
| 		return;
 | |
| 	asm volatile(
 | |
| 		"	lfpc	%0\n"
 | |
| 		"	ld	1,%O0+16(%R0)\n"
 | |
| 		"	ld	3,%O0+32(%R0)\n"
 | |
| 		"	ld	5,%O0+48(%R0)\n"
 | |
| 		"	ld	7,%O0+64(%R0)\n"
 | |
| 		"	ld	8,%O0+72(%R0)\n"
 | |
| 		"	ld	9,%O0+80(%R0)\n"
 | |
| 		"	ld	10,%O0+88(%R0)\n"
 | |
| 		"	ld	11,%O0+96(%R0)\n"
 | |
| 		"	ld	12,%O0+104(%R0)\n"
 | |
| 		"	ld	13,%O0+112(%R0)\n"
 | |
| 		"	ld	14,%O0+120(%R0)\n"
 | |
| 		"	ld	15,%O0+128(%R0)\n"
 | |
| 		: : "Q" (*fpregs));
 | |
| }
 | |
| 
 | |
| static inline void save_access_regs(unsigned int *acrs)
 | |
| {
 | |
| 	typedef struct { int _[NUM_ACRS]; } acrstype;
 | |
| 
 | |
| 	asm volatile("stam 0,15,%0" : "=Q" (*(acrstype *)acrs));
 | |
| }
 | |
| 
 | |
| static inline void restore_access_regs(unsigned int *acrs)
 | |
| {
 | |
| 	typedef struct { int _[NUM_ACRS]; } acrstype;
 | |
| 
 | |
| 	asm volatile("lam 0,15,%0" : : "Q" (*(acrstype *)acrs));
 | |
| }
 | |
| 
 | |
| #define switch_to(prev,next,last) do {					\
 | |
| 	if (prev->mm) {							\
 | |
| 		save_fp_regs(&prev->thread.fp_regs);			\
 | |
| 		save_access_regs(&prev->thread.acrs[0]);		\
 | |
| 		save_ri_cb(prev->thread.ri_cb);				\
 | |
| 	}								\
 | |
| 	if (next->mm) {							\
 | |
| 		restore_fp_regs(&next->thread.fp_regs);			\
 | |
| 		restore_access_regs(&next->thread.acrs[0]);		\
 | |
| 		restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb);	\
 | |
| 		update_cr_regs(next);					\
 | |
| 	}								\
 | |
| 	prev = __switch_to(prev,next);					\
 | |
| } while (0)
 | |
| 
 | |
| #define finish_arch_switch(prev) do {					     \
 | |
| 	set_fs(current->thread.mm_segment);				     \
 | |
| } while (0)
 | |
| 
 | |
| #endif /* __ASM_SWITCH_TO_H */
 |