@@ -88,6 +88,8 @@ pub enum CopyKvmFdError {
8888     CreateVcpuError ( #[ from]   kvm_ioctls:: Error ) , 
8989} 
9090
91+ thread_local ! ( static  TLS_VCPU_PTR :  VcpuCell  = const  {  Cell :: new( None )  } ) ; 
92+ 
9193/// A wrapper around creating and using a vcpu. 
9294#[ derive( Debug ) ]  
9395pub  struct  Vcpu  { 
@@ -110,61 +112,35 @@ pub struct Vcpu {
110112} 
111113
112114impl  Vcpu  { 
113-     thread_local ! ( static  TLS_VCPU_PTR :  VcpuCell  = const  {  Cell :: new( None )  } ) ; 
114- 
115115    /// Associates `self` with the current thread. 
116116     /// 
117117     /// It is a prerequisite to successfully run `init_thread_local_data()` before using 
118118     /// `run_on_thread_local()` on the current thread. 
119119     /// This function will panic if there already is a `Vcpu` present in the TLS. 
120120     fn  init_thread_local_data ( & mut  self )  { 
121-         Self :: TLS_VCPU_PTR . with ( |cell :  & VcpuCell | { 
121+         TLS_VCPU_PTR . with ( |cell :  & VcpuCell | { 
122122            assert ! ( cell. get( ) . is_none( ) ) ; 
123123            cell. set ( Some ( self  as  * mut  Vcpu ) ) ; 
124124        } ) 
125125    } 
126126
127-     /// Runs `func` for the `Vcpu` associated with the current thread. 
128-      /// 
129-      /// It requires that `init_thread_local_data()` was run on this thread. 
130-      /// 
131-      /// Fails if there is no `Vcpu` associated with the current thread. 
132-      /// 
133-      /// # Safety 
134-      /// 
135-      /// This is marked unsafe as it allows temporary aliasing through 
136-      /// dereferencing from pointer an already borrowed `Vcpu`. 
137-      unsafe  fn  run_on_thread_local < F > ( func :  F )  -> Result < ( ) ,  VcpuError > 
138-     where 
139-         F :  FnOnce ( & mut  Vcpu ) , 
140-     { 
141-         Self :: TLS_VCPU_PTR . with ( |cell :  & VcpuCell | { 
142-             if  let  Some ( vcpu_ptr)  = cell. get ( )  { 
143-                 // SAFETY: Dereferencing here is safe since `TLS_VCPU_PTR` is populated/non-empty, 
144-                 // and it is being cleared on `Vcpu::drop` so there is no dangling pointer. 
145-                 let  vcpu_ref = unsafe  {  & mut  * vcpu_ptr } ; 
146-                 func ( vcpu_ref) ; 
147-                 Ok ( ( ) ) 
148-             }  else  { 
149-                 Err ( VcpuError :: VcpuTlsNotPresent ) 
150-             } 
151-         } ) 
152-     } 
153- 
154127    /// Registers a signal handler which makes use of TLS and kvm immediate exit to 
155128     /// kick the vcpu running on the current thread, if there is one. 
156129     fn  register_kick_signal_handler ( & mut  self )  { 
157130        self . init_thread_local_data ( ) ; 
158131
159132        extern  "C"  fn  handle_signal ( _:  c_int ,  _:  * mut  siginfo_t ,  _:  * mut  c_void )  { 
160-             // SAFETY: This is safe because it's temporarily aliasing the `Vcpu` object, but we are 
161-             // only reading `vcpu.fd` which does not change for the lifetime of the `Vcpu`. 
162-             unsafe  { 
163-                 let  _ = Vcpu :: run_on_thread_local ( |vcpu| { 
133+             TLS_VCPU_PTR . with ( |cell :  & VcpuCell | { 
134+                 if  let  Some ( vcpu_ptr)  = cell. get ( )  { 
135+                     // SAFETY: Dereferencing here is safe since `TLS_VCPU_PTR` is 
136+                     // populated/non-empty, and it is being cleared on 
137+                     // `Vcpu::drop` so there is no dangling pointer. 
138+                     let  vcpu = unsafe  {  & mut  * vcpu_ptr } ; 
139+ 
164140                    vcpu. kvm_vcpu . fd . set_kvm_immediate_exit ( 1 ) ; 
165141                    fence ( Ordering :: Release ) ; 
166-                 } ) ; 
167-             } 
142+                 } 
143+             } ) 
168144        } 
169145
170146        register_signal_handler ( sigrtmin ( )  + VCPU_RTSIG_OFFSET ,  handle_signal) 
@@ -595,7 +571,7 @@ fn handle_kvm_exit(
595571
596572impl  Drop  for  Vcpu  { 
597573    fn  drop ( & mut  self )  { 
598-         Self :: TLS_VCPU_PTR . with ( |cell| { 
574+         TLS_VCPU_PTR . with ( |cell| { 
599575            // The reason for not asserting TLS being set here is that 
600576            // it can happen that Vcpu::Drop is called on vcpus which never were 
601577            // put on their threads. This can happen if some error occurs during Vmm 
@@ -611,7 +587,7 @@ impl Drop for Vcpu {
611587
612588                // Have to do this trick because `update` method is 
613589                // not stable on Cell. 
614-                 Self :: TLS_VCPU_PTR . with ( |cell| cell. take ( ) ) ; 
590+                 TLS_VCPU_PTR . with ( |cell| cell. take ( ) ) ; 
615591            } 
616592        } ) 
617593    } 
@@ -1017,34 +993,6 @@ pub(crate) mod tests {
1017993        assert ! ( vcpu. kvm_vcpu. peripherals. mmio_bus. is_some( ) ) ; 
1018994    } 
1019995
1020-     #[ test]  
1021-     fn  test_vcpu_tls ( )  { 
1022-         let  ( _,  _,  mut  vcpu)  = setup_vcpu ( 0x1000 ) ; 
1023- 
1024-         // Running on the TLS vcpu should fail before we actually initialize it. 
1025-         unsafe  { 
1026-             Vcpu :: run_on_thread_local ( |_| ( ) ) . unwrap_err ( ) ; 
1027-         } 
1028- 
1029-         // Initialize vcpu TLS. 
1030-         vcpu. init_thread_local_data ( ) ; 
1031- 
1032-         // Validate TLS vcpu is the local vcpu by changing the `id` then validating against 
1033-         // the one in TLS. 
1034-         vcpu. kvm_vcpu . index  = 12 ; 
1035-         unsafe  { 
1036-             Vcpu :: run_on_thread_local ( |v| assert_eq ! ( v. kvm_vcpu. index,  12 ) ) . unwrap ( ) ; 
1037-         } 
1038- 
1039-         // Reset vcpu TLS. 
1040-         Vcpu :: TLS_VCPU_PTR . with ( |cell| cell. take ( ) ) ; 
1041- 
1042-         // Running on the TLS vcpu after TLS reset should fail. 
1043-         unsafe  { 
1044-             Vcpu :: run_on_thread_local ( |_| ( ) ) . unwrap_err ( ) ; 
1045-         } 
1046-     } 
1047- 
1048996    #[ test]  
1049997    #[ should_panic]  
1050998    fn  test_tls_double_init ( )  { 
0 commit comments