mt_compat_sched.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include <linux/compat.h>
  2. #include <linux/fs.h>
  3. #include <linux/uaccess.h>
  4. #include "mt_sched_drv.h"
  5. #ifdef CONFIG_COMPAT
  6. struct compat_ioctl_arg {
  7. compat_int_t pid;
  8. compat_uint_t len;
  9. compat_uptr_t mask;
  10. compat_uptr_t mt_mask;
  11. };
  12. #define COMPAT_IOCTL_SETAFFINITY _IOW(IOC_MAGIC, 0, struct compat_ioctl_arg)
  13. #define COMPAT_IOCTL_GETAFFINITY _IOR(IOC_MAGIC, 2, struct compat_ioctl_arg)
  14. static int compat_get_sched_allocation_data(
  15. struct compat_ioctl_arg __user *data32,
  16. struct ioctl_arg __user *data)
  17. {
  18. compat_int_t i;
  19. compat_uint_t u;
  20. compat_uptr_t p;
  21. int err;
  22. err = get_user(i, &data32->pid);
  23. err |= put_user(i, &data->pid);
  24. err |= get_user(u, &data32->len);
  25. err |= put_user(u, &data->len);
  26. err |= get_user(p, &data32->mask);
  27. err |= put_user(compat_ptr(p), &data->mask);
  28. err |= get_user(p, &data32->mt_mask);
  29. err |= put_user(compat_ptr(p), &data->mt_mask);
  30. return err;
  31. }
  32. static int compat_put_sched_allocation_data(
  33. struct compat_ioctl_arg __user *data32,
  34. struct ioctl_arg __user *data)
  35. {
  36. pid_t i;
  37. unsigned int u;
  38. unsigned long *p;
  39. int err;
  40. err = get_user(i, &data->pid);
  41. err |= put_user(i, &data32->pid);
  42. err |= get_user(u, &data->len);
  43. err |= put_user(u, &data32->len);
  44. err |= get_user(p, &data->mask);
  45. err |= put_user(ptr_to_compat(p), &data32->mask);
  46. err |= get_user(p, &data->mt_mask);
  47. err |= put_user(ptr_to_compat(p), &data32->mt_mask);
  48. return err;
  49. }
  50. long sched_ioctl_compat(struct file *filp, unsigned int cmd, unsigned long arg)
  51. {
  52. long ret;
  53. if (!filp->f_op || !filp->f_op->unlocked_ioctl)
  54. return -ENOTTY;
  55. switch (cmd) {
  56. case COMPAT_IOCTL_SETAFFINITY:
  57. {
  58. struct compat_ioctl_arg __user *data32;
  59. struct ioctl_arg __user *data;
  60. int err;
  61. data32 = compat_ptr(arg);
  62. data = compat_alloc_user_space(sizeof(*data));
  63. if (data == NULL)
  64. return -EFAULT;
  65. err = compat_get_sched_allocation_data(data32, data);
  66. if (err)
  67. return err;
  68. #if MT_SCHED_AFFININTY_DEBUG
  69. pr_debug("MT_SCHED: %s [COMPAT_IOCTL_SETAFFINITY]\n", __func__);
  70. #endif
  71. return filp->f_op->unlocked_ioctl(filp, IOCTL_SETAFFINITY, (unsigned long)data);
  72. }
  73. case COMPAT_IOCTL_GETAFFINITY:
  74. {
  75. struct compat_ioctl_arg __user *data32;
  76. struct ioctl_arg __user *data;
  77. int err;
  78. data32 = compat_ptr(arg);
  79. data = compat_alloc_user_space(sizeof(*data));
  80. if (data == NULL)
  81. return -EFAULT;
  82. err = compat_get_sched_allocation_data(data32, data);
  83. if (err)
  84. return err;
  85. #if MT_SCHED_AFFININTY_DEBUG
  86. pr_debug("MT_SCHED: %s [COMPAT_IOCTL_GETAFFINITY]\n", __func__);
  87. #endif
  88. ret = filp->f_op->unlocked_ioctl(filp, IOCTL_GETAFFINITY, (unsigned long)data);
  89. err = compat_put_sched_allocation_data(data32, data);
  90. return ret ? ret : err;
  91. }
  92. case IOCTL_EXITAFFINITY:
  93. #if MT_SCHED_AFFININTY_DEBUG
  94. pr_debug("MT_SCHED: %s [IOCTL_EXITAFFINITY]\n", __func__);
  95. #endif
  96. return filp->f_op->unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
  97. default:
  98. return -ENOIOCTLCMD;
  99. }
  100. }
  101. #endif