syscall.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Access to user system call parameters and results
  3. *
  4. * Copyright (C) 2008 Intel Corp. Shaohua Li <shaohua.li@intel.com>
  5. *
  6. * This copyrighted material is made available to anyone wishing to use,
  7. * modify, copy, or redistribute it subject to the terms and conditions
  8. * of the GNU General Public License v.2.
  9. *
  10. * See asm-generic/syscall.h for descriptions of what we must do here.
  11. */
  12. #ifndef _ASM_SYSCALL_H
  13. #define _ASM_SYSCALL_H 1
  14. #include <linux/sched.h>
  15. #include <linux/err.h>
  16. static inline long syscall_get_nr(struct task_struct *task,
  17. struct pt_regs *regs)
  18. {
  19. if ((long)regs->cr_ifs < 0) /* Not a syscall */
  20. return -1;
  21. #ifdef CONFIG_IA32_SUPPORT
  22. if (IS_IA32_PROCESS(regs))
  23. return regs->r1;
  24. #endif
  25. return regs->r15;
  26. }
  27. static inline void syscall_rollback(struct task_struct *task,
  28. struct pt_regs *regs)
  29. {
  30. #ifdef CONFIG_IA32_SUPPORT
  31. if (IS_IA32_PROCESS(regs))
  32. regs->r8 = regs->r1;
  33. #endif
  34. /* do nothing */
  35. }
  36. static inline long syscall_get_error(struct task_struct *task,
  37. struct pt_regs *regs)
  38. {
  39. #ifdef CONFIG_IA32_SUPPORT
  40. if (IS_IA32_PROCESS(regs))
  41. return regs->r8;
  42. #endif
  43. return regs->r10 == -1 ? regs->r8:0;
  44. }
  45. static inline long syscall_get_return_value(struct task_struct *task,
  46. struct pt_regs *regs)
  47. {
  48. return regs->r8;
  49. }
  50. static inline void syscall_set_return_value(struct task_struct *task,
  51. struct pt_regs *regs,
  52. int error, long val)
  53. {
  54. #ifdef CONFIG_IA32_SUPPORT
  55. if (IS_IA32_PROCESS(regs)) {
  56. regs->r8 = (long) error ? error : val;
  57. return;
  58. }
  59. #endif
  60. if (error) {
  61. /* error < 0, but ia64 uses > 0 return value */
  62. regs->r8 = -error;
  63. regs->r10 = -1;
  64. } else {
  65. regs->r8 = val;
  66. regs->r10 = 0;
  67. }
  68. }
  69. extern void ia64_syscall_get_set_arguments(struct task_struct *task,
  70. struct pt_regs *regs, unsigned int i, unsigned int n,
  71. unsigned long *args, int rw);
  72. static inline void syscall_get_arguments(struct task_struct *task,
  73. struct pt_regs *regs,
  74. unsigned int i, unsigned int n,
  75. unsigned long *args)
  76. {
  77. BUG_ON(i + n > 6);
  78. #ifdef CONFIG_IA32_SUPPORT
  79. if (IS_IA32_PROCESS(regs)) {
  80. switch (i + n) {
  81. case 6:
  82. if (!n--) break;
  83. *args++ = regs->r13;
  84. case 5:
  85. if (!n--) break;
  86. *args++ = regs->r15;
  87. case 4:
  88. if (!n--) break;
  89. *args++ = regs->r14;
  90. case 3:
  91. if (!n--) break;
  92. *args++ = regs->r10;
  93. case 2:
  94. if (!n--) break;
  95. *args++ = regs->r9;
  96. case 1:
  97. if (!n--) break;
  98. *args++ = regs->r11;
  99. case 0:
  100. if (!n--) break;
  101. default:
  102. BUG();
  103. break;
  104. }
  105. return;
  106. }
  107. #endif
  108. ia64_syscall_get_set_arguments(task, regs, i, n, args, 0);
  109. }
  110. static inline void syscall_set_arguments(struct task_struct *task,
  111. struct pt_regs *regs,
  112. unsigned int i, unsigned int n,
  113. unsigned long *args)
  114. {
  115. BUG_ON(i + n > 6);
  116. #ifdef CONFIG_IA32_SUPPORT
  117. if (IS_IA32_PROCESS(regs)) {
  118. switch (i + n) {
  119. case 6:
  120. if (!n--) break;
  121. regs->r13 = *args++;
  122. case 5:
  123. if (!n--) break;
  124. regs->r15 = *args++;
  125. case 4:
  126. if (!n--) break;
  127. regs->r14 = *args++;
  128. case 3:
  129. if (!n--) break;
  130. regs->r10 = *args++;
  131. case 2:
  132. if (!n--) break;
  133. regs->r9 = *args++;
  134. case 1:
  135. if (!n--) break;
  136. regs->r11 = *args++;
  137. case 0:
  138. if (!n--) break;
  139. }
  140. return;
  141. }
  142. #endif
  143. ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
  144. }
  145. #endif /* _ASM_SYSCALL_H */