diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/ia64/include/asm/processor.h | 5 | ||||
-rw-r--r-- | arch/ia64/kernel/fsys.S | 191 |
3 files changed, 15 insertions, 182 deletions
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index 241d1c53ba69..d4eb9383f5f6 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild | |||
@@ -1,6 +1,7 @@ | |||
1 | include include/asm-generic/Kbuild.asm | 1 | include include/asm-generic/Kbuild.asm |
2 | 2 | ||
3 | header-y += break.h | 3 | header-y += break.h |
4 | header-y += cmpxchg.h | ||
4 | header-y += fpu.h | 5 | header-y += fpu.h |
5 | header-y += gcc_intrin.h | 6 | header-y += gcc_intrin.h |
6 | header-y += ia64regs.h | 7 | header-y += ia64regs.h |
diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index 5a994ec8f06d..832dd3789e9d 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h | |||
@@ -34,8 +34,7 @@ | |||
34 | * each (assuming 8KB page size), for a total of 8TB of user virtual | 34 | * each (assuming 8KB page size), for a total of 8TB of user virtual |
35 | * address space. | 35 | * address space. |
36 | */ | 36 | */ |
37 | #define TASK_SIZE_OF(tsk) ((tsk)->thread.task_size) | 37 | #define TASK_SIZE DEFAULT_TASK_SIZE |
38 | #define TASK_SIZE TASK_SIZE_OF(current) | ||
39 | 38 | ||
40 | /* | 39 | /* |
41 | * This decides where the kernel will search for a free chunk of vm | 40 | * This decides where the kernel will search for a free chunk of vm |
@@ -280,7 +279,6 @@ struct thread_struct { | |||
280 | __u8 pad[3]; | 279 | __u8 pad[3]; |
281 | __u64 ksp; /* kernel stack pointer */ | 280 | __u64 ksp; /* kernel stack pointer */ |
282 | __u64 map_base; /* base address for get_unmapped_area() */ | 281 | __u64 map_base; /* base address for get_unmapped_area() */ |
283 | __u64 task_size; /* limit for task size */ | ||
284 | __u64 rbs_bot; /* the base address for the RBS */ | 282 | __u64 rbs_bot; /* the base address for the RBS */ |
285 | int last_fph_cpu; /* CPU that may hold the contents of f32-f127 */ | 283 | int last_fph_cpu; /* CPU that may hold the contents of f32-f127 */ |
286 | 284 | ||
@@ -303,7 +301,6 @@ struct thread_struct { | |||
303 | .ksp = 0, \ | 301 | .ksp = 0, \ |
304 | .map_base = DEFAULT_MAP_BASE, \ | 302 | .map_base = DEFAULT_MAP_BASE, \ |
305 | .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \ | 303 | .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \ |
306 | .task_size = DEFAULT_TASK_SIZE, \ | ||
307 | .last_fph_cpu = -1, \ | 304 | .last_fph_cpu = -1, \ |
308 | INIT_THREAD_PM \ | 305 | INIT_THREAD_PM \ |
309 | .dbr = {0, }, \ | 306 | .dbr = {0, }, \ |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index cc26edac0ec6..e662f178b990 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
@@ -372,175 +372,6 @@ ENTRY(fsys_clock_gettime) | |||
372 | END(fsys_clock_gettime) | 372 | END(fsys_clock_gettime) |
373 | 373 | ||
374 | /* | 374 | /* |
375 | * long fsys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset, size_t sigsetsize). | ||
376 | */ | ||
377 | #if _NSIG_WORDS != 1 | ||
378 | # error Sorry, fsys_rt_sigprocmask() needs to be updated for _NSIG_WORDS != 1. | ||
379 | #endif | ||
380 | ENTRY(fsys_rt_sigprocmask) | ||
381 | .prologue | ||
382 | .altrp b6 | ||
383 | .body | ||
384 | |||
385 | add r2=IA64_TASK_BLOCKED_OFFSET,r16 | ||
386 | add r9=TI_FLAGS+IA64_TASK_SIZE,r16 | ||
387 | cmp4.ltu p6,p0=SIG_SETMASK,r32 | ||
388 | |||
389 | cmp.ne p15,p0=r0,r34 // oset != NULL? | ||
390 | tnat.nz p8,p0=r34 | ||
391 | add r31=IA64_TASK_SIGHAND_OFFSET,r16 | ||
392 | ;; | ||
393 | ld8 r3=[r2] // read/prefetch current->blocked | ||
394 | ld4 r9=[r9] | ||
395 | tnat.nz.or p6,p0=r35 | ||
396 | |||
397 | cmp.ne.or p6,p0=_NSIG_WORDS*8,r35 | ||
398 | tnat.nz.or p6,p0=r32 | ||
399 | (p6) br.spnt.few .fail_einval // fail with EINVAL | ||
400 | ;; | ||
401 | #ifdef CONFIG_SMP | ||
402 | ld8 r31=[r31] // r31 <- current->sighand | ||
403 | #endif | ||
404 | and r9=TIF_ALLWORK_MASK,r9 | ||
405 | tnat.nz.or p8,p0=r33 | ||
406 | ;; | ||
407 | cmp.ne p7,p0=0,r9 | ||
408 | cmp.eq p6,p0=r0,r33 // set == NULL? | ||
409 | add r31=IA64_SIGHAND_SIGLOCK_OFFSET,r31 // r31 <- current->sighand->siglock | ||
410 | (p8) br.spnt.few .fail_efault // fail with EFAULT | ||
411 | (p7) br.spnt.many fsys_fallback_syscall // got pending kernel work... | ||
412 | (p6) br.dpnt.many .store_mask // -> short-circuit to just reading the signal mask | ||
413 | |||
414 | /* Argh, we actually have to do some work and _update_ the signal mask: */ | ||
415 | |||
416 | EX(.fail_efault, probe.r.fault r33, 3) // verify user has read-access to *set | ||
417 | EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set | ||
418 | mov r17=(1 << (SIGKILL - 1)) | (1 << (SIGSTOP - 1)) | ||
419 | ;; | ||
420 | |||
421 | RSM_PSR_I(p0, r18, r19) // mask interrupt delivery | ||
422 | andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP | ||
423 | mov r8=EINVAL // default to EINVAL | ||
424 | |||
425 | #ifdef CONFIG_SMP | ||
426 | // __ticket_spin_trylock(r31) | ||
427 | ld4 r17=[r31] | ||
428 | ;; | ||
429 | mov.m ar.ccv=r17 | ||
430 | extr.u r9=r17,17,15 | ||
431 | adds r19=1,r17 | ||
432 | extr.u r18=r17,0,15 | ||
433 | ;; | ||
434 | cmp.eq p6,p7=r9,r18 | ||
435 | ;; | ||
436 | (p6) cmpxchg4.acq r9=[r31],r19,ar.ccv | ||
437 | (p6) dep.z r20=r19,1,15 // next serving ticket for unlock | ||
438 | (p7) br.cond.spnt.many .lock_contention | ||
439 | ;; | ||
440 | cmp4.eq p0,p7=r9,r17 | ||
441 | adds r31=2,r31 | ||
442 | (p7) br.cond.spnt.many .lock_contention | ||
443 | ld8 r3=[r2] // re-read current->blocked now that we hold the lock | ||
444 | ;; | ||
445 | #else | ||
446 | ld8 r3=[r2] // re-read current->blocked now that we hold the lock | ||
447 | #endif | ||
448 | add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16 | ||
449 | add r19=IA64_TASK_SIGNAL_OFFSET,r16 | ||
450 | cmp4.eq p6,p0=SIG_BLOCK,r32 | ||
451 | ;; | ||
452 | ld8 r19=[r19] // r19 <- current->signal | ||
453 | cmp4.eq p7,p0=SIG_UNBLOCK,r32 | ||
454 | cmp4.eq p8,p0=SIG_SETMASK,r32 | ||
455 | ;; | ||
456 | ld8 r18=[r18] // r18 <- current->pending.signal | ||
457 | .pred.rel.mutex p6,p7,p8 | ||
458 | (p6) or r14=r3,r14 // SIG_BLOCK | ||
459 | (p7) andcm r14=r3,r14 // SIG_UNBLOCK | ||
460 | |||
461 | (p8) mov r14=r14 // SIG_SETMASK | ||
462 | (p6) mov r8=0 // clear error code | ||
463 | // recalc_sigpending() | ||
464 | add r17=IA64_SIGNAL_GROUP_STOP_COUNT_OFFSET,r19 | ||
465 | |||
466 | add r19=IA64_SIGNAL_SHARED_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r19 | ||
467 | ;; | ||
468 | ld4 r17=[r17] // r17 <- current->signal->group_stop_count | ||
469 | (p7) mov r8=0 // clear error code | ||
470 | |||
471 | ld8 r19=[r19] // r19 <- current->signal->shared_pending | ||
472 | ;; | ||
473 | cmp4.gt p6,p7=r17,r0 // p6/p7 <- (current->signal->group_stop_count > 0)? | ||
474 | (p8) mov r8=0 // clear error code | ||
475 | |||
476 | or r18=r18,r19 // r18 <- current->pending | current->signal->shared_pending | ||
477 | ;; | ||
478 | // r18 <- (current->pending | current->signal->shared_pending) & ~current->blocked: | ||
479 | andcm r18=r18,r14 | ||
480 | add r9=TI_FLAGS+IA64_TASK_SIZE,r16 | ||
481 | ;; | ||
482 | |||
483 | (p7) cmp.ne.or.andcm p6,p7=r18,r0 // p6/p7 <- signal pending | ||
484 | mov r19=0 // i must not leak kernel bits... | ||
485 | (p6) br.cond.dpnt.many .sig_pending | ||
486 | ;; | ||
487 | |||
488 | 1: ld4 r17=[r9] // r17 <- current->thread_info->flags | ||
489 | ;; | ||
490 | mov ar.ccv=r17 | ||
491 | and r18=~_TIF_SIGPENDING,r17 // r18 <- r17 & ~(1 << TIF_SIGPENDING) | ||
492 | ;; | ||
493 | |||
494 | st8 [r2]=r14 // update current->blocked with new mask | ||
495 | cmpxchg4.acq r8=[r9],r18,ar.ccv // current->thread_info->flags <- r18 | ||
496 | ;; | ||
497 | cmp.ne p6,p0=r17,r8 // update failed? | ||
498 | (p6) br.cond.spnt.few 1b // yes -> retry | ||
499 | |||
500 | #ifdef CONFIG_SMP | ||
501 | // __ticket_spin_unlock(r31) | ||
502 | st2.rel [r31]=r20 | ||
503 | mov r20=0 // i must not leak kernel bits... | ||
504 | #endif | ||
505 | SSM_PSR_I(p0, p9, r31) | ||
506 | ;; | ||
507 | |||
508 | srlz.d // ensure psr.i is set again | ||
509 | mov r18=0 // i must not leak kernel bits... | ||
510 | |||
511 | .store_mask: | ||
512 | EX(.fail_efault, (p15) probe.w.fault r34, 3) // verify user has write-access to *oset | ||
513 | EX(.fail_efault, (p15) st8 [r34]=r3) | ||
514 | mov r2=0 // i must not leak kernel bits... | ||
515 | mov r3=0 // i must not leak kernel bits... | ||
516 | mov r8=0 // return 0 | ||
517 | mov r9=0 // i must not leak kernel bits... | ||
518 | mov r14=0 // i must not leak kernel bits... | ||
519 | mov r17=0 // i must not leak kernel bits... | ||
520 | mov r31=0 // i must not leak kernel bits... | ||
521 | FSYS_RETURN | ||
522 | |||
523 | .sig_pending: | ||
524 | #ifdef CONFIG_SMP | ||
525 | // __ticket_spin_unlock(r31) | ||
526 | st2.rel [r31]=r20 // release the lock | ||
527 | #endif | ||
528 | SSM_PSR_I(p0, p9, r17) | ||
529 | ;; | ||
530 | srlz.d | ||
531 | br.sptk.many fsys_fallback_syscall // with signal pending, do the heavy-weight syscall | ||
532 | |||
533 | #ifdef CONFIG_SMP | ||
534 | .lock_contention: | ||
535 | /* Rather than spinning here, fall back on doing a heavy-weight syscall. */ | ||
536 | SSM_PSR_I(p0, p9, r17) | ||
537 | ;; | ||
538 | srlz.d | ||
539 | br.sptk.many fsys_fallback_syscall | ||
540 | #endif | ||
541 | END(fsys_rt_sigprocmask) | ||
542 | |||
543 | /* | ||
544 | * fsys_getcpu doesn't use the third parameter in this implementation. It reads | 375 | * fsys_getcpu doesn't use the third parameter in this implementation. It reads |
545 | * current_thread_info()->cpu and corresponding node in cpu_to_node_map. | 376 | * current_thread_info()->cpu and corresponding node in cpu_to_node_map. |
546 | */ | 377 | */ |
@@ -559,11 +390,15 @@ ENTRY(fsys_getcpu) | |||
559 | ;; | 390 | ;; |
560 | tnat.nz p7,p0 = r33 // I guard against NaT argument | 391 | tnat.nz p7,p0 = r33 // I guard against NaT argument |
561 | (p7) br.cond.spnt.few .fail_einval // B | 392 | (p7) br.cond.spnt.few .fail_einval // B |
393 | ;; | ||
394 | cmp.ne p6,p0=r32,r0 | ||
395 | cmp.ne p7,p0=r33,r0 | ||
396 | ;; | ||
562 | #ifdef CONFIG_NUMA | 397 | #ifdef CONFIG_NUMA |
563 | movl r17=cpu_to_node_map | 398 | movl r17=cpu_to_node_map |
564 | ;; | 399 | ;; |
565 | EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles | 400 | EX(.fail_efault, (p6) probe.w.fault r32, 3) // M This takes 5 cycles |
566 | EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles | 401 | EX(.fail_efault, (p7) probe.w.fault r33, 3) // M This takes 5 cycles |
567 | shladd r18=r3,1,r17 | 402 | shladd r18=r3,1,r17 |
568 | ;; | 403 | ;; |
569 | ld2 r20=[r18] // r20 = cpu_to_node_map[cpu] | 404 | ld2 r20=[r18] // r20 = cpu_to_node_map[cpu] |
@@ -573,20 +408,20 @@ EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles | |||
573 | (p8) br.spnt.many fsys_fallback_syscall | 408 | (p8) br.spnt.many fsys_fallback_syscall |
574 | ;; | 409 | ;; |
575 | ;; | 410 | ;; |
576 | EX(.fail_efault, st4 [r32] = r3) | 411 | EX(.fail_efault, (p6) st4 [r32] = r3) |
577 | EX(.fail_efault, st2 [r33] = r20) | 412 | EX(.fail_efault, (p7) st2 [r33] = r20) |
578 | mov r8=0 | 413 | mov r8=0 |
579 | ;; | 414 | ;; |
580 | #else | 415 | #else |
581 | EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles | 416 | EX(.fail_efault, (p6) probe.w.fault r32, 3) // M This takes 5 cycles |
582 | EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles | 417 | EX(.fail_efault, (p7) probe.w.fault r33, 3) // M This takes 5 cycles |
583 | and r2 = TIF_ALLWORK_MASK,r2 | 418 | and r2 = TIF_ALLWORK_MASK,r2 |
584 | ;; | 419 | ;; |
585 | cmp.ne p8,p0=0,r2 | 420 | cmp.ne p8,p0=0,r2 |
586 | (p8) br.spnt.many fsys_fallback_syscall | 421 | (p8) br.spnt.many fsys_fallback_syscall |
587 | ;; | 422 | ;; |
588 | EX(.fail_efault, st4 [r32] = r3) | 423 | EX(.fail_efault, (p6) st4 [r32] = r3) |
589 | EX(.fail_efault, st2 [r33] = r0) | 424 | EX(.fail_efault, (p7) st2 [r33] = r0) |
590 | mov r8=0 | 425 | mov r8=0 |
591 | ;; | 426 | ;; |
592 | #endif | 427 | #endif |
@@ -916,7 +751,7 @@ paravirt_fsyscall_table: | |||
916 | data8 0 // sigaltstack | 751 | data8 0 // sigaltstack |
917 | data8 0 // rt_sigaction | 752 | data8 0 // rt_sigaction |
918 | data8 0 // rt_sigpending | 753 | data8 0 // rt_sigpending |
919 | data8 fsys_rt_sigprocmask // rt_sigprocmask | 754 | data8 0 // rt_sigprocmask |
920 | data8 0 // rt_sigqueueinfo // 1180 | 755 | data8 0 // rt_sigqueueinfo // 1180 |
921 | data8 0 // rt_sigreturn | 756 | data8 0 // rt_sigreturn |
922 | data8 0 // rt_sigsuspend | 757 | data8 0 // rt_sigsuspend |