File: /usr/src/linux/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;
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     		insert_vm_struct(current->mm, mpnt);
69     		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
70     	} 
71     
72     	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
73     		struct page *page = bprm->page[i];
74     		if (page) {
75     			bprm->page[i] = NULL;
76     			put_dirty_page(current,page,stack_base);
77     		}
78     		stack_base += PAGE_SIZE;
79     	}
80     	up_write(&current->mm->mmap_sem);
81     	
82     	return 0;
83     }
84     
85     EXPORT_SYMBOL(setup_arg_pages32);
86