static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
                struct file *interpreter, unsigned long *interp_map_addr,
-               unsigned long no_base)
+               unsigned long no_base, struct elf_phdr *interp_elf_phdata)
 {
-       struct elf_phdr *elf_phdata;
        struct elf_phdr *eppnt;
        unsigned long load_addr = 0;
        int load_addr_set = 0;
        if (!interpreter->f_op->mmap)
                goto out;
 
-       elf_phdata = load_elf_phdrs(interp_elf_ex, interpreter);
-       if (!elf_phdata)
-               goto out;
-
-       total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
+       total_size = total_mapping_size(interp_elf_phdata,
+                                       interp_elf_ex->e_phnum);
        if (!total_size) {
                error = -EINVAL;
-               goto out_close;
+               goto out;
        }
 
-       eppnt = elf_phdata;
+       eppnt = interp_elf_phdata;
        for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
                if (eppnt->p_type == PT_LOAD) {
                        int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
                                *interp_map_addr = map_addr;
                        error = map_addr;
                        if (BAD_ADDR(map_addr))
-                               goto out_close;
+                               goto out;
 
                        if (!load_addr_set &&
                            interp_elf_ex->e_type == ET_DYN) {
                            eppnt->p_memsz > TASK_SIZE ||
                            TASK_SIZE - eppnt->p_memsz < k) {
                                error = -ENOMEM;
-                               goto out_close;
+                               goto out;
                        }
 
                        /*
                 */
                if (padzero(elf_bss)) {
                        error = -EFAULT;
-                       goto out_close;
+                       goto out;
                }
 
                /* What we have mapped so far */
                /* Map the last of the bss segment */
                error = vm_brk(elf_bss, last_bss - elf_bss);
                if (BAD_ADDR(error))
-                       goto out_close;
+                       goto out;
        }
 
        error = load_addr;
-
-out_close:
-       kfree(elf_phdata);
 out:
        return error;
 }
        int load_addr_set = 0;
        char * elf_interpreter = NULL;
        unsigned long error;
-       struct elf_phdr *elf_ppnt, *elf_phdata;
+       struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL;
        unsigned long elf_bss, elf_brk;
        int retval, i;
        unsigned long elf_entry;
                /* Verify the interpreter has a valid arch */
                if (!elf_check_arch(&loc->interp_elf_ex))
                        goto out_free_dentry;
+
+               /* Load the interpreter program headers */
+               interp_elf_phdata = load_elf_phdrs(&loc->interp_elf_ex,
+                                                  interpreter);
+               if (!interp_elf_phdata)
+                       goto out_free_dentry;
        }
 
        /* Flush all traces of the currently running executable */
                elf_entry = load_elf_interp(&loc->interp_elf_ex,
                                            interpreter,
                                            &interp_map_addr,
-                                           load_bias);
+                                           load_bias, interp_elf_phdata);
                if (!IS_ERR((void *)elf_entry)) {
                        /*
                         * load_elf_interp() returns relocation
 
        /* error cleanup */
 out_free_dentry:
+       kfree(interp_elf_phdata);
        allow_write_access(interpreter);
        if (interpreter)
                fput(interpreter);