Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 096c49ec authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'vmwgfx-fixes-4.16' of git://people.freedesktop.org/~thomash/linux into drm-fixes

Two vmwgfx fixes for 4.16. Both cc'd stable.

* 'vmwgfx-fixes-4.16' of git://people.freedesktop.org/~thomash/linux:
  drm/vmwgfx: Fix a destoy-while-held mutex problem.
  drm/vmwgfx: Fix black screen and device errors when running without fbdev
parents cec1b948 73a88250
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1337,6 +1337,19 @@ static void __vmw_svga_disable(struct vmw_private *dev_priv)
 */
void vmw_svga_disable(struct vmw_private *dev_priv)
{
	/*
	 * Disabling SVGA will turn off device modesetting capabilities, so
	 * notify KMS about that so that it doesn't cache atomic state that
	 * isn't valid anymore, for example crtcs turned on.
	 * Strictly we'd want to do this under the SVGA lock (or an SVGA mutex),
	 * but vmw_kms_lost_device() takes the reservation sem and thus we'll
	 * end up with lock order reversal. Thus, a master may actually perform
	 * a new modeset just after we call vmw_kms_lost_device() and race with
	 * vmw_svga_disable(), but that should at worst cause atomic KMS state
	 * to be inconsistent with the device, causing modesetting problems.
	 *
	 */
	vmw_kms_lost_device(dev_priv->dev);
	ttm_write_lock(&dev_priv->reservation_sem, false);
	spin_lock(&dev_priv->svga_lock);
	if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) {
+1 −0
Original line number Diff line number Diff line
@@ -938,6 +938,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
				struct drm_file *file_priv);
void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv);
void vmw_kms_lost_device(struct drm_device *dev);

int vmw_dumb_create(struct drm_file *file_priv,
		    struct drm_device *dev,
+30 −9
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_rect.h>


/* Might need a hrtimer here? */
#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)

@@ -2517,9 +2516,12 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
 * Helper to be used if an error forces the caller to undo the actions of
 * vmw_kms_helper_resource_prepare.
 */
void vmw_kms_helper_resource_revert(struct vmw_resource *res)
void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx)
{
	vmw_kms_helper_buffer_revert(res->backup);
	struct vmw_resource *res = ctx->res;

	vmw_kms_helper_buffer_revert(ctx->buf);
	vmw_dmabuf_unreference(&ctx->buf);
	vmw_resource_unreserve(res, false, NULL, 0);
	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
}
@@ -2536,10 +2538,14 @@ void vmw_kms_helper_resource_revert(struct vmw_resource *res)
 * interrupted by a signal.
 */
int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
				    bool interruptible)
				    bool interruptible,
				    struct vmw_validation_ctx *ctx)
{
	int ret = 0;

	ctx->buf = NULL;
	ctx->res = res;

	if (interruptible)
		ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex);
	else
@@ -2558,6 +2564,8 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
						    res->dev_priv->has_mob);
		if (ret)
			goto out_unreserve;

		ctx->buf = vmw_dmabuf_reference(res->backup);
	}
	ret = vmw_resource_validate(res);
	if (ret)
@@ -2565,7 +2573,7 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
	return 0;

out_revert:
	vmw_kms_helper_buffer_revert(res->backup);
	vmw_kms_helper_buffer_revert(ctx->buf);
out_unreserve:
	vmw_resource_unreserve(res, false, NULL, 0);
out_unlock:
@@ -2581,11 +2589,13 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
 * @out_fence: Optional pointer to a fence pointer. If non-NULL, a
 * ref-counted fence pointer is returned here.
 */
void vmw_kms_helper_resource_finish(struct vmw_resource *res,
void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
				    struct vmw_fence_obj **out_fence)
{
	if (res->backup || out_fence)
		vmw_kms_helper_buffer_finish(res->dev_priv, NULL, res->backup,
	struct vmw_resource *res = ctx->res;

	if (ctx->buf || out_fence)
		vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf,
					     out_fence, NULL);

	vmw_resource_unreserve(res, false, NULL, 0);
@@ -2851,3 +2861,14 @@ int vmw_kms_set_config(struct drm_mode_set *set,

	return drm_atomic_helper_set_config(set, ctx);
}


/**
 * vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost
 *
 * @dev: Pointer to the drm device
 */
void vmw_kms_lost_device(struct drm_device *dev)
{
	drm_atomic_helper_shutdown(dev);
}
+9 −4
Original line number Diff line number Diff line
@@ -240,6 +240,11 @@ struct vmw_display_unit {
	int set_gui_y;
};

struct vmw_validation_ctx {
	struct vmw_resource *res;
	struct vmw_dma_buffer *buf;
};

#define vmw_crtc_to_du(x) \
	container_of(x, struct vmw_display_unit, crtc)
#define vmw_connector_to_du(x) \
@@ -296,9 +301,10 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
				  struct drm_vmw_fence_rep __user *
				  user_fence_rep);
int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
				    bool interruptible);
void vmw_kms_helper_resource_revert(struct vmw_resource *res);
void vmw_kms_helper_resource_finish(struct vmw_resource *res,
				    bool interruptible,
				    struct vmw_validation_ctx *ctx);
void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx);
void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
				    struct vmw_fence_obj **out_fence);
int vmw_kms_readback(struct vmw_private *dev_priv,
		     struct drm_file *file_priv,
@@ -439,5 +445,4 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,

int vmw_kms_set_config(struct drm_mode_set *set,
		       struct drm_modeset_acquire_ctx *ctx);

#endif
+3 −2
Original line number Diff line number Diff line
@@ -909,12 +909,13 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
	struct vmw_framebuffer_surface *vfbs =
		container_of(framebuffer, typeof(*vfbs), base);
	struct vmw_kms_sou_surface_dirty sdirty;
	struct vmw_validation_ctx ctx;
	int ret;

	if (!srf)
		srf = &vfbs->surface->res;

	ret = vmw_kms_helper_resource_prepare(srf, true);
	ret = vmw_kms_helper_resource_prepare(srf, true, &ctx);
	if (ret)
		return ret;

@@ -933,7 +934,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
	ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips,
				   dest_x, dest_y, num_clips, inc,
				   &sdirty.base);
	vmw_kms_helper_resource_finish(srf, out_fence);
	vmw_kms_helper_resource_finish(&ctx, out_fence);

	return ret;
}
Loading