@@ -282,6 +282,7 @@ impl VCpu {
282282 vmcs:: VmcsField :: SecondaryVmExecControl ,
283283 ( vmcs:: SecondaryExecFlags :: VIRTUALIZE_APIC_ACCESSES
284284 | vmcs:: SecondaryExecFlags :: ENABLE_EPT
285+ | vmcs:: SecondaryExecFlags :: ENABLE_RDTSCP
285286 | vmcs:: SecondaryExecFlags :: ENABLE_VPID
286287 | vmcs:: SecondaryExecFlags :: ENABLE_INVPCID
287288 | vmcs:: SecondaryExecFlags :: UNRESTRICTED_GUEST )
@@ -320,7 +321,17 @@ impl VCpu {
320321 msr:: IA32_VMX_ENTRY_CTLS ,
321322 ) ?;
322323
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+
324335 vmcs. write_field ( vmcs:: VmcsField :: MsrBitmap , msr_bitmap as u64 ) ?;
325336
326337 // Do not VMEXIT on any exceptions
@@ -476,6 +487,20 @@ impl VCpu {
476487 let mut responses = virtdev:: ResponseEventArray :: default ( ) ;
477488
478489 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+ }
479504 vmexit:: ExitInformation :: CrAccess ( info) => {
480505 emulate:: controlreg:: emulate_access ( self , guest_cpu, info) ?;
481506 self . skip_emulated_instruction ( ) ?;
0 commit comments