aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/ia32/ia32_signal.c12
-rw-r--r--arch/x86/include/asm/uaccess.h14
-rw-r--r--arch/x86/kernel/signal.c24
3 files changed, 27 insertions, 23 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 673ac9b63d6b..05e62a312bd9 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -250,11 +250,12 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
250 250
251 get_user_ex(tmp, &sc->fpstate); 251 get_user_ex(tmp, &sc->fpstate);
252 buf = compat_ptr(tmp); 252 buf = compat_ptr(tmp);
253 err |= restore_i387_xstate_ia32(buf);
254 253
255 get_user_ex(*pax, &sc->ax); 254 get_user_ex(*pax, &sc->ax);
256 } get_user_catch(err); 255 } get_user_catch(err);
257 256
257 err |= restore_i387_xstate_ia32(buf);
258
258 return err; 259 return err;
259} 260}
260 261
@@ -502,7 +503,6 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
502 put_user_ex(sig, &frame->sig); 503 put_user_ex(sig, &frame->sig);
503 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo); 504 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
504 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc); 505 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
505 err |= copy_siginfo_to_user32(&frame->info, info);
506 506
507 /* Create the ucontext. */ 507 /* Create the ucontext. */
508 if (cpu_has_xsave) 508 if (cpu_has_xsave)
@@ -514,9 +514,6 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
514 put_user_ex(sas_ss_flags(regs->sp), 514 put_user_ex(sas_ss_flags(regs->sp),
515 &frame->uc.uc_stack.ss_flags); 515 &frame->uc.uc_stack.ss_flags);
516 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 516 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
517 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
518 regs, set->sig[0]);
519 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
520 517
521 if (ka->sa.sa_flags & SA_RESTORER) 518 if (ka->sa.sa_flags & SA_RESTORER)
522 restorer = ka->sa.sa_restorer; 519 restorer = ka->sa.sa_restorer;
@@ -532,6 +529,11 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
532 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode); 529 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
533 } put_user_catch(err); 530 } put_user_catch(err);
534 531
532 err |= copy_siginfo_to_user32(&frame->info, info);
533 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
534 regs, set->sig[0]);
535 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
536
535 if (err) 537 if (err)
536 return -EFAULT; 538 return -EFAULT;
537 539
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index b92ece13c238..a91acfbb1a98 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -416,9 +416,8 @@ do { \
416} while (0) 416} while (0)
417 417
418#define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ 418#define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
419 asm volatile(ASM_STAC "\n" \ 419 asm volatile("1: mov"itype" %1,%"rtype"0\n" \
420 "1: mov"itype" %1,%"rtype"0\n" \ 420 "2:\n" \
421 "2: " ASM_CLAC "\n" \
422 _ASM_EXTABLE_EX(1b, 2b) \ 421 _ASM_EXTABLE_EX(1b, 2b) \
423 : ltype(x) : "m" (__m(addr))) 422 : ltype(x) : "m" (__m(addr)))
424 423
@@ -460,9 +459,8 @@ struct __large_struct { unsigned long buf[100]; };
460 : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) 459 : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
461 460
462#define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ 461#define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
463 asm volatile(ASM_STAC "\n" \ 462 asm volatile("1: mov"itype" %"rtype"0,%1\n" \
464 "1: mov"itype" %"rtype"0,%1\n" \ 463 "2:\n" \
465 "2: " ASM_CLAC "\n" \
466 _ASM_EXTABLE_EX(1b, 2b) \ 464 _ASM_EXTABLE_EX(1b, 2b) \
467 : : ltype(x), "m" (__m(addr))) 465 : : ltype(x), "m" (__m(addr)))
468 466
@@ -470,13 +468,13 @@ struct __large_struct { unsigned long buf[100]; };
470 * uaccess_try and catch 468 * uaccess_try and catch
471 */ 469 */
472#define uaccess_try do { \ 470#define uaccess_try do { \
473 int prev_err = current_thread_info()->uaccess_err; \
474 current_thread_info()->uaccess_err = 0; \ 471 current_thread_info()->uaccess_err = 0; \
472 stac(); \
475 barrier(); 473 barrier();
476 474
477#define uaccess_catch(err) \ 475#define uaccess_catch(err) \
476 clac(); \
478 (err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \ 477 (err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \
479 current_thread_info()->uaccess_err = prev_err; \
480} while (0) 478} while (0)
481 479
482/** 480/**
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index b280908a376e..932612887e92 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -114,11 +114,12 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
114 regs->orig_ax = -1; /* disable syscall checks */ 114 regs->orig_ax = -1; /* disable syscall checks */
115 115
116 get_user_ex(buf, &sc->fpstate); 116 get_user_ex(buf, &sc->fpstate);
117 err |= restore_i387_xstate(buf);
118 117
119 get_user_ex(*pax, &sc->ax); 118 get_user_ex(*pax, &sc->ax);
120 } get_user_catch(err); 119 } get_user_catch(err);
121 120
121 err |= restore_i387_xstate(buf);
122
122 return err; 123 return err;
123} 124}
124 125
@@ -357,7 +358,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
357 put_user_ex(sig, &frame->sig); 358 put_user_ex(sig, &frame->sig);
358 put_user_ex(&frame->info, &frame->pinfo); 359 put_user_ex(&frame->info, &frame->pinfo);
359 put_user_ex(&frame->uc, &frame->puc); 360 put_user_ex(&frame->uc, &frame->puc);
360 err |= copy_siginfo_to_user(&frame->info, info);
361 361
362 /* Create the ucontext. */ 362 /* Create the ucontext. */
363 if (cpu_has_xsave) 363 if (cpu_has_xsave)
@@ -369,9 +369,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
369 put_user_ex(sas_ss_flags(regs->sp), 369 put_user_ex(sas_ss_flags(regs->sp),
370 &frame->uc.uc_stack.ss_flags); 370 &frame->uc.uc_stack.ss_flags);
371 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 371 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
372 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
373 regs, set->sig[0]);
374 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
375 372
376 /* Set up to return from userspace. */ 373 /* Set up to return from userspace. */
377 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); 374 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
@@ -389,6 +386,11 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
389 put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode); 386 put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
390 } put_user_catch(err); 387 } put_user_catch(err);
391 388
389 err |= copy_siginfo_to_user(&frame->info, info);
390 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
391 regs, set->sig[0]);
392 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
393
392 if (err) 394 if (err)
393 return -EFAULT; 395 return -EFAULT;
394 396
@@ -436,8 +438,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
436 put_user_ex(sas_ss_flags(regs->sp), 438 put_user_ex(sas_ss_flags(regs->sp),
437 &frame->uc.uc_stack.ss_flags); 439 &frame->uc.uc_stack.ss_flags);
438 put_user_ex(me->sas_ss_size, &frame->uc.uc_stack.ss_size); 440 put_user_ex(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
439 err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
440 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
441 441
442 /* Set up to return from userspace. If provided, use a stub 442 /* Set up to return from userspace. If provided, use a stub
443 already in userspace. */ 443 already in userspace. */
@@ -450,6 +450,9 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
450 } 450 }
451 } put_user_catch(err); 451 } put_user_catch(err);
452 452
453 err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
454 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
455
453 if (err) 456 if (err)
454 return -EFAULT; 457 return -EFAULT;
455 458
@@ -855,9 +858,6 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
855 &frame->uc.uc_stack.ss_flags); 858 &frame->uc.uc_stack.ss_flags);
856 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 859 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
857 put_user_ex(0, &frame->uc.uc__pad0); 860 put_user_ex(0, &frame->uc.uc__pad0);
858 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
859 regs, set->sig[0]);
860 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
861 861
862 if (ka->sa.sa_flags & SA_RESTORER) { 862 if (ka->sa.sa_flags & SA_RESTORER) {
863 restorer = ka->sa.sa_restorer; 863 restorer = ka->sa.sa_restorer;
@@ -869,6 +869,10 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
869 put_user_ex(restorer, &frame->pretcode); 869 put_user_ex(restorer, &frame->pretcode);
870 } put_user_catch(err); 870 } put_user_catch(err);
871 871
872 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
873 regs, set->sig[0]);
874 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
875
872 if (err) 876 if (err)
873 return -EFAULT; 877 return -EFAULT;
874 878