.. | .. |
---|
89 | 89 | { |
---|
90 | 90 | void *reloc_page; |
---|
91 | 91 | |
---|
92 | | - reloc_page = qxl_bo_kmap_local_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK); |
---|
| 92 | + reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK); |
---|
93 | 93 | *(uint64_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = qxl_bo_physical_address(qdev, |
---|
94 | 94 | info->src_bo, |
---|
95 | 95 | info->src_offset); |
---|
96 | | - qxl_bo_kunmap_local_page(qdev, info->dst_bo, reloc_page); |
---|
| 96 | + qxl_bo_kunmap_atomic_page(qdev, info->dst_bo, reloc_page); |
---|
97 | 97 | } |
---|
98 | 98 | |
---|
99 | 99 | static void |
---|
.. | .. |
---|
105 | 105 | if (info->src_bo && !info->src_bo->is_primary) |
---|
106 | 106 | id = info->src_bo->surface_id; |
---|
107 | 107 | |
---|
108 | | - reloc_page = qxl_bo_kmap_local_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK); |
---|
| 108 | + reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK); |
---|
109 | 109 | *(uint32_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = id; |
---|
110 | | - qxl_bo_kunmap_local_page(qdev, info->dst_bo, reloc_page); |
---|
| 110 | + qxl_bo_kunmap_atomic_page(qdev, info->dst_bo, reloc_page); |
---|
111 | 111 | } |
---|
112 | 112 | |
---|
113 | 113 | /* return holding the reference to this object */ |
---|
.. | .. |
---|
149 | 149 | struct qxl_bo *cmd_bo; |
---|
150 | 150 | void *fb_cmd; |
---|
151 | 151 | int i, ret, num_relocs; |
---|
| 152 | + int unwritten; |
---|
152 | 153 | |
---|
153 | 154 | switch (cmd->type) { |
---|
154 | 155 | case QXL_CMD_DRAW: |
---|
.. | .. |
---|
184 | 185 | goto out_free_reloc; |
---|
185 | 186 | |
---|
186 | 187 | /* TODO copy slow path code from i915 */ |
---|
187 | | - fb_cmd = qxl_bo_kmap_local_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK)); |
---|
| 188 | + fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK)); |
---|
| 189 | + unwritten = __copy_from_user_inatomic_nocache |
---|
| 190 | + (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_MASK), |
---|
| 191 | + u64_to_user_ptr(cmd->command), cmd->command_size); |
---|
188 | 192 | |
---|
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 { |
---|
| 193 | + { |
---|
194 | 194 | struct qxl_drawable *draw = fb_cmd; |
---|
195 | 195 | |
---|
196 | 196 | draw->mm_time = qdev->rom->mm_clock; |
---|
197 | 197 | } |
---|
198 | 198 | |
---|
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 | + qxl_bo_kunmap_atomic_page(qdev, cmd_bo, fb_cmd); |
---|
| 200 | + if (unwritten) { |
---|
| 201 | + DRM_ERROR("got unwritten %d\n", unwritten); |
---|
| 202 | + ret = -EFAULT; |
---|
202 | 203 | goto out_free_release; |
---|
203 | 204 | } |
---|
204 | 205 | |
---|