@@ -51,10 +51,6 @@ pub enum VcpuError {
51
51
VcpuResponse ( KvmVcpuError ) ,
52
52
/// Cannot spawn a new vCPU thread: {0}
53
53
VcpuSpawn ( io:: Error ) ,
54
- /// Cannot clean init vcpu TLS
55
- VcpuTlsInit ,
56
- /// Vcpu not present in TLS
57
- VcpuTlsNotPresent ,
58
54
/// Error with gdb request sent
59
55
#[ cfg( feature = "gdb" ) ]
60
56
GdbRequest ( GdbTargetError ) ,
@@ -119,33 +115,10 @@ impl Vcpu {
119
115
/// It is a prerequisite to successfully run `init_thread_local_data()` before using
120
116
/// `run_on_thread_local()` on the current thread.
121
117
/// This function will return an error if there already is a `Vcpu` present in the TLS.
122
- fn init_thread_local_data ( & mut self ) -> Result < ( ) , VcpuError > {
118
+ fn init_thread_local_data ( & mut self ) {
123
119
Self :: TLS_VCPU_PTR . with ( |cell : & VcpuCell | {
124
- if cell. get ( ) . is_some ( ) {
125
- return Err ( VcpuError :: VcpuTlsInit ) ;
126
- }
120
+ assert ! ( cell. get( ) . is_none( ) ) ;
127
121
cell. set ( Some ( self as * mut Vcpu ) ) ;
128
- Ok ( ( ) )
129
- } )
130
- }
131
-
132
- /// Deassociates `self` from the current thread.
133
- ///
134
- /// Should be called if the current `self` had called `init_thread_local_data()` and
135
- /// now needs to move to a different thread.
136
- ///
137
- /// Fails if `self` was not previously associated with the current thread.
138
- fn reset_thread_local_data ( & mut self ) -> Result < ( ) , VcpuError > {
139
- // Best-effort to clean up TLS. If the `Vcpu` was moved to another thread
140
- // _before_ running this, then there is nothing we can do.
141
- Self :: TLS_VCPU_PTR . with ( |cell : & VcpuCell | {
142
- if let Some ( vcpu_ptr) = cell. get ( ) {
143
- if std:: ptr:: eq ( vcpu_ptr, self ) {
144
- Self :: TLS_VCPU_PTR . with ( |cell : & VcpuCell | cell. take ( ) ) ;
145
- return Ok ( ( ) ) ;
146
- }
147
- }
148
- Err ( VcpuError :: VcpuTlsNotPresent )
149
122
} )
150
123
}
151
124
@@ -159,20 +132,15 @@ impl Vcpu {
159
132
///
160
133
/// This is marked unsafe as it allows temporary aliasing through
161
134
/// dereferencing from pointer an already borrowed `Vcpu`.
162
- unsafe fn run_on_thread_local < F > ( func : F ) -> Result < ( ) , VcpuError >
135
+ unsafe fn run_on_thread_local < F > ( func : F )
163
136
where
164
137
F : FnOnce ( & mut Vcpu ) ,
165
138
{
166
139
Self :: TLS_VCPU_PTR . with ( |cell : & VcpuCell | {
167
- if let Some ( vcpu_ptr) = cell. get ( ) {
168
- // SAFETY: Dereferencing here is safe since `TLS_VCPU_PTR` is populated/non-empty,
169
- // and it is being cleared on `Vcpu::drop` so there is no dangling pointer.
170
- let vcpu_ref = unsafe { & mut * vcpu_ptr } ;
171
- func ( vcpu_ref) ;
172
- Ok ( ( ) )
173
- } else {
174
- Err ( VcpuError :: VcpuTlsNotPresent )
175
- }
140
+ let vcpu_ptr = cell. get ( ) . unwrap ( ) ;
141
+ // SAFETY: Dereferencing here is safe since `TLS_VCPU_PTR` is populated/non-empty.
142
+ let vcpu_ref = unsafe { & mut * vcpu_ptr } ;
143
+ func ( vcpu_ref) ;
176
144
} )
177
145
}
178
146
@@ -183,7 +151,7 @@ impl Vcpu {
183
151
// SAFETY: This is safe because it's temporarily aliasing the `Vcpu` object, but we are
184
152
// only reading `vcpu.fd` which does not change for the lifetime of the `Vcpu`.
185
153
unsafe {
186
- let _ = Vcpu :: run_on_thread_local ( |vcpu| {
154
+ Vcpu :: run_on_thread_local ( |vcpu| {
187
155
vcpu. kvm_vcpu . fd . set_kvm_immediate_exit ( 1 ) ;
188
156
fence ( Ordering :: Release ) ;
189
157
} ) ;
@@ -254,8 +222,7 @@ impl Vcpu {
254
222
. name ( format ! ( "fc_vcpu {}" , self . kvm_vcpu. index) )
255
223
. spawn ( move || {
256
224
let filter = & * seccomp_filter;
257
- self . init_thread_local_data ( )
258
- . expect ( "Cannot cleanly initialize vcpu TLS." ) ;
225
+ self . init_thread_local_data ( ) ;
259
226
// Synchronization to make sure thread local data is initialized.
260
227
barrier. wait ( ) ;
261
228
self . run ( filter) ;
@@ -617,12 +584,6 @@ fn handle_kvm_exit(
617
584
}
618
585
}
619
586
620
- impl Drop for Vcpu {
621
- fn drop ( & mut self ) {
622
- let _ = self . reset_thread_local_data ( ) ;
623
- }
624
- }
625
-
626
587
/// List of events that the Vcpu can receive.
627
588
#[ derive( Debug , Clone ) ]
628
589
pub enum VcpuEvent {
@@ -1025,43 +986,37 @@ pub(crate) mod tests {
1025
986
}
1026
987
1027
988
#[ test]
1028
- fn test_vcpu_tls ( ) {
1029
- let ( _, _, mut vcpu) = setup_vcpu ( 0x1000 ) ;
1030
-
989
+ #[ should_panic]
990
+ fn test_vcpu_tls_not_set_panic ( ) {
1031
991
// Running on the TLS vcpu should fail before we actually initialize it.
1032
992
unsafe {
1033
- Vcpu :: run_on_thread_local ( |_| ( ) ) . unwrap_err ( ) ;
993
+ Vcpu :: run_on_thread_local ( |_| ( ) ) ;
1034
994
}
995
+ }
996
+
997
+ #[ test]
998
+ fn test_vcpu_tls_set ( ) {
999
+ let ( _, _, mut vcpu) = setup_vcpu ( 0x1000 ) ;
1035
1000
1036
1001
// Initialize vcpu TLS.
1037
- vcpu. init_thread_local_data ( ) . unwrap ( ) ;
1002
+ vcpu. init_thread_local_data ( ) ;
1038
1003
1039
1004
// Validate TLS vcpu is the local vcpu by changing the `id` then validating against
1040
1005
// the one in TLS.
1041
1006
vcpu. kvm_vcpu . index = 12 ;
1042
1007
unsafe {
1043
- Vcpu :: run_on_thread_local ( |v| assert_eq ! ( v. kvm_vcpu. index, 12 ) ) . unwrap ( ) ;
1044
- }
1045
-
1046
- // Reset vcpu TLS.
1047
- vcpu. reset_thread_local_data ( ) . unwrap ( ) ;
1048
-
1049
- // Running on the TLS vcpu after TLS reset should fail.
1050
- unsafe {
1051
- Vcpu :: run_on_thread_local ( |_| ( ) ) . unwrap_err ( ) ;
1008
+ Vcpu :: run_on_thread_local ( |v| assert_eq ! ( v. kvm_vcpu. index, 12 ) ) ;
1052
1009
}
1053
-
1054
- // Second reset should return error.
1055
- vcpu. reset_thread_local_data ( ) . unwrap_err ( ) ;
1056
1010
}
1057
1011
1058
1012
#[ test]
1013
+ #[ should_panic]
1059
1014
fn test_invalid_tls ( ) {
1060
1015
let ( _, _, mut vcpu) = setup_vcpu ( 0x1000 ) ;
1061
1016
// Initialize vcpu TLS.
1062
- vcpu. init_thread_local_data ( ) . unwrap ( ) ;
1017
+ vcpu. init_thread_local_data ( ) ;
1063
1018
// Trying to initialize non-empty TLS should error.
1064
- vcpu. init_thread_local_data ( ) . unwrap_err ( ) ;
1019
+ vcpu. init_thread_local_data ( ) ;
1065
1020
}
1066
1021
1067
1022
#[ test]
@@ -1080,7 +1035,7 @@ pub(crate) mod tests {
1080
1035
let handle = std:: thread:: Builder :: new ( )
1081
1036
. name ( "test_vcpu_kick" . to_string ( ) )
1082
1037
. spawn ( move || {
1083
- vcpu. init_thread_local_data ( ) . unwrap ( ) ;
1038
+ vcpu. init_thread_local_data ( ) ;
1084
1039
// Notify TLS was populated.
1085
1040
vcpu_barrier. wait ( ) ;
1086
1041
// Loop for max 1 second to check if the signal handler has run.
0 commit comments