| .. | .. |
|---|
| 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; |
|---|