import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / s390x / kernel / exec32.c
1 /*
2  * Support for 32-bit Linux for S390 ELF binaries.
3  *
4  * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
5  * Author(s): Gerhard Tonn (ton@de.ibm.com)
6  *
7  * Seperated from binfmt_elf32.c to reduce exports for module enablement.
8  *
9  */
10
11 #include <linux/config.h>
12 #include <linux/slab.h>
13 #include <linux/file.h>
14 #include <linux/mman.h>
15 #include <linux/a.out.h>
16 #include <linux/stat.h>
17 #include <linux/fcntl.h>
18 #include <linux/smp_lock.h>
19 #include <linux/init.h>
20 #include <linux/pagemap.h>
21 #include <linux/highmem.h>
22 #include <linux/spinlock.h>
23 #define __NO_VERSION__
24 #include <linux/module.h>
25
26 #include <asm/uaccess.h>
27 #include <asm/pgalloc.h>
28 #include <asm/mmu_context.h>
29
30 #ifdef CONFIG_KMOD
31 #include <linux/kmod.h>
32 #endif
33
34
35 extern void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address);
36
37 #undef STACK_TOP
38 #define STACK_TOP TASK31_SIZE
39
40 int setup_arg_pages32(struct linux_binprm *bprm)
41 {
42         unsigned long stack_base;
43         struct vm_area_struct *mpnt;
44         int i, ret;
45
46         stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
47
48         bprm->p += stack_base;
49         if (bprm->loader)
50                 bprm->loader += stack_base;
51         bprm->exec += stack_base;
52
53         mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
54         if (!mpnt) 
55                 return -ENOMEM; 
56         
57         down_write(&current->mm->mmap_sem);
58         {
59                 mpnt->vm_mm = current->mm;
60                 mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
61                 mpnt->vm_end = STACK_TOP;
62                 mpnt->vm_page_prot = PAGE_COPY;
63                 mpnt->vm_flags = VM_STACK_FLAGS;
64                 mpnt->vm_ops = NULL;
65                 mpnt->vm_pgoff = 0;
66                 mpnt->vm_file = NULL;
67                 mpnt->vm_private_data = (void *) 0;
68                 if ((ret = insert_vm_struct(current->mm, mpnt))) {
69                         up_write(&current->mm->mmap_sem);
70                         kmem_cache_free(vm_area_cachep, mpnt);
71                         return ret;
72                 }
73                 current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
74         } 
75
76         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
77                 struct page *page = bprm->page[i];
78                 if (page) {
79                         bprm->page[i] = NULL;
80                         put_dirty_page(current,page,stack_base);
81                 }
82                 stack_base += PAGE_SIZE;
83         }
84         up_write(&current->mm->mmap_sem);
85         
86         return 0;
87 }
88
89 EXPORT_SYMBOL(setup_arg_pages32);