aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-06-07 20:58:58 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-07-14 00:13:51 -0400
commitff82c319e6327b12cd94c5c57754abff243ab3e4 (patch)
tree9545c320549d37f6f9bf99b6ea3eacd6e549706a /arch/powerpc
parent34d97e07cc81ab6f1e63696127cc7a5d2c4fce4b (diff)
powerpc/book3e: Fix single step when using HW page tables
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>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S6
-rw-r--r--arch/powerpc/mm/tlb_nohash.c13
2 files changed, 15 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 316465a32a9c..5c43063d2506 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -191,6 +191,12 @@ exc_##n##_bad_stack: \
191 sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ 191 sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \
192 b bad_stack_book3e; /* bad stack error */ 192 b bad_stack_book3e; /* bad stack error */
193 193
194/* WARNING: If you change the layout of this stub, make sure you chcek
195 * the debug exception handler which handles single stepping
196 * into exceptions from userspace, and the MM code in
197 * arch/powerpc/mm/tlb_nohash.c which patches the branch here
198 * and would need to be updated if that branch is moved
199 */
194#define EXCEPTION_STUB(loc, label) \ 200#define EXCEPTION_STUB(loc, label) \
195 . = interrupt_base_book3e + loc; \ 201 . = interrupt_base_book3e + loc; \
196 nop; /* To make debug interrupts happy */ \ 202 nop; /* To make debug interrupts happy */ \
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index e81d5d67f834..2ce42bf1f67e 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -391,10 +391,15 @@ static void __early_init_mmu(int boot_cpu)
391 /* Check if HW loader is supported */ 391 /* Check if HW loader is supported */
392 if ((tlb0cfg & TLBnCFG_IND) && 392 if ((tlb0cfg & TLBnCFG_IND) &&
393 (tlb0cfg & TLBnCFG_PT)) { 393 (tlb0cfg & TLBnCFG_PT)) {
394 patch_branch(ibase + (0x1c0 / 4), 394 /* Our exceptions vectors start with a NOP and -then- a branch
395 (unsigned long)&exc_data_tlb_miss_htw_book3e, 0); 395 * to deal with single stepping from userspace which stops on
396 patch_branch(ibase + (0x1e0 / 4), 396 * the second instruction. Thus we need to patch the second
397 (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0); 397 * instruction of the exception, not the first one
398 */
399 patch_branch(ibase + (0x1c0 / 4) + 1,
400 (unsigned long)&exc_data_tlb_miss_htw_book3e, 0);
401 patch_branch(ibase + (0x1e0 / 4) + 1,
402 (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0);
398 book3e_htw_enabled = 1; 403 book3e_htw_enabled = 1;
399 } 404 }
400 pr_info("MMU: Book3E Page Tables %s\n", 405 pr_info("MMU: Book3E Page Tables %s\n",