* Exception vector entry code. This code runs with address translation
  * turned off (i.e. using physical addresses). We assume SPRG_THREAD has
  * the physical address of the current task thread_struct.
- * Note that we have to have decremented r1 before we write to any fields
- * of the exception frame, since a critical interrupt could occur at any
- * time, and it will write to the area immediately below the current r1.
  */
 #define NORMAL_EXCEPTION_PROLOG                                                     \
        mtspr   SPRN_SPRG_SCRATCH0,r10; /* save two registers to work with */\
        mtspr   SPRN_SPRG_SCRATCH1,r11;                                      \
-       mtspr   SPRN_SPRG_SCRATCH2,r1;                                       \
        mfcr    r10;                    /* save CR in r10 for now          */\
        mfspr   r11,SPRN_SRR1;          /* check whether user or kernel    */\
        andi.   r11,r11,MSR_PR;                                              \
-       beq     1f;                                                          \
-       mfspr   r1,SPRN_SPRG_THREAD;    /* if from user, start at top of   */\
-       lwz     r1,TASK_STACK-THREAD(r1); /* this thread's kernel stack   */\
-       addi    r1,r1,THREAD_SIZE;                                           \
-1:     subi    r1,r1,INT_FRAME_SIZE;   /* Allocate an exception frame     */\
        tophys(r11,r1);                                                      \
+       beq     1f;                                                          \
+       mfspr   r11,SPRN_SPRG_THREAD;   /* if from user, start at top of   */\
+       lwz     r11,TASK_STACK-THREAD(r11); /* this thread's kernel stack */\
+       addi    r11,r11,THREAD_SIZE;                                         \
+       tophys(r11,r11);                                                     \
+1:     subi    r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame     */\
        stw     r10,_CCR(r11);          /* save various registers          */\
        stw     r12,GPR12(r11);                                              \
        stw     r9,GPR9(r11);                                                \
        stw     r12,GPR11(r11);                                              \
        mflr    r10;                                                         \
        stw     r10,_LINK(r11);                                              \
-       mfspr   r10,SPRN_SPRG_SCRATCH2;                                      \
        mfspr   r12,SPRN_SRR0;                                               \
-       stw     r10,GPR1(r11);                                               \
+       stw     r1,GPR1(r11);                                                \
        mfspr   r9,SPRN_SRR1;                                                \
-       stw     r10,0(r11);                                                  \
+       stw     r1,0(r11);                                                   \
+       tovirt(r1,r11);                 /* set new kernel sp */ \
        rlwinm  r9,r9,0,14,12;          /* clear MSR_WE (necessary?)       */\
        stw     r0,GPR0(r11);                                                \
        SAVE_4GPRS(3, r11);                                                  \