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
35extern 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
40int 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
85EXPORT_SYMBOL(setup_arg_pages32);
86