@@ -213,16 +213,55 @@ 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 )
217
+ {
218
+ u8 * buf ;
219
+ struct opregion_header * header ;
220
+ struct vbt v ;
221
+
222
+ gvt_dbg_core ("init vgpu%d opregion\n" , vgpu -> id );
223
+ vgpu_opregion (vgpu )-> va = (void * )__get_free_pages (GFP_KERNEL |
224
+ __GFP_ZERO ,
225
+ get_order (INTEL_GVT_OPREGION_SIZE ));
226
+ if (!vgpu_opregion (vgpu )-> va ) {
227
+ gvt_err ("fail to get memory for vgpu virt opregion\n" );
228
+ return - ENOMEM ;
229
+ }
230
+
231
+ /* emulated opregion with VBT mailbox only */
232
+ buf = (u8 * )vgpu_opregion (vgpu )-> va ;
233
+ header = (struct opregion_header * )buf ;
234
+ memcpy (header -> signature , OPREGION_SIGNATURE ,
235
+ sizeof (OPREGION_SIGNATURE ));
236
+ header -> size = 0x8 ;
237
+ header -> opregion_ver = 0x02000000 ;
238
+ header -> mboxes = MBOX_VBT ;
239
+
240
+ /* for unknown reason, the value in LID field is incorrect
241
+ * which block the windows guest, so workaround it by force
242
+ * setting it to "OPEN"
243
+ */
244
+ buf [INTEL_GVT_OPREGION_CLID ] = 0x3 ;
245
+
246
+ /* emulated vbt from virt vbt generation */
247
+ virt_vbt_generation (& v );
248
+ memcpy (buf + INTEL_GVT_OPREGION_VBT_OFFSET , & v , sizeof (struct vbt ));
249
+
250
+ return 0 ;
251
+ }
252
+
216
253
static int init_vgpu_opregion (struct intel_vgpu * vgpu , u32 gpa )
217
254
{
218
- int i ;
255
+ int i , ret ;
219
256
220
257
if (WARN ((vgpu_opregion (vgpu )-> va ),
221
258
"vgpu%d: opregion has been initialized already.\n" ,
222
259
vgpu -> id ))
223
260
return - EINVAL ;
224
261
225
- vgpu_opregion (vgpu )-> va = vgpu -> gvt -> opregion .opregion_va ;
262
+ ret = alloc_and_init_virt_opregion (vgpu );
263
+ if (ret < 0 )
264
+ return ret ;
226
265
227
266
for (i = 0 ; i < INTEL_GVT_OPREGION_PAGES ; i ++ )
228
267
vgpu_opregion (vgpu )-> gfn [i ] = (gpa >> PAGE_SHIFT ) + i ;
@@ -304,64 +343,6 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa)
304
343
return 0 ;
305
344
}
306
345
307
- /**
308
- * intel_gvt_clean_opregion - clean host opergion related stuffs
309
- * @gvt: a GVT device
310
- *
311
- */
312
- void intel_gvt_clean_opregion (struct intel_gvt * gvt )
313
- {
314
- free_pages ((unsigned long )gvt -> opregion .opregion_va ,
315
- get_order (INTEL_GVT_OPREGION_SIZE ));
316
- gvt -> opregion .opregion_va = NULL ;
317
- }
318
-
319
- /**
320
- * intel_gvt_init_opregion - initialize host opergion related stuffs
321
- * @gvt: a GVT device
322
- *
323
- * Returns:
324
- * Zero on success, negative error code if failed.
325
- */
326
- int intel_gvt_init_opregion (struct intel_gvt * gvt )
327
- {
328
- u8 * buf ;
329
- struct opregion_header * header ;
330
- struct vbt v ;
331
-
332
- gvt_dbg_core ("init host opregion\n" );
333
-
334
- gvt -> opregion .opregion_va = (void * )__get_free_pages (GFP_KERNEL |
335
- __GFP_ZERO ,
336
- get_order (INTEL_GVT_OPREGION_SIZE ));
337
-
338
- if (!gvt -> opregion .opregion_va ) {
339
- gvt_err ("fail to get memory for virt opregion\n" );
340
- return - ENOMEM ;
341
- }
342
-
343
- /* emulated opregion with VBT mailbox only */
344
- buf = (u8 * )gvt -> opregion .opregion_va ;
345
- header = (struct opregion_header * )buf ;
346
- memcpy (header -> signature , OPREGION_SIGNATURE ,
347
- sizeof (OPREGION_SIGNATURE ));
348
- header -> size = 0x8 ;
349
- header -> opregion_ver = 0x02000000 ;
350
- header -> mboxes = MBOX_VBT ;
351
-
352
- /* for unknown reason, the value in LID field is incorrect
353
- * which block the windows guest, so workaround it by force
354
- * setting it to "OPEN"
355
- */
356
- buf [INTEL_GVT_OPREGION_CLID ] = 0x3 ;
357
-
358
- /* emulated vbt from virt vbt generation */
359
- virt_vbt_generation (& v );
360
- memcpy (buf + INTEL_GVT_OPREGION_VBT_OFFSET , & v , sizeof (struct vbt ));
361
-
362
- return 0 ;
363
- }
364
-
365
346
#define GVT_OPREGION_FUNC (scic ) \
366
347
({ \
367
348
u32 __ret; \
0 commit comments