syscall.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #ifndef __ASM_SPARC_SYSCALL_H
  2. #define __ASM_SPARC_SYSCALL_H
  3. #include <uapi/linux/audit.h>
  4. #include <linux/kernel.h>
  5. #include <linux/compat.h>
  6. #include <linux/sched.h>
  7. #include <asm/ptrace.h>
  8. #include <asm/thread_info.h>
  9. /*
  10. * The syscall table always contains 32 bit pointers since we know that the
  11. * address of the function to be called is (way) below 4GB. So the "int"
  12. * type here is what we want [need] for both 32 bit and 64 bit systems.
  13. */
  14. extern const unsigned int sys_call_table[];
  15. /* The system call number is given by the user in %g1 */
  16. static inline long syscall_get_nr(struct task_struct *task,
  17. struct pt_regs *regs)
  18. {
  19. int syscall_p = pt_regs_is_syscall(regs);
  20. return (syscall_p ? regs->u_regs[UREG_G1] : -1L);
  21. }
  22. static inline void syscall_rollback(struct task_struct *task,
  23. struct pt_regs *regs)
  24. {
  25. /* XXX This needs some thought. On Sparc we don't
  26. * XXX save away the original %o0 value somewhere.
  27. * XXX Instead we hold it in register %l5 at the top
  28. * XXX level trap frame and pass this down to the signal
  29. * XXX dispatch code which is the only place that value
  30. * XXX ever was needed.
  31. */
  32. }
  33. #ifdef CONFIG_SPARC32
  34. static inline bool syscall_has_error(struct pt_regs *regs)
  35. {
  36. return (regs->psr & PSR_C) ? true : false;
  37. }
  38. static inline void syscall_set_error(struct pt_regs *regs)
  39. {
  40. regs->psr |= PSR_C;
  41. }
  42. static inline void syscall_clear_error(struct pt_regs *regs)
  43. {
  44. regs->psr &= ~PSR_C;
  45. }
  46. #else
  47. static inline bool syscall_has_error(struct pt_regs *regs)
  48. {
  49. return (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)) ? true : false;
  50. }
  51. static inline void syscall_set_error(struct pt_regs *regs)
  52. {
  53. regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY);
  54. }
  55. static inline void syscall_clear_error(struct pt_regs *regs)
  56. {
  57. regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY);
  58. }
  59. #endif
  60. static inline long syscall_get_error(struct task_struct *task,
  61. struct pt_regs *regs)
  62. {
  63. long val = regs->u_regs[UREG_I0];
  64. return (syscall_has_error(regs) ? -val : 0);
  65. }
  66. static inline long syscall_get_return_value(struct task_struct *task,
  67. struct pt_regs *regs)
  68. {
  69. long val = regs->u_regs[UREG_I0];
  70. return val;
  71. }
  72. static inline void syscall_set_return_value(struct task_struct *task,
  73. struct pt_regs *regs,
  74. int error, long val)
  75. {
  76. if (error) {
  77. syscall_set_error(regs);
  78. regs->u_regs[UREG_I0] = -error;
  79. } else {
  80. syscall_clear_error(regs);
  81. regs->u_regs[UREG_I0] = val;
  82. }
  83. }
  84. static inline void syscall_get_arguments(struct task_struct *task,
  85. struct pt_regs *regs,
  86. unsigned int i, unsigned int n,
  87. unsigned long *args)
  88. {
  89. int zero_extend = 0;
  90. unsigned int j;
  91. #ifdef CONFIG_SPARC64
  92. if (test_tsk_thread_flag(task, TIF_32BIT))
  93. zero_extend = 1;
  94. #endif
  95. for (j = 0; j < n; j++) {
  96. unsigned long val = regs->u_regs[UREG_I0 + i + j];
  97. if (zero_extend)
  98. args[j] = (u32) val;
  99. else
  100. args[j] = val;
  101. }
  102. }
  103. static inline void syscall_set_arguments(struct task_struct *task,
  104. struct pt_regs *regs,
  105. unsigned int i, unsigned int n,
  106. const unsigned long *args)
  107. {
  108. unsigned int j;
  109. for (j = 0; j < n; j++)
  110. regs->u_regs[UREG_I0 + i + j] = args[j];
  111. }
  112. static inline int syscall_get_arch(void)
  113. {
  114. #if defined(CONFIG_SPARC64) && defined(CONFIG_COMPAT)
  115. return in_compat_syscall() ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64;
  116. #elif defined(CONFIG_SPARC64)
  117. return AUDIT_ARCH_SPARC64;
  118. #else
  119. return AUDIT_ARCH_SPARC;
  120. #endif
  121. }
  122. #endif /* __ASM_SPARC_SYSCALL_H */