signal.c (f8544ec4f49ffb9cb93419e41f0d8c0fb39eb78f) | signal.c (4725c86055f5bbdcdfe47199c0715881893a2c79) |
---|---|
1/* 2 * Copyright IBM Corp. 1999, 2006 3 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 4 * 5 * Based on Intel version 6 * 7 * Copyright (C) 1991, 1992 Linus Torvalds 8 * --- 48 unchanged lines hidden (view full) --- 57 58 /* Copy a 'clean' PSW mask to the user to avoid leaking 59 information about whether PER is currently on. */ 60 user_sregs.regs.psw.mask = PSW_USER_BITS | 61 (regs->psw.mask & PSW_MASK_USER); 62 user_sregs.regs.psw.addr = regs->psw.addr; 63 memcpy(&user_sregs.regs.gprs, ®s->gprs, sizeof(sregs->regs.gprs)); 64 memcpy(&user_sregs.regs.acrs, current->thread.acrs, | 1/* 2 * Copyright IBM Corp. 1999, 2006 3 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 4 * 5 * Based on Intel version 6 * 7 * Copyright (C) 1991, 1992 Linus Torvalds 8 * --- 48 unchanged lines hidden (view full) --- 57 58 /* Copy a 'clean' PSW mask to the user to avoid leaking 59 information about whether PER is currently on. */ 60 user_sregs.regs.psw.mask = PSW_USER_BITS | 61 (regs->psw.mask & PSW_MASK_USER); 62 user_sregs.regs.psw.addr = regs->psw.addr; 63 memcpy(&user_sregs.regs.gprs, ®s->gprs, sizeof(sregs->regs.gprs)); 64 memcpy(&user_sregs.regs.acrs, current->thread.acrs, |
65 sizeof(sregs->regs.acrs)); | 65 sizeof(user_sregs.regs.acrs)); |
66 /* 67 * We have to store the fp registers to current->thread.fp_regs 68 * to merge them with the emulated registers. 69 */ | 66 /* 67 * We have to store the fp registers to current->thread.fp_regs 68 * to merge them with the emulated registers. 69 */ |
70 save_fp_regs(¤t->thread.fp_regs); | 70 save_fp_ctl(¤t->thread.fp_regs.fpc); 71 save_fp_regs(current->thread.fp_regs.fprs); |
71 memcpy(&user_sregs.fpregs, ¤t->thread.fp_regs, | 72 memcpy(&user_sregs.fpregs, ¤t->thread.fp_regs, |
72 sizeof(s390_fp_regs)); | 73 sizeof(user_sregs.fpregs)); |
73 if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs))) 74 return -EFAULT; 75 return 0; 76} 77 78static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) 79{ 80 _sigregs user_sregs; 81 82 /* Alwys make any pending restarted system call return -EINTR */ 83 current_thread_info()->restart_block.fn = do_no_restart_syscall; 84 | 74 if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs))) 75 return -EFAULT; 76 return 0; 77} 78 79static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) 80{ 81 _sigregs user_sregs; 82 83 /* Alwys make any pending restarted system call return -EINTR */ 84 current_thread_info()->restart_block.fn = do_no_restart_syscall; 85 |
85 if (__copy_from_user(&user_sregs, sregs, sizeof(_sigregs))) | 86 if (__copy_from_user(&user_sregs, sregs, sizeof(user_sregs))) |
86 return -EFAULT; | 87 return -EFAULT; |
88 89 /* Loading the floating-point-control word can fail. Do that first. */ 90 if (restore_fp_ctl(&user_sregs.fpregs.fpc)) 91 return -EINVAL; 92 |
|
87 /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ 88 regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | 89 (user_sregs.regs.psw.mask & PSW_MASK_USER); 90 /* Check for invalid user address space control. */ 91 if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME) 92 regs->psw.mask = PSW_ASC_PRIMARY | 93 (regs->psw.mask & ~PSW_MASK_ASC); 94 /* Check for invalid amode */ 95 if (regs->psw.mask & PSW_MASK_EA) 96 regs->psw.mask |= PSW_MASK_BA; 97 regs->psw.addr = user_sregs.regs.psw.addr; 98 memcpy(®s->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs)); 99 memcpy(¤t->thread.acrs, &user_sregs.regs.acrs, | 93 /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ 94 regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | 95 (user_sregs.regs.psw.mask & PSW_MASK_USER); 96 /* Check for invalid user address space control. */ 97 if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME) 98 regs->psw.mask = PSW_ASC_PRIMARY | 99 (regs->psw.mask & ~PSW_MASK_ASC); 100 /* Check for invalid amode */ 101 if (regs->psw.mask & PSW_MASK_EA) 102 regs->psw.mask |= PSW_MASK_BA; 103 regs->psw.addr = user_sregs.regs.psw.addr; 104 memcpy(®s->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs)); 105 memcpy(¤t->thread.acrs, &user_sregs.regs.acrs, |
100 sizeof(sregs->regs.acrs)); | 106 sizeof(current->thread.acrs)); |
101 restore_access_regs(current->thread.acrs); 102 103 memcpy(¤t->thread.fp_regs, &user_sregs.fpregs, | 107 restore_access_regs(current->thread.acrs); 108 109 memcpy(¤t->thread.fp_regs, &user_sregs.fpregs, |
104 sizeof(s390_fp_regs)); 105 current->thread.fp_regs.fpc &= FPC_VALID_MASK; | 110 sizeof(current->thread.fp_regs)); |
106 | 111 |
107 restore_fp_regs(¤t->thread.fp_regs); | 112 restore_fp_regs(current->thread.fp_regs.fprs); |
108 clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */ 109 return 0; 110} 111 112SYSCALL_DEFINE0(sigreturn) 113{ 114 struct pt_regs *regs = task_pt_regs(current); 115 sigframe __user *frame = (sigframe __user *)regs->gprs[15]; --- 304 unchanged lines hidden --- | 113 clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */ 114 return 0; 115} 116 117SYSCALL_DEFINE0(sigreturn) 118{ 119 struct pt_regs *regs = task_pt_regs(current); 120 sigframe __user *frame = (sigframe __user *)regs->gprs[15]; --- 304 unchanged lines hidden --- |