diff options
| -rw-r--r-- | arch/frv/kernel/signal.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 7fc29615ef01..5fb2d0661c78 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
| @@ -253,6 +253,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
| 253 | struct sigframe __user *frame; | 253 | struct sigframe __user *frame; |
| 254 | int rsig; | 254 | int rsig; |
| 255 | 255 | ||
| 256 | set_fs(USER_DS); | ||
| 257 | |||
| 256 | frame = get_sigframe(ka, sizeof(*frame)); | 258 | frame = get_sigframe(ka, sizeof(*frame)); |
| 257 | 259 | ||
| 258 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 260 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
| @@ -296,22 +298,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
| 296 | (unsigned long) (frame->retcode + 2)); | 298 | (unsigned long) (frame->retcode + 2)); |
| 297 | } | 299 | } |
| 298 | 300 | ||
| 299 | /* set up registers for signal handler */ | 301 | /* Set up registers for the signal handler */ |
| 300 | __frame->sp = (unsigned long) frame; | ||
| 301 | __frame->lr = (unsigned long) &frame->retcode; | ||
| 302 | __frame->gr8 = sig; | ||
| 303 | |||
| 304 | if (current->personality & FDPIC_FUNCPTRS) { | 302 | if (current->personality & FDPIC_FUNCPTRS) { |
| 305 | struct fdpic_func_descriptor __user *funcptr = | 303 | struct fdpic_func_descriptor __user *funcptr = |
| 306 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; | 304 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; |
| 307 | __get_user(__frame->pc, &funcptr->text); | 305 | struct fdpic_func_descriptor desc; |
| 308 | __get_user(__frame->gr15, &funcptr->GOT); | 306 | if (copy_from_user(&desc, funcptr, sizeof(desc))) |
| 307 | goto give_sigsegv; | ||
| 308 | __frame->pc = desc.text; | ||
| 309 | __frame->gr15 = desc.GOT; | ||
| 309 | } else { | 310 | } else { |
| 310 | __frame->pc = (unsigned long) ka->sa.sa_handler; | 311 | __frame->pc = (unsigned long) ka->sa.sa_handler; |
| 311 | __frame->gr15 = 0; | 312 | __frame->gr15 = 0; |
| 312 | } | 313 | } |
| 313 | 314 | ||
| 314 | set_fs(USER_DS); | 315 | __frame->sp = (unsigned long) frame; |
| 316 | __frame->lr = (unsigned long) &frame->retcode; | ||
| 317 | __frame->gr8 = sig; | ||
| 315 | 318 | ||
| 316 | /* the tracer may want to single-step inside the handler */ | 319 | /* the tracer may want to single-step inside the handler */ |
| 317 | if (test_thread_flag(TIF_SINGLESTEP)) | 320 | if (test_thread_flag(TIF_SINGLESTEP)) |
| @@ -341,6 +344,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 341 | struct rt_sigframe __user *frame; | 344 | struct rt_sigframe __user *frame; |
| 342 | int rsig; | 345 | int rsig; |
| 343 | 346 | ||
| 347 | set_fs(USER_DS); | ||
| 348 | |||
| 344 | frame = get_sigframe(ka, sizeof(*frame)); | 349 | frame = get_sigframe(ka, sizeof(*frame)); |
| 345 | 350 | ||
| 346 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 351 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
| @@ -395,22 +400,23 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 395 | } | 400 | } |
| 396 | 401 | ||
| 397 | /* Set up registers for signal handler */ | 402 | /* Set up registers for signal handler */ |
| 398 | __frame->sp = (unsigned long) frame; | ||
| 399 | __frame->lr = (unsigned long) &frame->retcode; | ||
| 400 | __frame->gr8 = sig; | ||
| 401 | __frame->gr9 = (unsigned long) &frame->info; | ||
| 402 | |||
| 403 | if (current->personality & FDPIC_FUNCPTRS) { | 403 | if (current->personality & FDPIC_FUNCPTRS) { |
| 404 | struct fdpic_func_descriptor __user *funcptr = | 404 | struct fdpic_func_descriptor __user *funcptr = |
| 405 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; | 405 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; |
| 406 | __get_user(__frame->pc, &funcptr->text); | 406 | struct fdpic_func_descriptor desc; |
| 407 | __get_user(__frame->gr15, &funcptr->GOT); | 407 | if (copy_from_user(&desc, funcptr, sizeof(desc))) |
| 408 | goto give_sigsegv; | ||
| 409 | __frame->pc = desc.text; | ||
| 410 | __frame->gr15 = desc.GOT; | ||
| 408 | } else { | 411 | } else { |
| 409 | __frame->pc = (unsigned long) ka->sa.sa_handler; | 412 | __frame->pc = (unsigned long) ka->sa.sa_handler; |
| 410 | __frame->gr15 = 0; | 413 | __frame->gr15 = 0; |
| 411 | } | 414 | } |
| 412 | 415 | ||
| 413 | set_fs(USER_DS); | 416 | __frame->sp = (unsigned long) frame; |
| 417 | __frame->lr = (unsigned long) &frame->retcode; | ||
| 418 | __frame->gr8 = sig; | ||
| 419 | __frame->gr9 = (unsigned long) &frame->info; | ||
| 414 | 420 | ||
| 415 | /* the tracer may want to single-step inside the handler */ | 421 | /* the tracer may want to single-step inside the handler */ |
| 416 | if (test_thread_flag(TIF_SINGLESTEP)) | 422 | if (test_thread_flag(TIF_SINGLESTEP)) |
