Commit 21f4cfbb authored by David S. Miller's avatar David S. Miller

[SPARC64]: Non-executable page support.

Based upon the PAX patches.  Credit to PaX Team
<pageexec@freemail.hu>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent b46041d9
...@@ -41,6 +41,9 @@ ...@@ -41,6 +41,9 @@
CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
ldxa [%g3 + %g6] ASI_P, %g5 ! Load VPTE ldxa [%g3 + %g6] ASI_P, %g5 ! Load VPTE
1: brgez,pn %g5, 3f ! Not valid, branch out 1: brgez,pn %g5, 3f ! Not valid, branch out
sethi %hi(_PAGE_EXEC), %g4 ! Delay-slot
andcc %g5, %g4, %g0 ! Executable?
be,pn %xcc, 3f ! Nope, branch.
nop ! Delay-slot nop ! Delay-slot
2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB 2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB
retry ! Trap return retry ! Trap return
...@@ -69,9 +72,6 @@ winfix_trampoline: ...@@ -69,9 +72,6 @@ winfix_trampoline:
done ! Do it to it done ! Do it to it
/* ITLB ** ICACHE line 4: Unused... */ /* ITLB ** ICACHE line 4: Unused... */
nop
nop
nop
nop nop
nop nop
nop nop
......
...@@ -257,7 +257,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, ...@@ -257,7 +257,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
* in that case. * in that case.
*/ */
if (!(fault_code & FAULT_CODE_WRITE) && if (!(fault_code & (FAULT_CODE_WRITE|FAULT_CODE_ITLB)) &&
(insn & 0xc0800000) == 0xc0800000) { (insn & 0xc0800000) == 0xc0800000) {
if (insn & 0x2000) if (insn & 0x2000)
asi = (regs->tstate >> 24); asi = (regs->tstate >> 24);
...@@ -408,6 +408,16 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs) ...@@ -408,6 +408,16 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs)
*/ */
good_area: good_area:
si_code = SEGV_ACCERR; si_code = SEGV_ACCERR;
/* If we took a ITLB miss on a non-executable page, catch
* that here.
*/
if ((fault_code & FAULT_CODE_ITLB) && !(vma->vm_flags & VM_EXEC)) {
BUG_ON(address != regs->tpc);
BUG_ON(regs->tstate & TSTATE_PRIV);
goto bad_area;
}
if (fault_code & FAULT_CODE_WRITE) { if (fault_code & FAULT_CODE_WRITE) {
if (!(vma->vm_flags & VM_WRITE)) if (!(vma->vm_flags & VM_WRITE))
goto bad_area; goto bad_area;
......
...@@ -180,16 +180,27 @@ ...@@ -180,16 +180,27 @@
/* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */ /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
#define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ #define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
__ACCESS_BITS | _PAGE_WRITE) __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
#define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ #define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
__ACCESS_BITS) __ACCESS_BITS | _PAGE_EXEC)
#define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ #define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
__ACCESS_BITS) __ACCESS_BITS | _PAGE_EXEC)
#define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ #define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
__PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS) __PRIV_BITS | \
__ACCESS_BITS | __DIRTY_BITS | _PAGE_EXEC)
#define PAGE_SHARED_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
_PAGE_CACHE | \
__ACCESS_BITS | _PAGE_WRITE)
#define PAGE_COPY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
_PAGE_CACHE | __ACCESS_BITS)
#define PAGE_READONLY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
_PAGE_CACHE | __ACCESS_BITS)
#define _PFN_MASK _PAGE_PADDR #define _PFN_MASK _PAGE_PADDR
...@@ -197,18 +208,18 @@ ...@@ -197,18 +208,18 @@
__ACCESS_BITS | _PAGE_E) __ACCESS_BITS | _PAGE_E)
#define __P000 PAGE_NONE #define __P000 PAGE_NONE
#define __P001 PAGE_READONLY #define __P001 PAGE_READONLY_NOEXEC
#define __P010 PAGE_COPY #define __P010 PAGE_COPY_NOEXEC
#define __P011 PAGE_COPY #define __P011 PAGE_COPY_NOEXEC
#define __P100 PAGE_READONLY #define __P100 PAGE_READONLY
#define __P101 PAGE_READONLY #define __P101 PAGE_READONLY
#define __P110 PAGE_COPY #define __P110 PAGE_COPY
#define __P111 PAGE_COPY #define __P111 PAGE_COPY
#define __S000 PAGE_NONE #define __S000 PAGE_NONE
#define __S001 PAGE_READONLY #define __S001 PAGE_READONLY_NOEXEC
#define __S010 PAGE_SHARED #define __S010 PAGE_SHARED_NOEXEC
#define __S011 PAGE_SHARED #define __S011 PAGE_SHARED_NOEXEC
#define __S100 PAGE_READONLY #define __S100 PAGE_READONLY
#define __S101 PAGE_READONLY #define __S101 PAGE_READONLY
#define __S110 PAGE_SHARED #define __S110 PAGE_SHARED
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment