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, &regs->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, &regs->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(&current->thread.fp_regs);
70 save_fp_ctl(&current->thread.fp_regs.fpc);
71 save_fp_regs(current->thread.fp_regs.fprs);
71 memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
72 memcpy(&user_sregs.fpregs, &current->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(&regs->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs));
99 memcpy(&current->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(&regs->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs));
105 memcpy(&current->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(&current->thread.fp_regs, &user_sregs.fpregs,
107 restore_access_regs(current->thread.acrs);
108
109 memcpy(&current->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(&current->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 ---