aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel
diff options
context:
space:
mode:
authorAl Viro <viro@ZenIV.linux.org.uk>2012-10-20 10:52:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-23 22:16:45 -0400
commit3185bd26188223195dc2e659a3d00219cad71a0f (patch)
tree1363b0619f9e416b308aee3c804fab13e6efa72c /arch/alpha/kernel
parent3d0ceac129f3ea0b125289055a3aa7519d38df77 (diff)
alpha: separate thread-synchronous flags
... and fix the race in updating unaligned control ones Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/alpha/kernel')
-rw-r--r--arch/alpha/kernel/osf_sys.c25
-rw-r--r--arch/alpha/kernel/process.c2
-rw-r--r--arch/alpha/kernel/traps.c6
3 files changed, 14 insertions, 19 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 9eb090582cf1..1e6956a90608 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -793,8 +793,7 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
793 case GSI_UACPROC: 793 case GSI_UACPROC:
794 if (nbytes < sizeof(unsigned int)) 794 if (nbytes < sizeof(unsigned int))
795 return -EINVAL; 795 return -EINVAL;
796 w = (current_thread_info()->flags >> ALPHA_UAC_SHIFT) & 796 w = current_thread_info()->status & UAC_BITMASK;
797 UAC_BITMASK;
798 if (put_user(w, (unsigned int __user *)buffer)) 797 if (put_user(w, (unsigned int __user *)buffer))
799 return -EFAULT; 798 return -EFAULT;
800 return 1; 799 return 1;
@@ -904,24 +903,20 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,
904 break; 903 break;
905 904
906 case SSI_NVPAIRS: { 905 case SSI_NVPAIRS: {
907 unsigned long v, w, i; 906 unsigned __user *p = buffer;
908 unsigned int old, new; 907 unsigned i;
909 908
910 for (i = 0; i < nbytes; ++i) { 909 for (i = 0, p = buffer; i < nbytes; ++i, p += 2) {
910 unsigned v, w, status;
911 911
912 if (get_user(v, 2*i + (unsigned int __user *)buffer)) 912 if (get_user(v, p) || get_user(w, p + 1))
913 return -EFAULT;
914 if (get_user(w, 2*i + 1 + (unsigned int __user *)buffer))
915 return -EFAULT; 913 return -EFAULT;
916 switch (v) { 914 switch (v) {
917 case SSIN_UACPROC: 915 case SSIN_UACPROC:
918 again: 916 w &= UAC_BITMASK;
919 old = current_thread_info()->flags; 917 status = current_thread_info()->status;
920 new = old & ~(UAC_BITMASK << ALPHA_UAC_SHIFT); 918 status = (status & ~UAC_BITMASK) | w;
921 new = new | (w & UAC_BITMASK) << ALPHA_UAC_SHIFT; 919 current_thread_info()->status = status;
922 if (cmpxchg(&current_thread_info()->flags,
923 old, new) != old)
924 goto again;
925 break; 920 break;
926 921
927 default: 922 default:
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 4054e0ffe2b2..51987dcf79b8 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(pm_power_off);
49void 49void
50cpu_idle(void) 50cpu_idle(void)
51{ 51{
52 set_thread_flag(TIF_POLLING_NRFLAG); 52 current_thread_info()->status |= TS_POLLING;
53 53
54 while (1) { 54 while (1) {
55 /* FIXME -- EV6 and LCA45 know how to power down 55 /* FIXME -- EV6 and LCA45 know how to power down
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 80d987c0e9aa..272666d006df 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -780,17 +780,17 @@ do_entUnaUser(void __user * va, unsigned long opcode,
780 /* Check the UAC bits to decide what the user wants us to do 780 /* Check the UAC bits to decide what the user wants us to do
781 with the unaliged access. */ 781 with the unaliged access. */
782 782
783 if (!test_thread_flag (TIF_UAC_NOPRINT)) { 783 if (!(current_thread_info()->status & TS_UAC_NOPRINT)) {
784 if (__ratelimit(&ratelimit)) { 784 if (__ratelimit(&ratelimit)) {
785 printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n", 785 printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
786 current->comm, task_pid_nr(current), 786 current->comm, task_pid_nr(current),
787 regs->pc - 4, va, opcode, reg); 787 regs->pc - 4, va, opcode, reg);
788 } 788 }
789 } 789 }
790 if (test_thread_flag (TIF_UAC_SIGBUS)) 790 if ((current_thread_info()->status & TS_UAC_SIGBUS))
791 goto give_sigbus; 791 goto give_sigbus;
792 /* Not sure why you'd want to use this, but... */ 792 /* Not sure why you'd want to use this, but... */
793 if (test_thread_flag (TIF_UAC_NOFIX)) 793 if ((current_thread_info()->status & TS_UAC_NOFIX))
794 return; 794 return;
795 795
796 /* Don't bother reading ds in the access check since we already 796 /* Don't bother reading ds in the access check since we already