#include <asm/unistd.h>
 
 #include "ptrace.h"
+#include "signal.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 #define SWI_THUMB_SIGRETURN    (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
 
-static const unsigned long retcodes[4] = {
+const unsigned long sigreturn_codes[4] = {
        SWI_SYS_SIGRETURN,      SWI_THUMB_SIGRETURN,
        SWI_SYS_RT_SIGRETURN,   SWI_THUMB_RT_SIGRETURN
 };
                if (ka->sa.sa_flags & SA_SIGINFO)
                        idx += 2;
 
-               if (__put_user(retcodes[idx], rc))
+               if (__put_user(sigreturn_codes[idx], rc))
                        return 1;
 
-               /*
-                * Ensure that the instruction cache sees
-                * the return code written onto the stack.
-                */
-               flush_icache_range((unsigned long)rc,
-                                  (unsigned long)(rc + 1));
-
-               retcode = ((unsigned long)rc) + thumb;
+               if (cpsr & MODE32_BIT) {
+                       /*
+                        * 32-bit code can use the new high-page
+                        * signal return code support.
+                        */
+                       retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
+               } else {
+                       /*
+                        * Ensure that the instruction cache sees
+                        * the return code written onto the stack.
+                        */
+                       flush_icache_range((unsigned long)rc,
+                                          (unsigned long)(rc + 1));
+
+                       retcode = ((unsigned long)rc) + thumb;
+               }
        }
 
        regs->ARM_r0 = usig;
 
--- /dev/null
+/*
+ *  linux/arch/arm/kernel/signal.h
+ *
+ *  Copyright (C) 2005 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define KERN_SIGRETURN_CODE    0xffff0500
+
+extern const unsigned long sigreturn_codes[4];
 
 #include <asm/traps.h>
 
 #include "ptrace.h"
+#include "signal.h"
 
 const char *processor_modes[]=
 { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
        memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
        memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
        memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
+
+       /*
+        * Copy signal return handlers into the vector page, and
+        * set sigreturn to be a pointer to these.
+        */
+       memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
+              sizeof(sigreturn_codes));
+
        flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
        modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 }