Commit a7c88728 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull drm fixes from Dave Airlie:
 "Probably the last one before Christmas, I'll see if there is much
  demand over next few weeks for more fixes, I expect it'll be quiet
  enough.

  This has one exynos fix, and a bunch of i915 core and i915 GVT fixes.

  Summary:

  exynos:
   - component delete fix

  i915:
   - Fix to drop an unused and harmful display W/A
   - Fix to define EHL power wells independent of ICL
   - Fix for priority inversion on bonded requests
   - Fix in mmio offset calculation of DSB instance
   - Fix memory leak from get_task_pid when banning clients
   - Fixes to avoid dereference of uninitialized ops in dma_fence
     tracing and keep reference to execbuf object until submitted.
   - vGPU state setting locking fix (Zhenyu)
   - Fix vGPU display dmabuf as read-only (Zhenyu)
   - Properly handle vGPU display dmabuf page pin when rendering (Tina)
   - Fix one guest boot warning to handle guc reset state (Fred)"

* tag 'drm-fixes-2019-12-21' of git://anongit.freedesktop.org/drm/drm:
  drm/exynos: gsc: add missed component_del
  drm/i915: Fix pid leak with banned clients
  drm/i915/gem: Keep request alive while attaching fences
  drm/i915: Fix WARN_ON condition for cursor plane ddb allocation
  drm/i915/gvt: Fix guest boot warning
  drm/i915/tgl: Drop Wa#1178
  drm/i915/ehl: Define EHL powerwells independently of ICL
  drm/i915: Set fence_work.ops before dma_fence_init
  drm/i915: Copy across scheduler behaviour flags across submit fences
  drm/i915/dsb: Fix in mmio offset calculation of DSB instance
  drm/i915/gvt: Pin vgpu dma address before using
  drm/i915/gvt: set guest display buffer as readonly
  drm/i915/gvt: use vgpu lock for active state setting
parents f8f04d08 0c517e6c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1313,6 +1313,7 @@ static int gsc_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;

	component_del(dev, &gsc_component_ops);
	pm_runtime_dont_use_autosuspend(dev);
	pm_runtime_disable(dev);

+150 −3
Original line number Diff line number Diff line
@@ -3688,6 +3688,151 @@ static const struct i915_power_well_desc icl_power_wells[] = {
	},
};

static const struct i915_power_well_desc ehl_power_wells[] = {
	{
		.name = "always-on",
		.always_on = true,
		.domains = POWER_DOMAIN_MASK,
		.ops = &i9xx_always_on_power_well_ops,
		.id = DISP_PW_ID_NONE,
	},
	{
		.name = "power well 1",
		/* Handled by the DMC firmware */
		.always_on = true,
		.domains = 0,
		.ops = &hsw_power_well_ops,
		.id = SKL_DISP_PW_1,
		{
			.hsw.regs = &hsw_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_PW_1,
			.hsw.has_fuses = true,
		},
	},
	{
		.name = "DC off",
		.domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS,
		.ops = &gen9_dc_off_power_well_ops,
		.id = SKL_DISP_DC_OFF,
	},
	{
		.name = "power well 2",
		.domains = ICL_PW_2_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = SKL_DISP_PW_2,
		{
			.hsw.regs = &hsw_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_PW_2,
			.hsw.has_fuses = true,
		},
	},
	{
		.name = "power well 3",
		.domains = ICL_PW_3_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &hsw_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_PW_3,
			.hsw.irq_pipe_mask = BIT(PIPE_B),
			.hsw.has_vga = true,
			.hsw.has_fuses = true,
		},
	},
	{
		.name = "DDI A IO",
		.domains = ICL_DDI_IO_A_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_ddi_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_DDI_A,
		},
	},
	{
		.name = "DDI B IO",
		.domains = ICL_DDI_IO_B_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_ddi_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_DDI_B,
		},
	},
	{
		.name = "DDI C IO",
		.domains = ICL_DDI_IO_C_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_ddi_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_DDI_C,
		},
	},
	{
		.name = "DDI D IO",
		.domains = ICL_DDI_IO_D_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_ddi_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_DDI_D,
		},
	},
	{
		.name = "AUX A",
		.domains = ICL_AUX_A_IO_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_aux_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_AUX_A,
		},
	},
	{
		.name = "AUX B",
		.domains = ICL_AUX_B_IO_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_aux_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_AUX_B,
		},
	},
	{
		.name = "AUX C",
		.domains = ICL_AUX_C_TC1_IO_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_aux_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_AUX_C,
		},
	},
	{
		.name = "AUX D",
		.domains = ICL_AUX_D_TC2_IO_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_aux_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_AUX_D,
		},
	},
	{
		.name = "power well 4",
		.domains = ICL_PW_4_POWER_DOMAINS,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &hsw_power_well_regs,
			.hsw.idx = ICL_PW_CTL_IDX_PW_4,
			.hsw.has_fuses = true,
			.hsw.irq_pipe_mask = BIT(PIPE_C),
		},
	},
};

static const struct i915_power_well_desc tgl_power_wells[] = {
	{
		.name = "always-on",
@@ -3832,7 +3977,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
	{
		.name = "AUX A",
		.domains = TGL_AUX_A_IO_POWER_DOMAINS,
		.ops = &icl_combo_phy_aux_power_well_ops,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_aux_power_well_regs,
@@ -3842,7 +3987,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
	{
		.name = "AUX B",
		.domains = TGL_AUX_B_IO_POWER_DOMAINS,
		.ops = &icl_combo_phy_aux_power_well_ops,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_aux_power_well_regs,
@@ -3852,7 +3997,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
	{
		.name = "AUX C",
		.domains = TGL_AUX_C_IO_POWER_DOMAINS,
		.ops = &icl_combo_phy_aux_power_well_ops,
		.ops = &hsw_power_well_ops,
		.id = DISP_PW_ID_NONE,
		{
			.hsw.regs = &icl_aux_power_well_regs,
@@ -4162,6 +4307,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
	 */
	if (IS_GEN(dev_priv, 12)) {
		err = set_power_wells(power_domains, tgl_power_wells);
	} else if (IS_ELKHARTLAKE(dev_priv)) {
		err = set_power_wells(power_domains, ehl_power_wells);
	} else if (IS_GEN(dev_priv, 11)) {
		err = set_power_wells(power_domains, icl_power_wells);
	} else if (IS_CANNONLAKE(dev_priv)) {
+1 −2
Original line number Diff line number Diff line
@@ -2167,8 +2167,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
	ext_data.fpriv = file->driver_priv;
	if (client_is_banned(ext_data.fpriv)) {
		DRM_DEBUG("client %s[%d] banned from creating ctx\n",
			  current->comm,
			  pid_nr(get_task_pid(current, PIDTYPE_PID)));
			  current->comm, task_pid_nr(current));
		return -EIO;
	}

+2 −0
Original line number Diff line number Diff line
@@ -2694,6 +2694,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
	err = eb_submit(&eb);
err_request:
	add_to_client(eb.request, file);
	i915_request_get(eb.request);
	i915_request_add(eb.request);

	if (fences)
@@ -2709,6 +2710,7 @@ err_request:
			fput(out_fence->file);
		}
	}
	i915_request_put(eb.request);

err_batch_unpin:
	if (eb.batch_flags & I915_DISPATCH_SECURE)
+60 −4
Original line number Diff line number Diff line
@@ -36,13 +36,32 @@

#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))

static int vgpu_pin_dma_address(struct intel_vgpu *vgpu,
				unsigned long size,
				dma_addr_t dma_addr)
{
	int ret = 0;

	if (intel_gvt_hypervisor_dma_pin_guest_page(vgpu, dma_addr))
		ret = -EINVAL;

	return ret;
}

static void vgpu_unpin_dma_address(struct intel_vgpu *vgpu,
				   dma_addr_t dma_addr)
{
	intel_gvt_hypervisor_dma_unmap_guest_page(vgpu, dma_addr);
}

static int vgpu_gem_get_pages(
		struct drm_i915_gem_object *obj)
{
	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
	struct intel_vgpu *vgpu;
	struct sg_table *st;
	struct scatterlist *sg;
	int i, ret;
	int i, j, ret;
	gen8_pte_t __iomem *gtt_entries;
	struct intel_vgpu_fb_info *fb_info;
	u32 page_num;
@@ -51,6 +70,10 @@ static int vgpu_gem_get_pages(
	if (WARN_ON(!fb_info))
		return -ENODEV;

	vgpu = fb_info->obj->vgpu;
	if (WARN_ON(!vgpu))
		return -ENODEV;

	st = kmalloc(sizeof(*st), GFP_KERNEL);
	if (unlikely(!st))
		return -ENOMEM;
@@ -64,21 +87,53 @@ static int vgpu_gem_get_pages(
	gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
		(fb_info->start >> PAGE_SHIFT);
	for_each_sg(st->sgl, sg, page_num, i) {
		dma_addr_t dma_addr =
			GEN8_DECODE_PTE(readq(&gtt_entries[i]));
		if (vgpu_pin_dma_address(vgpu, PAGE_SIZE, dma_addr)) {
			ret = -EINVAL;
			goto out;
		}

		sg->offset = 0;
		sg->length = PAGE_SIZE;
		sg_dma_address(sg) =
			GEN8_DECODE_PTE(readq(&gtt_entries[i]));
		sg_dma_len(sg) = PAGE_SIZE;
		sg_dma_address(sg) = dma_addr;
	}

	__i915_gem_object_set_pages(obj, st, PAGE_SIZE);
out:
	if (ret) {
		dma_addr_t dma_addr;

		for_each_sg(st->sgl, sg, i, j) {
			dma_addr = sg_dma_address(sg);
			if (dma_addr)
				vgpu_unpin_dma_address(vgpu, dma_addr);
		}
		sg_free_table(st);
		kfree(st);
	}

	return ret;

	return 0;
}

static void vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
		struct sg_table *pages)
{
	struct scatterlist *sg;

	if (obj->base.dma_buf) {
		struct intel_vgpu_fb_info *fb_info = obj->gvt_info;
		struct intel_vgpu_dmabuf_obj *obj = fb_info->obj;
		struct intel_vgpu *vgpu = obj->vgpu;
		int i;

		for_each_sg(pages->sgl, sg, fb_info->size, i)
			vgpu_unpin_dma_address(vgpu,
					       sg_dma_address(sg));
	}

	sg_free_table(pages);
	kfree(pages);
}
@@ -163,6 +218,7 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev,
	drm_gem_private_object_init(dev, &obj->base,
		roundup(info->size, PAGE_SIZE));
	i915_gem_object_init(obj, &intel_vgpu_gem_ops, &lock_class);
	i915_gem_object_set_readonly(obj);

	obj->read_domains = I915_GEM_DOMAIN_GTT;
	obj->write_domain = 0;
Loading