mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 01:34:14 +08:00
drm/i915/overlay: Fix unpinning along init error paths
As pointed out by Dan Carpenter, it was seemingly possible to hit an error whilst mapping the buffer for the regs (except the only likely error returns should not happen during init) and so leak a pin count on the bo. To handle this we would need to reacquire the struct mutex, so for simplicity rearrange for the lock to be held for the entire function. For extra pedagogy, test that we only call init once. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
dc501fbc43
commit
79d2427338
@ -1409,6 +1409,11 @@ void intel_setup_overlay(struct drm_device *dev)
|
||||
overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
|
||||
if (!overlay)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
if (WARN_ON(dev_priv->overlay))
|
||||
goto out_free;
|
||||
|
||||
overlay->dev = dev;
|
||||
|
||||
reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
|
||||
@ -1416,8 +1421,6 @@ void intel_setup_overlay(struct drm_device *dev)
|
||||
goto out_free;
|
||||
overlay->reg_bo = reg_bo;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
if (OVERLAY_NEEDS_PHYSICAL(dev)) {
|
||||
ret = i915_gem_attach_phys_object(dev, reg_bo,
|
||||
I915_GEM_PHYS_OVERLAY_REGS,
|
||||
@ -1442,8 +1445,6 @@ void intel_setup_overlay(struct drm_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
/* init all values */
|
||||
overlay->color_key = 0x0101fe;
|
||||
overlay->brightness = -19;
|
||||
@ -1452,7 +1453,7 @@ void intel_setup_overlay(struct drm_device *dev)
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs)
|
||||
goto out_free_bo;
|
||||
goto out_unpin_bo;
|
||||
|
||||
memset(regs, 0, sizeof(struct overlay_registers));
|
||||
update_polyphase_filter(regs);
|
||||
@ -1461,15 +1462,17 @@ void intel_setup_overlay(struct drm_device *dev)
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
|
||||
dev_priv->overlay = overlay;
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
DRM_INFO("initialized overlay support\n");
|
||||
return;
|
||||
|
||||
out_unpin_bo:
|
||||
i915_gem_object_unpin(reg_bo);
|
||||
if (!OVERLAY_NEEDS_PHYSICAL(dev))
|
||||
i915_gem_object_unpin(reg_bo);
|
||||
out_free_bo:
|
||||
drm_gem_object_unreference(®_bo->base);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
out_free:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
kfree(overlay);
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user