@@ -282,6 +282,7 @@ impl VCpu {
282
282
vmcs:: VmcsField :: SecondaryVmExecControl ,
283
283
( vmcs:: SecondaryExecFlags :: VIRTUALIZE_APIC_ACCESSES
284
284
| vmcs:: SecondaryExecFlags :: ENABLE_EPT
285
+ | vmcs:: SecondaryExecFlags :: ENABLE_RDTSCP
285
286
| vmcs:: SecondaryExecFlags :: ENABLE_VPID
286
287
| vmcs:: SecondaryExecFlags :: ENABLE_INVPCID
287
288
| vmcs:: SecondaryExecFlags :: UNRESTRICTED_GUEST )
@@ -320,7 +321,17 @@ impl VCpu {
320
321
msr:: IA32_VMX_ENTRY_CTLS ,
321
322
) ?;
322
323
323
- let msr_bitmap = Box :: into_raw ( Box :: new ( Raw4kPage :: default ( ) ) ) ;
324
+ let mut msr_page = Raw4kPage :: default ( ) ;
325
+
326
+ // For now, we need to exit on MSR_IA32_APICBASE (msr=0x1b)
327
+ // so we can tell the kernel the platform it's running on
328
+ // doesn't support x2apic
329
+ // TODO(alschwalm): remove this once we support x2apic in
330
+ // the guest
331
+ msr_page. 0 [ 3 ] |= 1 << 3 ;
332
+
333
+ let msr_bitmap = Box :: into_raw ( Box :: new ( msr_page) ) ;
334
+
324
335
vmcs. write_field ( vmcs:: VmcsField :: MsrBitmap , msr_bitmap as u64 ) ?;
325
336
326
337
// Do not VMEXIT on any exceptions
@@ -476,6 +487,20 @@ impl VCpu {
476
487
let mut responses = virtdev:: ResponseEventArray :: default ( ) ;
477
488
478
489
match exit. info {
490
+ //TODO(alschwalm): Once we have guest x2apic support, remove this
491
+ vmexit:: ExitInformation :: RdMsr => {
492
+ match guest_cpu. rcx as u32 {
493
+ msr:: IA32_APIC_BASE => {
494
+ let mut real_apic_base =
495
+ unsafe { msr:: rdmsr ( msr:: IA32_APIC_BASE ) } ;
496
+ real_apic_base &= !( 1 << 10 ) ; // mask X2APIC_ENABLE
497
+ guest_cpu. rdx = real_apic_base >> 32 ;
498
+ guest_cpu. rax = real_apic_base & 0xffffffff ;
499
+ }
500
+ _ => unreachable ! ( ) ,
501
+ }
502
+ self . skip_emulated_instruction ( ) ?;
503
+ }
479
504
vmexit:: ExitInformation :: CrAccess ( info) => {
480
505
emulate:: controlreg:: emulate_access ( self , guest_cpu, info) ?;
481
506
self . skip_emulated_instruction ( ) ?;
0 commit comments