diff options
-rw-r--r-- | arch/x86/ia32/ia32_signal.c | 12 | ||||
-rw-r--r-- | arch/x86/include/asm/uaccess.h | 14 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 24 |
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 | ||