Skip to content

Commit 5502f5b

Browse files
committed
refactor: assert on TLS reset
The reset must be called only once on vcpu drop. Replace errors with asserts in this case. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent c3f6891 commit 5502f5b

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

src/vmm/src/vstate/vcpu.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -126,21 +126,16 @@ impl Vcpu {
126126

127127
/// Deassociates `self` from the current thread.
128128
///
129-
/// Should be called if the current `self` had called `init_thread_local_data()` and
130-
/// now needs to move to a different thread.
131-
///
132-
/// Fails if `self` was not previously associated with the current thread.
133-
fn reset_thread_local_data(&mut self) -> Result<(), VcpuError> {
129+
/// Must be called after `init_thread_local_data`.
130+
fn reset_thread_local_data(&mut self) {
134131
// Best-effort to clean up TLS. If the `Vcpu` was moved to another thread
135132
// _before_ running this, then there is nothing we can do.
136-
Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| {
137-
if let Some(vcpu_ptr) = cell.get() {
138-
if std::ptr::eq(vcpu_ptr, self) {
139-
Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| cell.take());
140-
return Ok(());
141-
}
142-
}
143-
Err(VcpuError::VcpuTlsNotPresent)
133+
Self::TLS_VCPU_PTR.with(|cell| {
134+
let vcpu_ptr = cell.get().unwrap();
135+
assert!(std::ptr::eq(vcpu_ptr, self));
136+
// Have to do this trick because `update` method is
137+
// not stable on Cell.
138+
Self::TLS_VCPU_PTR.with(|cell| cell.take());
144139
})
145140
}
146141

@@ -615,7 +610,7 @@ fn handle_kvm_exit(
615610

616611
impl Drop for Vcpu {
617612
fn drop(&mut self) {
618-
let _ = self.reset_thread_local_data();
613+
self.reset_thread_local_data();
619614
}
620615
}
621616

@@ -1039,15 +1034,24 @@ pub(crate) mod tests {
10391034
}
10401035

10411036
// Reset vcpu TLS.
1042-
vcpu.reset_thread_local_data().unwrap();
1037+
vcpu.reset_thread_local_data();
10431038

10441039
// Running on the TLS vcpu after TLS reset should fail.
10451040
unsafe {
10461041
Vcpu::run_on_thread_local(|_| ()).unwrap_err();
10471042
}
10481043

10491044
// Second reset should return error.
1050-
vcpu.reset_thread_local_data().unwrap_err();
1045+
vcpu.reset_thread_local_data();
1046+
}
1047+
1048+
#[test]
1049+
#[should_panic]
1050+
fn test_vcpu_tls_double_reset() {
1051+
let (_, _, mut vcpu) = setup_vcpu(0x1000);
1052+
vcpu.init_thread_local_data();
1053+
vcpu.reset_thread_local_data();
1054+
vcpu.reset_thread_local_data();
10511055
}
10521056

10531057
#[test]

0 commit comments

Comments
 (0)