diff options
Diffstat (limited to 'arch/x86/um/signal_64.c')
-rw-r--r-- | arch/x86/um/signal_64.c | 33 |
1 files changed, 7 insertions, 26 deletions
diff --git a/arch/x86/um/signal_64.c b/arch/x86/um/signal_64.c index 4e5b9b07a8c7..74c2598b0b31 100644 --- a/arch/x86/um/signal_64.c +++ b/arch/x86/um/signal_64.c | |||
@@ -68,7 +68,7 @@ static int copy_sc_from_user(struct pt_regs *regs, | |||
68 | 68 | ||
69 | static int copy_sc_to_user(struct sigcontext __user *to, | 69 | static int copy_sc_to_user(struct sigcontext __user *to, |
70 | struct _fpstate __user *to_fp, struct pt_regs *regs, | 70 | struct _fpstate __user *to_fp, struct pt_regs *regs, |
71 | unsigned long mask, unsigned long sp) | 71 | unsigned long mask) |
72 | { | 72 | { |
73 | struct faultinfo * fi = ¤t->thread.arch.faultinfo; | 73 | struct faultinfo * fi = ¤t->thread.arch.faultinfo; |
74 | struct sigcontext sc; | 74 | struct sigcontext sc; |
@@ -81,11 +81,7 @@ static int copy_sc_to_user(struct sigcontext __user *to, | |||
81 | PUTREG(DI, di); | 81 | PUTREG(DI, di); |
82 | PUTREG(SI, si); | 82 | PUTREG(SI, si); |
83 | PUTREG(BP, bp); | 83 | PUTREG(BP, bp); |
84 | /* | 84 | PUTREG(SP, sp); |
85 | * Must use original RSP, which is passed in, rather than what's in | ||
86 | * signal frame. | ||
87 | */ | ||
88 | sc.sp = sp; | ||
89 | PUTREG(BX, bx); | 85 | PUTREG(BX, bx); |
90 | PUTREG(DX, dx); | 86 | PUTREG(DX, dx); |
91 | PUTREG(CX, cx); | 87 | PUTREG(CX, cx); |
@@ -141,7 +137,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
141 | siginfo_t *info, sigset_t *set) | 137 | siginfo_t *info, sigset_t *set) |
142 | { | 138 | { |
143 | struct rt_sigframe __user *frame; | 139 | struct rt_sigframe __user *frame; |
144 | unsigned long save_sp = PT_REGS_RSP(regs); | ||
145 | int err = 0; | 140 | int err = 0; |
146 | struct task_struct *me = current; | 141 | struct task_struct *me = current; |
147 | 142 | ||
@@ -159,26 +154,15 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
159 | goto out; | 154 | goto out; |
160 | } | 155 | } |
161 | 156 | ||
162 | /* | ||
163 | * Update SP now because the page fault handler refuses to extend | ||
164 | * the stack if the faulting address is too far below the current | ||
165 | * SP, which frame now certainly is. If there's an error, the original | ||
166 | * value is restored on the way out. | ||
167 | * When writing the sigcontext to the stack, we have to write the | ||
168 | * original value, so that's passed to copy_sc_to_user, which does | ||
169 | * the right thing with it. | ||
170 | */ | ||
171 | PT_REGS_RSP(regs) = (unsigned long) frame; | ||
172 | |||
173 | /* Create the ucontext. */ | 157 | /* Create the ucontext. */ |
174 | err |= __put_user(0, &frame->uc.uc_flags); | 158 | err |= __put_user(0, &frame->uc.uc_flags); |
175 | err |= __put_user(0, &frame->uc.uc_link); | 159 | err |= __put_user(0, &frame->uc.uc_link); |
176 | err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); | 160 | err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); |
177 | err |= __put_user(sas_ss_flags(save_sp), | 161 | err |= __put_user(sas_ss_flags(PT_REGS_RSP(regs)), |
178 | &frame->uc.uc_stack.ss_flags); | 162 | &frame->uc.uc_stack.ss_flags); |
179 | err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); | 163 | err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); |
180 | err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, | 164 | err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, |
181 | set->sig[0], save_sp); | 165 | set->sig[0]); |
182 | err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); | 166 | err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); |
183 | if (sizeof(*set) == 16) { | 167 | if (sizeof(*set) == 16) { |
184 | __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); | 168 | __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); |
@@ -197,10 +181,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
197 | err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); | 181 | err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); |
198 | else | 182 | else |
199 | /* could use a vstub here */ | 183 | /* could use a vstub here */ |
200 | goto restore_sp; | 184 | return err; |
201 | 185 | ||
202 | if (err) | 186 | if (err) |
203 | goto restore_sp; | 187 | return err; |
204 | 188 | ||
205 | /* Set up registers for signal handler */ | 189 | /* Set up registers for signal handler */ |
206 | { | 190 | { |
@@ -209,6 +193,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
209 | sig = ed->signal_invmap[sig]; | 193 | sig = ed->signal_invmap[sig]; |
210 | } | 194 | } |
211 | 195 | ||
196 | PT_REGS_RSP(regs) = (unsigned long) frame; | ||
212 | PT_REGS_RDI(regs) = sig; | 197 | PT_REGS_RDI(regs) = sig; |
213 | /* In case the signal handler was declared without prototypes */ | 198 | /* In case the signal handler was declared without prototypes */ |
214 | PT_REGS_RAX(regs) = 0; | 199 | PT_REGS_RAX(regs) = 0; |
@@ -222,10 +207,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
222 | PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; | 207 | PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; |
223 | out: | 208 | out: |
224 | return err; | 209 | return err; |
225 | |||
226 | restore_sp: | ||
227 | PT_REGS_RSP(regs) = save_sp; | ||
228 | return err; | ||
229 | } | 210 | } |
230 | 211 | ||
231 | long sys_rt_sigreturn(struct pt_regs *regs) | 212 | long sys_rt_sigreturn(struct pt_regs *regs) |