home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / x86 / include / asm / syscall.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  4.3 KB  |  214 lines

  1. /*
  2.  * Access to user system call parameters and results
  3.  *
  4.  * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
  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.  
  13. #ifndef _ASM_X86_SYSCALL_H
  14. #define _ASM_X86_SYSCALL_H
  15.  
  16. #include <linux/sched.h>
  17. #include <linux/err.h>
  18.  
  19. static inline long syscall_get_nr(struct task_struct *task,
  20.                   struct pt_regs *regs)
  21. {
  22.     /*
  23.      * We always sign-extend a -1 value being set here,
  24.      * so this is always either -1L or a syscall number.
  25.      */
  26.     return regs->orig_ax;
  27. }
  28.  
  29. static inline void syscall_rollback(struct task_struct *task,
  30.                     struct pt_regs *regs)
  31. {
  32.     regs->ax = regs->orig_ax;
  33. }
  34.  
  35. static inline long syscall_get_error(struct task_struct *task,
  36.                      struct pt_regs *regs)
  37. {
  38.     unsigned long error = regs->ax;
  39. #ifdef CONFIG_IA32_EMULATION
  40.     /*
  41.      * TS_COMPAT is set for 32-bit syscall entries and then
  42.      * remains set until we return to user mode.
  43.      */
  44.     if (task_thread_info(task)->status & TS_COMPAT)
  45.         /*
  46.          * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
  47.          * and will match correctly in comparisons.
  48.          */
  49.         error = (long) (int) error;
  50. #endif
  51.     return IS_ERR_VALUE(error) ? error : 0;
  52. }
  53.  
  54. static inline long syscall_get_return_value(struct task_struct *task,
  55.                         struct pt_regs *regs)
  56. {
  57.     return regs->ax;
  58. }
  59.  
  60. static inline void syscall_set_return_value(struct task_struct *task,
  61.                         struct pt_regs *regs,
  62.                         int error, long val)
  63. {
  64.     regs->ax = (long) error ?: val;
  65. }
  66.  
  67. #ifdef CONFIG_X86_32
  68.  
  69. static inline void syscall_get_arguments(struct task_struct *task,
  70.                      struct pt_regs *regs,
  71.                      unsigned int i, unsigned int n,
  72.                      unsigned long *args)
  73. {
  74.     BUG_ON(i + n > 6);
  75.     memcpy(args, ®s->bx + i, n * sizeof(args[0]));
  76. }
  77.  
  78. static inline void syscall_set_arguments(struct task_struct *task,
  79.                      struct pt_regs *regs,
  80.                      unsigned int i, unsigned int n,
  81.                      const unsigned long *args)
  82. {
  83.     BUG_ON(i + n > 6);
  84.     memcpy(®s->bx + i, args, n * sizeof(args[0]));
  85. }
  86.  
  87. #else     /* CONFIG_X86_64 */
  88.  
  89. static inline void syscall_get_arguments(struct task_struct *task,
  90.                      struct pt_regs *regs,
  91.                      unsigned int i, unsigned int n,
  92.                      unsigned long *args)
  93. {
  94. # ifdef CONFIG_IA32_EMULATION
  95.     if (task_thread_info(task)->status & TS_COMPAT)
  96.         switch (i) {
  97.         case 0:
  98.             if (!n--) break;
  99.             *args++ = regs->bx;
  100.         case 1:
  101.             if (!n--) break;
  102.             *args++ = regs->cx;
  103.         case 2:
  104.             if (!n--) break;
  105.             *args++ = regs->dx;
  106.         case 3:
  107.             if (!n--) break;
  108.             *args++ = regs->si;
  109.         case 4:
  110.             if (!n--) break;
  111.             *args++ = regs->di;
  112.         case 5:
  113.             if (!n--) break;
  114.             *args++ = regs->bp;
  115.         case 6:
  116.             if (!n--) break;
  117.         default:
  118.             BUG();
  119.             break;
  120.         }
  121.     else
  122. # endif
  123.         switch (i) {
  124.         case 0:
  125.             if (!n--) break;
  126.             *args++ = regs->di;
  127.         case 1:
  128.             if (!n--) break;
  129.             *args++ = regs->si;
  130.         case 2:
  131.             if (!n--) break;
  132.             *args++ = regs->dx;
  133.         case 3:
  134.             if (!n--) break;
  135.             *args++ = regs->r10;
  136.         case 4:
  137.             if (!n--) break;
  138.             *args++ = regs->r8;
  139.         case 5:
  140.             if (!n--) break;
  141.             *args++ = regs->r9;
  142.         case 6:
  143.             if (!n--) break;
  144.         default:
  145.             BUG();
  146.             break;
  147.         }
  148. }
  149.  
  150. static inline void syscall_set_arguments(struct task_struct *task,
  151.                      struct pt_regs *regs,
  152.                      unsigned int i, unsigned int n,
  153.                      const unsigned long *args)
  154. {
  155. # ifdef CONFIG_IA32_EMULATION
  156.     if (task_thread_info(task)->status & TS_COMPAT)
  157.         switch (i) {
  158.         case 0:
  159.             if (!n--) break;
  160.             regs->bx = *args++;
  161.         case 1:
  162.             if (!n--) break;
  163.             regs->cx = *args++;
  164.         case 2:
  165.             if (!n--) break;
  166.             regs->dx = *args++;
  167.         case 3:
  168.             if (!n--) break;
  169.             regs->si = *args++;
  170.         case 4:
  171.             if (!n--) break;
  172.             regs->di = *args++;
  173.         case 5:
  174.             if (!n--) break;
  175.             regs->bp = *args++;
  176.         case 6:
  177.             if (!n--) break;
  178.         default:
  179.             BUG();
  180.             break;
  181.         }
  182.     else
  183. # endif
  184.         switch (i) {
  185.         case 0:
  186.             if (!n--) break;
  187.             regs->di = *args++;
  188.         case 1:
  189.             if (!n--) break;
  190.             regs->si = *args++;
  191.         case 2:
  192.             if (!n--) break;
  193.             regs->dx = *args++;
  194.         case 3:
  195.             if (!n--) break;
  196.             regs->r10 = *args++;
  197.         case 4:
  198.             if (!n--) break;
  199.             regs->r8 = *args++;
  200.         case 5:
  201.             if (!n--) break;
  202.             regs->r9 = *args++;
  203.         case 6:
  204.             if (!n--) break;
  205.         default:
  206.             BUG();
  207.             break;
  208.         }
  209. }
  210.  
  211. #endif    /* CONFIG_X86_32 */
  212.  
  213. #endif    /* _ASM_X86_SYSCALL_H */
  214.