aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/include/asm/Kbuild1
-rw-r--r--arch/ia64/include/asm/processor.h5
-rw-r--r--arch/ia64/kernel/fsys.S191
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 @@
1include include/asm-generic/Kbuild.asm 1include include/asm-generic/Kbuild.asm
2 2
3header-y += break.h 3header-y += break.h
4header-y += cmpxchg.h
4header-y += fpu.h 5header-y += fpu.h
5header-y += gcc_intrin.h 6header-y += gcc_intrin.h
6header-y += ia64regs.h 7header-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)
372END(fsys_clock_gettime) 372END(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
380ENTRY(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
416EX(.fail_efault, probe.r.fault r33, 3) // verify user has read-access to *set
417EX(.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
4881: 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:
512EX(.fail_efault, (p15) probe.w.fault r34, 3) // verify user has write-access to *oset
513EX(.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
541END(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 ;;
565EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles 400EX(.fail_efault, (p6) probe.w.fault r32, 3) // M This takes 5 cycles
566EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles 401EX(.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 ;;
576EX(.fail_efault, st4 [r32] = r3) 411EX(.fail_efault, (p6) st4 [r32] = r3)
577EX(.fail_efault, st2 [r33] = r20) 412EX(.fail_efault, (p7) st2 [r33] = r20)
578 mov r8=0 413 mov r8=0
579 ;; 414 ;;
580#else 415#else
581EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles 416EX(.fail_efault, (p6) probe.w.fault r32, 3) // M This takes 5 cycles
582EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles 417EX(.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 ;;
588EX(.fail_efault, st4 [r32] = r3) 423EX(.fail_efault, (p6) st4 [r32] = r3)
589EX(.fail_efault, st2 [r33] = r0) 424EX(.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