diff options
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index d3aee08e6814..215973a2c8d5 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -36,8 +36,7 @@ #include <asm/firmware.h> #include <asm/page_64.h> #include <asm/exception.h> - -#define DO_SOFT_DISABLE +#include <asm/irqflags.h> /* * We layout physical memory as follows: @@ -450,8 +449,8 @@ bad_stack: */ fast_exc_return_irq: /* restores irq state too */ ld r3,SOFTE(r1) + TRACE_AND_RESTORE_IRQ(r3); ld r12,_MSR(r1) - stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */ rldicl r4,r12,49,63 /* get MSR_EE to LSB */ stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */ b 1f @@ -621,7 +620,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) mtlr r10 andi. r10,r12,MSR_RI /* check for unrecoverable exception */ - beq- unrecov_slb + beq- 2f .machine push .machine "power4" @@ -643,6 +642,22 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) rfid b . /* prevent speculative execution */ +2: +#ifdef CONFIG_PPC_ISERIES +BEGIN_FW_FTR_SECTION + b unrecov_slb +END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) +#endif /* CONFIG_PPC_ISERIES */ + mfspr r11,SPRN_SRR0 + clrrdi r10,r13,32 + LOAD_HANDLER(r10,unrecov_slb) + mtspr SPRN_SRR0,r10 + mfmsr r10 + ori r10,r10,MSR_IR|MSR_DR|MSR_RI + mtspr SPRN_SRR1,r10 + rfid + b . + unrecov_slb: EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) DISABLE_INTS @@ -808,7 +823,7 @@ _STATIC(load_up_altivec) * Hash table stuff */ .align 7 -_GLOBAL(do_hash_page) +_STATIC(do_hash_page) std r3,_DAR(r1) std r4,_DSISR(r1) @@ -820,6 +835,27 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFCLR(CPU_FTR_SLB) /* + * On iSeries, we soft-disable interrupts here, then + * hard-enable interrupts so that the hash_page code can spin on + * the hash_table_lock without problems on a shared processor. + */ + DISABLE_INTS + + /* + * Currently, trace_hardirqs_off() will be called by DISABLE_INTS + * and will clobber volatile registers when irq tracing is enabled + * so we need to reload them. It may be possible to be smarter here + * and move the irq tracing elsewhere but let's keep it simple for + * now + */ +#ifdef CONFIG_TRACE_IRQFLAGS + ld r3,_DAR(r1) + ld r4,_DSISR(r1) + ld r5,_TRAP(r1) + ld r12,_MSR(r1) + clrrdi r5,r5,4 +#endif /* CONFIG_TRACE_IRQFLAGS */ + /* * We need to set the _PAGE_USER bit if MSR_PR is set or if we are * accessing a userspace segment (even from the kernel). We assume * kernel addresses always have the high bit set. @@ -832,13 +868,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */ /* - * On iSeries, we soft-disable interrupts here, then - * hard-enable interrupts so that the hash_page code can spin on - * the hash_table_lock without problems on a shared processor. - */ - DISABLE_INTS - - /* * r3 contains the faulting address * r4 contains the required access permissions * r5 contains the trap number @@ -848,7 +877,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) bl .hash_page /* build HPTE if possible */ cmpdi r3,0 /* see if hash_page succeeded */ -#ifdef DO_SOFT_DISABLE BEGIN_FW_FTR_SECTION /* * If we had interrupts soft-enabled at the point where the @@ -860,7 +888,7 @@ BEGIN_FW_FTR_SECTION */ beq 13f END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) -#endif + BEGIN_FW_FTR_SECTION /* * Here we have interrupts hard-disabled, so it is sufficient @@ -874,11 +902,12 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) /* * hash_page couldn't handle it, set soft interrupt enable back - * to what it was before the trap. Note that .local_irq_restore + * to what it was before the trap. Note that .raw_local_irq_restore * handles any interrupts pending at this point. */ ld r3,SOFTE(r1) - bl .local_irq_restore + TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f) + bl .raw_local_irq_restore b 11f /* Here we have a page fault that hash_page can't handle. */ @@ -1477,6 +1506,10 @@ _INIT_STATIC(start_here_multiplatform) addi r2,r2,0x4000 add r2,r2,r26 + /* Set initial ptr to current */ + LOAD_REG_IMMEDIATE(r4, init_task) + std r4,PACACURRENT(r13) + /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -1505,10 +1538,6 @@ _INIT_GLOBAL(start_here_common) li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) - /* ptr to current */ - LOAD_REG_IMMEDIATE(r4, init_task) - std r4,PACACURRENT(r13) - /* Load the TOC */ ld r2,PACATOC(r13) std r1,PACAKSAVE(r13) |