]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
powerpc/book3e: Fix single step when using HW page tables
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 8 Jun 2010 00:58:58 +0000 (10:58 +1000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 14 Jul 2010 04:13:51 +0000 (14:13 +1000)
We patch the TLB miss exception vectors to point to alternate
functions when using HW page table on BookE.

However, we were patching in a new branch in the first instruction
of the exception handler instead of the second one, thus overriding
the nop that is in the first instruction.

This cause problems when single stepping as we rely on that nop for
the single step to stop properly within the exception vector range
rather than on the target of the branch.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/mm/tlb_nohash.c

index 316465a32a9c28b3020c569d416a49e76c869743..5c43063d250629a3fc708327f96880bc5d34e805 100644 (file)
@@ -191,6 +191,12 @@ exc_##n##_bad_stack:                                                           \
        sth     r1,PACA_TRAP_SAVE(r13); /* store trap */                    \
        b       bad_stack_book3e;       /* bad stack error */
 
+/* WARNING: If you change the layout of this stub, make sure you chcek
+       *   the debug exception handler which handles single stepping
+       *   into exceptions from userspace, and the MM code in
+       *   arch/powerpc/mm/tlb_nohash.c which patches the branch here
+       *   and would need to be updated if that branch is moved
+       */
 #define        EXCEPTION_STUB(loc, label)                                      \
        . = interrupt_base_book3e + loc;                                \
        nop;    /* To make debug interrupts happy */                    \
index e81d5d67f834021c9304e9c35ab2030864a027a9..2ce42bf1f67e047952c834c80b031479be903bc2 100644 (file)
@@ -391,10 +391,15 @@ static void __early_init_mmu(int boot_cpu)
                /* Check if HW loader is supported */
                if ((tlb0cfg & TLBnCFG_IND) &&
                    (tlb0cfg & TLBnCFG_PT)) {
-                       patch_branch(ibase + (0x1c0 / 4),
-                            (unsigned long)&exc_data_tlb_miss_htw_book3e, 0);
-                       patch_branch(ibase + (0x1e0 / 4),
-                            (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0);
+                       /* Our exceptions vectors start with a NOP and -then- a branch
+                        * to deal with single stepping from userspace which stops on
+                        * the second instruction. Thus we need to patch the second
+                        * instruction of the exception, not the first one
+                        */
+                       patch_branch(ibase + (0x1c0 / 4) + 1,
+                               (unsigned long)&exc_data_tlb_miss_htw_book3e, 0);
+                       patch_branch(ibase + (0x1e0 / 4) + 1,
+                               (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0);
                        book3e_htw_enabled = 1;
                }
                pr_info("MMU: Book3E Page Tables %s\n",