commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.git] / arch / x86_64 / kernel / sys_x86_64.c
1 /*
2  * linux/arch/x86_64/kernel/sys_x86_64.c
3  */
4
5 #include <linux/errno.h>
6 #include <linux/sched.h>
7 #include <linux/mm.h>
8 #include <linux/smp.h>
9 #include <linux/smp_lock.h>
10 #include <linux/sem.h>
11 #include <linux/msg.h>
12 #include <linux/shm.h>
13 #include <linux/stat.h>
14 #include <linux/mman.h>
15 #include <linux/file.h>
16 #include <linux/utsname.h>
17 #include <linux/personality.h>
18
19 #include <asm/uaccess.h>
20 #include <asm/ipc.h>
21 #include <asm/ia32.h>
22
23 /*
24  * sys_pipe() is the normal C calling standard for creating
25  * a pipe. It's not the way Unix traditionally does this, though.
26  */
27 asmlinkage long sys_pipe(int *fildes)
28 {
29         int fd[2];
30         int error;
31
32         error = do_pipe(fd);
33         if (!error) {
34                 if (copy_to_user(fildes, fd, 2*sizeof(int)))
35                         error = -EFAULT;
36         }
37         return error;
38 }
39
40 long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
41         unsigned long fd, unsigned long off)
42 {
43         long error;
44         struct file * file;
45
46         error = -EINVAL;
47         if (off & ~PAGE_MASK)
48                 goto out;
49
50         error = -EBADF;
51         file = NULL;
52         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
53         if (!(flags & MAP_ANONYMOUS)) {
54                 file = fget(fd);
55                 if (!file)
56                         goto out;
57         }
58         down_write(&current->mm->mmap_sem);
59         error = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, off >> PAGE_SHIFT);
60         up_write(&current->mm->mmap_sem);
61
62         if (file)
63                 fput(file);
64 out:
65         return error;
66 }
67
68 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
69 {
70         struct vm_area_struct *vma;
71         unsigned long end = TASK_SIZE;
72
73 #ifdef CONFIG_IA32_EMULATION
74         if (test_thread_flag(TIF_IA32)) { 
75                 if (!addr) 
76                         addr = TASK_UNMAPPED_32;
77                 end = IA32_PAGE_OFFSET; 
78         } else 
79 #endif
80         if (flags & MAP_32BIT) { 
81                 /* This is usually used needed to map code in small model, so it needs to 
82                    be in the first 31bit. Limit it to that.
83                    This means we need to move the unmapped base down for this case. This can 
84                    give conflicts with the heap, but we assume that glibc malloc knows how 
85                    to fall back to mmap. Give it 1GB of playground for now. -AK */ 
86                 if (!addr) 
87                         addr = 0x40000000; 
88                 end = 0x80000000;               
89         } else { 
90                 if (!addr) 
91                         addr = TASK_UNMAPPED_64; 
92                 end = TASK_SIZE; 
93                 }
94
95         if (len > end)
96                 return -ENOMEM;
97         addr = PAGE_ALIGN(addr);
98
99         for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
100                 /* At this point:  (!vma || addr < vma->vm_end). */
101                 if (end - len < addr)
102                         return -ENOMEM;
103                 if (!vma || addr + len <= vma->vm_start)
104                         return addr;
105                 addr = vma->vm_end;
106         }
107 }
108
109 asmlinkage long sys_uname(struct new_utsname * name)
110 {
111         int err;
112         down_read(&uts_sem);
113         err = copy_to_user(name, &system_utsname, sizeof (*name));
114         up_read(&uts_sem);
115         if (current->personality == PER_LINUX32) 
116                 err |= copy_to_user(&name->machine, "i386", 5);                 
117         return err ? -EFAULT : 0;
118 }
119
120 asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg)
121 {
122         unsigned long raddr;
123         return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr;
124
125
126 asmlinkage long sys_time64(long * tloc)
127 {
128         struct timeval now; 
129         int i; 
130
131         do_gettimeofday(&now);
132         i = now.tv_sec;
133         if (tloc) {
134                 if (put_user(i,tloc))
135                         i = -EFAULT;
136         }
137         return i;
138 }