sys_ia64.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * This file contains various system calls that have different calling
  4. * conventions on different platforms.
  5. *
  6. * Copyright (C) 1999-2000, 2002-2003, 2005 Hewlett-Packard Co
  7. * David Mosberger-Tang <davidm@hpl.hp.com>
  8. */
  9. #include <linux/errno.h>
  10. #include <linux/fs.h>
  11. #include <linux/mm.h>
  12. #include <linux/mman.h>
  13. #include <linux/sched.h>
  14. #include <linux/sched/mm.h>
  15. #include <linux/sched/task_stack.h>
  16. #include <linux/shm.h>
  17. #include <linux/file.h> /* doh, must come after sched.h... */
  18. #include <linux/smp.h>
  19. #include <linux/syscalls.h>
  20. #include <linux/highuid.h>
  21. #include <linux/hugetlb.h>
  22. #include <asm/shmparam.h>
  23. #include <linux/uaccess.h>
  24. unsigned long
  25. arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len,
  26. unsigned long pgoff, unsigned long flags)
  27. {
  28. long map_shared = (flags & MAP_SHARED);
  29. unsigned long align_mask = 0;
  30. struct mm_struct *mm = current->mm;
  31. struct vm_unmapped_area_info info;
  32. if (len > RGN_MAP_LIMIT)
  33. return -ENOMEM;
  34. /* handle fixed mapping: prevent overlap with huge pages */
  35. if (flags & MAP_FIXED) {
  36. if (is_hugepage_only_range(mm, addr, len))
  37. return -EINVAL;
  38. return addr;
  39. }
  40. #ifdef CONFIG_HUGETLB_PAGE
  41. if (REGION_NUMBER(addr) == RGN_HPAGE)
  42. addr = 0;
  43. #endif
  44. if (!addr)
  45. addr = TASK_UNMAPPED_BASE;
  46. if (map_shared && (TASK_SIZE > 0xfffffffful))
  47. /*
  48. * For 64-bit tasks, align shared segments to 1MB to avoid potential
  49. * performance penalty due to virtual aliasing (see ASDM). For 32-bit
  50. * tasks, we prefer to avoid exhausting the address space too quickly by
  51. * limiting alignment to a single page.
  52. */
  53. align_mask = PAGE_MASK & (SHMLBA - 1);
  54. info.flags = 0;
  55. info.length = len;
  56. info.low_limit = addr;
  57. info.high_limit = TASK_SIZE;
  58. info.align_mask = align_mask;
  59. info.align_offset = 0;
  60. return vm_unmapped_area(&info);
  61. }
  62. asmlinkage long
  63. ia64_getpriority (int which, int who)
  64. {
  65. long prio;
  66. prio = sys_getpriority(which, who);
  67. if (prio >= 0) {
  68. force_successful_syscall_return();
  69. prio = 20 - prio;
  70. }
  71. return prio;
  72. }
  73. /* XXX obsolete, but leave it here until the old libc is gone... */
  74. asmlinkage unsigned long
  75. sys_getpagesize (void)
  76. {
  77. return PAGE_SIZE;
  78. }
  79. asmlinkage unsigned long
  80. ia64_brk (unsigned long brk)
  81. {
  82. unsigned long retval = sys_brk(brk);
  83. force_successful_syscall_return();
  84. return retval;
  85. }
  86. /*
  87. * On IA-64, we return the two file descriptors in ret0 and ret1 (r8
  88. * and r9) as this is faster than doing a copy_to_user().
  89. */
  90. asmlinkage long
  91. sys_ia64_pipe (void)
  92. {
  93. struct pt_regs *regs = task_pt_regs(current);
  94. int fd[2];
  95. int retval;
  96. retval = do_pipe_flags(fd, 0);
  97. if (retval)
  98. goto out;
  99. retval = fd[0];
  100. regs->r9 = fd[1];
  101. out:
  102. return retval;
  103. }
  104. int ia64_mmap_check(unsigned long addr, unsigned long len,
  105. unsigned long flags)
  106. {
  107. unsigned long roff;
  108. /*
  109. * Don't permit mappings into unmapped space, the virtual page table
  110. * of a region, or across a region boundary. Note: RGN_MAP_LIMIT is
  111. * equal to 2^n-PAGE_SIZE (for some integer n <= 61) and len > 0.
  112. */
  113. roff = REGION_OFFSET(addr);
  114. if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len)))
  115. return -EINVAL;
  116. return 0;
  117. }
  118. /*
  119. * mmap2() is like mmap() except that the offset is expressed in units
  120. * of PAGE_SIZE (instead of bytes). This allows to mmap2() (pieces
  121. * of) files that are larger than the address space of the CPU.
  122. */
  123. asmlinkage unsigned long
  124. sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
  125. {
  126. addr = ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
  127. if (!IS_ERR((void *) addr))
  128. force_successful_syscall_return();
  129. return addr;
  130. }
  131. asmlinkage unsigned long
  132. sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off)
  133. {
  134. if (offset_in_page(off) != 0)
  135. return -EINVAL;
  136. addr = ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
  137. if (!IS_ERR((void *) addr))
  138. force_successful_syscall_return();
  139. return addr;
  140. }
  141. asmlinkage unsigned long
  142. ia64_mremap (unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags,
  143. unsigned long new_addr)
  144. {
  145. addr = sys_mremap(addr, old_len, new_len, flags, new_addr);
  146. if (!IS_ERR((void *) addr))
  147. force_successful_syscall_return();
  148. return addr;
  149. }
  150. #ifndef CONFIG_PCI
  151. asmlinkage long
  152. sys_pciconfig_read (unsigned long bus, unsigned long dfn, unsigned long off, unsigned long len,
  153. void *buf)
  154. {
  155. return -ENOSYS;
  156. }
  157. asmlinkage long
  158. sys_pciconfig_write (unsigned long bus, unsigned long dfn, unsigned long off, unsigned long len,
  159. void *buf)
  160. {
  161. return -ENOSYS;
  162. }
  163. #endif /* CONFIG_PCI */