From e77987c4da036c06b1046207ee340e693ab6bab4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 30 Jun 2004 06:21:47 -0700 Subject: [SPARC64]: Document reserved and soft2 bits in PTE. --- include/asm-sparc64/pgtable.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 44b67330f500..cdb7979e6139 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -114,7 +114,10 @@ #define _PAGE_SZ8K _AC(0x0000000000000000,UL) /* 8K Page */ #define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */ #define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */ +#define _PAGE_SOFT2 _AC(0x07FC000000000000,UL) /* Software bits, set 2 */ +#define _PAGE_RES1 _AC(0x0003000000000000,UL) /* Reserved */ #define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */ +#define _PAGE_RES2 _AC(0x0000780000000000,UL) /* Reserved */ #define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr [40:13]*/ #define _PAGE_PADDR _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr [42:13] */ #define _PAGE_SOFT _AC(0x0000000000001F80,UL) /* Software bits */ -- cgit v1.2.3 From b46041d99bbdf366b61c44ac9ded5dd5536a265a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 30 Jun 2004 09:02:26 -0700 Subject: [SPARC64]: Reserve a software PTE bit for _PAGE_EXEC. Based upon the PAX sparc64 patches. Credit to PaX Team Also, reformat the comments here so the lines fit in 80 columns. Signed-off-by: David S. Miller --- include/asm-sparc64/pgtable.h | 73 +++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index cdb7979e6139..505db07e2554 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -106,36 +106,49 @@ #endif /* !(__ASSEMBLY__) */ /* Spitfire/Cheetah TTE bits. */ -#define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */ -#define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit up to date */ -#define _PAGE_SZ4MB _AC(0x6000000000000000,UL) /* 4MB Page */ -#define _PAGE_SZ512K _AC(0x4000000000000000,UL) /* 512K Page */ -#define _PAGE_SZ64K _AC(0x2000000000000000,UL) /* 64K Page */ -#define _PAGE_SZ8K _AC(0x0000000000000000,UL) /* 8K Page */ -#define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */ -#define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */ -#define _PAGE_SOFT2 _AC(0x07FC000000000000,UL) /* Software bits, set 2 */ -#define _PAGE_RES1 _AC(0x0003000000000000,UL) /* Reserved */ -#define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */ -#define _PAGE_RES2 _AC(0x0000780000000000,UL) /* Reserved */ -#define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr [40:13]*/ -#define _PAGE_PADDR _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr [42:13] */ -#define _PAGE_SOFT _AC(0x0000000000001F80,UL) /* Software bits */ -#define _PAGE_L _AC(0x0000000000000040,UL) /* Locked TTE */ -#define _PAGE_CP _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */ -#define _PAGE_CV _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */ -#define _PAGE_E _AC(0x0000000000000008,UL) /* side-Effect */ -#define _PAGE_P _AC(0x0000000000000004,UL) /* Privileged Page */ -#define _PAGE_W _AC(0x0000000000000002,UL) /* Writable */ -#define _PAGE_G _AC(0x0000000000000001,UL) /* Global */ - -/* Here are the SpitFire software bits we use in the TTE's. */ -#define _PAGE_FILE _AC(0x0000000000001000,UL) /* Pagecache page */ -#define _PAGE_MODIFIED _AC(0x0000000000000800,UL) /* Modified (dirty) */ -#define _PAGE_ACCESSED _AC(0x0000000000000400,UL) /* Accessed (ref'd) */ -#define _PAGE_READ _AC(0x0000000000000200,UL) /* Readable SW Bit */ -#define _PAGE_WRITE _AC(0x0000000000000100,UL) /* Writable SW Bit */ -#define _PAGE_PRESENT _AC(0x0000000000000080,UL) /* Present */ +#define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */ +#define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit up to date*/ +#define _PAGE_SZ4MB _AC(0x6000000000000000,UL) /* 4MB Page */ +#define _PAGE_SZ512K _AC(0x4000000000000000,UL) /* 512K Page */ +#define _PAGE_SZ64K _AC(0x2000000000000000,UL) /* 64K Page */ +#define _PAGE_SZ8K _AC(0x0000000000000000,UL) /* 8K Page */ +#define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */ +#define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */ +#define _PAGE_SOFT2 _AC(0x07FC000000000000,UL) /* Software bits, set 2 */ +#define _PAGE_RES1 _AC(0x0003000000000000,UL) /* Reserved */ +#define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */ +#define _PAGE_RES2 _AC(0x0000780000000000,UL) /* Reserved */ +#define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr[40:13]*/ +#define _PAGE_PADDR _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr[42:13] */ +#define _PAGE_SOFT _AC(0x0000000000001F80,UL) /* Software bits */ +#define _PAGE_L _AC(0x0000000000000040,UL) /* Locked TTE */ +#define _PAGE_CP _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */ +#define _PAGE_CV _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */ +#define _PAGE_E _AC(0x0000000000000008,UL) /* side-Effect */ +#define _PAGE_P _AC(0x0000000000000004,UL) /* Privileged Page */ +#define _PAGE_W _AC(0x0000000000000002,UL) /* Writable */ +#define _PAGE_G _AC(0x0000000000000001,UL) /* Global */ + +/* Here are the SpitFire software bits we use in the TTE's. + * + * WARNING: If you are going to try and start using some + * of the soft2 bits, you will need to make + * modifications to the swap entry implementation. + * For example, one thing that could happen is that + * swp_entry_to_pte() would BUG_ON() if you tried + * to use one of the soft2 bits for _PAGE_FILE. + * + * Like other architectures, I have aliased _PAGE_FILE with + * _PAGE_MODIFIED. This works because _PAGE_FILE is never + * interpreted that way unless _PAGE_PRESENT is clear. + */ +#define _PAGE_EXEC _AC(0x0000000000001000,UL) /* Executable SW bit */ +#define _PAGE_MODIFIED _AC(0x0000000000000800,UL) /* Modified (dirty) */ +#define _PAGE_FILE _AC(0x0000000000000800,UL) /* Pagecache page */ +#define _PAGE_ACCESSED _AC(0x0000000000000400,UL) /* Accessed (ref'd) */ +#define _PAGE_READ _AC(0x0000000000000200,UL) /* Readable SW Bit */ +#define _PAGE_WRITE _AC(0x0000000000000100,UL) /* Writable SW Bit */ +#define _PAGE_PRESENT _AC(0x0000000000000080,UL) /* Present */ #if PAGE_SHIFT == 13 #define _PAGE_SZBITS _PAGE_SZ8K -- cgit v1.2.3 From 21f4cfbb029f12f5fc2d77a576af5ce8fb6c429c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 30 Jun 2004 10:38:22 -0700 Subject: [SPARC64]: Non-executable page support. Based upon the PAX patches. Credit to PaX Team Signed-off-by: David S. Miller --- arch/sparc64/kernel/itlb_base.S | 6 +++--- arch/sparc64/mm/fault.c | 12 +++++++++++- include/asm-sparc64/pgtable.h | 31 +++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/arch/sparc64/kernel/itlb_base.S b/arch/sparc64/kernel/itlb_base.S index 36c41501a344..b5e32dfa4fbc 100644 --- a/arch/sparc64/kernel/itlb_base.S +++ b/arch/sparc64/kernel/itlb_base.S @@ -41,6 +41,9 @@ CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset ldxa [%g3 + %g6] ASI_P, %g5 ! Load VPTE 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 2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB retry ! Trap return @@ -69,9 +72,6 @@ winfix_trampoline: done ! Do it to it /* ITLB ** ICACHE line 4: Unused... */ - nop - nop - nop nop nop nop diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 5fc4644aad99..ac57b9e7960d 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -257,7 +257,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, * in that case. */ - if (!(fault_code & FAULT_CODE_WRITE) && + if (!(fault_code & (FAULT_CODE_WRITE|FAULT_CODE_ITLB)) && (insn & 0xc0800000) == 0xc0800000) { if (insn & 0x2000) asi = (regs->tstate >> 24); @@ -408,6 +408,16 @@ continue_fault: */ good_area: 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 (!(vma->vm_flags & VM_WRITE)) goto bad_area; diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 505db07e2554..e3d4f6575a0e 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -180,16 +180,27 @@ /* 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 | \ - __ACCESS_BITS | _PAGE_WRITE) + __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC) #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 | \ - __ACCESS_BITS) + __ACCESS_BITS | _PAGE_EXEC) #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 @@ -197,18 +208,18 @@ __ACCESS_BITS | _PAGE_E) #define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY +#define __P001 PAGE_READONLY_NOEXEC +#define __P010 PAGE_COPY_NOEXEC +#define __P011 PAGE_COPY_NOEXEC #define __P100 PAGE_READONLY #define __P101 PAGE_READONLY #define __P110 PAGE_COPY #define __P111 PAGE_COPY #define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED +#define __S001 PAGE_READONLY_NOEXEC +#define __S010 PAGE_SHARED_NOEXEC +#define __S011 PAGE_SHARED_NOEXEC #define __S100 PAGE_READONLY #define __S101 PAGE_READONLY #define __S110 PAGE_SHARED -- cgit v1.2.3