diff options
author | Al Viro <viro@ZenIV.linux.org.uk> | 2012-10-20 10:52:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-23 22:16:45 -0400 |
commit | 3185bd26188223195dc2e659a3d00219cad71a0f (patch) | |
tree | 1363b0619f9e416b308aee3c804fab13e6efa72c /arch/alpha/kernel | |
parent | 3d0ceac129f3ea0b125289055a3aa7519d38df77 (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.c | 25 | ||||
-rw-r--r-- | arch/alpha/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/alpha/kernel/traps.c | 6 |
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(¤t_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); | |||
49 | void | 49 | void |
50 | cpu_idle(void) | 50 | cpu_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 |