@@ -26,8 +26,12 @@ extern "C" {
2626const PER_CORE_HOST_STACK_SIZE : usize = 1024 * 1024 ;
2727
2828declare_per_core ! {
29+ // NOTE: The per-core stack cannot be part of the VCpu type because an
30+ // instance of VCpu will (briefly) reside _on_ the stack
2931 static mut HOST_STACK : [ u8 ; PER_CORE_HOST_STACK_SIZE ]
3032 = [ 0u8 ; PER_CORE_HOST_STACK_SIZE ] ;
33+
34+ static mut VCPU : Option <VCpu > = None ;
3135}
3236
3337/// The post-startup point where a core begins executing its statically
@@ -47,7 +51,7 @@ pub fn mp_entry_point() -> ! {
4751 vm
4852 } ;
4953
50- let mut vcpu = VCpu :: new ( vm) . expect ( "Failed to create vcpu" ) ;
54+ let vcpu = VCpu :: new ( vm) . expect ( "Failed to create vcpu" ) ;
5155
5256 let vm_id = vm. id ;
5357 let is_vm_bsp = vm. bsp_id ( ) == core_id;
@@ -108,17 +112,23 @@ impl VCpu {
108112 /// Note that the result must be `Pin`, as the `VCpu` pushes its own
109113 /// address on to the per-core host stack so it can be retrieved on
110114 /// VMEXIT.
111- pub fn new ( vm : & ' static VirtualMachine ) -> Result < Pin < Box < Self > > > {
115+ pub fn new ( vm : & ' static VirtualMachine ) -> Result < & ' static mut Self > {
112116 let vmx = vmx:: Vmx :: enable ( ) ?;
113117 let vmcs = vmcs:: Vmcs :: new ( ) ?. activate ( vmx) ?;
114118
115- let mut vcpu = Box :: pin ( Self {
119+ let vcpu = Self {
116120 vm : vm,
117121 vmcs : vmcs,
118122 local_apic : virtdev:: lapic:: LocalApic :: new ( ) ,
119123 stack : get_per_core_mut ! ( HOST_STACK ) ,
120124 pending_interrupts : BTreeMap :: new ( ) ,
121- } ) ;
125+ } ;
126+
127+ unsafe {
128+ // Move the VCpu off the stack to the final static location
129+ * get_per_core_mut ! ( VCPU ) = Some ( vcpu) ;
130+ }
131+ let vcpu = get_per_core_mut ! ( VCPU ) . as_mut ( ) . unwrap ( ) ;
122132
123133 // All VCpus in a VM must share the same address space
124134 let eptp = vcpu. vm . guest_space . eptp ( ) ;
@@ -136,13 +146,13 @@ impl VCpu {
136146 - mem:: size_of :: < * const Self > ( ) as u64 ;
137147
138148 // 'push' the address of this VCpu to the host stack for the vmexit
139- let raw_vcpu: * mut Self = ( & mut * vcpu) as * mut Self ;
149+ let raw_vcpu = vcpu as * mut Self ;
140150 unsafe {
141151 core:: ptr:: write ( stack_base as * mut * mut Self , raw_vcpu) ;
142152 }
143153
144154 Self :: initialize_host_vmcs ( & mut vcpu. vmcs , stack_base) ?;
145- Self :: initialize_guest_vmcs ( & mut vcpu) ?;
155+ Self :: initialize_guest_vmcs ( vcpu) ?;
146156 Self :: initialize_ctrl_vmcs ( & mut vcpu. vmcs ) ?;
147157
148158 Ok ( vcpu)
@@ -157,7 +167,7 @@ impl VCpu {
157167 }
158168
159169 /// Begin execution in the guest context for this core
160- pub fn launch ( self : Pin < Box < Self > > ) -> Result < !> {
170+ pub fn launch ( & mut self ) -> Result < !> {
161171 let rflags = unsafe { vmlaunch_wrapper ( ) } ;
162172 error:: check_vm_insruction ( rflags, "Failed to launch vm" . into ( ) ) ?;
163173
0 commit comments