Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-fixes-2019-06-21' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
"Just catching up on the week since back from holidays, everything
seems quite sane.

core:
- copy_to_user fix for really legacy codepaths.

vmwgfx:
- two dma fixes
- one virt hw interaction fix

i915:
- modesetting fix
- gvt fix

panfrost:
- BO unmapping fix

imx:
- image converter fixes"

* tag 'drm-fixes-2019-06-21' of git://anongit.freedesktop.org/drm/drm:
drm/i915: Don't clobber M/N values during fastset check
drm: return -EFAULT if copy_to_user() fails
drm/panfrost: Make sure a BO is only unmapped when appropriate
drm/i915/gvt: ignore unexpected pvinfo write
gpu: ipu-v3: image-convert: Fix image downsize coefficients
gpu: ipu-v3: image-convert: Fix input bytesperline for packed formats
gpu: ipu-v3: image-convert: Fix input bytesperline width/height align
drm/vmwgfx: fix a warning due to missing dma_parms
drm/vmwgfx: Honor the sg list segment size limitation
drm/vmwgfx: Use the backdoor port if the HB port is not available

+209 -65
+4 -1
drivers/gpu/drm/drm_bufs.c
··· 1340 1340 .size = from->buf_size, 1341 1341 .low_mark = from->low_mark, 1342 1342 .high_mark = from->high_mark}; 1343 - return copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags)); 1343 + 1344 + if (copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags))) 1345 + return -EFAULT; 1346 + return 0; 1344 1347 } 1345 1348 1346 1349 int drm_legacy_infobufs(struct drm_device *dev, void *data,
+4 -1
drivers/gpu/drm/drm_ioc32.c
··· 375 375 .size = from->buf_size, 376 376 .low_mark = from->low_mark, 377 377 .high_mark = from->high_mark}; 378 - return copy_to_user(to + count, &v, offsetof(drm_buf_desc32_t, flags)); 378 + 379 + if (copy_to_user(to + count, &v, offsetof(drm_buf_desc32_t, flags))) 380 + return -EFAULT; 381 + return 0; 379 382 } 380 383 381 384 static int drm_legacy_infobufs32(struct drm_device *dev, void *data,
+9 -6
drivers/gpu/drm/i915/gvt/handlers.c
··· 1254 1254 static int pvinfo_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, 1255 1255 void *p_data, unsigned int bytes) 1256 1256 { 1257 - u32 data; 1258 - int ret; 1259 - 1260 - write_vreg(vgpu, offset, p_data, bytes); 1261 - data = vgpu_vreg(vgpu, offset); 1257 + u32 data = *(u32 *)p_data; 1258 + bool invalid_write = false; 1262 1259 1263 1260 switch (offset) { 1264 1261 case _vgtif_reg(display_ready): 1265 1262 send_display_ready_uevent(vgpu, data ? 1 : 0); 1266 1263 break; 1267 1264 case _vgtif_reg(g2v_notify): 1268 - ret = handle_g2v_notification(vgpu, data); 1265 + handle_g2v_notification(vgpu, data); 1269 1266 break; 1270 1267 /* add xhot and yhot to handled list to avoid error log */ 1271 1268 case _vgtif_reg(cursor_x_hot): ··· 1279 1282 case _vgtif_reg(execlist_context_descriptor_hi): 1280 1283 break; 1281 1284 case _vgtif_reg(rsv5[0])..._vgtif_reg(rsv5[3]): 1285 + invalid_write = true; 1282 1286 enter_failsafe_mode(vgpu, GVT_FAILSAFE_INSUFFICIENT_RESOURCE); 1283 1287 break; 1284 1288 default: 1289 + invalid_write = true; 1285 1290 gvt_vgpu_err("invalid pvinfo write offset %x bytes %x data %x\n", 1286 1291 offset, bytes, data); 1287 1292 break; 1288 1293 } 1294 + 1295 + if (!invalid_write) 1296 + write_vreg(vgpu, offset, p_data, bytes); 1297 + 1289 1298 return 0; 1290 1299 } 1291 1300
+29 -9
drivers/gpu/drm/i915/intel_display.c
··· 12005 12005 m2_n2->gmch_m, m2_n2->gmch_n, !adjust) && 12006 12006 intel_compare_m_n(m_n->link_m, m_n->link_n, 12007 12007 m2_n2->link_m, m2_n2->link_n, !adjust)) { 12008 - if (adjust) 12009 - *m2_n2 = *m_n; 12010 - 12011 12008 return true; 12012 12009 } 12013 12010 ··· 13146 13149 return 0; 13147 13150 } 13148 13151 13152 + static void intel_crtc_check_fastset(struct intel_crtc_state *old_crtc_state, 13153 + struct intel_crtc_state *new_crtc_state) 13154 + { 13155 + struct drm_i915_private *dev_priv = 13156 + to_i915(new_crtc_state->base.crtc->dev); 13157 + 13158 + if (!intel_pipe_config_compare(dev_priv, old_crtc_state, 13159 + new_crtc_state, true)) 13160 + return; 13161 + 13162 + new_crtc_state->base.mode_changed = false; 13163 + new_crtc_state->update_pipe = true; 13164 + 13165 + /* 13166 + * If we're not doing the full modeset we want to 13167 + * keep the current M/N values as they may be 13168 + * sufficiently different to the computed values 13169 + * to cause problems. 13170 + * 13171 + * FIXME: should really copy more fuzzy state here 13172 + */ 13173 + new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n; 13174 + new_crtc_state->dp_m_n = old_crtc_state->dp_m_n; 13175 + new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2; 13176 + new_crtc_state->has_drrs = old_crtc_state->has_drrs; 13177 + } 13178 + 13149 13179 /** 13150 13180 * intel_atomic_check - validate state object 13151 13181 * @dev: drm device ··· 13221 13197 return ret; 13222 13198 } 13223 13199 13224 - if (intel_pipe_config_compare(dev_priv, 13225 - to_intel_crtc_state(old_crtc_state), 13226 - pipe_config, true)) { 13227 - crtc_state->mode_changed = false; 13228 - pipe_config->update_pipe = true; 13229 - } 13200 + intel_crtc_check_fastset(to_intel_crtc_state(old_crtc_state), 13201 + pipe_config); 13230 13202 13231 13203 if (needs_modeset(crtc_state)) 13232 13204 any_ms = true;
+2 -1
drivers/gpu/drm/panfrost/panfrost_gem.c
··· 19 19 struct panfrost_gem_object *bo = to_panfrost_bo(obj); 20 20 struct panfrost_device *pfdev = obj->dev->dev_private; 21 21 22 - panfrost_mmu_unmap(bo); 22 + if (bo->is_mapped) 23 + panfrost_mmu_unmap(bo); 23 24 24 25 spin_lock(&pfdev->mm_lock); 25 26 drm_mm_remove_node(&bo->node);
+1
drivers/gpu/drm/panfrost/panfrost_gem.h
··· 11 11 struct drm_gem_shmem_object base; 12 12 13 13 struct drm_mm_node node; 14 + bool is_mapped; 14 15 }; 15 16 16 17 static inline
+8
drivers/gpu/drm/panfrost/panfrost_mmu.c
··· 156 156 struct sg_table *sgt; 157 157 int ret; 158 158 159 + if (WARN_ON(bo->is_mapped)) 160 + return 0; 161 + 159 162 sgt = drm_gem_shmem_get_pages_sgt(obj); 160 163 if (WARN_ON(IS_ERR(sgt))) 161 164 return PTR_ERR(sgt); ··· 192 189 193 190 pm_runtime_mark_last_busy(pfdev->dev); 194 191 pm_runtime_put_autosuspend(pfdev->dev); 192 + bo->is_mapped = true; 195 193 196 194 return 0; 197 195 } ··· 206 202 size_t len = bo->node.size << PAGE_SHIFT; 207 203 size_t unmapped_len = 0; 208 204 int ret; 205 + 206 + if (WARN_ON(!bo->is_mapped)) 207 + return; 209 208 210 209 dev_dbg(pfdev->dev, "unmap: iova=%llx, len=%zx", iova, len); 211 210 ··· 237 230 238 231 pm_runtime_mark_last_busy(pfdev->dev); 239 232 pm_runtime_put_autosuspend(pfdev->dev); 233 + bo->is_mapped = false; 240 234 } 241 235 242 236 static void mmu_tlb_inv_context_s1(void *cookie)
+3
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
··· 747 747 if (unlikely(ret != 0)) 748 748 goto out_err0; 749 749 750 + dma_set_max_seg_size(dev->dev, min_t(unsigned int, U32_MAX & PAGE_MASK, 751 + SCATTERLIST_MAX_SEGMENT)); 752 + 750 753 if (dev_priv->capabilities & SVGA_CAP_GMR2) { 751 754 DRM_INFO("Max GMR ids is %u\n", 752 755 (unsigned)dev_priv->max_gmr_ids);
+117 -29
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
··· 136 136 return 0; 137 137 } 138 138 139 + /** 140 + * vmw_port_hb_out - Send the message payload either through the 141 + * high-bandwidth port if available, or through the backdoor otherwise. 142 + * @channel: The rpc channel. 143 + * @msg: NULL-terminated message. 144 + * @hb: Whether the high-bandwidth port is available. 145 + * 146 + * Return: The port status. 147 + */ 148 + static unsigned long vmw_port_hb_out(struct rpc_channel *channel, 149 + const char *msg, bool hb) 150 + { 151 + unsigned long si, di, eax, ebx, ecx, edx; 152 + unsigned long msg_len = strlen(msg); 153 + 154 + if (hb) { 155 + unsigned long bp = channel->cookie_high; 156 + 157 + si = (uintptr_t) msg; 158 + di = channel->cookie_low; 159 + 160 + VMW_PORT_HB_OUT( 161 + (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, 162 + msg_len, si, di, 163 + VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), 164 + VMW_HYPERVISOR_MAGIC, bp, 165 + eax, ebx, ecx, edx, si, di); 166 + 167 + return ebx; 168 + } 169 + 170 + /* HB port not available. Send the message 4 bytes at a time. */ 171 + ecx = MESSAGE_STATUS_SUCCESS << 16; 172 + while (msg_len && (HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS)) { 173 + unsigned int bytes = min_t(size_t, msg_len, 4); 174 + unsigned long word = 0; 175 + 176 + memcpy(&word, msg, bytes); 177 + msg_len -= bytes; 178 + msg += bytes; 179 + si = channel->cookie_high; 180 + di = channel->cookie_low; 181 + 182 + VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16), 183 + word, si, di, 184 + VMW_HYPERVISOR_PORT | (channel->channel_id << 16), 185 + VMW_HYPERVISOR_MAGIC, 186 + eax, ebx, ecx, edx, si, di); 187 + } 188 + 189 + return ecx; 190 + } 191 + 192 + /** 193 + * vmw_port_hb_in - Receive the message payload either through the 194 + * high-bandwidth port if available, or through the backdoor otherwise. 195 + * @channel: The rpc channel. 196 + * @reply: Pointer to buffer holding reply. 197 + * @reply_len: Length of the reply. 198 + * @hb: Whether the high-bandwidth port is available. 199 + * 200 + * Return: The port status. 201 + */ 202 + static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply, 203 + unsigned long reply_len, bool hb) 204 + { 205 + unsigned long si, di, eax, ebx, ecx, edx; 206 + 207 + if (hb) { 208 + unsigned long bp = channel->cookie_low; 209 + 210 + si = channel->cookie_high; 211 + di = (uintptr_t) reply; 212 + 213 + VMW_PORT_HB_IN( 214 + (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, 215 + reply_len, si, di, 216 + VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), 217 + VMW_HYPERVISOR_MAGIC, bp, 218 + eax, ebx, ecx, edx, si, di); 219 + 220 + return ebx; 221 + } 222 + 223 + /* HB port not available. Retrieve the message 4 bytes at a time. */ 224 + ecx = MESSAGE_STATUS_SUCCESS << 16; 225 + while (reply_len) { 226 + unsigned int bytes = min_t(unsigned long, reply_len, 4); 227 + 228 + si = channel->cookie_high; 229 + di = channel->cookie_low; 230 + 231 + VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16), 232 + MESSAGE_STATUS_SUCCESS, si, di, 233 + VMW_HYPERVISOR_PORT | (channel->channel_id << 16), 234 + VMW_HYPERVISOR_MAGIC, 235 + eax, ebx, ecx, edx, si, di); 236 + 237 + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) 238 + break; 239 + 240 + memcpy(reply, &ebx, bytes); 241 + reply_len -= bytes; 242 + reply += bytes; 243 + } 244 + 245 + return ecx; 246 + } 139 247 140 248 141 249 /** ··· 256 148 */ 257 149 static int vmw_send_msg(struct rpc_channel *channel, const char *msg) 258 150 { 259 - unsigned long eax, ebx, ecx, edx, si, di, bp; 151 + unsigned long eax, ebx, ecx, edx, si, di; 260 152 size_t msg_len = strlen(msg); 261 153 int retries = 0; 262 - 263 154 264 155 while (retries < RETRIES) { 265 156 retries++; ··· 273 166 VMW_HYPERVISOR_MAGIC, 274 167 eax, ebx, ecx, edx, si, di); 275 168 276 - if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 || 277 - (HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) { 278 - /* Expected success + high-bandwidth. Give up. */ 169 + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { 170 + /* Expected success. Give up. */ 279 171 return -EINVAL; 280 172 } 281 173 282 174 /* Send msg */ 283 - si = (uintptr_t) msg; 284 - di = channel->cookie_low; 285 - bp = channel->cookie_high; 286 - 287 - VMW_PORT_HB_OUT( 288 - (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, 289 - msg_len, si, di, 290 - VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), 291 - VMW_HYPERVISOR_MAGIC, bp, 292 - eax, ebx, ecx, edx, si, di); 175 + ebx = vmw_port_hb_out(channel, msg, 176 + !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB)); 293 177 294 178 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) != 0) { 295 179 return 0; ··· 309 211 static int vmw_recv_msg(struct rpc_channel *channel, void **msg, 310 212 size_t *msg_len) 311 213 { 312 - unsigned long eax, ebx, ecx, edx, si, di, bp; 214 + unsigned long eax, ebx, ecx, edx, si, di; 313 215 char *reply; 314 216 size_t reply_len; 315 217 int retries = 0; ··· 331 233 VMW_HYPERVISOR_MAGIC, 332 234 eax, ebx, ecx, edx, si, di); 333 235 334 - if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 || 335 - (HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) { 236 + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { 336 237 DRM_ERROR("Failed to get reply size for host message.\n"); 337 238 return -EINVAL; 338 239 } ··· 349 252 350 253 351 254 /* Receive buffer */ 352 - si = channel->cookie_high; 353 - di = (uintptr_t) reply; 354 - bp = channel->cookie_low; 355 - 356 - VMW_PORT_HB_IN( 357 - (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, 358 - reply_len, si, di, 359 - VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), 360 - VMW_HYPERVISOR_MAGIC, bp, 361 - eax, ebx, ecx, edx, si, di); 362 - 255 + ebx = vmw_port_hb_in(channel, reply, reply_len, 256 + !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB)); 363 257 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) { 364 258 kfree(reply); 365 259
+5 -5
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
··· 441 441 if (unlikely(ret != 0)) 442 442 return ret; 443 443 444 - ret = sg_alloc_table_from_pages(&vmw_tt->sgt, vsgt->pages, 445 - vsgt->num_pages, 0, 446 - (unsigned long) 447 - vsgt->num_pages << PAGE_SHIFT, 448 - GFP_KERNEL); 444 + ret = __sg_alloc_table_from_pages 445 + (&vmw_tt->sgt, vsgt->pages, vsgt->num_pages, 0, 446 + (unsigned long) vsgt->num_pages << PAGE_SHIFT, 447 + dma_get_max_seg_size(dev_priv->dev->dev), 448 + GFP_KERNEL); 449 449 if (unlikely(ret != 0)) 450 450 goto out_sg_alloc_fail; 451 451
+27 -13
drivers/gpu/ipu-v3/ipu-image-convert.c
··· 400 400 if (WARN_ON(resized_width == 0 || resized_height == 0)) 401 401 return -EINVAL; 402 402 403 - while (downsized_width >= resized_width * 2) { 403 + while (downsized_width > 1024 || 404 + downsized_width >= resized_width * 2) { 404 405 downsized_width >>= 1; 405 406 downsize_coeff_h++; 406 407 } 407 408 408 - while (downsized_height >= resized_height * 2) { 409 + while (downsized_height > 1024 || 410 + downsized_height >= resized_height * 2) { 409 411 downsized_height >>= 1; 410 412 downsize_coeff_v++; 411 413 } ··· 1878 1876 enum ipu_rotate_mode rot_mode) 1879 1877 { 1880 1878 const struct ipu_image_pixfmt *infmt, *outfmt; 1881 - u32 w_align, h_align; 1879 + u32 w_align_out, h_align_out; 1880 + u32 w_align_in, h_align_in; 1882 1881 1883 1882 infmt = get_format(in->pix.pixelformat); 1884 1883 outfmt = get_format(out->pix.pixelformat); ··· 1911 1908 } 1912 1909 1913 1910 /* align input width/height */ 1914 - w_align = ilog2(tile_width_align(IMAGE_CONVERT_IN, infmt, rot_mode)); 1915 - h_align = ilog2(tile_height_align(IMAGE_CONVERT_IN, infmt, rot_mode)); 1916 - in->pix.width = clamp_align(in->pix.width, MIN_W, MAX_W, w_align); 1917 - in->pix.height = clamp_align(in->pix.height, MIN_H, MAX_H, h_align); 1911 + w_align_in = ilog2(tile_width_align(IMAGE_CONVERT_IN, infmt, 1912 + rot_mode)); 1913 + h_align_in = ilog2(tile_height_align(IMAGE_CONVERT_IN, infmt, 1914 + rot_mode)); 1915 + in->pix.width = clamp_align(in->pix.width, MIN_W, MAX_W, 1916 + w_align_in); 1917 + in->pix.height = clamp_align(in->pix.height, MIN_H, MAX_H, 1918 + h_align_in); 1918 1919 1919 1920 /* align output width/height */ 1920 - w_align = ilog2(tile_width_align(IMAGE_CONVERT_OUT, outfmt, rot_mode)); 1921 - h_align = ilog2(tile_height_align(IMAGE_CONVERT_OUT, outfmt, rot_mode)); 1922 - out->pix.width = clamp_align(out->pix.width, MIN_W, MAX_W, w_align); 1923 - out->pix.height = clamp_align(out->pix.height, MIN_H, MAX_H, h_align); 1921 + w_align_out = ilog2(tile_width_align(IMAGE_CONVERT_OUT, outfmt, 1922 + rot_mode)); 1923 + h_align_out = ilog2(tile_height_align(IMAGE_CONVERT_OUT, outfmt, 1924 + rot_mode)); 1925 + out->pix.width = clamp_align(out->pix.width, MIN_W, MAX_W, 1926 + w_align_out); 1927 + out->pix.height = clamp_align(out->pix.height, MIN_H, MAX_H, 1928 + h_align_out); 1924 1929 1925 1930 /* set input/output strides and image sizes */ 1926 1931 in->pix.bytesperline = infmt->planar ? 1927 - clamp_align(in->pix.width, 2 << w_align, MAX_W, w_align) : 1932 + clamp_align(in->pix.width, 2 << w_align_in, MAX_W, 1933 + w_align_in) : 1928 1934 clamp_align((in->pix.width * infmt->bpp) >> 3, 1929 - 2 << w_align, MAX_W, w_align); 1935 + ((2 << w_align_in) * infmt->bpp) >> 3, 1936 + (MAX_W * infmt->bpp) >> 3, 1937 + w_align_in); 1930 1938 in->pix.sizeimage = infmt->planar ? 1931 1939 (in->pix.height * in->pix.bytesperline * infmt->bpp) >> 3 : 1932 1940 in->pix.height * in->pix.bytesperline;