@@ -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 ) ,
@@ -121,34 +117,12 @@ impl Vcpu {
121
117
/// This function will return an error if there already is a `Vcpu` present in the TLS.
122
118
fn init_thread_local_data ( & mut self ) -> Result < ( ) , VcpuError > {
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
122
Ok ( ( ) )
129
123
} )
130
124
}
131
125
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 vcpu_ptr == self as * mut Vcpu {
144
- Self :: TLS_VCPU_PTR . with ( |cell : & VcpuCell | cell. take ( ) ) ;
145
- return Ok ( ( ) ) ;
146
- }
147
- }
148
- Err ( VcpuError :: VcpuTlsNotPresent )
149
- } )
150
- }
151
-
152
126
/// Runs `func` for the `Vcpu` associated with the current thread.
153
127
///
154
128
/// It requires that `init_thread_local_data()` was run on this thread.
@@ -159,20 +133,15 @@ impl Vcpu {
159
133
///
160
134
/// This is marked unsafe as it allows temporary aliasing through
161
135
/// dereferencing from pointer an already borrowed `Vcpu`.
162
- unsafe fn run_on_thread_local < F > ( func : F ) -> Result < ( ) , VcpuError >
136
+ unsafe fn run_on_thread_local < F > ( func : F )
163
137
where
164
138
F : FnOnce ( & mut Vcpu ) ,
165
139
{
166
140
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
- }
141
+ let vcpu_ptr = cell. get ( ) . unwrap ( ) ;
142
+ // SAFETY: Dereferencing here is safe since `TLS_VCPU_PTR` is populated/non-empty.
143
+ let vcpu_ref = unsafe { & mut * vcpu_ptr } ;
144
+ func ( vcpu_ref) ;
176
145
} )
177
146
}
178
147
@@ -183,7 +152,7 @@ impl Vcpu {
183
152
// SAFETY: This is safe because it's temporarily aliasing the `Vcpu` object, but we are
184
153
// only reading `vcpu.fd` which does not change for the lifetime of the `Vcpu`.
185
154
unsafe {
186
- let _ = Vcpu :: run_on_thread_local ( |vcpu| {
155
+ Vcpu :: run_on_thread_local ( |vcpu| {
187
156
vcpu. kvm_vcpu . fd . set_kvm_immediate_exit ( 1 ) ;
188
157
fence ( Ordering :: Release ) ;
189
158
} ) ;
@@ -617,12 +586,6 @@ fn handle_kvm_exit(
617
586
}
618
587
}
619
588
620
- impl Drop for Vcpu {
621
- fn drop ( & mut self ) {
622
- let _ = self . reset_thread_local_data ( ) ;
623
- }
624
- }
625
-
626
589
/// List of events that the Vcpu can receive.
627
590
#[ derive( Debug , Clone ) ]
628
591
pub enum VcpuEvent {
@@ -1025,43 +988,39 @@ pub(crate) mod tests {
1025
988
}
1026
989
1027
990
#[ test]
1028
- fn test_vcpu_tls ( ) {
991
+ #[ should_panic]
992
+ fn test_vcpu_tls_not_set_panic ( ) {
1029
993
let ( _, _, mut vcpu) = setup_vcpu ( 0x1000 ) ;
1030
994
1031
995
// Running on the TLS vcpu should fail before we actually initialize it.
1032
996
unsafe {
1033
- Vcpu :: run_on_thread_local ( |_| ( ) ) . unwrap_err ( ) ;
997
+ Vcpu :: run_on_thread_local ( |_| ( ) ) ;
1034
998
}
999
+ }
1000
+
1001
+ #[ test]
1002
+ fn test_vcpu_tls_set ( ) {
1003
+ let ( _, _, mut vcpu) = setup_vcpu ( 0x1000 ) ;
1035
1004
1036
1005
// Initialize vcpu TLS.
1037
- vcpu. init_thread_local_data ( ) . unwrap ( ) ;
1006
+ vcpu. init_thread_local_data ( ) ;
1038
1007
1039
1008
// Validate TLS vcpu is the local vcpu by changing the `id` then validating against
1040
1009
// the one in TLS.
1041
1010
vcpu. kvm_vcpu . index = 12 ;
1042
1011
unsafe {
1043
- Vcpu :: run_on_thread_local ( |v| assert_eq ! ( v. kvm_vcpu. index, 12 ) ) . unwrap ( ) ;
1012
+ Vcpu :: run_on_thread_local ( |v| assert_eq ! ( v. kvm_vcpu. index, 12 ) ) ;
1044
1013
}
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 ( ) ;
1052
- }
1053
-
1054
- // Second reset should return error.
1055
- vcpu. reset_thread_local_data ( ) . unwrap_err ( ) ;
1056
1014
}
1057
1015
1058
1016
#[ test]
1017
+ #[ should_panic]
1059
1018
fn test_invalid_tls ( ) {
1060
1019
let ( _, _, mut vcpu) = setup_vcpu ( 0x1000 ) ;
1061
1020
// Initialize vcpu TLS.
1062
- vcpu. init_thread_local_data ( ) . unwrap ( ) ;
1021
+ vcpu. init_thread_local_data ( ) ;
1063
1022
// Trying to initialize non-empty TLS should error.
1064
- vcpu. init_thread_local_data ( ) . unwrap_err ( ) ;
1023
+ vcpu. init_thread_local_data ( ) ;
1065
1024
}
1066
1025
1067
1026
#[ test]
0 commit comments