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

Commit bc9ebca2 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2018-04-19' of...

Merge tag 'drm-intel-next-fixes-2018-04-19' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

- Fix for FDO #105549: Avoid OOPS on bad VBT (Jani)
- Fix rare pre-emption race (Chris)
- Fix RC6 race against PM transitions (Tvrtko)

* tag 'drm-intel-next-fixes-2018-04-19' of git://anongit.freedesktop.org/drm/drm-intel:
  drm/i915/audio: Fix audio detection issue on GLK
  drm/i915: Call i915_perf_fini() on init_hw error unwind
  drm/i915/bios: filter out invalid DDC pins from VBT child devices
  drm/i915/pmu: Inspect runtime PM state more carefully while estimating RC6
  drm/i915: Do no use kfree() to free a kmem_cache_alloc() return value
  drm/i915/execlists: Clear user-active flag on preemption completion
  drm/i915/gvt: Add drm_format_mod update
  drm/i915/gvt: Disable primary/sprite/cursor plane at virtual display initialization
  drm/i915/gvt: Delete redundant error message in fb_decode.c
  drm/i915/gvt: Cancel dma map when resetting ggtt entries
  drm/i915/gvt: Missed to cancel dma map for ggtt entries
  drm/i915/gvt: Make MI_USER_INTERRUPT nop in cmd parser
  drm/i915/gvt: Mark expected switch fall-through in handle_g2v_notification
  drm/i915/gvt: throw error on unhandled vfio ioctls
parents e1898f99 b4615730
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -1080,6 +1080,7 @@ static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
{
{
	set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt,
	set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt,
			s->workload->pending_events);
			s->workload->pending_events);
	patch_value(s, cmd_ptr(s, 0), MI_NOOP);
	return 0;
	return 0;
}
}


+10 −0
Original line number Original line Diff line number Diff line
@@ -169,6 +169,8 @@ static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
{
{
	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
	int pipe;

	vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
	vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
			SDE_PORTC_HOTPLUG_CPT |
			SDE_PORTC_HOTPLUG_CPT |
			SDE_PORTD_HOTPLUG_CPT);
			SDE_PORTD_HOTPLUG_CPT);
@@ -267,6 +269,14 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
	if (IS_BROADWELL(dev_priv))
	if (IS_BROADWELL(dev_priv))
		vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;
		vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;


	/* Disable Primary/Sprite/Cursor plane */
	for_each_pipe(dev_priv, pipe) {
		vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
		vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
		vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~CURSOR_MODE;
		vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= CURSOR_MODE_DISABLE;
	}

	vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
	vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
}
}


+1 −0
Original line number Original line Diff line number Diff line
@@ -323,6 +323,7 @@ static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
		      struct intel_vgpu_fb_info *fb_info)
		      struct intel_vgpu_fb_info *fb_info)
{
{
	gvt_dmabuf->drm_format = fb_info->drm_format;
	gvt_dmabuf->drm_format = fb_info->drm_format;
	gvt_dmabuf->drm_format_mod = fb_info->drm_format_mod;
	gvt_dmabuf->width = fb_info->width;
	gvt_dmabuf->width = fb_info->width;
	gvt_dmabuf->height = fb_info->height;
	gvt_dmabuf->height = fb_info->height;
	gvt_dmabuf->stride = fb_info->stride;
	gvt_dmabuf->stride = fb_info->stride;
+9 −18
Original line number Original line Diff line number Diff line
@@ -245,16 +245,13 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
	plane->hw_format = fmt;
	plane->hw_format = fmt;


	plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
	plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
	if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
	if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
		gvt_vgpu_err("invalid gma address: %lx\n",
			     (unsigned long)plane->base);
		return  -EINVAL;
		return  -EINVAL;
	}


	plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
	plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
	if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
	if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
		gvt_vgpu_err("invalid gma address: %lx\n",
		gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n",
				(unsigned long)plane->base);
				plane->base);
		return  -EINVAL;
		return  -EINVAL;
	}
	}


@@ -371,16 +368,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
			alpha_plane, alpha_force);
			alpha_plane, alpha_force);


	plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
	plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
	if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
	if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
		gvt_vgpu_err("invalid gma address: %lx\n",
			     (unsigned long)plane->base);
		return  -EINVAL;
		return  -EINVAL;
	}


	plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
	plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
	if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
	if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
		gvt_vgpu_err("invalid gma address: %lx\n",
		gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n",
				(unsigned long)plane->base);
				plane->base);
		return  -EINVAL;
		return  -EINVAL;
	}
	}


@@ -476,16 +470,13 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
	plane->drm_format = drm_format;
	plane->drm_format = drm_format;


	plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
	plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
	if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
	if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
		gvt_vgpu_err("invalid gma address: %lx\n",
			     (unsigned long)plane->base);
		return  -EINVAL;
		return  -EINVAL;
	}


	plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
	plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
	if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
	if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
		gvt_vgpu_err("invalid gma address: %lx\n",
		gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n",
				(unsigned long)plane->base);
				plane->base);
		return  -EINVAL;
		return  -EINVAL;
	}
	}


+45 −7
Original line number Original line Diff line number Diff line
@@ -530,6 +530,16 @@ static void ggtt_set_guest_entry(struct intel_vgpu_mm *mm,
			   false, 0, mm->vgpu);
			   false, 0, mm->vgpu);
}
}


static void ggtt_get_host_entry(struct intel_vgpu_mm *mm,
		struct intel_gvt_gtt_entry *entry, unsigned long index)
{
	struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops;

	GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT);

	pte_ops->get_entry(NULL, entry, index, false, 0, mm->vgpu);
}

static void ggtt_set_host_entry(struct intel_vgpu_mm *mm,
static void ggtt_set_host_entry(struct intel_vgpu_mm *mm,
		struct intel_gvt_gtt_entry *entry, unsigned long index)
		struct intel_gvt_gtt_entry *entry, unsigned long index)
{
{
@@ -1818,6 +1828,18 @@ int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, unsigned int off,
	return ret;
	return ret;
}
}


static void ggtt_invalidate_pte(struct intel_vgpu *vgpu,
		struct intel_gvt_gtt_entry *entry)
{
	struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
	unsigned long pfn;

	pfn = pte_ops->get_pfn(entry);
	if (pfn != vgpu->gvt->gtt.scratch_mfn)
		intel_gvt_hypervisor_dma_unmap_guest_page(vgpu,
						pfn << PAGE_SHIFT);
}

static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
	void *p_data, unsigned int bytes)
	void *p_data, unsigned int bytes)
{
{
@@ -1844,10 +1866,10 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,


	memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
	memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
			bytes);
			bytes);
	m = e;


	if (ops->test_present(&e)) {
	if (ops->test_present(&e)) {
		gfn = ops->get_pfn(&e);
		gfn = ops->get_pfn(&e);
		m = e;


		/* one PTE update may be issued in multiple writes and the
		/* one PTE update may be issued in multiple writes and the
		 * first write may not construct a valid gfn
		 * first write may not construct a valid gfn
@@ -1868,8 +1890,12 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
			ops->set_pfn(&m, gvt->gtt.scratch_mfn);
			ops->set_pfn(&m, gvt->gtt.scratch_mfn);
		} else
		} else
			ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
			ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
	} else
	} else {
		ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index);
		ggtt_invalidate_pte(vgpu, &m);
		ops->set_pfn(&m, gvt->gtt.scratch_mfn);
		ops->set_pfn(&m, gvt->gtt.scratch_mfn);
		ops->clear_present(&m);
	}


out:
out:
	ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
	ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
@@ -2030,7 +2056,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
		return PTR_ERR(gtt->ggtt_mm);
		return PTR_ERR(gtt->ggtt_mm);
	}
	}


	intel_vgpu_reset_ggtt(vgpu);
	intel_vgpu_reset_ggtt(vgpu, false);


	return create_scratch_page_tree(vgpu);
	return create_scratch_page_tree(vgpu);
}
}
@@ -2315,17 +2341,19 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu)
/**
/**
 * intel_vgpu_reset_ggtt - reset the GGTT entry
 * intel_vgpu_reset_ggtt - reset the GGTT entry
 * @vgpu: a vGPU
 * @vgpu: a vGPU
 * @invalidate_old: invalidate old entries
 *
 *
 * This function is called at the vGPU create stage
 * This function is called at the vGPU create stage
 * to reset all the GGTT entries.
 * to reset all the GGTT entries.
 *
 *
 */
 */
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old)
{
{
	struct intel_gvt *gvt = vgpu->gvt;
	struct intel_gvt *gvt = vgpu->gvt;
	struct drm_i915_private *dev_priv = gvt->dev_priv;
	struct drm_i915_private *dev_priv = gvt->dev_priv;
	struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
	struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
	struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE};
	struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE};
	struct intel_gvt_gtt_entry old_entry;
	u32 index;
	u32 index;
	u32 num_entries;
	u32 num_entries;


@@ -2334,13 +2362,23 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)


	index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
	index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
	num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
	num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
	while (num_entries--)
	while (num_entries--) {
		if (invalidate_old) {
			ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
			ggtt_invalidate_pte(vgpu, &old_entry);
		}
		ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
		ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
	}


	index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
	index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
	num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
	num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
	while (num_entries--)
	while (num_entries--) {
		if (invalidate_old) {
			ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
			ggtt_invalidate_pte(vgpu, &old_entry);
		}
		ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
		ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
	}


	ggtt_invalidate(dev_priv);
	ggtt_invalidate(dev_priv);
}
}
@@ -2360,5 +2398,5 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
	 * removing the shadow pages.
	 * removing the shadow pages.
	 */
	 */
	intel_vgpu_destroy_all_ppgtt_mm(vgpu);
	intel_vgpu_destroy_all_ppgtt_mm(vgpu);
	intel_vgpu_reset_ggtt(vgpu);
	intel_vgpu_reset_ggtt(vgpu, true);
}
}
Loading