diff options
| -rw-r--r-- | arch/frv/kernel/signal.c | 99 |
1 files changed, 40 insertions, 59 deletions
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index d822700d4f15..8e37cf237e6d 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
| @@ -180,17 +180,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, | |||
| 180 | /* | 180 | /* |
| 181 | * | 181 | * |
| 182 | */ | 182 | */ |
| 183 | static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | 183 | static int setup_frame(struct ksignal *ksig, sigset_t *set) |
| 184 | { | 184 | { |
| 185 | struct sigframe __user *frame; | 185 | struct sigframe __user *frame; |
| 186 | int rsig; | 186 | int rsig, sig = ksig->sig; |
| 187 | 187 | ||
| 188 | set_fs(USER_DS); | 188 | set_fs(USER_DS); |
| 189 | 189 | ||
| 190 | frame = get_sigframe(ka, sizeof(*frame)); | 190 | frame = get_sigframe(&ksig->ka, sizeof(*frame)); |
| 191 | 191 | ||
| 192 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 192 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
| 193 | goto give_sigsegv; | 193 | return -EFAULT; |
| 194 | 194 | ||
| 195 | rsig = sig; | 195 | rsig = sig; |
| 196 | if (sig < 32 && | 196 | if (sig < 32 && |
| @@ -199,22 +199,22 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
| 199 | rsig = __current_thread_info->exec_domain->signal_invmap[sig]; | 199 | rsig = __current_thread_info->exec_domain->signal_invmap[sig]; |
| 200 | 200 | ||
| 201 | if (__put_user(rsig, &frame->sig) < 0) | 201 | if (__put_user(rsig, &frame->sig) < 0) |
| 202 | goto give_sigsegv; | 202 | return -EFAULT; |
| 203 | 203 | ||
| 204 | if (setup_sigcontext(&frame->sc, set->sig[0])) | 204 | if (setup_sigcontext(&frame->sc, set->sig[0])) |
| 205 | goto give_sigsegv; | 205 | return -EFAULT; |
| 206 | 206 | ||
| 207 | if (_NSIG_WORDS > 1) { | 207 | if (_NSIG_WORDS > 1) { |
| 208 | if (__copy_to_user(frame->extramask, &set->sig[1], | 208 | if (__copy_to_user(frame->extramask, &set->sig[1], |
| 209 | sizeof(frame->extramask))) | 209 | sizeof(frame->extramask))) |
| 210 | goto give_sigsegv; | 210 | return -EFAULT; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /* Set up to return from userspace. If provided, use a stub | 213 | /* Set up to return from userspace. If provided, use a stub |
| 214 | * already in userspace. */ | 214 | * already in userspace. */ |
| 215 | if (ka->sa.sa_flags & SA_RESTORER) { | 215 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
| 216 | if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0) | 216 | if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode) < 0) |
| 217 | goto give_sigsegv; | 217 | return -EFAULT; |
| 218 | } | 218 | } |
| 219 | else { | 219 | else { |
| 220 | /* Set up the following code on the stack: | 220 | /* Set up the following code on the stack: |
| @@ -224,7 +224,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
| 224 | if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || | 224 | if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || |
| 225 | __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) || | 225 | __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) || |
| 226 | __put_user(0xc0700000, &frame->retcode[1])) | 226 | __put_user(0xc0700000, &frame->retcode[1])) |
| 227 | goto give_sigsegv; | 227 | return -EFAULT; |
| 228 | 228 | ||
| 229 | flush_icache_range((unsigned long) frame->retcode, | 229 | flush_icache_range((unsigned long) frame->retcode, |
| 230 | (unsigned long) (frame->retcode + 2)); | 230 | (unsigned long) (frame->retcode + 2)); |
| @@ -233,14 +233,14 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
| 233 | /* Set up registers for the signal handler */ | 233 | /* Set up registers for the signal handler */ |
| 234 | if (current->personality & FDPIC_FUNCPTRS) { | 234 | if (current->personality & FDPIC_FUNCPTRS) { |
| 235 | struct fdpic_func_descriptor __user *funcptr = | 235 | struct fdpic_func_descriptor __user *funcptr = |
| 236 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; | 236 | (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler; |
| 237 | struct fdpic_func_descriptor desc; | 237 | struct fdpic_func_descriptor desc; |
| 238 | if (copy_from_user(&desc, funcptr, sizeof(desc))) | 238 | if (copy_from_user(&desc, funcptr, sizeof(desc))) |
| 239 | goto give_sigsegv; | 239 | return -EFAULT; |
| 240 | __frame->pc = desc.text; | 240 | __frame->pc = desc.text; |
| 241 | __frame->gr15 = desc.GOT; | 241 | __frame->gr15 = desc.GOT; |
| 242 | } else { | 242 | } else { |
| 243 | __frame->pc = (unsigned long) ka->sa.sa_handler; | 243 | __frame->pc = (unsigned long) ksig->ka.sa.sa_handler; |
| 244 | __frame->gr15 = 0; | 244 | __frame->gr15 = 0; |
| 245 | } | 245 | } |
| 246 | 246 | ||
| @@ -255,29 +255,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
| 255 | #endif | 255 | #endif |
| 256 | 256 | ||
| 257 | return 0; | 257 | return 0; |
| 258 | |||
| 259 | give_sigsegv: | ||
| 260 | force_sigsegv(sig, current); | ||
| 261 | return -EFAULT; | ||
| 262 | |||
| 263 | } /* end setup_frame() */ | 258 | } /* end setup_frame() */ |
| 264 | 259 | ||
| 265 | /*****************************************************************************/ | 260 | /*****************************************************************************/ |
| 266 | /* | 261 | /* |
| 267 | * | 262 | * |
| 268 | */ | 263 | */ |
| 269 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 264 | static int setup_rt_frame(struct ksignal *ksig, sigset_t *set) |
| 270 | sigset_t *set) | ||
| 271 | { | 265 | { |
| 272 | struct rt_sigframe __user *frame; | 266 | struct rt_sigframe __user *frame; |
| 273 | int rsig; | 267 | int rsig, sig = ksig->sig; |
| 274 | 268 | ||
| 275 | set_fs(USER_DS); | 269 | set_fs(USER_DS); |
| 276 | 270 | ||
| 277 | frame = get_sigframe(ka, sizeof(*frame)); | 271 | frame = get_sigframe(&ksig->ka, sizeof(*frame)); |
| 278 | 272 | ||
| 279 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 273 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
| 280 | goto give_sigsegv; | 274 | return -EFAULT; |
| 281 | 275 | ||
| 282 | rsig = sig; | 276 | rsig = sig; |
| 283 | if (sig < 32 && | 277 | if (sig < 32 && |
| @@ -288,28 +282,28 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 288 | if (__put_user(rsig, &frame->sig) || | 282 | if (__put_user(rsig, &frame->sig) || |
| 289 | __put_user(&frame->info, &frame->pinfo) || | 283 | __put_user(&frame->info, &frame->pinfo) || |
| 290 | __put_user(&frame->uc, &frame->puc)) | 284 | __put_user(&frame->uc, &frame->puc)) |
| 291 | goto give_sigsegv; | 285 | return -EFAULT; |
| 292 | 286 | ||
| 293 | if (copy_siginfo_to_user(&frame->info, info)) | 287 | if (copy_siginfo_to_user(&frame->info, &ksig->info)) |
| 294 | goto give_sigsegv; | 288 | return -EFAULT; |
| 295 | 289 | ||
| 296 | /* Create the ucontext. */ | 290 | /* Create the ucontext. */ |
| 297 | if (__put_user(0, &frame->uc.uc_flags) || | 291 | if (__put_user(0, &frame->uc.uc_flags) || |
| 298 | __put_user(NULL, &frame->uc.uc_link) || | 292 | __put_user(NULL, &frame->uc.uc_link) || |
| 299 | __save_altstack(&frame->uc.uc_stack, __frame->sp)) | 293 | __save_altstack(&frame->uc.uc_stack, __frame->sp)) |
| 300 | goto give_sigsegv; | 294 | return -EFAULT; |
| 301 | 295 | ||
| 302 | if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0])) | 296 | if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0])) |
| 303 | goto give_sigsegv; | 297 | return -EFAULT; |
| 304 | 298 | ||
| 305 | if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) | 299 | if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) |
| 306 | goto give_sigsegv; | 300 | return -EFAULT; |
| 307 | 301 | ||
| 308 | /* Set up to return from userspace. If provided, use a stub | 302 | /* Set up to return from userspace. If provided, use a stub |
| 309 | * already in userspace. */ | 303 | * already in userspace. */ |
| 310 | if (ka->sa.sa_flags & SA_RESTORER) { | 304 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
| 311 | if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) | 305 | if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode)) |
| 312 | goto give_sigsegv; | 306 | return -EFAULT; |
| 313 | } | 307 | } |
| 314 | else { | 308 | else { |
| 315 | /* Set up the following code on the stack: | 309 | /* Set up the following code on the stack: |
| @@ -319,7 +313,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 319 | if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || | 313 | if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || |
| 320 | __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) || | 314 | __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) || |
| 321 | __put_user(0xc0700000, &frame->retcode[1])) | 315 | __put_user(0xc0700000, &frame->retcode[1])) |
| 322 | goto give_sigsegv; | 316 | return -EFAULT; |
| 323 | 317 | ||
| 324 | flush_icache_range((unsigned long) frame->retcode, | 318 | flush_icache_range((unsigned long) frame->retcode, |
| 325 | (unsigned long) (frame->retcode + 2)); | 319 | (unsigned long) (frame->retcode + 2)); |
| @@ -328,14 +322,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 328 | /* Set up registers for signal handler */ | 322 | /* Set up registers for signal handler */ |
| 329 | if (current->personality & FDPIC_FUNCPTRS) { | 323 | if (current->personality & FDPIC_FUNCPTRS) { |
| 330 | struct fdpic_func_descriptor __user *funcptr = | 324 | struct fdpic_func_descriptor __user *funcptr = |
| 331 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; | 325 | (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler; |
| 332 | struct fdpic_func_descriptor desc; | 326 | struct fdpic_func_descriptor desc; |
| 333 | if (copy_from_user(&desc, funcptr, sizeof(desc))) | 327 | if (copy_from_user(&desc, funcptr, sizeof(desc))) |
| 334 | goto give_sigsegv; | 328 | return -EFAULT; |
| 335 | __frame->pc = desc.text; | 329 | __frame->pc = desc.text; |
| 336 | __frame->gr15 = desc.GOT; | 330 | __frame->gr15 = desc.GOT; |
| 337 | } else { | 331 | } else { |
| 338 | __frame->pc = (unsigned long) ka->sa.sa_handler; | 332 | __frame->pc = (unsigned long) ksig->ka.sa.sa_handler; |
| 339 | __frame->gr15 = 0; | 333 | __frame->gr15 = 0; |
| 340 | } | 334 | } |
| 341 | 335 | ||
| @@ -349,21 +343,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 349 | sig, current->comm, current->pid, frame, __frame->pc, | 343 | sig, current->comm, current->pid, frame, __frame->pc, |
| 350 | frame->pretcode); | 344 | frame->pretcode); |
| 351 | #endif | 345 | #endif |
| 352 | |||
| 353 | return 0; | 346 | return 0; |
| 354 | 347 | ||
| 355 | give_sigsegv: | ||
| 356 | force_sigsegv(sig, current); | ||
| 357 | return -EFAULT; | ||
| 358 | |||
| 359 | } /* end setup_rt_frame() */ | 348 | } /* end setup_rt_frame() */ |
| 360 | 349 | ||
| 361 | /*****************************************************************************/ | 350 | /*****************************************************************************/ |
| 362 | /* | 351 | /* |
| 363 | * OK, we're invoking a handler | 352 | * OK, we're invoking a handler |
| 364 | */ | 353 | */ |
| 365 | static void handle_signal(unsigned long sig, siginfo_t *info, | 354 | static void handle_signal(struct ksignal *ksig) |
| 366 | struct k_sigaction *ka) | ||
| 367 | { | 355 | { |
| 368 | sigset_t *oldset = sigmask_to_save(); | 356 | sigset_t *oldset = sigmask_to_save(); |
| 369 | int ret; | 357 | int ret; |
| @@ -378,7 +366,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info, | |||
| 378 | break; | 366 | break; |
| 379 | 367 | ||
| 380 | case -ERESTARTSYS: | 368 | case -ERESTARTSYS: |
| 381 | if (!(ka->sa.sa_flags & SA_RESTART)) { | 369 | if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { |
| 382 | __frame->gr8 = -EINTR; | 370 | __frame->gr8 = -EINTR; |
| 383 | break; | 371 | break; |
| 384 | } | 372 | } |
| @@ -392,16 +380,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info, | |||
| 392 | } | 380 | } |
| 393 | 381 | ||
| 394 | /* Set up the stack frame */ | 382 | /* Set up the stack frame */ |
| 395 | if (ka->sa.sa_flags & SA_SIGINFO) | 383 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
| 396 | ret = setup_rt_frame(sig, ka, info, oldset); | 384 | ret = setup_rt_frame(ksig, oldset); |
| 397 | else | 385 | else |
| 398 | ret = setup_frame(sig, ka, oldset); | 386 | ret = setup_frame(ksig, oldset); |
| 399 | |||
| 400 | if (ret) | ||
| 401 | return; | ||
| 402 | 387 | ||
| 403 | signal_delivered(sig, info, ka, __frame, | 388 | signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); |
| 404 | test_thread_flag(TIF_SINGLESTEP)); | ||
| 405 | } /* end handle_signal() */ | 389 | } /* end handle_signal() */ |
| 406 | 390 | ||
| 407 | /*****************************************************************************/ | 391 | /*****************************************************************************/ |
| @@ -412,13 +396,10 @@ static void handle_signal(unsigned long sig, siginfo_t *info, | |||
| 412 | */ | 396 | */ |
| 413 | static void do_signal(void) | 397 | static void do_signal(void) |
| 414 | { | 398 | { |
| 415 | struct k_sigaction ka; | 399 | struct ksignal ksig; |
| 416 | siginfo_t info; | ||
| 417 | int signr; | ||
| 418 | 400 | ||
| 419 | signr = get_signal_to_deliver(&info, &ka, __frame, NULL); | 401 | if (get_signal(&ksig)) { |
| 420 | if (signr > 0) { | 402 | handle_signal(&ksig); |
| 421 | handle_signal(signr, &info, &ka); | ||
| 422 | return; | 403 | return; |
| 423 | } | 404 | } |
| 424 | 405 | ||
