aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
authorSergei Trofimovich <slyfox@gentoo.org>2011-08-25 18:59:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-08-25 19:25:33 -0400
commit2df7a7d1cd07626dd235ca102830ebfc6c01a09e (patch)
treedb226e5a1728f600e8f711400e97098023f3c2f4 /arch/alpha
parent06ed4625fdfffee1251708cd30de276186d5fdcf (diff)
alpha: unbreak osf_setsysinfo(SSI_NVPAIRS, [SSIN_UACPROC, UAC_SIGBUS])
The bug was accidentally found by the following program: #include <asm/sysinfo.h> #include <asm/unistd.h> #include <sys/syscall.h> static int setsysinfo(unsigned long op, void *buffer, unsigned long size, int *start, void *arg, unsigned long flag) { return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag); } int main(int argc, char **argv) { short x[10]; unsigned int buf[2] = { SSIN_UACPROC, UAC_SIGBUS, }; setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0); int *y = (int*) (x+1); *y = 0; return 0; } The program shoud fail on SIGBUS, but didn't. The patch is a second part of userspace flag fix (commit 745dd2405e28 "Alpha: Rearrange thread info flags fixing two regressions"). Deleted outdated out-of-sync 'UAC_SHIFT' (the cause of bug) in favour of 'ALPHA_UAC_SHIFT'. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> Acked-by: Michael Cree <mcree@orcon.net.nz> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Matt Turner <mattst88@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/include/asm/sysinfo.h9
-rw-r--r--arch/alpha/include/asm/thread_info.h8
-rw-r--r--arch/alpha/kernel/osf_sys.c12
3 files changed, 11 insertions, 18 deletions
diff --git a/arch/alpha/include/asm/sysinfo.h b/arch/alpha/include/asm/sysinfo.h
index 086aba284df2..e77d77cd07b8 100644
--- a/arch/alpha/include/asm/sysinfo.h
+++ b/arch/alpha/include/asm/sysinfo.h
@@ -27,13 +27,4 @@
27#define UAC_NOFIX 2 27#define UAC_NOFIX 2
28#define UAC_SIGBUS 4 28#define UAC_SIGBUS 4
29 29
30
31#ifdef __KERNEL__
32
33/* This is the shift that is applied to the UAC bits as stored in the
34 per-thread flags. See thread_info.h. */
35#define UAC_SHIFT 6
36
37#endif
38
39#endif /* __ASM_ALPHA_SYSINFO_H */ 30#endif /* __ASM_ALPHA_SYSINFO_H */
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 6f32f9c84a2d..ff73db022342 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -74,9 +74,9 @@ register struct thread_info *__current_thread_info __asm__("$8");
74#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 74#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
75#define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */ 75#define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */
76#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */ 76#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */
77#define TIF_UAC_NOPRINT 10 /* see sysinfo.h */ 77#define TIF_UAC_NOPRINT 10 /* ! Preserve sequence of following */
78#define TIF_UAC_NOFIX 11 78#define TIF_UAC_NOFIX 11 /* ! flags as they match */
79#define TIF_UAC_SIGBUS 12 79#define TIF_UAC_SIGBUS 12 /* ! userspace part of 'osf_sysinfo' */
80#define TIF_MEMDIE 13 /* is terminating due to OOM killer */ 80#define TIF_MEMDIE 13 /* is terminating due to OOM killer */
81#define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */ 81#define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */
82#define TIF_FREEZE 16 /* is freezing for suspend */ 82#define TIF_FREEZE 16 /* is freezing for suspend */
@@ -97,7 +97,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
97#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \ 97#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
98 | _TIF_SYSCALL_TRACE) 98 | _TIF_SYSCALL_TRACE)
99 99
100#define ALPHA_UAC_SHIFT 10 100#define ALPHA_UAC_SHIFT TIF_UAC_NOPRINT
101#define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \ 101#define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
102 1 << TIF_UAC_SIGBUS) 102 1 << TIF_UAC_SIGBUS)
103 103
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 326f0a2d56e5..01e8715e26d9 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -42,6 +42,7 @@
42#include <asm/uaccess.h> 42#include <asm/uaccess.h>
43#include <asm/system.h> 43#include <asm/system.h>
44#include <asm/sysinfo.h> 44#include <asm/sysinfo.h>
45#include <asm/thread_info.h>
45#include <asm/hwrpb.h> 46#include <asm/hwrpb.h>
46#include <asm/processor.h> 47#include <asm/processor.h>
47 48
@@ -633,9 +634,10 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
633 case GSI_UACPROC: 634 case GSI_UACPROC:
634 if (nbytes < sizeof(unsigned int)) 635 if (nbytes < sizeof(unsigned int))
635 return -EINVAL; 636 return -EINVAL;
636 w = (current_thread_info()->flags >> UAC_SHIFT) & UAC_BITMASK; 637 w = (current_thread_info()->flags >> ALPHA_UAC_SHIFT) &
637 if (put_user(w, (unsigned int __user *)buffer)) 638 UAC_BITMASK;
638 return -EFAULT; 639 if (put_user(w, (unsigned int __user *)buffer))
640 return -EFAULT;
639 return 1; 641 return 1;
640 642
641 case GSI_PROC_TYPE: 643 case GSI_PROC_TYPE:
@@ -756,8 +758,8 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,
756 case SSIN_UACPROC: 758 case SSIN_UACPROC:
757 again: 759 again:
758 old = current_thread_info()->flags; 760 old = current_thread_info()->flags;
759 new = old & ~(UAC_BITMASK << UAC_SHIFT); 761 new = old & ~(UAC_BITMASK << ALPHA_UAC_SHIFT);
760 new = new | (w & UAC_BITMASK) << UAC_SHIFT; 762 new = new | (w & UAC_BITMASK) << ALPHA_UAC_SHIFT;
761 if (cmpxchg(&current_thread_info()->flags, 763 if (cmpxchg(&current_thread_info()->flags,
762 old, new) != old) 764 old, new) != old)
763 goto again; 765 goto again;