diff -ru linux-2.4.20/Documentation/Configure.help linux-2.4.20-imp/Documentation/Configure.help --- linux-2.4.20/Documentation/Configure.help 2003-02-10 12:17:10.000000000 -0600 +++ linux-2.4.20-imp/Documentation/Configure.help 2003-02-10 12:19:01.000000000 -0600 @@ -25577,6 +25577,11 @@ unambiguous, let us know... Unless your identity-mapped regions are very large, select a granule size of 16MB. (This is the "large" choice.) +General speculation (EXPERIMENTAL) +CONFIG_IA64_NORECOV + Enable execution of binaries without recovery code. + (IMPACT Compiler Research Group) + Enable SGI SN extra debugging code CONFIG_IA64_SGI_SN_DEBUG Turns on extra debugging code in the SGI SN (Scalable NUMA) platform diff -ru linux-2.4.20/Makefile linux-2.4.20-imp/Makefile --- linux-2.4.20/Makefile 2003-02-10 12:17:10.000000000 -0600 +++ linux-2.4.20-imp/Makefile 2003-02-10 12:19:01.000000000 -0600 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 20 -EXTRAVERSION = +EXTRAVERSION =imp KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -ru linux-2.4.20/arch/ia64/config.in linux-2.4.20-imp/arch/ia64/config.in --- linux-2.4.20/arch/ia64/config.in 2003-02-10 12:17:11.000000000 -0600 +++ linux-2.4.20-imp/arch/ia64/config.in 2003-02-10 12:19:01.000000000 -0600 @@ -286,4 +286,5 @@ bool ' Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ fi +bool 'General speculation' CONFIG_IA64_NORECOV endmenu diff -ru linux-2.4.20/arch/ia64/kernel/ivt.S linux-2.4.20-imp/arch/ia64/kernel/ivt.S --- linux-2.4.20/arch/ia64/kernel/ivt.S 2002-11-28 17:53:09.000000000 -0600 +++ linux-2.4.20-imp/arch/ia64/kernel/ivt.S 2003-02-10 12:19:01.000000000 -0600 @@ -1155,10 +1155,26 @@ // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) ENTRY(unaligned_access) DBG_FAULT(30) +#if !defined(CONFIG_IA64_NORECOV) mov r16=cr.ipsr mov r31=pr // prepare to save predicates ;; br.sptk.many dispatch_unaligned_handler +#else + mov r31=pr // prepare to save predicates + mov r16=cr.isr + ;; + tbit.nz p6,p7=r16,IA64_ISR_SP_BIT // is speculation bit on? + mov r16=cr.ipsr +(p7) br.sptk.many dispatch_unaligned_handler + ;; +(p6) dep r16=-1,r16,IA64_PSR_ED_BIT,1 + ;; + mov cr.ipsr=r16 + mov pr=r31,-1 + ;; + rfi +#endif END(unaligned_access) .align 256 diff -ru linux-2.4.20/fs/binfmt_elf.c linux-2.4.20-imp/fs/binfmt_elf.c --- linux-2.4.20/fs/binfmt_elf.c 2002-08-02 19:39:45.000000000 -0500 +++ linux-2.4.20-imp/fs/binfmt_elf.c 2003-02-10 12:19:01.000000000 -0600 @@ -599,6 +599,10 @@ current->mm->end_code = 0; current->mm->mmap = NULL; current->flags &= ~PF_FORKNOEXEC; +#if defined(CONFIG_IA64_NORECOV) + // set the recovery code flag to the default value + current->mm->no_recov = 0; +#endif elf_entry = (unsigned long) elf_ex.e_entry; /* Do this so that we can load the interpreter, if need be. We will @@ -644,6 +648,11 @@ if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; +#if defined(CONFIG_IA64_NORECOV) + if (elf_ppnt->p_flags & PF_IA_64_NORECOV) + current->mm->no_recov = 1; +#endif + elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE; vaddr = elf_ppnt->p_vaddr; diff -ru linux-2.4.20/include/asm-ia64/mman.h linux-2.4.20-imp/include/asm-ia64/mman.h --- linux-2.4.20/include/asm-ia64/mman.h 2001-01-04 14:50:17.000000000 -0600 +++ linux-2.4.20-imp/include/asm-ia64/mman.h 2003-02-10 12:19:01.000000000 -0600 @@ -10,6 +10,9 @@ #define PROT_WRITE 0x2 /* page can be written */ #define PROT_EXEC 0x4 /* page can be executed */ #define PROT_NONE 0x0 /* page can not be accessed */ +#if defined(CONFIG_IA64_NORECOV) +#define PROT_NAT 0x40 /* page is NaT */ +#endif #define MAP_SHARED 0x01 /* Share changes */ #define MAP_PRIVATE 0x02 /* Changes are private */ diff -ru linux-2.4.20/include/asm-ia64/pgtable.h linux-2.4.20-imp/include/asm-ia64/pgtable.h --- linux-2.4.20/include/asm-ia64/pgtable.h 2003-02-10 12:17:13.000000000 -0600 +++ linux-2.4.20-imp/include/asm-ia64/pgtable.h 2003-02-10 12:22:41.000000000 -0600 @@ -57,6 +57,9 @@ #define _PAGE_D (1 << _PAGE_D_BIT) /* page dirty bit */ #define _PAGE_PPN_MASK (((__IA64_UL(1) << IA64_MAX_PHYS_BITS) - 1) & ~0xfffUL) #define _PAGE_ED (__IA64_UL(1) << 52) /* exception deferral */ +#if defined(CONFIG_IA64_NORECOV) +#define _PAGE_CLEAR_ED_MASK (~(_PAGE_ED)) +#endif #define _PAGE_PROTNONE (__IA64_UL(1) << 63) #define _PFN_MASK _PAGE_PPN_MASK @@ -118,6 +121,22 @@ #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX) #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX) +#if defined(CONFIG_IA64_NORECOV) + +// NO_ED page definitions + +#define PAGE_SHARED_NO_ED __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)) +#define PAGE_READONLY_NO_ED __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)) +#define PAGE_COPY_NO_ED __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)) + +/* attributes for page zero page: + * NAT attribute is set. Page is present, dirty, accessed, low privilege + * level. We are trying to avoid all exception conditions. + */ + +#define PAGE_ZERO __pgprot((__DIRTY_BITS | _PAGE_PL_3 | _PAGE_AR_RW | _PAGE_MA_NAT) & _PAGE_CLEAR_ED_MASK) +#endif + # ifndef __ASSEMBLY__ #include @@ -151,6 +170,29 @@ #define __S110 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX) #define __S111 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX) +#if defined(CONFIG_IA64_NORECOV) + +// These 16 definitions were added to add NO_ED option + +#define __P1000 PAGE_NONE +#define __P1001 PAGE_READONLY_NO_ED +#define __P1010 PAGE_READONLY_NO_ED /* write to priv pg -> copy & make writable */ +#define __P1011 PAGE_READONLY_NO_ED /* ditto */ +#define __P1100 __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX)) +#define __P1101 __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)) +#define __P1110 PAGE_COPY_NO_ED +#define __P1111 PAGE_COPY_NO_ED + +#define __S1000 PAGE_NONE +#define __S1001 PAGE_READONLY_NO_ED +#define __S1010 PAGE_SHARED_NO_ED /* we don't have (and don't need) write-only */ +#define __S1011 PAGE_SHARED_NO_ED +#define __S1100 __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX)) +#define __S1101 __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)) +#define __S1110 __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)) +#define __S1111 __pgprot(_PAGE_CLEAR_ED_MASK & (__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)) +#endif + #define pgd_ERROR(e) printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e)) #define pmd_ERROR(e) printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pte_ERROR(e) printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) diff -ru linux-2.4.20/include/linux/elf.h linux-2.4.20-imp/include/linux/elf.h --- linux-2.4.20/include/linux/elf.h 2002-11-28 17:53:15.000000000 -0600 +++ linux-2.4.20-imp/include/linux/elf.h 2003-02-10 12:19:01.000000000 -0600 @@ -453,6 +453,10 @@ #define PF_W 0x2 #define PF_X 0x1 +#if defined(CONFIG_IA64_NORECOV) +#define PF_IA_64_NORECOV 0x80000000 //this executable has no recovery code +#endif + typedef struct elf32_phdr{ Elf32_Word p_type; Elf32_Off p_offset; diff -ru linux-2.4.20/include/linux/mm.h linux-2.4.20-imp/include/linux/mm.h --- linux-2.4.20/include/linux/mm.h 2003-02-10 12:17:13.000000000 -0600 +++ linux-2.4.20-imp/include/linux/mm.h 2003-02-10 12:23:29.000000000 -0600 @@ -122,7 +122,16 @@ * mapping from the currently active vm_flags protection bits (the * low four bits) to a page protection mask.. */ + +#if !defined(CONFIG_IA64_NORECOV) extern pgprot_t protection_map[16]; +#else + +// changed this from 16 to 32 to add the translation entries without ED bit + +extern pgprot_t protection_map[32]; + +#endif /* diff -ru linux-2.4.20/include/linux/sched.h linux-2.4.20-imp/include/linux/sched.h --- linux-2.4.20/include/linux/sched.h 2003-02-10 12:17:13.000000000 -0600 +++ linux-2.4.20-imp/include/linux/sched.h 2003-02-10 12:24:45.000000000 -0600 @@ -233,6 +233,15 @@ unsigned dumpable:1; +#if defined(CONFIG_IA64_NORECOV) + + /* This might not work: add a flag for no recovery code to make + * memory allocation easier + */ + + unsigned long no_recov; +#endif + /* Architecture-specific MM context */ mm_context_t context; }; diff -ru linux-2.4.20/mm/mmap.c linux-2.4.20-imp/mm/mmap.c --- linux-2.4.20/mm/mmap.c 2003-02-10 12:17:13.000000000 -0600 +++ linux-2.4.20-imp/mm/mmap.c 2003-02-10 12:28:50.000000000 -0600 @@ -39,10 +39,26 @@ * x: (no) no x: (no) yes x: (no) yes x: (yes) yes * */ +#if !defined(CONFIG_IA64_NORECOV) pgprot_t protection_map[16] = { __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111 }; +#else + +/* Added the last 16 because the bit masking did not work. The last 16 all + * have the ED field cleared. You may or may not need the last row but to be + * "safe," I have put it in. 32 used to be 16. (See also mm.h) + */ + +pgprot_t protection_map[32] = { + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111, + __P1000, __P1001, __P1010, __P1011, __P1100, __P1101, __P1110, __P1111, + __S1000, __S1001, __S1010, __S1011, __S1100, __S1101, __S1110, __S1111 +}; + +#endif int sysctl_overcommit_memory; int max_map_count = DEFAULT_MAX_MAP_COUNT; @@ -400,6 +416,16 @@ int error; rb_node_t ** rb_link, * rb_parent; +#if defined(CONFIG_IA64_NORECOV) + + /* check NaT page for 0 page translation; save result and clear + * the bit in prot + */ + + int nat = (prot & PROT_NAT) ? 1 : 0; + prot = prot & ~(PROT_NAT); +#endif + if (file && (!file->f_op || !file->f_op->mmap)) return -ENODEV; @@ -515,7 +541,19 @@ vma->vm_start = addr; vma->vm_end = addr + len; vma->vm_flags = vm_flags; +#if !defined(CONFIG_IA64_NORECOV) vma->vm_page_prot = protection_map[vm_flags & 0x0f]; +#else + // set the appropriate flags for the zero page + if (nat) + vma->vm_page_prot = PAGE_ZERO; + + // set the appropriate flags for no recovery code + else if (mm->no_recov) + vma->vm_page_prot = protection_map[(vm_flags & 0x0f) | 0x10]; + else + vma->vm_page_prot = protection_map[vm_flags & 0x0f]; +#endif vma->vm_ops = NULL; vma->vm_pgoff = pgoff; vma->vm_file = NULL; @@ -1088,7 +1126,16 @@ vma->vm_start = addr; vma->vm_end = addr + len; vma->vm_flags = flags; +#if !defined(CONFIG_IA64_NORECOV) vma->vm_page_prot = protection_map[flags & 0x0f]; +#else + // make sure the ed bit is cleared if no recovery code is generated + + if (mm->no_recov) + vma->vm_page_prot = protection_map[(vma->vm_flags & 0x0f) | 0x10]; + else + vma->vm_page_prot = protection_map[flags & 0x0f]; +#endif vma->vm_ops = NULL; vma->vm_pgoff = 0; vma->vm_file = NULL;