diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem_submit.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem_submit.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 9766f9ae4b7d..880d6a9af7c8 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c | |||
@@ -64,6 +64,14 @@ void msm_gem_submit_free(struct msm_gem_submit *submit) | |||
64 | kfree(submit); | 64 | kfree(submit); |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline unsigned long __must_check | ||
68 | copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) | ||
69 | { | ||
70 | if (access_ok(VERIFY_READ, from, n)) | ||
71 | return __copy_from_user_inatomic(to, from, n); | ||
72 | return -EFAULT; | ||
73 | } | ||
74 | |||
67 | static int submit_lookup_objects(struct msm_gem_submit *submit, | 75 | static int submit_lookup_objects(struct msm_gem_submit *submit, |
68 | struct drm_msm_gem_submit *args, struct drm_file *file) | 76 | struct drm_msm_gem_submit *args, struct drm_file *file) |
69 | { | 77 | { |
@@ -71,6 +79,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
71 | int ret = 0; | 79 | int ret = 0; |
72 | 80 | ||
73 | spin_lock(&file->table_lock); | 81 | spin_lock(&file->table_lock); |
82 | pagefault_disable(); | ||
74 | 83 | ||
75 | for (i = 0; i < args->nr_bos; i++) { | 84 | for (i = 0; i < args->nr_bos; i++) { |
76 | struct drm_msm_gem_submit_bo submit_bo; | 85 | struct drm_msm_gem_submit_bo submit_bo; |
@@ -84,10 +93,15 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
84 | */ | 93 | */ |
85 | submit->bos[i].flags = 0; | 94 | submit->bos[i].flags = 0; |
86 | 95 | ||
87 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); | 96 | ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo)); |
88 | if (ret) { | 97 | if (unlikely(ret)) { |
89 | ret = -EFAULT; | 98 | pagefault_enable(); |
90 | goto out_unlock; | 99 | spin_unlock(&file->table_lock); |
100 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); | ||
101 | if (ret) | ||
102 | goto out; | ||
103 | spin_lock(&file->table_lock); | ||
104 | pagefault_disable(); | ||
91 | } | 105 | } |
92 | 106 | ||
93 | if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { | 107 | if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { |
@@ -127,9 +141,12 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
127 | } | 141 | } |
128 | 142 | ||
129 | out_unlock: | 143 | out_unlock: |
130 | submit->nr_bos = i; | 144 | pagefault_enable(); |
131 | spin_unlock(&file->table_lock); | 145 | spin_unlock(&file->table_lock); |
132 | 146 | ||
147 | out: | ||
148 | submit->nr_bos = i; | ||
149 | |||
133 | return ret; | 150 | return ret; |
134 | } | 151 | } |
135 | 152 | ||
@@ -377,6 +394,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
377 | if (ret) | 394 | if (ret) |
378 | return ret; | 395 | return ret; |
379 | 396 | ||
397 | priv->struct_mutex_task = current; | ||
398 | |||
380 | submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); | 399 | submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); |
381 | if (!submit) { | 400 | if (!submit) { |
382 | ret = -ENOMEM; | 401 | ret = -ENOMEM; |
@@ -468,6 +487,7 @@ out: | |||
468 | if (ret) | 487 | if (ret) |
469 | msm_gem_submit_free(submit); | 488 | msm_gem_submit_free(submit); |
470 | out_unlock: | 489 | out_unlock: |
490 | priv->struct_mutex_task = NULL; | ||
471 | mutex_unlock(&dev->struct_mutex); | 491 | mutex_unlock(&dev->struct_mutex); |
472 | return ret; | 492 | return ret; |
473 | } | 493 | } |