From: Zhi Wang <zhi.wang.linux@xxxxxxxxx> To support the early init of GVT-g, which will be put in i915, after the GVT-g is moved into a dedicated module, we need to save the MMIO snapshot in the early init of GVT-g, when the HW hasn't been touched. v3: - Fix errors when CONFIG_DRM_I915_WERROR is turned on. (Jani) Cc: Christoph Hellwig <hch@xxxxxx> Cc: Jason Gunthorpe <jgg@xxxxxxxxxx> Cc: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Vivi Rodrigo <rodrigo.vivi@xxxxxxxxx> Cc: Zhenyu Wang <zhenyuw@xxxxxxxxxxxxxxx> Cc: Zhi Wang <zhi.a.wang@xxxxxxxxx> Tested-by: Terrence Xu <terrence.xu@xxxxxxxxx> Signed-off-by: Zhi Wang <zhi.wang.linux@xxxxxxxxx> --- drivers/gpu/drm/i915/gvt/firmware.c | 40 +----------- drivers/gpu/drm/i915/gvt/handlers.c | 39 ------------ drivers/gpu/drm/i915/gvt/mmio_info_table.c | 72 +++++++++++++++++++++- drivers/gpu/drm/i915/gvt/mmio_info_table.h | 3 + 4 files changed, 77 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/firmware.c b/drivers/gpu/drm/i915/gvt/firmware.c index 1a8274a3f4b1..28719c2f253f 100644 --- a/drivers/gpu/drm/i915/gvt/firmware.c +++ b/drivers/gpu/drm/i915/gvt/firmware.c @@ -66,12 +66,6 @@ static struct bin_attribute firmware_attr = { .mmap = NULL, }; -static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data) -{ - *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore, - _MMIO(offset)); - return 0; -} static int expose_firmware_sysfs(struct intel_gvt *gvt) { @@ -81,7 +75,7 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt) void *firmware; void *p; unsigned long size, crc32_start; - int i, ret; + int ret; size = sizeof(*h) + info->mmio_size + info->cfg_space_size; firmware = vzalloc(size); @@ -99,17 +93,11 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt) p = firmware + h->cfg_space_offset; - for (i = 0; i < h->cfg_space_size; i += 4) - pci_read_config_dword(pdev, i, p + i); - - memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size); + memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size); p = firmware + h->mmio_offset; - /* Take a snapshot of hw mmio registers. */ - intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p); - - memcpy(gvt->firmware.mmio, p, info->mmio_size); + memcpy(p, gvt->firmware.mmio, info->mmio_size); crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4; h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start); @@ -142,9 +130,6 @@ void intel_gvt_free_firmware(struct intel_gvt *gvt) { if (!gvt->firmware.firmware_loaded) clean_firmware_sysfs(gvt); - - kfree(gvt->firmware.cfg_space); - vfree(gvt->firmware.mmio); } static int verify_firmware(struct intel_gvt *gvt, @@ -204,36 +189,17 @@ static int verify_firmware(struct intel_gvt *gvt, */ int intel_gvt_load_firmware(struct intel_gvt *gvt) { - struct intel_gvt_device_info *info = &gvt->device_info; struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev); struct intel_gvt_firmware *firmware = &gvt->firmware; struct gvt_firmware_header *h; const struct firmware *fw; char *path; - void *mem; int ret; path = kmalloc(PATH_MAX, GFP_KERNEL); if (!path) return -ENOMEM; - mem = kmalloc(info->cfg_space_size, GFP_KERNEL); - if (!mem) { - kfree(path); - return -ENOMEM; - } - - firmware->cfg_space = mem; - - mem = vmalloc(info->mmio_size); - if (!mem) { - kfree(path); - kfree(firmware->cfg_space); - return -ENOMEM; - } - - firmware->mmio = mem; - sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%02x.golden_hw_state", GVT_FIRMWARE_PATH, pdev->vendor, pdev->device, pdev->revision); diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 2c064da3db6d..ba7b330a2c71 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -2406,45 +2406,6 @@ int intel_gvt_setup_mmio_handlers(struct intel_gvt *gvt) return ret; } -/** - * intel_gvt_for_each_tracked_mmio - iterate each tracked mmio - * @gvt: a GVT device - * @handler: the handler - * @data: private data given to handler - * - * Returns: - * Zero on success, negative error code if failed. - */ -int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt, - int (*handler)(struct intel_gvt *gvt, u32 offset, void *data), - void *data) -{ - struct gvt_mmio_block *block = gvt->mmio.mmio_block; - struct intel_gvt_mmio_info *e; - int i, j, ret; - - hash_for_each(gvt->mmio.mmio_info_table, i, e, node) { - ret = handler(gvt, e->offset, data); - if (ret) - return ret; - } - - for (i = 0; i < gvt->mmio.num_mmio_block; i++, block++) { - /* pvinfo data doesn't come from hw mmio */ - if (i915_mmio_reg_offset(block->offset) == VGT_PVINFO_PAGE) - continue; - - for (j = 0; j < block->size; j += 4) { - ret = handler(gvt, - i915_mmio_reg_offset(block->offset) + j, - data); - if (ret) - return ret; - } - } - return 0; -} - /** * intel_vgpu_default_mmio_read - default MMIO read handler * @vgpu: a vGPU diff --git a/drivers/gpu/drm/i915/gvt/mmio_info_table.c b/drivers/gpu/drm/i915/gvt/mmio_info_table.c index 723190c25313..76535e3cc9ba 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_info_table.c +++ b/drivers/gpu/drm/i915/gvt/mmio_info_table.c @@ -1398,6 +1398,54 @@ void intel_gvt_clean_mmio_info(struct intel_gvt *gvt) vfree(gvt->mmio.mmio_attribute); gvt->mmio.mmio_attribute = NULL; + kfree(gvt->firmware.cfg_space); + vfree(gvt->firmware.mmio); +} + +static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data) +{ + *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore, + _MMIO(offset)); + return 0; +} + +/** + * intel_gvt_for_each_tracked_mmio - iterate each tracked mmio + * @gvt: a GVT device + * @handler: the handler + * @data: private data given to handler + * + * Returns: + * Zero on success, negative error code if failed. + */ +int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt, + int (*handler)(struct intel_gvt *gvt, u32 offset, void *data), + void *data) +{ + struct gvt_mmio_block *block = gvt->mmio.mmio_block; + struct intel_gvt_mmio_info *e; + int i, j, ret; + + hash_for_each(gvt->mmio.mmio_info_table, i, e, node) { + ret = handler(gvt, e->offset, data); + if (ret) + return ret; + } + + for (i = 0; i < gvt->mmio.num_mmio_block; i++, block++) { + /* pvinfo data doesn't come from hw mmio */ + if (i915_mmio_reg_offset(block->offset) == VGT_PVINFO_PAGE) + continue; + + for (j = 0; j < block->size; j += 4) { + ret = handler(gvt, + i915_mmio_reg_offset(block->offset) + j, + data); + if (ret) + return ret; + } + } + return 0; } /** @@ -1414,8 +1462,10 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt) { struct intel_gvt_device_info *info = &gvt->device_info; struct drm_i915_private *i915 = gvt->gt->i915; + struct pci_dev *pdev = to_pci_dev(i915->drm.dev); int size = info->mmio_size / 4 * sizeof(*gvt->mmio.mmio_attribute); - int ret; + void *mem; + int i, ret; gvt->mmio.mmio_attribute = vzalloc(size); if (!gvt->mmio.mmio_attribute) @@ -1454,6 +1504,26 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt) gvt->mmio.mmio_block = mmio_blocks; gvt->mmio.num_mmio_block = ARRAY_SIZE(mmio_blocks); + mem = kzalloc(info->cfg_space_size, GFP_KERNEL); + if (!mem) + goto err; + + gvt->firmware.cfg_space = mem; + + for (i = 0; i < info->cfg_space_size; i += 4) + pci_read_config_dword(pdev, i, mem + i); + + mem = vzalloc(info->mmio_size); + if (!mem) { + kfree(gvt->firmware.cfg_space); + goto err; + } + + gvt->firmware.mmio = mem; + + /* Take a snapshot of hw mmio registers. */ + intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, mem); + return 0; err: intel_gvt_clean_mmio_info(gvt); diff --git a/drivers/gpu/drm/i915/gvt/mmio_info_table.h b/drivers/gpu/drm/i915/gvt/mmio_info_table.h index 0303fd447330..7572b255d5d0 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_info_table.h +++ b/drivers/gpu/drm/i915/gvt/mmio_info_table.h @@ -29,6 +29,9 @@ unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt); bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device); +int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt, + int (*handler)(struct intel_gvt *gvt, u32 offset, void *data), + void *data); struct intel_gvt_mmio_info *intel_gvt_find_mmio_info(struct intel_gvt *gvt, unsigned int offset); int intel_gvt_setup_mmio_info(struct intel_gvt *gvt); -- 2.25.1