Commit f574c843191728d9407b766a027f779dcd27b272

Authored by Tony Luck
1 parent d56557af19

[IA64] fix siglock

When ia64 converted to using ticket locks, an inline implementation
of trylock/unlock in fsys.S was missed.  This was not noticed because
in most circumstances it simply resulted in using the slow path because
the siglock was apparently not available (under old spinlock rules).

Problems occur when the ticket spinlock has value 0x0 (when first
initialised, or when it wraps around). At this point the fsys.S
code acquires the lock (changing the 0x0 to 0x1. If another process
attempts to get the lock at this point, it will change the value from
0x1 to 0x2 (using new ticket lock rules). Then the fsys.S code will
free the lock using old spinlock rules by writing 0x0 to it. From
here a variety of bad things can happen.

Signed-off-by: Tony Luck <tony.luck@intel.com>

Showing 1 changed file with 39 additions and 7 deletions Side-by-side Diff

arch/ia64/kernel/fsys.S
... ... @@ -424,14 +424,26 @@
424 424 andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP
425 425  
426 426 #ifdef CONFIG_SMP
427   - mov r17=1
428   - ;;
429   - cmpxchg4.acq r18=[r31],r17,ar.ccv // try to acquire the lock
  427 + // __ticket_spin_trylock(r31)
  428 + ld4 r17=[r31]
430 429 mov r8=EINVAL // default to EINVAL
431 430 ;;
  431 + extr r9=r17,17,15
  432 + ;;
  433 + xor r18=r17,r9
  434 + adds r19=1,r17
  435 + ;;
  436 + extr.u r18=r18,0,15
  437 + ;;
  438 + cmp.eq p0,p7=0,r18
  439 +(p7) br.cond.spnt.many .lock_contention
  440 + mov.m ar.ccv=r17
  441 + ;;
  442 + cmpxchg4.acq r9=[r31],r19,ar.ccv
  443 + ;;
  444 + cmp4.eq p0,p7=r9,r17
  445 +(p7) br.cond.spnt.many .lock_contention
432 446 ld8 r3=[r2] // re-read current->blocked now that we hold the lock
433   - cmp4.ne p6,p0=r18,r0
434   -(p6) br.cond.spnt.many .lock_contention
435 447 ;;
436 448 #else
437 449 ld8 r3=[r2] // re-read current->blocked now that we hold the lock
... ... @@ -490,7 +502,17 @@
490 502 (p6) br.cond.spnt.few 1b // yes -> retry
491 503  
492 504 #ifdef CONFIG_SMP
493   - st4.rel [r31]=r0 // release the lock
  505 + // __ticket_spin_unlock(r31)
  506 + adds r31=2,r31
  507 + ;;
  508 + ld2.bias r2=[r31]
  509 + mov r3=65534
  510 + ;;
  511 + adds r2=2,r2
  512 + ;;
  513 + and r3=r3,r2
  514 + ;;
  515 + st2.rel [r31]=r3
494 516 #endif
495 517 SSM_PSR_I(p0, p9, r31)
496 518 ;;
... ... @@ -512,7 +534,17 @@
512 534  
513 535 .sig_pending:
514 536 #ifdef CONFIG_SMP
515   - st4.rel [r31]=r0 // release the lock
  537 + // __ticket_spin_unlock(r31)
  538 + adds r31=2,r31
  539 + ;;
  540 + ld2.bias r2=[r31]
  541 + mov r3=65534
  542 + ;;
  543 + adds r2=2,r2
  544 + ;;
  545 + and r3=r3,r2
  546 + ;;
  547 + st2.rel [r31]=r3
516 548 #endif
517 549 SSM_PSR_I(p0, p9, r17)
518 550 ;;