Commit 66e7a806 authored by Zhi Wang's avatar Zhi Wang
Browse files

i915/gvt: Save the initial HW state snapshot in i915



Save the initial HW state snapshot in i915 so that the rest code of GVT-g
can be moved into a dedicated module while it can still get a clean
initial HW state saved at the correct time during the initialization of
i915. The futhrer vGPU created by GVT-g will use this HW state as the
initial HW state.

v6:
- Remove the reference of intel_gvt_device_info.(Christoph)
- Refine the save_mmio() function. (Christoph)

Cc: Christoph Hellwig <hch@lst.de>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Vivi Rodrigo <rodrigo.vivi@intel.com>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
Cc: Zhi Wang <zhi.a.wang@intel.com>
Signed-off-by: default avatarZhi Wang <zhi.a.wang@intel.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Tested-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Acked-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20220407071945.72148-3-zhi.a.wang@intel.com
parent e0f74ed4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -432,6 +432,8 @@ struct i915_virtual_gpu {
	struct mutex lock; /* serialises sending of g2v_notify command pkts */
	bool active;
	u32 caps;
	u32 *initial_mmio;
	u8 *initial_cfg_space;
};

struct i915_selftest_stash {
+90 −2
Original line number Diff line number Diff line
@@ -86,6 +86,85 @@ void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv)
	dev_priv->params.enable_gvt = 0;
}

static void free_initial_hw_state(struct drm_i915_private *dev_priv)
{
	struct i915_virtual_gpu *vgpu = &dev_priv->vgpu;

	vfree(vgpu->initial_mmio);
	vgpu->initial_mmio = NULL;

	kfree(vgpu->initial_cfg_space);
	vgpu->initial_cfg_space = NULL;
}

static void save_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset,
		      u32 size)
{
	struct drm_i915_private *dev_priv = iter->i915;
	u32 *mmio, i;

	for (i = offset; i < offset + size; i += 4) {
		mmio = iter->data + i;
		*mmio = intel_uncore_read_notrace(to_gt(dev_priv)->uncore,
						  _MMIO(i));
	}
}

static int handle_mmio(struct intel_gvt_mmio_table_iter *iter,
		       u32 offset, u32 size)
{
	if (WARN_ON(!IS_ALIGNED(offset, 4)))
		return -EINVAL;

	save_mmio(iter, offset, size);
	return 0;
}

static int save_initial_hw_state(struct drm_i915_private *dev_priv)
{
	struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
	struct i915_virtual_gpu *vgpu = &dev_priv->vgpu;
	struct intel_gvt_mmio_table_iter iter;
	void *mem;
	int i, ret;

	mem = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL);
	if (!mem)
		return -ENOMEM;

	vgpu->initial_cfg_space = mem;

	for (i = 0; i < PCI_CFG_SPACE_EXP_SIZE; i += 4)
		pci_read_config_dword(pdev, i, mem + i);

	mem = vzalloc(2 * SZ_1M);
	if (!mem) {
		ret = -ENOMEM;
		goto err_mmio;
	}

	vgpu->initial_mmio = mem;

	iter.i915 = dev_priv;
	iter.data = vgpu->initial_mmio;
	iter.handle_mmio_cb = handle_mmio;

	ret = intel_gvt_iterate_mmio_table(&iter);
	if (ret)
		goto err_iterate;

	return 0;

err_iterate:
	vfree(vgpu->initial_mmio);
	vgpu->initial_mmio = NULL;
err_mmio:
	kfree(vgpu->initial_cfg_space);
	vgpu->initial_cfg_space = NULL;

	return ret;
}

/**
 * intel_gvt_init - initialize GVT components
 * @dev_priv: drm i915 private data
@@ -115,15 +194,23 @@ int intel_gvt_init(struct drm_i915_private *dev_priv)
		return -EIO;
	}

	ret = save_initial_hw_state(dev_priv);
	if (ret) {
		drm_dbg(&dev_priv->drm, "Fail to save initial HW state\n");
		goto err_save_hw_state;
	}

	ret = intel_gvt_init_device(dev_priv);
	if (ret) {
		drm_dbg(&dev_priv->drm, "Fail to init GVT device\n");
		goto bail;
		goto err_init_device;
	}

	return 0;

bail:
err_init_device:
	free_initial_hw_state(dev_priv);
err_save_hw_state:
	dev_priv->params.enable_gvt = 0;
	return 0;
}
@@ -147,6 +234,7 @@ void intel_gvt_driver_remove(struct drm_i915_private *dev_priv)
		return;

	intel_gvt_clean_device(dev_priv);
	free_initial_hw_state(dev_priv);
}

/**