@@ -267,6 +267,44 @@ static int hax_vmx_enable_check(void)
267
267
return 0 ;
268
268
}
269
269
270
+ /*
271
+ * Allows the guest to read from and/or write to the specified MSRs without
272
+ * causing a VM exit.
273
+ * |start| is the start MSR address, |count| the number of MSRs. Together they
274
+ * specify a range of consecutive MSR addresses.
275
+ * |read| and |write| determine if each MSR can be read or written freely by the
276
+ * guest, respectively.
277
+ */
278
+ static void set_msr_access (uint32_t start , uint32_t count , bool read , bool write )
279
+ {
280
+ uint32_t end = start + count - 1 ;
281
+ uint32_t read_base , write_base , bit ;
282
+ uint8_t * msr_bitmap = hax_page_va (msr_bitmap_page );
283
+
284
+ hax_assert (((start ^ (start << 1 )) & 0x80000000 ) == 0 );
285
+ hax_assert ((start & 0x3fffe000 ) == 0 );
286
+ hax_assert (((start ^ end ) & 0xffffe000 ) == 0 );
287
+ hax_assert (msr_bitmap );
288
+
289
+ // See IA SDM Vol. 3C 24.6.9 for the layout of the MSR bitmaps page
290
+ read_base = start & 0x80000000 ? 1024 : 0 ;
291
+ write_base = read_base + 2048 ;
292
+ for (bit = (start & 0x1fff ); bit <= (end & 0x1fff ); bit ++ ) {
293
+ // Bit clear means allowed
294
+ if (read ) {
295
+ btr (msr_bitmap + read_base , bit );
296
+ } else {
297
+ bts (msr_bitmap + read_base , bit );
298
+ }
299
+
300
+ if (write ) {
301
+ btr (msr_bitmap + write_base , bit );
302
+ } else {
303
+ bts (msr_bitmap + write_base , bit );
304
+ }
305
+ }
306
+ }
307
+
270
308
static int hax_vmx_init (void )
271
309
{
272
310
int ret = - ENOMEM ;
@@ -297,6 +335,15 @@ static int hax_vmx_init(void)
297
335
if ((ret = hax_vmx_enable_check ()) < 0 )
298
336
goto out_5 ;
299
337
338
+ // Set MSRs loaded on VM entries/exits to pass-through
339
+ // See Intel SDM Vol. 3C 24.6.9 (MSR-Bitmap Address)
340
+
341
+ // 4 consecutive MSRs starting from IA32_STAR:
342
+ // IA32_STAR, IA32_LSTAR, IA32_CSTAR and IA32_SF_MASK
343
+ set_msr_access (IA32_STAR , 4 , true, true);
344
+ set_msr_access (IA32_KERNEL_GS_BASE , 1 , true, true);
345
+ set_msr_access (IA32_TSC_AUX , 1 , true, true);
346
+
300
347
return 0 ;
301
348
out_5 :
302
349
hax_disable_vmx ();
@@ -393,44 +440,6 @@ int hax_get_capability(void *buf, int bufLeng, int *outLength)
393
440
return 0 ;
394
441
}
395
442
396
- /*
397
- * Allows the guest to read from and/or write to the specified MSRs without
398
- * causing a VM exit.
399
- * |start| is the start MSR address, |count| the number of MSRs. Together they
400
- * specify a range of consecutive MSR addresses.
401
- * |read| and |write| determine if each MSR can be read or written freely by the
402
- * guest, respectively.
403
- */
404
- static void set_msr_access (uint32_t start , uint32_t count , bool read , bool write )
405
- {
406
- uint32_t end = start + count - 1 ;
407
- uint32_t read_base , write_base , bit ;
408
- uint8_t * msr_bitmap = hax_page_va (msr_bitmap_page );
409
-
410
- hax_assert (((start ^ (start << 1 )) & 0x80000000 ) == 0 );
411
- hax_assert ((start & 0x3fffe000 ) == 0 );
412
- hax_assert (((start ^ end ) & 0xffffe000 ) == 0 );
413
- hax_assert (msr_bitmap );
414
-
415
- // See IA SDM Vol. 3C 24.6.9 for the layout of the MSR bitmaps page
416
- read_base = start & 0x80000000 ? 1024 : 0 ;
417
- write_base = read_base + 2048 ;
418
- for (bit = (start & 0x1fff ); bit <= (end & 0x1fff ); bit ++ ) {
419
- // Bit clear means allowed
420
- if (read ) {
421
- btr (msr_bitmap + read_base , bit );
422
- } else {
423
- bts (msr_bitmap + read_base , bit );
424
- }
425
-
426
- if (write ) {
427
- btr (msr_bitmap + write_base , bit );
428
- } else {
429
- bts (msr_bitmap + write_base , bit );
430
- }
431
- }
432
- }
433
-
434
443
/*
435
444
* Probes the host CPU to determine its performance monitoring capabilities.
436
445
*/
0 commit comments