compat.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Copyright 2010 Tilera Corporation. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation, version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11. * NON INFRINGEMENT. See the GNU General Public License for
  12. * more details.
  13. */
  14. /* Adjust unistd.h to provide 32-bit numbers and functions. */
  15. #define __SYSCALL_COMPAT
  16. #include <linux/compat.h>
  17. #include <linux/syscalls.h>
  18. #include <linux/kdev_t.h>
  19. #include <linux/fs.h>
  20. #include <linux/fcntl.h>
  21. #include <linux/uaccess.h>
  22. #include <linux/signal.h>
  23. #include <asm/syscalls.h>
  24. /*
  25. * Syscalls that take 64-bit numbers traditionally take them in 32-bit
  26. * "high" and "low" value parts on 32-bit architectures.
  27. * In principle, one could imagine passing some register arguments as
  28. * fully 64-bit on TILE-Gx in 32-bit mode, but it seems easier to
  29. * adapt the usual convention.
  30. */
  31. COMPAT_SYSCALL_DEFINE4(truncate64, char __user *, filename, u32, dummy,
  32. u32, low, u32, high)
  33. {
  34. return sys_truncate(filename, ((loff_t)high << 32) | low);
  35. }
  36. COMPAT_SYSCALL_DEFINE4(ftruncate64, unsigned int, fd, u32, dummy,
  37. u32, low, u32, high)
  38. {
  39. return sys_ftruncate(fd, ((loff_t)high << 32) | low);
  40. }
  41. COMPAT_SYSCALL_DEFINE6(pread64, unsigned int, fd, char __user *, ubuf,
  42. size_t, count, u32, dummy, u32, low, u32, high)
  43. {
  44. return sys_pread64(fd, ubuf, count, ((loff_t)high << 32) | low);
  45. }
  46. COMPAT_SYSCALL_DEFINE6(pwrite64, unsigned int, fd, char __user *, ubuf,
  47. size_t, count, u32, dummy, u32, low, u32, high)
  48. {
  49. return sys_pwrite64(fd, ubuf, count, ((loff_t)high << 32) | low);
  50. }
  51. COMPAT_SYSCALL_DEFINE4(lookup_dcookie, u32, low, u32, high,
  52. char __user *, buf, size_t, len)
  53. {
  54. return sys_lookup_dcookie(((loff_t)high << 32) | low, buf, len);
  55. }
  56. COMPAT_SYSCALL_DEFINE6(sync_file_range2, int, fd, unsigned int, flags,
  57. u32, offset_lo, u32, offset_hi,
  58. u32, nbytes_lo, u32, nbytes_hi)
  59. {
  60. return sys_sync_file_range(fd, ((loff_t)offset_hi << 32) | offset_lo,
  61. ((loff_t)nbytes_hi << 32) | nbytes_lo,
  62. flags);
  63. }
  64. COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode,
  65. u32, offset_lo, u32, offset_hi,
  66. u32, len_lo, u32, len_hi)
  67. {
  68. return sys_fallocate(fd, mode, ((loff_t)offset_hi << 32) | offset_lo,
  69. ((loff_t)len_hi << 32) | len_lo);
  70. }
  71. /*
  72. * Avoid bug in generic sys_llseek() that specifies offset_high and
  73. * offset_low as "unsigned long", thus making it possible to pass
  74. * a sign-extended high 32 bits in offset_low.
  75. */
  76. COMPAT_SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned int, offset_high,
  77. unsigned int, offset_low, loff_t __user *, result,
  78. unsigned int, origin)
  79. {
  80. return sys_llseek(fd, offset_high, offset_low, result, origin);
  81. }
  82. /* Provide the compat syscall number to call mapping. */
  83. #undef __SYSCALL
  84. #define __SYSCALL(nr, call) [nr] = (call),
  85. /* See comments in sys.c */
  86. #define compat_sys_fadvise64_64 sys32_fadvise64_64
  87. #define compat_sys_readahead sys32_readahead
  88. #define sys_llseek compat_sys_llseek
  89. /* Call the assembly trampolines where necessary. */
  90. #define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn
  91. #define sys_clone _sys_clone
  92. /*
  93. * Note that we can't include <linux/unistd.h> here since the header
  94. * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
  95. */
  96. void *compat_sys_call_table[__NR_syscalls] = {
  97. [0 ... __NR_syscalls-1] = sys_ni_syscall,
  98. #include <asm/unistd.h>
  99. };