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 branch 'drm-intel-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel

* 'drm-intel-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel:
drm/i915: Rephrase pwrite bounds checking to avoid any potential overflow
drm/i915: Sanity check pread/pwrite
drm/i915: Use pipe state to tell when pipe is off
drm/i915: vblank status not valid while training display port
drivers/gpu/drm/i915/i915_gem.c: Add missing error handling code
drm/i915: Fix refleak during eviction.
drm/i915: fix GMCH power reporting

+96 -83
+3 -3
drivers/gpu/drm/i915/i915_dma.c
··· 1787 1787 } 1788 1788 } 1789 1789 1790 - div_u64(diff, diff1); 1790 + diff = div_u64(diff, diff1); 1791 1791 ret = ((m * diff) + c); 1792 - div_u64(ret, 10); 1792 + ret = div_u64(ret, 10); 1793 1793 1794 1794 dev_priv->last_count1 = total_count; 1795 1795 dev_priv->last_time1 = now; ··· 1858 1858 1859 1859 /* More magic constants... */ 1860 1860 diff = diff * 1181; 1861 - div_u64(diff, diffms * 10); 1861 + diff = div_u64(diff, diffms * 10); 1862 1862 dev_priv->gfx_power = diff; 1863 1863 } 1864 1864
+26 -20
drivers/gpu/drm/i915/i915_gem.c
··· 469 469 return -ENOENT; 470 470 obj_priv = to_intel_bo(obj); 471 471 472 - /* Bounds check source. 473 - * 474 - * XXX: This could use review for overflow issues... 475 - */ 476 - if (args->offset > obj->size || args->size > obj->size || 477 - args->offset + args->size > obj->size) { 478 - drm_gem_object_unreference_unlocked(obj); 479 - return -EINVAL; 472 + /* Bounds check source. */ 473 + if (args->offset > obj->size || args->size > obj->size - args->offset) { 474 + ret = -EINVAL; 475 + goto err; 476 + } 477 + 478 + if (!access_ok(VERIFY_WRITE, 479 + (char __user *)(uintptr_t)args->data_ptr, 480 + args->size)) { 481 + ret = -EFAULT; 482 + goto err; 480 483 } 481 484 482 485 if (i915_gem_object_needs_bit17_swizzle(obj)) { ··· 491 488 file_priv); 492 489 } 493 490 491 + err: 494 492 drm_gem_object_unreference_unlocked(obj); 495 - 496 493 return ret; 497 494 } 498 495 ··· 581 578 582 579 user_data = (char __user *) (uintptr_t) args->data_ptr; 583 580 remain = args->size; 584 - if (!access_ok(VERIFY_READ, user_data, remain)) 585 - return -EFAULT; 586 581 587 582 588 583 mutex_lock(&dev->struct_mutex); ··· 933 932 return -ENOENT; 934 933 obj_priv = to_intel_bo(obj); 935 934 936 - /* Bounds check destination. 937 - * 938 - * XXX: This could use review for overflow issues... 939 - */ 940 - if (args->offset > obj->size || args->size > obj->size || 941 - args->offset + args->size > obj->size) { 942 - drm_gem_object_unreference_unlocked(obj); 943 - return -EINVAL; 935 + /* Bounds check destination. */ 936 + if (args->offset > obj->size || args->size > obj->size - args->offset) { 937 + ret = -EINVAL; 938 + goto err; 939 + } 940 + 941 + if (!access_ok(VERIFY_READ, 942 + (char __user *)(uintptr_t)args->data_ptr, 943 + args->size)) { 944 + ret = -EFAULT; 945 + goto err; 944 946 } 945 947 946 948 /* We can only do the GTT pwrite on untiled buffers, as otherwise ··· 977 973 DRM_INFO("pwrite failed %d\n", ret); 978 974 #endif 979 975 976 + err: 980 977 drm_gem_object_unreference_unlocked(obj); 981 - 982 978 return ret; 983 979 } 984 980 ··· 3260 3256 (int) reloc->offset, 3261 3257 reloc->read_domains, 3262 3258 reloc->write_domain); 3259 + drm_gem_object_unreference(target_obj); 3260 + i915_gem_object_unpin(obj); 3263 3261 return -EINVAL; 3264 3262 } 3265 3263 if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+22 -27
drivers/gpu/drm/i915/i915_gem_evict.c
··· 93 93 { 94 94 drm_i915_private_t *dev_priv = dev->dev_private; 95 95 struct list_head eviction_list, unwind_list; 96 - struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; 96 + struct drm_i915_gem_object *obj_priv; 97 97 struct list_head *render_iter, *bsd_iter; 98 98 int ret = 0; 99 99 ··· 175 175 return -ENOSPC; 176 176 177 177 found: 178 + /* drm_mm doesn't allow any other other operations while 179 + * scanning, therefore store to be evicted objects on a 180 + * temporary list. */ 178 181 INIT_LIST_HEAD(&eviction_list); 179 - list_for_each_entry_safe(obj_priv, tmp_obj_priv, 180 - &unwind_list, evict_list) { 182 + while (!list_empty(&unwind_list)) { 183 + obj_priv = list_first_entry(&unwind_list, 184 + struct drm_i915_gem_object, 185 + evict_list); 181 186 if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { 182 - /* drm_mm doesn't allow any other other operations while 183 - * scanning, therefore store to be evicted objects on a 184 - * temporary list. */ 185 187 list_move(&obj_priv->evict_list, &eviction_list); 186 - } else 187 - drm_gem_object_unreference(&obj_priv->base); 188 - } 189 - 190 - /* Unbinding will emit any required flushes */ 191 - list_for_each_entry_safe(obj_priv, tmp_obj_priv, 192 - &eviction_list, evict_list) { 193 - #if WATCH_LRU 194 - DRM_INFO("%s: evicting %p\n", __func__, &obj_priv->base); 195 - #endif 196 - ret = i915_gem_object_unbind(&obj_priv->base); 197 - if (ret) 198 - return ret; 199 - 188 + continue; 189 + } 190 + list_del(&obj_priv->evict_list); 200 191 drm_gem_object_unreference(&obj_priv->base); 201 192 } 202 193 203 - /* The just created free hole should be on the top of the free stack 204 - * maintained by drm_mm, so this BUG_ON actually executes in O(1). 205 - * Furthermore all accessed data has just recently been used, so it 206 - * should be really fast, too. */ 207 - BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size, 208 - alignment, 0)); 194 + /* Unbinding will emit any required flushes */ 195 + while (!list_empty(&eviction_list)) { 196 + obj_priv = list_first_entry(&eviction_list, 197 + struct drm_i915_gem_object, 198 + evict_list); 199 + if (ret == 0) 200 + ret = i915_gem_object_unbind(&obj_priv->base); 201 + list_del(&obj_priv->evict_list); 202 + drm_gem_object_unreference(&obj_priv->base); 203 + } 209 204 210 - return 0; 205 + return ret; 211 206 } 212 207 213 208 int
+36 -22
drivers/gpu/drm/i915/intel_display.c
··· 1013 1013 DRM_DEBUG_KMS("vblank wait timed out\n"); 1014 1014 } 1015 1015 1016 - /** 1017 - * intel_wait_for_vblank_off - wait for vblank after disabling a pipe 1016 + /* 1017 + * intel_wait_for_pipe_off - wait for pipe to turn off 1018 1018 * @dev: drm device 1019 1019 * @pipe: pipe to wait for 1020 1020 * ··· 1022 1022 * spinning on the vblank interrupt status bit, since we won't actually 1023 1023 * see an interrupt when the pipe is disabled. 1024 1024 * 1025 - * So this function waits for the display line value to settle (it 1026 - * usually ends up stopping at the start of the next frame). 1025 + * On Gen4 and above: 1026 + * wait for the pipe register state bit to turn off 1027 + * 1028 + * Otherwise: 1029 + * wait for the display line value to settle (it usually 1030 + * ends up stopping at the start of the next frame). 1031 + * 1027 1032 */ 1028 - void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) 1033 + static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) 1029 1034 { 1030 1035 struct drm_i915_private *dev_priv = dev->dev_private; 1031 - int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); 1032 - unsigned long timeout = jiffies + msecs_to_jiffies(100); 1033 - u32 last_line; 1034 1036 1035 - /* Wait for the display line to settle */ 1036 - do { 1037 - last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; 1038 - mdelay(5); 1039 - } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && 1040 - time_after(timeout, jiffies)); 1037 + if (INTEL_INFO(dev)->gen >= 4) { 1038 + int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF); 1041 1039 1042 - if (time_after(jiffies, timeout)) 1043 - DRM_DEBUG_KMS("vblank wait timed out\n"); 1040 + /* Wait for the Pipe State to go off */ 1041 + if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, 1042 + 100, 0)) 1043 + DRM_DEBUG_KMS("pipe_off wait timed out\n"); 1044 + } else { 1045 + u32 last_line; 1046 + int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); 1047 + unsigned long timeout = jiffies + msecs_to_jiffies(100); 1048 + 1049 + /* Wait for the display line to settle */ 1050 + do { 1051 + last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; 1052 + mdelay(5); 1053 + } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && 1054 + time_after(timeout, jiffies)); 1055 + if (time_after(jiffies, timeout)) 1056 + DRM_DEBUG_KMS("pipe_off wait timed out\n"); 1057 + } 1044 1058 } 1045 1059 1046 1060 /* Parameters have changed, update FBC info */ ··· 2342 2328 I915_READ(dspbase_reg); 2343 2329 } 2344 2330 2345 - /* Wait for vblank for the disable to take effect */ 2346 - intel_wait_for_vblank_off(dev, pipe); 2347 - 2348 2331 /* Don't disable pipe A or pipe A PLLs if needed */ 2349 2332 if (pipeconf_reg == PIPEACONF && 2350 - (dev_priv->quirks & QUIRK_PIPEA_FORCE)) 2333 + (dev_priv->quirks & QUIRK_PIPEA_FORCE)) { 2334 + /* Wait for vblank for the disable to take effect */ 2335 + intel_wait_for_vblank(dev, pipe); 2351 2336 goto skip_pipe_off; 2337 + } 2352 2338 2353 2339 /* Next, disable display pipes */ 2354 2340 temp = I915_READ(pipeconf_reg); ··· 2357 2343 I915_READ(pipeconf_reg); 2358 2344 } 2359 2345 2360 - /* Wait for vblank for the disable to take effect. */ 2361 - intel_wait_for_vblank_off(dev, pipe); 2346 + /* Wait for the pipe to turn off */ 2347 + intel_wait_for_pipe_off(dev, pipe); 2362 2348 2363 2349 temp = I915_READ(dpll_reg); 2364 2350 if ((temp & DPLL_VCO_ENABLE) != 0) {
+9 -10
drivers/gpu/drm/i915/intel_dp.c
··· 1138 1138 intel_dp_set_link_train(struct intel_dp *intel_dp, 1139 1139 uint32_t dp_reg_value, 1140 1140 uint8_t dp_train_pat, 1141 - uint8_t train_set[4], 1142 - bool first) 1141 + uint8_t train_set[4]) 1143 1142 { 1144 1143 struct drm_device *dev = intel_dp->base.enc.dev; 1145 1144 struct drm_i915_private *dev_priv = dev->dev_private; 1146 - struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); 1147 1145 int ret; 1148 1146 1149 1147 I915_WRITE(intel_dp->output_reg, dp_reg_value); 1150 1148 POSTING_READ(intel_dp->output_reg); 1151 - if (first) 1152 - intel_wait_for_vblank(dev, intel_crtc->pipe); 1153 1149 1154 1150 intel_dp_aux_native_write_1(intel_dp, 1155 1151 DP_TRAINING_PATTERN_SET, ··· 1170 1174 uint8_t voltage; 1171 1175 bool clock_recovery = false; 1172 1176 bool channel_eq = false; 1173 - bool first = true; 1174 1177 int tries; 1175 1178 u32 reg; 1176 1179 uint32_t DP = intel_dp->DP; 1180 + struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); 1181 + 1182 + /* Enable output, wait for it to become active */ 1183 + I915_WRITE(intel_dp->output_reg, intel_dp->DP); 1184 + POSTING_READ(intel_dp->output_reg); 1185 + intel_wait_for_vblank(dev, intel_crtc->pipe); 1177 1186 1178 1187 /* Write the link configuration data */ 1179 1188 intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, ··· 1211 1210 reg = DP | DP_LINK_TRAIN_PAT_1; 1212 1211 1213 1212 if (!intel_dp_set_link_train(intel_dp, reg, 1214 - DP_TRAINING_PATTERN_1, train_set, first)) 1213 + DP_TRAINING_PATTERN_1, train_set)) 1215 1214 break; 1216 - first = false; 1217 1215 /* Set training pattern 1 */ 1218 1216 1219 1217 udelay(100); ··· 1266 1266 1267 1267 /* channel eq pattern */ 1268 1268 if (!intel_dp_set_link_train(intel_dp, reg, 1269 - DP_TRAINING_PATTERN_2, train_set, 1270 - false)) 1269 + DP_TRAINING_PATTERN_2, train_set)) 1271 1270 break; 1272 1271 1273 1272 udelay(400);
-1
drivers/gpu/drm/i915/intel_drv.h
··· 229 229 struct drm_crtc *crtc); 230 230 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, 231 231 struct drm_file *file_priv); 232 - extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); 233 232 extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); 234 233 extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); 235 234 extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,