syscall.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Access to user system call parameters and results
  3. *
  4. * Copyright IBM Corp. 2008
  5. * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License (version 2 only)
  9. * as published by the Free Software Foundation.
  10. */
  11. #ifndef _ASM_SYSCALL_H
  12. #define _ASM_SYSCALL_H 1
  13. #include <linux/sched.h>
  14. #include <asm/ptrace.h>
  15. static inline long syscall_get_nr(struct task_struct *task,
  16. struct pt_regs *regs)
  17. {
  18. return regs->svcnr ? regs->svcnr : -1;
  19. }
  20. static inline void syscall_rollback(struct task_struct *task,
  21. struct pt_regs *regs)
  22. {
  23. regs->gprs[2] = regs->orig_gpr2;
  24. }
  25. static inline long syscall_get_error(struct task_struct *task,
  26. struct pt_regs *regs)
  27. {
  28. return (regs->gprs[2] >= -4096UL) ? -regs->gprs[2] : 0;
  29. }
  30. static inline long syscall_get_return_value(struct task_struct *task,
  31. struct pt_regs *regs)
  32. {
  33. return regs->gprs[2];
  34. }
  35. static inline void syscall_set_return_value(struct task_struct *task,
  36. struct pt_regs *regs,
  37. int error, long val)
  38. {
  39. regs->gprs[2] = error ? -error : val;
  40. }
  41. static inline void syscall_get_arguments(struct task_struct *task,
  42. struct pt_regs *regs,
  43. unsigned int i, unsigned int n,
  44. unsigned long *args)
  45. {
  46. unsigned long mask = -1UL;
  47. BUG_ON(i + n > 6);
  48. #ifdef CONFIG_COMPAT
  49. if (test_tsk_thread_flag(task, TIF_31BIT))
  50. mask = 0xffffffff;
  51. #endif
  52. if (i + n == 6)
  53. args[--n] = regs->args[0] & mask;
  54. while (n-- > 0)
  55. if (i + n > 0)
  56. args[n] = regs->gprs[2 + i + n] & mask;
  57. if (i == 0)
  58. args[0] = regs->orig_gpr2 & mask;
  59. }
  60. static inline void syscall_set_arguments(struct task_struct *task,
  61. struct pt_regs *regs,
  62. unsigned int i, unsigned int n,
  63. const unsigned long *args)
  64. {
  65. BUG_ON(i + n > 6);
  66. if (i + n == 6)
  67. regs->args[0] = args[--n];
  68. while (n-- > 0)
  69. if (i + n > 0)
  70. regs->gprs[2 + i + n] = args[n];
  71. if (i == 0)
  72. regs->orig_gpr2 = args[0];
  73. }
  74. #endif /* _ASM_SYSCALL_H */