static inline void setup_stack_canary_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
-       unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
+       unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu) - 20;
        struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
        struct desc_struct desc;
 
 
 
 #ifdef CONFIG_CC_STACKPROTECTOR
 #define __switch_canary                                                        \
-       "movl "__percpu_arg([current_task])",%%ebx\n\t"                 \
-       "movl %P[task_canary](%%ebx),%%ebx\n\t"                         \
-       "movl %%ebx,"__percpu_arg([stack_canary])"\n\t"
+       "movl %P[task_canary](%[next]), %%ebx\n\t"                      \
+       "movl %%ebx, "__percpu_arg([stack_canary])"\n\t"
 #define __switch_canary_oparam                                         \
        , [stack_canary] "=m" (per_cpu_var(stack_canary))
 #define __switch_canary_iparam                                         \
-       , [current_task] "m" (per_cpu_var(current_task))                \
        , [task_canary] "i" (offsetof(struct task_struct, stack_canary))
 #else  /* CC_STACKPROTECTOR */
 #define __switch_canary
                     "movl %[next_sp],%%esp\n\t"        /* restore ESP   */ \
                     "movl $1f,%[prev_ip]\n\t"  /* save    EIP   */     \
                     "pushl %[next_ip]\n\t"     /* restore EIP   */     \
+                    __switch_canary                                    \
                     "jmp __switch_to\n"        /* regparm call  */     \
                     "1:\t"                                             \
-                    __switch_canary                                    \
                     "popl %%ebp\n\t"           /* restore EBP   */     \
                     "popfl\n"                  /* restore flags */     \
                                                                        \
 
        jne 1f
        movl $per_cpu__gdt_page,%eax
        movl $per_cpu__stack_canary,%ecx
+       subl $20, %ecx
        movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
        shrl $16, %ecx
        movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
 
 
 #include <stdarg.h>
 
+#include <linux/stackprotector.h>
 #include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 {
        int cpu = smp_processor_id();
 
+       /*
+        * If we're the non-boot CPU, nothing set the stack canary up
+        * for us.  CPU0 already has it initialized but no harm in
+        * doing it again.  This is a good place for updating it, as
+        * we wont ever return from this function (so the invalid
+        * canaries already on the stack wont ever trigger).
+        */
+       boot_init_stack_canary();
+
        current_thread_info()->status |= TS_POLLING;
 
        /* endless idle loop with no priority at all */
 
        current_thread_info()->status |= TS_POLLING;
 
        /*
-        * If we're the non-boot CPU, nothing set the PDA stack
-        * canary up for us - and if we are the boot CPU we have
-        * a 0 stack canary. This is a good place for updating
-        * it, as we wont ever return from this function (so the
-        * invalid canaries already on the stack wont ever
-        * trigger):
+        * If we're the non-boot CPU, nothing set the stack canary up
+        * for us.  CPU0 already has it initialized but no harm in
+        * doing it again.  This is a good place for updating it, as
+        * we wont ever return from this function (so the invalid
+        * canaries already on the stack wont ever trigger).
         */
        boot_init_stack_canary();