diff options
-rw-r--r-- | drivers/gpu/drm/i915/gvt/gvt.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/gvt.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/opregion.c | 101 |
3 files changed, 42 insertions, 78 deletions
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index cef06d5..3a74a40 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c @@ -323,7 +323,6 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv) intel_gvt_clean_cmd_parser(gvt); intel_gvt_clean_sched_policy(gvt); intel_gvt_clean_workload_scheduler(gvt); - intel_gvt_clean_opregion(gvt); intel_gvt_clean_gtt(gvt); intel_gvt_clean_irq(gvt); intel_gvt_clean_mmio_info(gvt); @@ -397,13 +396,9 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) if (ret) goto out_clean_irq; - ret = intel_gvt_init_opregion(gvt); - if (ret) - goto out_clean_gtt; - ret = intel_gvt_init_workload_scheduler(gvt); if (ret) - goto out_clean_opregion; + goto out_clean_gtt; ret = intel_gvt_init_sched_policy(gvt); if (ret) @@ -460,8 +455,6 @@ out_clean_sched_policy: intel_gvt_clean_sched_policy(gvt); out_clean_workload_scheduler: intel_gvt_clean_workload_scheduler(gvt); -out_clean_opregion: - intel_gvt_clean_opregion(gvt); out_clean_gtt: intel_gvt_clean_gtt(gvt); out_clean_irq: diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 27e8186..3930667 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -125,7 +125,6 @@ struct intel_vgpu_irq { struct intel_vgpu_opregion { void *va; u32 gfn[INTEL_GVT_OPREGION_PAGES]; - struct page *pages[INTEL_GVT_OPREGION_PAGES]; }; #define vgpu_opregion(vgpu) (&(vgpu->opregion)) @@ -265,11 +264,6 @@ struct intel_gvt_firmware { bool firmware_loaded; }; -struct intel_gvt_opregion { - void *opregion_va; - u32 opregion_pa; -}; - #define NR_MAX_INTEL_VGPU_TYPES 20 struct intel_vgpu_type { char name[16]; @@ -293,7 +287,6 @@ struct intel_gvt { struct intel_gvt_firmware firmware; struct intel_gvt_irq irq; struct intel_gvt_gtt gtt; - struct intel_gvt_opregion opregion; struct intel_gvt_workload_scheduler scheduler; struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES]; DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS); @@ -511,9 +504,6 @@ static inline u64 intel_vgpu_get_bar_gpa(struct intel_vgpu *vgpu, int bar) PCI_BASE_ADDRESS_MEM_MASK; } -void intel_gvt_clean_opregion(struct intel_gvt *gvt); -int intel_gvt_init_opregion(struct intel_gvt *gvt); - void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu); int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa); diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c index 2533d1e..80720e5 100644 --- a/drivers/gpu/drm/i915/gvt/opregion.c +++ b/drivers/gpu/drm/i915/gvt/opregion.c @@ -213,16 +213,55 @@ static void virt_vbt_generation(struct vbt *v) v->driver_features.lvds_config = BDB_DRIVER_FEATURE_NO_LVDS; } +static int alloc_and_init_virt_opregion(struct intel_vgpu *vgpu) +{ + u8 *buf; + struct opregion_header *header; + struct vbt v; + + gvt_dbg_core("init vgpu%d opregion\n", vgpu->id); + vgpu_opregion(vgpu)->va = (void *)__get_free_pages(GFP_KERNEL | + __GFP_ZERO, + get_order(INTEL_GVT_OPREGION_SIZE)); + if (!vgpu_opregion(vgpu)->va) { + gvt_err("fail to get memory for vgpu virt opregion\n"); + return -ENOMEM; + } + + /* emulated opregion with VBT mailbox only */ + buf = (u8 *)vgpu_opregion(vgpu)->va; + header = (struct opregion_header *)buf; + memcpy(header->signature, OPREGION_SIGNATURE, + sizeof(OPREGION_SIGNATURE)); + header->size = 0x8; + header->opregion_ver = 0x02000000; + header->mboxes = MBOX_VBT; + + /* for unknown reason, the value in LID field is incorrect + * which block the windows guest, so workaround it by force + * setting it to "OPEN" + */ + buf[INTEL_GVT_OPREGION_CLID] = 0x3; + + /* emulated vbt from virt vbt generation */ + virt_vbt_generation(&v); + memcpy(buf + INTEL_GVT_OPREGION_VBT_OFFSET, &v, sizeof(struct vbt)); + + return 0; +} + static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa) { - int i; + int i, ret; if (WARN((vgpu_opregion(vgpu)->va), "vgpu%d: opregion has been initialized already.\n", vgpu->id)) return -EINVAL; - vgpu_opregion(vgpu)->va = vgpu->gvt->opregion.opregion_va; + ret = alloc_and_init_virt_opregion(vgpu); + if (ret < 0) + return ret; for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++) vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i; @@ -304,64 +343,6 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa) return 0; } -/** - * intel_gvt_clean_opregion - clean host opergion related stuffs - * @gvt: a GVT device - * - */ -void intel_gvt_clean_opregion(struct intel_gvt *gvt) -{ - free_pages((unsigned long)gvt->opregion.opregion_va, - get_order(INTEL_GVT_OPREGION_SIZE)); - gvt->opregion.opregion_va = NULL; -} - -/** - * intel_gvt_init_opregion - initialize host opergion related stuffs - * @gvt: a GVT device - * - * Returns: - * Zero on success, negative error code if failed. - */ -int intel_gvt_init_opregion(struct intel_gvt *gvt) -{ - u8 *buf; - struct opregion_header *header; - struct vbt v; - - gvt_dbg_core("init host opregion\n"); - - gvt->opregion.opregion_va = (void *)__get_free_pages(GFP_KERNEL | - __GFP_ZERO, - get_order(INTEL_GVT_OPREGION_SIZE)); - - if (!gvt->opregion.opregion_va) { - gvt_err("fail to get memory for virt opregion\n"); - return -ENOMEM; - } - - /* emulated opregion with VBT mailbox only */ - buf = (u8 *)gvt->opregion.opregion_va; - header = (struct opregion_header *)buf; - memcpy(header->signature, OPREGION_SIGNATURE, - sizeof(OPREGION_SIGNATURE)); - header->size = 0x8; - header->opregion_ver = 0x02000000; - header->mboxes = MBOX_VBT; - - /* for unknown reason, the value in LID field is incorrect - * which block the windows guest, so workaround it by force - * setting it to "OPEN" - */ - buf[INTEL_GVT_OPREGION_CLID] = 0x3; - - /* emulated vbt from virt vbt generation */ - virt_vbt_generation(&v); - memcpy(buf + INTEL_GVT_OPREGION_VBT_OFFSET, &v, sizeof(struct vbt)); - - return 0; -} - #define GVT_OPREGION_FUNC(scic) \ ({ \ u32 __ret; \ |