mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 15:43:35 -04:00
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: Zhi Wang <zhi.a.wang@intel.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Tested-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com> Acked-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20220407071945.72148-3-zhi.a.wang@intel.com
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user