Skip to content

Commit 4dff110

Browse files
xiongzhazhenyw
authored andcommitted
drm/i915/gvt: Alloc and Init guest opregion at vgpu creation
Currently guest opregion is allocated and initialised when guest write opregion base register. This is too late for kvmgt, so move it to vgpu_create time. Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com> Tested-by: Tina Zhang <tina.zhang@intel.com> Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
1 parent ea26c96 commit 4dff110

File tree

4 files changed

+53
-52
lines changed

4 files changed

+53
-52
lines changed

drivers/gpu/drm/i915/gvt/cfg_space.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
335335
case INTEL_GVT_PCI_OPREGION:
336336
if (WARN_ON(!IS_ALIGNED(offset, 4)))
337337
return -EINVAL;
338-
ret = intel_vgpu_init_opregion(vgpu, *(u32 *)p_data);
338+
ret = intel_vgpu_opregion_base_write_handler(vgpu,
339+
*(u32 *)p_data);
339340
if (ret)
340341
return ret;
341342

drivers/gpu/drm/i915/gvt/gvt.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ struct intel_vgpu_irq {
123123
};
124124

125125
struct intel_vgpu_opregion {
126+
bool mapped;
126127
void *va;
127128
u32 gfn[INTEL_GVT_OPREGION_PAGES];
128129
};
@@ -505,7 +506,8 @@ static inline u64 intel_vgpu_get_bar_gpa(struct intel_vgpu *vgpu, int bar)
505506
}
506507

507508
void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu);
508-
int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa);
509+
int intel_vgpu_init_opregion(struct intel_vgpu *vgpu);
510+
int intel_vgpu_opregion_base_write_handler(struct intel_vgpu *vgpu, u32 gpa);
509511

510512
int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci);
511513
void populate_pvinfo_page(struct intel_vgpu *vgpu);

drivers/gpu/drm/i915/gvt/opregion.c

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,15 @@ static void virt_vbt_generation(struct vbt *v)
213213
v->driver_features.lvds_config = BDB_DRIVER_FEATURE_NO_LVDS;
214214
}
215215

216-
static int alloc_and_init_virt_opregion(struct intel_vgpu *vgpu)
216+
/**
217+
* intel_vgpu_init_opregion - initialize the stuff used to emulate opregion
218+
* @vgpu: a vGPU
219+
* @gpa: guest physical address of opregion
220+
*
221+
* Returns:
222+
* Zero on success, negative error code if failed.
223+
*/
224+
int intel_vgpu_init_opregion(struct intel_vgpu *vgpu)
217225
{
218226
u8 *buf;
219227
struct opregion_header *header;
@@ -251,25 +259,6 @@ static int alloc_and_init_virt_opregion(struct intel_vgpu *vgpu)
251259
return 0;
252260
}
253261

254-
static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa)
255-
{
256-
int i, ret;
257-
258-
if (WARN((vgpu_opregion(vgpu)->va),
259-
"vgpu%d: opregion has been initialized already.\n",
260-
vgpu->id))
261-
return -EINVAL;
262-
263-
ret = alloc_and_init_virt_opregion(vgpu);
264-
if (ret < 0)
265-
return ret;
266-
267-
for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++)
268-
vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i;
269-
270-
return 0;
271-
}
272-
273262
static int map_vgpu_opregion(struct intel_vgpu *vgpu, bool map)
274263
{
275264
u64 mfn;
@@ -291,59 +280,62 @@ static int map_vgpu_opregion(struct intel_vgpu *vgpu, bool map)
291280
return ret;
292281
}
293282
}
283+
284+
vgpu_opregion(vgpu)->mapped = map;
285+
294286
return 0;
295287
}
296288

297289
/**
298-
* intel_vgpu_clean_opregion - clean the stuff used to emulate opregion
290+
* intel_vgpu_opregion_base_write_handler - Opregion base register write handler
291+
*
299292
* @vgpu: a vGPU
293+
* @gpa: guest physical address of opregion
300294
*
295+
* Returns:
296+
* Zero on success, negative error code if failed.
301297
*/
302-
void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu)
298+
int intel_vgpu_opregion_base_write_handler(struct intel_vgpu *vgpu, u32 gpa)
303299
{
304-
gvt_dbg_core("vgpu%d: clean vgpu opregion\n", vgpu->id);
305-
306-
if (!vgpu_opregion(vgpu)->va)
307-
return;
300+
int i, ret;
308301

309-
if (intel_gvt_host.hypervisor_type == INTEL_GVT_HYPERVISOR_XEN) {
302+
/**
303+
* Wins guest on Xengt will write this register twice: xen hvmloader and
304+
* windows graphic driver.
305+
*/
306+
if (vgpu_opregion(vgpu)->mapped)
310307
map_vgpu_opregion(vgpu, false);
311-
free_pages((unsigned long)vgpu_opregion(vgpu)->va,
312-
get_order(INTEL_GVT_OPREGION_SIZE));
313308

314-
vgpu_opregion(vgpu)->va = NULL;
315-
}
309+
for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++)
310+
vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i;
311+
312+
ret = map_vgpu_opregion(vgpu, true);
313+
314+
return ret;
316315
}
317316

318317
/**
319-
* intel_vgpu_init_opregion - initialize the stuff used to emulate opregion
318+
* intel_vgpu_clean_opregion - clean the stuff used to emulate opregion
320319
* @vgpu: a vGPU
321-
* @gpa: guest physical address of opregion
322320
*
323-
* Returns:
324-
* Zero on success, negative error code if failed.
325321
*/
326-
int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa)
322+
void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu)
327323
{
328-
int ret;
329-
330-
gvt_dbg_core("vgpu%d: init vgpu opregion\n", vgpu->id);
324+
gvt_dbg_core("vgpu%d: clean vgpu opregion\n", vgpu->id);
331325

332-
if (intel_gvt_host.hypervisor_type == INTEL_GVT_HYPERVISOR_XEN) {
333-
gvt_dbg_core("emulate opregion from kernel\n");
326+
if (!vgpu_opregion(vgpu)->va)
327+
return;
334328

335-
ret = init_vgpu_opregion(vgpu, gpa);
336-
if (ret)
337-
return ret;
329+
if (vgpu_opregion(vgpu)->mapped)
330+
map_vgpu_opregion(vgpu, false);
338331

339-
ret = map_vgpu_opregion(vgpu, true);
340-
if (ret)
341-
return ret;
342-
}
332+
free_pages((unsigned long)vgpu_opregion(vgpu)->va,
333+
get_order(INTEL_GVT_OPREGION_SIZE));
343334

344-
return 0;
335+
vgpu_opregion(vgpu)->va = NULL;
345336
}
346337

338+
347339
#define GVT_OPREGION_FUNC(scic) \
348340
({ \
349341
u32 __ret; \

drivers/gpu/drm/i915/gvt/vgpu.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,14 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
370370
if (ret)
371371
goto out_detach_hypervisor_vgpu;
372372

373-
ret = intel_vgpu_init_display(vgpu, param->resolution);
373+
ret = intel_vgpu_init_opregion(vgpu);
374374
if (ret)
375375
goto out_clean_gtt;
376376

377+
ret = intel_vgpu_init_display(vgpu, param->resolution);
378+
if (ret)
379+
goto out_clean_opregion;
380+
377381
ret = intel_vgpu_setup_submission(vgpu);
378382
if (ret)
379383
goto out_clean_display;
@@ -396,6 +400,8 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
396400
intel_vgpu_clean_submission(vgpu);
397401
out_clean_display:
398402
intel_vgpu_clean_display(vgpu);
403+
out_clean_opregion:
404+
intel_vgpu_clean_opregion(vgpu);
399405
out_clean_gtt:
400406
intel_vgpu_clean_gtt(vgpu);
401407
out_detach_hypervisor_vgpu:

0 commit comments

Comments
 (0)