diff options
Diffstat (limited to 'arch/x86/kernel/sys_x86_64.c')
| -rw-r--r-- | arch/x86/kernel/sys_x86_64.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index 3b360ef33817..6bc211accf08 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c | |||
| @@ -13,15 +13,17 @@ | |||
| 13 | #include <linux/utsname.h> | 13 | #include <linux/utsname.h> |
| 14 | #include <linux/personality.h> | 14 | #include <linux/personality.h> |
| 15 | #include <linux/random.h> | 15 | #include <linux/random.h> |
| 16 | #include <linux/uaccess.h> | ||
| 16 | 17 | ||
| 17 | #include <asm/uaccess.h> | ||
| 18 | #include <asm/ia32.h> | 18 | #include <asm/ia32.h> |
| 19 | #include <asm/syscalls.h> | ||
| 19 | 20 | ||
| 20 | asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, | 21 | asmlinkage long sys_mmap(unsigned long addr, unsigned long len, |
| 21 | unsigned long fd, unsigned long off) | 22 | unsigned long prot, unsigned long flags, |
| 23 | unsigned long fd, unsigned long off) | ||
| 22 | { | 24 | { |
| 23 | long error; | 25 | long error; |
| 24 | struct file * file; | 26 | struct file *file; |
| 25 | 27 | ||
| 26 | error = -EINVAL; | 28 | error = -EINVAL; |
| 27 | if (off & ~PAGE_MASK) | 29 | if (off & ~PAGE_MASK) |
| @@ -56,9 +58,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin, | |||
| 56 | unmapped base down for this case. This can give | 58 | unmapped base down for this case. This can give |
| 57 | conflicts with the heap, but we assume that glibc | 59 | conflicts with the heap, but we assume that glibc |
| 58 | malloc knows how to fall back to mmap. Give it 1GB | 60 | malloc knows how to fall back to mmap. Give it 1GB |
| 59 | of playground for now. -AK */ | 61 | of playground for now. -AK */ |
| 60 | *begin = 0x40000000; | 62 | *begin = 0x40000000; |
| 61 | *end = 0x80000000; | 63 | *end = 0x80000000; |
| 62 | if (current->flags & PF_RANDOMIZE) { | 64 | if (current->flags & PF_RANDOMIZE) { |
| 63 | new_begin = randomize_range(*begin, *begin + 0x02000000, 0); | 65 | new_begin = randomize_range(*begin, *begin + 0x02000000, 0); |
| 64 | if (new_begin) | 66 | if (new_begin) |
| @@ -66,9 +68,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin, | |||
| 66 | } | 68 | } |
| 67 | } else { | 69 | } else { |
| 68 | *begin = TASK_UNMAPPED_BASE; | 70 | *begin = TASK_UNMAPPED_BASE; |
| 69 | *end = TASK_SIZE; | 71 | *end = TASK_SIZE; |
| 70 | } | 72 | } |
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | unsigned long | 75 | unsigned long |
| 74 | arch_get_unmapped_area(struct file *filp, unsigned long addr, | 76 | arch_get_unmapped_area(struct file *filp, unsigned long addr, |
| @@ -78,11 +80,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 78 | struct vm_area_struct *vma; | 80 | struct vm_area_struct *vma; |
| 79 | unsigned long start_addr; | 81 | unsigned long start_addr; |
| 80 | unsigned long begin, end; | 82 | unsigned long begin, end; |
| 81 | 83 | ||
| 82 | if (flags & MAP_FIXED) | 84 | if (flags & MAP_FIXED) |
| 83 | return addr; | 85 | return addr; |
| 84 | 86 | ||
| 85 | find_start_end(flags, &begin, &end); | 87 | find_start_end(flags, &begin, &end); |
| 86 | 88 | ||
| 87 | if (len > end) | 89 | if (len > end) |
| 88 | return -ENOMEM; | 90 | return -ENOMEM; |
| @@ -96,12 +98,12 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 96 | } | 98 | } |
| 97 | if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32)) | 99 | if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32)) |
| 98 | && len <= mm->cached_hole_size) { | 100 | && len <= mm->cached_hole_size) { |
| 99 | mm->cached_hole_size = 0; | 101 | mm->cached_hole_size = 0; |
| 100 | mm->free_area_cache = begin; | 102 | mm->free_area_cache = begin; |
| 101 | } | 103 | } |
| 102 | addr = mm->free_area_cache; | 104 | addr = mm->free_area_cache; |
| 103 | if (addr < begin) | 105 | if (addr < begin) |
| 104 | addr = begin; | 106 | addr = begin; |
| 105 | start_addr = addr; | 107 | start_addr = addr; |
| 106 | 108 | ||
| 107 | full_search: | 109 | full_search: |
| @@ -127,7 +129,7 @@ full_search: | |||
| 127 | return addr; | 129 | return addr; |
| 128 | } | 130 | } |
| 129 | if (addr + mm->cached_hole_size < vma->vm_start) | 131 | if (addr + mm->cached_hole_size < vma->vm_start) |
| 130 | mm->cached_hole_size = vma->vm_start - addr; | 132 | mm->cached_hole_size = vma->vm_start - addr; |
| 131 | 133 | ||
| 132 | addr = vma->vm_end; | 134 | addr = vma->vm_end; |
| 133 | } | 135 | } |
| @@ -177,7 +179,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
| 177 | vma = find_vma(mm, addr-len); | 179 | vma = find_vma(mm, addr-len); |
| 178 | if (!vma || addr <= vma->vm_start) | 180 | if (!vma || addr <= vma->vm_start) |
| 179 | /* remember the address as a hint for next time */ | 181 | /* remember the address as a hint for next time */ |
| 180 | return (mm->free_area_cache = addr-len); | 182 | return mm->free_area_cache = addr-len; |
| 181 | } | 183 | } |
| 182 | 184 | ||
| 183 | if (mm->mmap_base < len) | 185 | if (mm->mmap_base < len) |
| @@ -194,7 +196,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
| 194 | vma = find_vma(mm, addr); | 196 | vma = find_vma(mm, addr); |
| 195 | if (!vma || addr+len <= vma->vm_start) | 197 | if (!vma || addr+len <= vma->vm_start) |
| 196 | /* remember the address as a hint for next time */ | 198 | /* remember the address as a hint for next time */ |
| 197 | return (mm->free_area_cache = addr); | 199 | return mm->free_area_cache = addr; |
| 198 | 200 | ||
| 199 | /* remember the largest hole we saw so far */ | 201 | /* remember the largest hole we saw so far */ |
| 200 | if (addr + mm->cached_hole_size < vma->vm_start) | 202 | if (addr + mm->cached_hole_size < vma->vm_start) |
| @@ -224,13 +226,13 @@ bottomup: | |||
| 224 | } | 226 | } |
| 225 | 227 | ||
| 226 | 228 | ||
| 227 | asmlinkage long sys_uname(struct new_utsname __user * name) | 229 | asmlinkage long sys_uname(struct new_utsname __user *name) |
| 228 | { | 230 | { |
| 229 | int err; | 231 | int err; |
| 230 | down_read(&uts_sem); | 232 | down_read(&uts_sem); |
| 231 | err = copy_to_user(name, utsname(), sizeof (*name)); | 233 | err = copy_to_user(name, utsname(), sizeof(*name)); |
| 232 | up_read(&uts_sem); | 234 | up_read(&uts_sem); |
| 233 | if (personality(current->personality) == PER_LINUX32) | 235 | if (personality(current->personality) == PER_LINUX32) |
| 234 | err |= copy_to_user(&name->machine, "i686", 5); | 236 | err |= copy_to_user(&name->machine, "i686", 5); |
| 235 | return err ? -EFAULT : 0; | 237 | return err ? -EFAULT : 0; |
| 236 | } | 238 | } |
