--- linux-2.6.15.i686/fs/binfmt_elf.c.huge 2006-01-19 10:28:24.000000000 -0800 +++ linux-2.6.15.i686/fs/binfmt_elf.c 2006-01-19 10:28:29.000000000 -0800 @@ -140,7 +140,11 @@ static int padzero(unsigned long elf_bss static int create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, int interp_aout, unsigned long load_addr, - unsigned long interp_load_addr) + unsigned long interp_load_addr +#ifdef CONFIG_HUGETLB_PAGE + , long huge_offset +#endif + ) { unsigned long p = bprm->p; int argc = bprm->argc; @@ -154,6 +158,9 @@ create_elf_tables(struct linux_binprm *b elf_addr_t *elf_info; int ei_index = 0; struct task_struct *tsk = current; +#ifdef CONFIG_HUGETLB_PAGE + int ei_execfilename_index; +#endif /* * If this architecture has a platform capability string, copy it @@ -205,6 +212,17 @@ create_elf_tables(struct linux_binprm *b NEW_AUX_ENT(AT_GID, (elf_addr_t) tsk->gid); NEW_AUX_ENT(AT_EGID, (elf_addr_t) tsk->egid); NEW_AUX_ENT(AT_SECURE, (elf_addr_t) security_bprm_secureexec(bprm)); +#ifdef CONFIG_HUGETLB_PAGE + NEW_AUX_ENT(AT_HUGEPAGESZ, HPAGE_SIZE); + if (huge_offset >= 0) { + NEW_AUX_ENT(AT_HUGEPAGEPHDR, load_addr + exec->e_phoff + huge_offset); + NEW_AUX_ENT(AT_EXECFILENAME, 0); + /* Save the AT_EXECFILENAME index. */ + ei_execfilename_index = ei_index - 1; + } else { + ei_execfilename_index = 0; + } +#endif if (k_platform) { NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(unsigned long)u_platform); } @@ -276,6 +294,11 @@ create_elf_tables(struct linux_binprm *b current->mm->env_end = p; /* Put the elf_info on the stack in the right place. */ +#ifdef CONFIG_HUGETLB_PAGE + if (ei_execfilename_index) { + elf_info[ei_execfilename_index] = (elf_addr_t)p; + } +#endif sp = (elf_addr_t __user *)envp + 1; if (copy_to_user(sp, elf_info, ei_index * sizeof(elf_addr_t))) return -EFAULT; @@ -588,6 +611,10 @@ static int load_elf_binary(struct linux_ struct elfhdr interp_elf_ex; struct exec interp_ex; } *loc; +#ifdef CONFIG_HUGETLB_PAGE + struct elf_phdr *huge_ppnt; + long huge_offset; +#endif loc = kmalloc(sizeof(*loc), GFP_KERNEL); if (!loc) { @@ -860,12 +887,37 @@ static int load_elf_binary(struct linux_ the correct location in memory. */ +#ifdef CONFIG_HUGETLB_PAGE + huge_ppnt = NULL; + huge_offset = -1; +#endif for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { int elf_prot = 0, elf_flags; unsigned long k, vaddr; +#ifdef CONFIG_HUGETLB_PAGE + if (elf_ppnt->p_type == PT_GNU_HUGE_PAGE) { + if (huge_ppnt) { + /* Only one PT_GNU_HUGE_PAGE segment + is allowed. */ + retval = -ENOEXEC; + goto out_free_dentry; + } + huge_ppnt = elf_ppnt; + continue; + } + else if (elf_ppnt->p_type != PT_LOAD + || (huge_ppnt != NULL + && huge_ppnt->p_offset == elf_ppnt->p_offset + && huge_ppnt->p_vaddr == elf_ppnt->p_vaddr)) { + if (elf_ppnt->p_type == PT_LOAD) + huge_offset = (long) huge_ppnt - (long) elf_phdata; + continue; + } +#else if (elf_ppnt->p_type != PT_LOAD) continue; +#endif if (unlikely (elf_brk > elf_bss)) { unsigned long nbyte; @@ -1024,7 +1076,11 @@ static int load_elf_binary(struct linux_ compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT), - load_addr, interp_load_addr); + load_addr, interp_load_addr +#ifdef CONFIG_HUGETLB_PAGE + , huge_offset +#endif + ); /* N.B. passed_fileno might not be initialized? */ if (interpreter_type == INTERPRETER_AOUT) current->mm->arg_start += strlen(passed_fileno) + 1; --- linux-2.6.15.i686/include/linux/auxvec.h.huge 2006-01-19 10:28:23.000000000 -0800 +++ linux-2.6.15.i686/include/linux/auxvec.h 2006-01-19 10:30:54.000000000 -0800 @@ -26,6 +26,10 @@ #define AT_SECURE 23 /* secure mode boolean */ +#define AT_EXECFILENAME 39 /* filename of program */ +#define AT_HUGEPAGESZ 40 /* system huge TLB page size */ +#define AT_HUGEPAGEPHDR 41 /* program header for huge TLB page segment */ + #define AT_VECTOR_SIZE 44 /* Size of auxiliary table. */ #endif /* _LINUX_AUXVEC_H */ --- linux-2.6.15.i686/include/linux/elf.h.huge 2006-01-19 10:28:23.000000000 -0800 +++ linux-2.6.15.i686/include/linux/elf.h 2006-01-19 10:28:29.000000000 -0800 @@ -46,6 +46,8 @@ typedef __s64 Elf64_Sxword; #define PT_GNU_STACK (PT_LOOS + 0x474e551) +#define PT_GNU_HUGE_PAGE (PT_LOOS + 0x474e553) + /* These constants define the different elf file types */ #define ET_NONE 0 #define ET_REL 1