diff options
author | Li Yang <leoli@freescale.com> | 2010-05-07 04:38:34 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2010-05-17 11:56:16 -0400 |
commit | 78e2e68a2b79f394b7cd61e07987a8a89af907f7 (patch) | |
tree | 41b534f2e557503a1d78f01d852e5eb8cb61b95a | |
parent | 4c5ddd52695f7bac6362ad13fd3dc878212d1368 (diff) |
powerpc/fsl-booke: Fix InstructionTLBError execute permission check
In CONFIG_PTE_64BIT the PTE format has unique permission bits for user
and supervisor execute. However on !CONFIG_PTE_64BIT we overload the
supervisor bit to imply user execute with _PAGE_USER set. This allows
us to use the same permission check mask for user or supervisor code on
!CONFIG_PTE_64BIT.
However, on CONFIG_PTE_64BIT we map _PAGE_EXEC to _PAGE_BAP_UX so we
need a different permission mask based on the fault coming from a kernel
address or user space.
Without unique permission masks we see issues like the following with
modules:
Unable to handle kernel paging request for instruction fetch
Faulting instruction address: 0xf938d040
Oops: Kernel access of bad area, sig: 11 [#1]
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Jin Qing <b24347@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/kernel/head_fsl_booke.S | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 725526547994..edd4a57fd29e 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -639,6 +639,13 @@ interrupt_base: | |||
639 | rlwinm r12,r12,0,16,1 | 639 | rlwinm r12,r12,0,16,1 |
640 | mtspr SPRN_MAS1,r12 | 640 | mtspr SPRN_MAS1,r12 |
641 | 641 | ||
642 | /* Make up the required permissions for kernel code */ | ||
643 | #ifdef CONFIG_PTE_64BIT | ||
644 | li r13,_PAGE_PRESENT | _PAGE_BAP_SX | ||
645 | oris r13,r13,_PAGE_ACCESSED@h | ||
646 | #else | ||
647 | li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | ||
648 | #endif | ||
642 | b 4f | 649 | b 4f |
643 | 650 | ||
644 | /* Get the PGD for the current thread */ | 651 | /* Get the PGD for the current thread */ |
@@ -646,15 +653,15 @@ interrupt_base: | |||
646 | mfspr r11,SPRN_SPRG_THREAD | 653 | mfspr r11,SPRN_SPRG_THREAD |
647 | lwz r11,PGDIR(r11) | 654 | lwz r11,PGDIR(r11) |
648 | 655 | ||
649 | 4: | 656 | /* Make up the required permissions for user code */ |
650 | /* Make up the required permissions */ | ||
651 | #ifdef CONFIG_PTE_64BIT | 657 | #ifdef CONFIG_PTE_64BIT |
652 | li r13,_PAGE_PRESENT | _PAGE_EXEC | 658 | li r13,_PAGE_PRESENT | _PAGE_BAP_UX |
653 | oris r13,r13,_PAGE_ACCESSED@h | 659 | oris r13,r13,_PAGE_ACCESSED@h |
654 | #else | 660 | #else |
655 | li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | 661 | li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC |
656 | #endif | 662 | #endif |
657 | 663 | ||
664 | 4: | ||
658 | FIND_PTE | 665 | FIND_PTE |
659 | andc. r13,r13,r11 /* Check permission */ | 666 | andc. r13,r13,r11 /* Check permission */ |
660 | 667 | ||