@@ -42,16 +42,6 @@ const VMX_PREEMPTION_TIMER_SET_VALUE: u32 = 1_000_000;
4242const QEMU_EXIT_PORT : u16 = 0x604 ;
4343const QEMU_EXIT_MAGIC : u64 = 0x2000 ;
4444
45- pub struct XState {
46- host_xcr0 : u64 ,
47- guest_xcr0 : u64 ,
48- host_xss : u64 ,
49- guest_xss : u64 ,
50-
51- xsave_available : bool ,
52- xsaves_available : bool ,
53- }
54-
5545#[ derive( PartialEq , Eq , Debug ) ]
5646pub enum VmCpuMode {
5747 Real ,
@@ -60,97 +50,6 @@ pub enum VmCpuMode {
6050 Mode64 , // IA-32E mode (CS.L = 1)
6151}
6252
63- impl XState {
64- /// Create a new [`XState`] instance with current host state
65- fn new ( ) -> Self {
66- // Check if XSAVE is available
67- let xsave_available = Self :: xsave_available ( ) ;
68- // Check if XSAVES and XRSTORS (as well as IA32_XSS) are available
69- let xsaves_available = if xsave_available {
70- Self :: xsaves_available ( )
71- } else {
72- false
73- } ;
74-
75- // Read XCR0 iff XSAVE is available
76- let xcr0 = if xsave_available {
77- unsafe { xcr0_read ( ) . bits ( ) }
78- } else {
79- 0
80- } ;
81- // Read IA32_XSS iff XSAVES is available
82- let xss = if xsaves_available {
83- Msr :: IA32_XSS . read ( )
84- } else {
85- 0
86- } ;
87-
88- Self {
89- host_xcr0 : xcr0,
90- guest_xcr0 : xcr0,
91- host_xss : xss,
92- guest_xss : xss,
93- xsave_available,
94- xsaves_available,
95- }
96- }
97-
98- /// Enable extended processor state management instructions, including XGETBV and XSAVE.
99- pub fn enable_xsave ( ) {
100- if Self :: xsave_available ( ) {
101- unsafe { Cr4 :: write ( Cr4 :: read ( ) | Cr4Flags :: OSXSAVE ) } ;
102- }
103- }
104-
105- /// Check if XSAVE is available on the current CPU.
106- pub fn xsave_available ( ) -> bool {
107- let cpuid = CpuId :: new ( ) ;
108- cpuid
109- . get_feature_info ( )
110- . map ( |f| f. has_xsave ( ) )
111- . unwrap_or ( false )
112- }
113-
114- /// Check if XSAVES and XRSTORS (as well as IA32_XSS) are available on the current CPU.
115- pub fn xsaves_available ( ) -> bool {
116- let cpuid = CpuId :: new ( ) ;
117- cpuid
118- . get_extended_state_info ( )
119- . map ( |f| f. has_xsaves_xrstors ( ) )
120- . unwrap_or ( false )
121- }
122-
123- /// Save the current host XCR0 and IA32_XSS values and load the guest values.
124- pub fn switch_to_guest ( & mut self ) {
125- unsafe {
126- if self . xsave_available {
127- self . host_xcr0 = xcr0_read ( ) . bits ( ) ;
128- xcr0_write ( Xcr0 :: from_bits_unchecked ( self . guest_xcr0 ) ) ;
129-
130- if self . xsaves_available {
131- self . host_xss = Msr :: IA32_XSS . read ( ) ;
132- Msr :: IA32_XSS . write ( self . guest_xss ) ;
133- }
134- }
135- }
136- }
137-
138- /// Save the current guest XCR0 and IA32_XSS values and load the host values.
139- pub fn switch_to_host ( & mut self ) {
140- unsafe {
141- if self . xsave_available {
142- self . guest_xcr0 = xcr0_read ( ) . bits ( ) ;
143- xcr0_write ( Xcr0 :: from_bits_unchecked ( self . host_xcr0 ) ) ;
144-
145- if self . xsaves_available {
146- self . guest_xss = Msr :: IA32_XSS . read ( ) ;
147- Msr :: IA32_XSS . write ( self . host_xss ) ;
148- }
149- }
150- }
151- }
152- }
153-
15453const MSR_IA32_EFER_LMA_BIT : u64 = 1 << 10 ;
15554const CR0_PE : usize = 1 << 0 ;
15655
@@ -169,10 +68,7 @@ pub struct VmxVcpu<H: AxVCpuHal> {
16968
17069 pending_events : VecDeque < ( u8 , Option < u32 > ) > ,
17170 // xstate: XState,
172- /// XState used by the guest OS, loaded before running the guest.
173- guest_xstate : XState ,
174- /// XState used by the hypervisor itself, stored before running the guest.
175- cur_xstate : XState ,
71+ xstate : XState ,
17672 entry : Option < GuestPhysAddr > ,
17773 ept_root : Option < HostPhysAddr > ,
17874
@@ -191,8 +87,7 @@ impl<H: AxVCpuHal> VmxVcpu<H> {
19187 msr_bitmap : MsrBitmap :: passthrough_all ( ) ?,
19288 eptp_list : EptpList :: new ( ) ?,
19389 pending_events : VecDeque :: with_capacity ( 8 ) ,
194- guest_xstate : XState :: new ( ) ,
195- cur_xstate : XState :: new ( ) ,
90+ xstate : XState :: new ( ) ,
19691 entry : None ,
19792 ept_root : None ,
19893 id,
@@ -1315,7 +1210,7 @@ impl<H: AxVCpuHal> VmxVcpu<H> {
13151210 } )
13161211 . ok_or ( ax_err_type ! ( InvalidInput ) )
13171212 . and_then ( |x| {
1318- self . guest_xstate . xcr0 = x;
1213+ self . xstate . guest_xcr0 = x. bits ( ) ;
13191214 self . advance_rip ( VM_EXIT_INSTR_LEN_XSETBV )
13201215 } )
13211216 } else {
@@ -1329,15 +1224,16 @@ impl<H: AxVCpuHal> VmxVcpu<H> {
13291224 ///
13301225 /// This function is generally called before VM-entry.
13311226 fn load_guest_xstate ( & mut self ) {
1332- self . xstate . switch_to_guest ( ) ;
1227+ // FIXME: Linux will throw a UD exception if we save/restore xstate.
1228+ // self.xstate.switch_to_guest();
13331229 }
13341230
13351231 /// Save the current guest state to the vcpu,
13361232 /// restore the host state from the vcpu into registers.
13371233 ///
13381234 /// This function is generally called after VM-exit.
13391235 fn load_host_xstate ( & mut self ) {
1340- self . xstate . switch_to_host ( ) ;
1236+ // self.xstate.switch_to_host();
13411237 }
13421238}
13431239
0 commit comments