.. | .. |
---|
23 | 23 | * Alon Levy |
---|
24 | 24 | */ |
---|
25 | 25 | |
---|
| 26 | +#include <linux/pci.h> |
---|
| 27 | +#include <linux/uaccess.h> |
---|
| 28 | + |
---|
26 | 29 | #include "qxl_drv.h" |
---|
27 | 30 | #include "qxl_object.h" |
---|
28 | 31 | |
---|
.. | .. |
---|
33 | 36 | static int qxl_alloc_ioctl(struct drm_device *dev, void *data, |
---|
34 | 37 | struct drm_file *file_priv) |
---|
35 | 38 | { |
---|
36 | | - struct qxl_device *qdev = dev->dev_private; |
---|
| 39 | + struct qxl_device *qdev = to_qxl(dev); |
---|
37 | 40 | struct drm_qxl_alloc *qxl_alloc = data; |
---|
38 | 41 | int ret; |
---|
39 | 42 | struct qxl_bo *qobj; |
---|
.. | .. |
---|
61 | 64 | static int qxl_map_ioctl(struct drm_device *dev, void *data, |
---|
62 | 65 | struct drm_file *file_priv) |
---|
63 | 66 | { |
---|
64 | | - struct qxl_device *qdev = dev->dev_private; |
---|
| 67 | + struct qxl_device *qdev = to_qxl(dev); |
---|
65 | 68 | struct drm_qxl_map *qxl_map = data; |
---|
66 | 69 | |
---|
67 | 70 | return qxl_mode_dumb_mmap(file_priv, &qdev->ddev, qxl_map->handle, |
---|
.. | .. |
---|
85 | 88 | apply_reloc(struct qxl_device *qdev, struct qxl_reloc_info *info) |
---|
86 | 89 | { |
---|
87 | 90 | void *reloc_page; |
---|
88 | | - reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK); |
---|
| 91 | + |
---|
| 92 | + reloc_page = qxl_bo_kmap_local_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK); |
---|
89 | 93 | *(uint64_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = qxl_bo_physical_address(qdev, |
---|
90 | 94 | info->src_bo, |
---|
91 | 95 | info->src_offset); |
---|
92 | | - qxl_bo_kunmap_atomic_page(qdev, info->dst_bo, reloc_page); |
---|
| 96 | + qxl_bo_kunmap_local_page(qdev, info->dst_bo, reloc_page); |
---|
93 | 97 | } |
---|
94 | 98 | |
---|
95 | 99 | static void |
---|
.. | .. |
---|
101 | 105 | if (info->src_bo && !info->src_bo->is_primary) |
---|
102 | 106 | id = info->src_bo->surface_id; |
---|
103 | 107 | |
---|
104 | | - reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK); |
---|
| 108 | + reloc_page = qxl_bo_kmap_local_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK); |
---|
105 | 109 | *(uint32_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = id; |
---|
106 | | - qxl_bo_kunmap_atomic_page(qdev, info->dst_bo, reloc_page); |
---|
| 110 | + qxl_bo_kunmap_local_page(qdev, info->dst_bo, reloc_page); |
---|
107 | 111 | } |
---|
108 | 112 | |
---|
109 | 113 | /* return holding the reference to this object */ |
---|
.. | .. |
---|
121 | 125 | qobj = gem_to_qxl_bo(gobj); |
---|
122 | 126 | |
---|
123 | 127 | ret = qxl_release_list_add(release, qobj); |
---|
124 | | - drm_gem_object_put_unlocked(gobj); |
---|
| 128 | + drm_gem_object_put(gobj); |
---|
125 | 129 | if (ret) |
---|
126 | 130 | return ret; |
---|
127 | 131 | |
---|
.. | .. |
---|
145 | 149 | struct qxl_bo *cmd_bo; |
---|
146 | 150 | void *fb_cmd; |
---|
147 | 151 | int i, ret, num_relocs; |
---|
148 | | - int unwritten; |
---|
149 | 152 | |
---|
150 | 153 | switch (cmd->type) { |
---|
151 | 154 | case QXL_CMD_DRAW: |
---|
.. | .. |
---|
162 | 165 | if (cmd->command_size > PAGE_SIZE - sizeof(union qxl_release_info)) |
---|
163 | 166 | return -EINVAL; |
---|
164 | 167 | |
---|
165 | | - if (!access_ok(VERIFY_READ, |
---|
166 | | - u64_to_user_ptr(cmd->command), |
---|
| 168 | + if (!access_ok(u64_to_user_ptr(cmd->command), |
---|
167 | 169 | cmd->command_size)) |
---|
168 | 170 | return -EFAULT; |
---|
169 | 171 | |
---|
.. | .. |
---|
182 | 184 | goto out_free_reloc; |
---|
183 | 185 | |
---|
184 | 186 | /* TODO copy slow path code from i915 */ |
---|
185 | | - fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK)); |
---|
186 | | - unwritten = __copy_from_user_inatomic_nocache |
---|
187 | | - (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_MASK), |
---|
188 | | - u64_to_user_ptr(cmd->command), cmd->command_size); |
---|
| 187 | + fb_cmd = qxl_bo_kmap_local_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK)); |
---|
189 | 188 | |
---|
190 | | - { |
---|
| 189 | + if (copy_from_user(fb_cmd + sizeof(union qxl_release_info) + |
---|
| 190 | + (release->release_offset & ~PAGE_MASK), |
---|
| 191 | + u64_to_user_ptr(cmd->command), cmd->command_size)) { |
---|
| 192 | + ret = -EFAULT; |
---|
| 193 | + } else { |
---|
191 | 194 | struct qxl_drawable *draw = fb_cmd; |
---|
| 195 | + |
---|
192 | 196 | draw->mm_time = qdev->rom->mm_clock; |
---|
193 | 197 | } |
---|
194 | 198 | |
---|
195 | | - qxl_bo_kunmap_atomic_page(qdev, cmd_bo, fb_cmd); |
---|
196 | | - if (unwritten) { |
---|
197 | | - DRM_ERROR("got unwritten %d\n", unwritten); |
---|
198 | | - ret = -EFAULT; |
---|
| 199 | + qxl_bo_kunmap_local_page(qdev, cmd_bo, fb_cmd); |
---|
| 200 | + if (ret) { |
---|
| 201 | + DRM_ERROR("copy from user failed %d\n", ret); |
---|
199 | 202 | goto out_free_release; |
---|
200 | 203 | } |
---|
201 | 204 | |
---|
.. | .. |
---|
272 | 275 | static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data, |
---|
273 | 276 | struct drm_file *file_priv) |
---|
274 | 277 | { |
---|
275 | | - struct qxl_device *qdev = dev->dev_private; |
---|
| 278 | + struct qxl_device *qdev = to_qxl(dev); |
---|
276 | 279 | struct drm_qxl_execbuffer *execbuffer = data; |
---|
277 | 280 | struct drm_qxl_command user_cmd; |
---|
278 | 281 | int cmd_num; |
---|
.. | .. |
---|
297 | 300 | static int qxl_update_area_ioctl(struct drm_device *dev, void *data, |
---|
298 | 301 | struct drm_file *file) |
---|
299 | 302 | { |
---|
300 | | - struct qxl_device *qdev = dev->dev_private; |
---|
| 303 | + struct qxl_device *qdev = to_qxl(dev); |
---|
301 | 304 | struct drm_qxl_update_area *update_area = data; |
---|
302 | 305 | struct qxl_rect area = {.left = update_area->left, |
---|
303 | 306 | .top = update_area->top, |
---|
.. | .. |
---|
318 | 321 | |
---|
319 | 322 | qobj = gem_to_qxl_bo(gobj); |
---|
320 | 323 | |
---|
321 | | - ret = qxl_bo_reserve(qobj, false); |
---|
| 324 | + ret = qxl_bo_reserve(qobj); |
---|
322 | 325 | if (ret) |
---|
323 | 326 | goto out; |
---|
324 | 327 | |
---|
.. | .. |
---|
340 | 343 | qxl_bo_unreserve(qobj); |
---|
341 | 344 | |
---|
342 | 345 | out: |
---|
343 | | - drm_gem_object_put_unlocked(gobj); |
---|
| 346 | + drm_gem_object_put(gobj); |
---|
344 | 347 | return ret; |
---|
345 | 348 | } |
---|
346 | 349 | |
---|
347 | 350 | static int qxl_getparam_ioctl(struct drm_device *dev, void *data, |
---|
348 | 351 | struct drm_file *file_priv) |
---|
349 | 352 | { |
---|
350 | | - struct qxl_device *qdev = dev->dev_private; |
---|
| 353 | + struct qxl_device *qdev = to_qxl(dev); |
---|
351 | 354 | struct drm_qxl_getparam *param = data; |
---|
352 | 355 | |
---|
353 | 356 | switch (param->param) { |
---|
.. | .. |
---|
366 | 369 | static int qxl_clientcap_ioctl(struct drm_device *dev, void *data, |
---|
367 | 370 | struct drm_file *file_priv) |
---|
368 | 371 | { |
---|
369 | | - struct qxl_device *qdev = dev->dev_private; |
---|
| 372 | + struct qxl_device *qdev = to_qxl(dev); |
---|
370 | 373 | struct drm_qxl_clientcap *param = data; |
---|
371 | 374 | int byte, idx; |
---|
372 | 375 | |
---|
.. | .. |
---|
387 | 390 | static int qxl_alloc_surf_ioctl(struct drm_device *dev, void *data, |
---|
388 | 391 | struct drm_file *file) |
---|
389 | 392 | { |
---|
390 | | - struct qxl_device *qdev = dev->dev_private; |
---|
| 393 | + struct qxl_device *qdev = to_qxl(dev); |
---|
391 | 394 | struct drm_qxl_alloc_surf *param = data; |
---|
392 | 395 | struct qxl_bo *qobj; |
---|
393 | 396 | int handle; |
---|