diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem_submit.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem_submit.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index cd0554f68316..4ff8c334e7c8 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c | |||
@@ -55,6 +55,14 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, | |||
55 | return submit; | 55 | return submit; |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline unsigned long __must_check | ||
59 | copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) | ||
60 | { | ||
61 | if (access_ok(VERIFY_READ, from, n)) | ||
62 | return __copy_from_user_inatomic(to, from, n); | ||
63 | return -EFAULT; | ||
64 | } | ||
65 | |||
58 | static int submit_lookup_objects(struct msm_gem_submit *submit, | 66 | static int submit_lookup_objects(struct msm_gem_submit *submit, |
59 | struct drm_msm_gem_submit *args, struct drm_file *file) | 67 | struct drm_msm_gem_submit *args, struct drm_file *file) |
60 | { | 68 | { |
@@ -62,6 +70,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
62 | int ret = 0; | 70 | int ret = 0; |
63 | 71 | ||
64 | spin_lock(&file->table_lock); | 72 | spin_lock(&file->table_lock); |
73 | pagefault_disable(); | ||
65 | 74 | ||
66 | for (i = 0; i < args->nr_bos; i++) { | 75 | for (i = 0; i < args->nr_bos; i++) { |
67 | struct drm_msm_gem_submit_bo submit_bo; | 76 | struct drm_msm_gem_submit_bo submit_bo; |
@@ -70,10 +79,15 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
70 | void __user *userptr = | 79 | void __user *userptr = |
71 | to_user_ptr(args->bos + (i * sizeof(submit_bo))); | 80 | to_user_ptr(args->bos + (i * sizeof(submit_bo))); |
72 | 81 | ||
73 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); | 82 | ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo)); |
74 | if (ret) { | 83 | if (unlikely(ret)) { |
75 | ret = -EFAULT; | 84 | pagefault_enable(); |
76 | goto out_unlock; | 85 | spin_unlock(&file->table_lock); |
86 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); | ||
87 | if (ret) | ||
88 | goto out; | ||
89 | spin_lock(&file->table_lock); | ||
90 | pagefault_disable(); | ||
77 | } | 91 | } |
78 | 92 | ||
79 | if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { | 93 | if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { |
@@ -113,9 +127,12 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
113 | } | 127 | } |
114 | 128 | ||
115 | out_unlock: | 129 | out_unlock: |
116 | submit->nr_bos = i; | 130 | pagefault_enable(); |
117 | spin_unlock(&file->table_lock); | 131 | spin_unlock(&file->table_lock); |
118 | 132 | ||
133 | out: | ||
134 | submit->nr_bos = i; | ||
135 | |||
119 | return ret; | 136 | return ret; |
120 | } | 137 | } |
121 | 138 | ||