[PARISC] Add ability for prctl to change unaligned trap behaviour
authorKyle McMartin <kyle@parisc-linux.org>
Sat, 22 Oct 2005 02:43:15 +0000 (22:43 -0400)
committerKyle McMartin <kyle@parisc-linux.org>
Sat, 22 Oct 2005 02:43:15 +0000 (22:43 -0400)
Add support for changing unaligned trap behaviour on a
per-thread basis.

Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
arch/parisc/kernel/unaligned.c
include/asm-parisc/processor.h

index 62eea35bcd69bc4295ee1d9b918955007df2a5f6..eaae8a021f9f2fb0e33917748922e25d88131881 100644 (file)
@@ -513,15 +513,18 @@ void handle_unaligned(struct pt_regs *regs)
        register int flop=0;    /* true if this is a flop */
 
        /* log a message with pacing */
        register int flop=0;    /* true if this is a flop */
 
        /* log a message with pacing */
-       if (user_mode(regs))
-       {
-               if (unaligned_count > 5 && jiffies - last_time > 5*HZ)
-               {
+       if (user_mode(regs)) {
+               if (current->thread.flags & PARISC_UAC_SIGBUS) {
+                       goto force_sigbus;
+               }
+
+               if (unaligned_count > 5 && jiffies - last_time > 5*HZ) {
                        unaligned_count = 0;
                        last_time = jiffies;
                }
                        unaligned_count = 0;
                        last_time = jiffies;
                }
-               if (++unaligned_count < 5)
-               {
+
+               if (!(current->thread.flags & PARISC_UAC_NOPRINT) 
+                   && ++unaligned_count < 5) {
                        char buf[256];
                        sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
                                current->comm, current->pid, regs->ior, regs->iaoq[0]);
                        char buf[256];
                        sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
                                current->comm, current->pid, regs->ior, regs->iaoq[0]);
@@ -530,6 +533,7 @@ void handle_unaligned(struct pt_regs *regs)
                        show_regs(regs);
 #endif         
                }
                        show_regs(regs);
 #endif         
                }
+
                if (!unaligned_enabled)
                        goto force_sigbus;
        }
                if (!unaligned_enabled)
                        goto force_sigbus;
        }
index a9dfadd05658e7a548c73318385c73b791999593..aae40e8c3aa85693d807c6fb92069f5efaee4d8b 100644 (file)
@@ -122,8 +122,27 @@ struct thread_struct {
 }; 
 
 /* Thread struct flags. */
 }; 
 
 /* Thread struct flags. */
+#define PARISC_UAC_NOPRINT     (1UL << 0)      /* see prctl and unaligned.c */
+#define PARISC_UAC_SIGBUS      (1UL << 1)
 #define PARISC_KERNEL_DEATH    (1UL << 31)     /* see die_if_kernel()... */
 
 #define PARISC_KERNEL_DEATH    (1UL << 31)     /* see die_if_kernel()... */
 
+#define PARISC_UAC_SHIFT       0
+#define PARISC_UAC_MASK                (PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS)
+
+#define SET_UNALIGN_CTL(task,value)                                       \
+        ({                                                                \
+        (task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \
+                                | (((value) << PARISC_UAC_SHIFT) &        \
+                                   PARISC_UAC_MASK));                     \
+        0;                                                                \
+        })
+
+#define GET_UNALIGN_CTL(task,addr)                                        \
+        ({                                                                \
+        put_user(((task)->thread.flags & PARISC_UAC_MASK)                 \
+                 >> PARISC_UAC_SHIFT, (int __user *) (addr));             \
+        })
+
 #define INIT_THREAD { \
        regs:   {       gr: { 0, }, \
                        fr: { 0, }, \
 #define INIT_THREAD { \
        regs:   {       gr: { 0, }, \
                        fr: { 0, }, \