@@ -213,7 +213,15 @@ static void virt_vbt_generation(struct vbt *v)
213
213
v -> driver_features .lvds_config = BDB_DRIVER_FEATURE_NO_LVDS ;
214
214
}
215
215
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 )
217
225
{
218
226
u8 * buf ;
219
227
struct opregion_header * header ;
@@ -251,25 +259,6 @@ static int alloc_and_init_virt_opregion(struct intel_vgpu *vgpu)
251
259
return 0 ;
252
260
}
253
261
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
-
273
262
static int map_vgpu_opregion (struct intel_vgpu * vgpu , bool map )
274
263
{
275
264
u64 mfn ;
@@ -291,59 +280,62 @@ static int map_vgpu_opregion(struct intel_vgpu *vgpu, bool map)
291
280
return ret ;
292
281
}
293
282
}
283
+
284
+ vgpu_opregion (vgpu )-> mapped = map ;
285
+
294
286
return 0 ;
295
287
}
296
288
297
289
/**
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
+ *
299
292
* @vgpu: a vGPU
293
+ * @gpa: guest physical address of opregion
300
294
*
295
+ * Returns:
296
+ * Zero on success, negative error code if failed.
301
297
*/
302
- void intel_vgpu_clean_opregion (struct intel_vgpu * vgpu )
298
+ int intel_vgpu_opregion_base_write_handler (struct intel_vgpu * vgpu , u32 gpa )
303
299
{
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 ;
308
301
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 )
310
307
map_vgpu_opregion (vgpu , false);
311
- free_pages ((unsigned long )vgpu_opregion (vgpu )-> va ,
312
- get_order (INTEL_GVT_OPREGION_SIZE ));
313
308
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 ;
316
315
}
317
316
318
317
/**
319
- * intel_vgpu_init_opregion - initialize the stuff used to emulate opregion
318
+ * intel_vgpu_clean_opregion - clean the stuff used to emulate opregion
320
319
* @vgpu: a vGPU
321
- * @gpa: guest physical address of opregion
322
320
*
323
- * Returns:
324
- * Zero on success, negative error code if failed.
325
321
*/
326
- int intel_vgpu_init_opregion (struct intel_vgpu * vgpu , u32 gpa )
322
+ void intel_vgpu_clean_opregion (struct intel_vgpu * vgpu )
327
323
{
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 );
331
325
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 ;
334
328
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);
338
331
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 ));
343
334
344
- return 0 ;
335
+ vgpu_opregion ( vgpu ) -> va = NULL ;
345
336
}
346
337
338
+
347
339
#define GVT_OPREGION_FUNC (scic ) \
348
340
({ \
349
341
u32 __ret; \
0 commit comments