1*8e194c0eSPaolo Bonzini // SPDX-License-Identifier: MIT 2*8e194c0eSPaolo Bonzini // 3*8e194c0eSPaolo Bonzini // This file is based on library/core/src/cell.rs from 4*8e194c0eSPaolo Bonzini // Rust 1.82.0. 5*8e194c0eSPaolo Bonzini // 6*8e194c0eSPaolo Bonzini // Permission is hereby granted, free of charge, to any 7*8e194c0eSPaolo Bonzini // person obtaining a copy of this software and associated 8*8e194c0eSPaolo Bonzini // documentation files (the "Software"), to deal in the 9*8e194c0eSPaolo Bonzini // Software without restriction, including without 10*8e194c0eSPaolo Bonzini // limitation the rights to use, copy, modify, merge, 11*8e194c0eSPaolo Bonzini // publish, distribute, sublicense, and/or sell copies of 12*8e194c0eSPaolo Bonzini // the Software, and to permit persons to whom the Software 13*8e194c0eSPaolo Bonzini // is furnished to do so, subject to the following 14*8e194c0eSPaolo Bonzini // conditions: 15*8e194c0eSPaolo Bonzini // 16*8e194c0eSPaolo Bonzini // The above copyright notice and this permission notice 17*8e194c0eSPaolo Bonzini // shall be included in all copies or substantial portions 18*8e194c0eSPaolo Bonzini // of the Software. 19*8e194c0eSPaolo Bonzini // 20*8e194c0eSPaolo Bonzini // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 21*8e194c0eSPaolo Bonzini // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 22*8e194c0eSPaolo Bonzini // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 23*8e194c0eSPaolo Bonzini // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 24*8e194c0eSPaolo Bonzini // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 25*8e194c0eSPaolo Bonzini // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26*8e194c0eSPaolo Bonzini // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 27*8e194c0eSPaolo Bonzini // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28*8e194c0eSPaolo Bonzini // DEALINGS IN THE SOFTWARE. 29*8e194c0eSPaolo Bonzini 30*8e194c0eSPaolo Bonzini //! BQL-protected mutable containers. 31*8e194c0eSPaolo Bonzini //! 32*8e194c0eSPaolo Bonzini //! Rust memory safety is based on this rule: Given an object `T`, it is only 33*8e194c0eSPaolo Bonzini //! possible to have one of the following: 34*8e194c0eSPaolo Bonzini //! 35*8e194c0eSPaolo Bonzini //! - Having several immutable references (`&T`) to the object (also known as 36*8e194c0eSPaolo Bonzini //! **aliasing**). 37*8e194c0eSPaolo Bonzini //! - Having one mutable reference (`&mut T`) to the object (also known as 38*8e194c0eSPaolo Bonzini //! **mutability**). 39*8e194c0eSPaolo Bonzini //! 40*8e194c0eSPaolo Bonzini //! This is enforced by the Rust compiler. However, there are situations where 41*8e194c0eSPaolo Bonzini //! this rule is not flexible enough. Sometimes it is required to have multiple 42*8e194c0eSPaolo Bonzini //! references to an object and yet mutate it. In particular, QEMU objects 43*8e194c0eSPaolo Bonzini //! usually have their pointer shared with the "outside world very early in 44*8e194c0eSPaolo Bonzini //! their lifetime", for example when they create their 45*8e194c0eSPaolo Bonzini //! [`MemoryRegion`s](crate::bindings::MemoryRegion). Therefore, individual 46*8e194c0eSPaolo Bonzini //! parts of a device must be made mutable in a controlled manner through the 47*8e194c0eSPaolo Bonzini //! use of cell types. 48*8e194c0eSPaolo Bonzini //! 49*8e194c0eSPaolo Bonzini //! This module provides a way to do so via the Big QEMU Lock. While 50*8e194c0eSPaolo Bonzini //! [`BqlCell<T>`] is essentially the same single-threaded primitive that is 51*8e194c0eSPaolo Bonzini //! available in `std::cell`, the BQL allows it to be used from a multi-threaded 52*8e194c0eSPaolo Bonzini //! context and to share references across threads, while maintaining Rust's 53*8e194c0eSPaolo Bonzini //! safety guarantees. For this reason, unlike its `std::cell` counterpart, 54*8e194c0eSPaolo Bonzini //! `BqlCell` implements the `Sync` trait. 55*8e194c0eSPaolo Bonzini //! 56*8e194c0eSPaolo Bonzini //! BQL checks are performed in debug builds but can be optimized away in 57*8e194c0eSPaolo Bonzini //! release builds, providing runtime safety during development with no overhead 58*8e194c0eSPaolo Bonzini //! in production. 59*8e194c0eSPaolo Bonzini //! 60*8e194c0eSPaolo Bonzini //! Warning: While `BqlCell` is similar to its `std::cell` counterpart, the two 61*8e194c0eSPaolo Bonzini //! are not interchangeable. Using `std::cell` types in QEMU device 62*8e194c0eSPaolo Bonzini //! implementations is usually incorrect and can lead to thread-safety issues. 63*8e194c0eSPaolo Bonzini //! 64*8e194c0eSPaolo Bonzini //! ## `BqlCell<T>` 65*8e194c0eSPaolo Bonzini //! 66*8e194c0eSPaolo Bonzini //! [`BqlCell<T>`] implements interior mutability by moving values in and out of 67*8e194c0eSPaolo Bonzini //! the cell. That is, an `&mut T` to the inner value can never be obtained as 68*8e194c0eSPaolo Bonzini //! long as the cell is shared. The value itself cannot be directly obtained 69*8e194c0eSPaolo Bonzini //! without copying it, cloning it, or replacing it with something else. This 70*8e194c0eSPaolo Bonzini //! type provides the following methods, all of which can be called only while 71*8e194c0eSPaolo Bonzini //! the BQL is held: 72*8e194c0eSPaolo Bonzini //! 73*8e194c0eSPaolo Bonzini //! - For types that implement [`Copy`], the [`get`](BqlCell::get) method 74*8e194c0eSPaolo Bonzini //! retrieves the current interior value by duplicating it. 75*8e194c0eSPaolo Bonzini //! - For types that implement [`Default`], the [`take`](BqlCell::take) method 76*8e194c0eSPaolo Bonzini //! replaces the current interior value with [`Default::default()`] and 77*8e194c0eSPaolo Bonzini //! returns the replaced value. 78*8e194c0eSPaolo Bonzini //! - All types have: 79*8e194c0eSPaolo Bonzini //! - [`replace`](BqlCell::replace): replaces the current interior value and 80*8e194c0eSPaolo Bonzini //! returns the replaced value. 81*8e194c0eSPaolo Bonzini //! - [`set`](BqlCell::set): this method replaces the interior value, 82*8e194c0eSPaolo Bonzini //! dropping the replaced value. 83*8e194c0eSPaolo Bonzini 84*8e194c0eSPaolo Bonzini use std::{cell::UnsafeCell, cmp::Ordering, fmt, mem}; 85*8e194c0eSPaolo Bonzini 86*8e194c0eSPaolo Bonzini use crate::bindings; 87*8e194c0eSPaolo Bonzini 88*8e194c0eSPaolo Bonzini // TODO: When building doctests do not include the actual BQL, because cargo 89*8e194c0eSPaolo Bonzini // does not know how to link them to libqemuutil. This can be fixed by 90*8e194c0eSPaolo Bonzini // running rustdoc from "meson test" instead of relying on cargo. 91*8e194c0eSPaolo Bonzini pub fn bql_locked() -> bool { 92*8e194c0eSPaolo Bonzini // SAFETY: the function does nothing but return a thread-local bool 93*8e194c0eSPaolo Bonzini !cfg!(MESON) || unsafe { bindings::bql_locked() } 94*8e194c0eSPaolo Bonzini } 95*8e194c0eSPaolo Bonzini 96*8e194c0eSPaolo Bonzini /// A mutable memory location that is protected by the Big QEMU Lock. 97*8e194c0eSPaolo Bonzini /// 98*8e194c0eSPaolo Bonzini /// # Memory layout 99*8e194c0eSPaolo Bonzini /// 100*8e194c0eSPaolo Bonzini /// `BqlCell<T>` has the same in-memory representation as its inner type `T`. 101*8e194c0eSPaolo Bonzini #[repr(transparent)] 102*8e194c0eSPaolo Bonzini pub struct BqlCell<T> { 103*8e194c0eSPaolo Bonzini value: UnsafeCell<T>, 104*8e194c0eSPaolo Bonzini } 105*8e194c0eSPaolo Bonzini 106*8e194c0eSPaolo Bonzini // SAFETY: Same as for std::sync::Mutex. In the end this *is* a Mutex, 107*8e194c0eSPaolo Bonzini // except it is stored out-of-line 108*8e194c0eSPaolo Bonzini unsafe impl<T: Send> Send for BqlCell<T> {} 109*8e194c0eSPaolo Bonzini unsafe impl<T: Send> Sync for BqlCell<T> {} 110*8e194c0eSPaolo Bonzini 111*8e194c0eSPaolo Bonzini impl<T: Copy> Clone for BqlCell<T> { 112*8e194c0eSPaolo Bonzini #[inline] 113*8e194c0eSPaolo Bonzini fn clone(&self) -> BqlCell<T> { 114*8e194c0eSPaolo Bonzini BqlCell::new(self.get()) 115*8e194c0eSPaolo Bonzini } 116*8e194c0eSPaolo Bonzini } 117*8e194c0eSPaolo Bonzini 118*8e194c0eSPaolo Bonzini impl<T: Default> Default for BqlCell<T> { 119*8e194c0eSPaolo Bonzini /// Creates a `BqlCell<T>`, with the `Default` value for T. 120*8e194c0eSPaolo Bonzini #[inline] 121*8e194c0eSPaolo Bonzini fn default() -> BqlCell<T> { 122*8e194c0eSPaolo Bonzini BqlCell::new(Default::default()) 123*8e194c0eSPaolo Bonzini } 124*8e194c0eSPaolo Bonzini } 125*8e194c0eSPaolo Bonzini 126*8e194c0eSPaolo Bonzini impl<T: PartialEq + Copy> PartialEq for BqlCell<T> { 127*8e194c0eSPaolo Bonzini #[inline] 128*8e194c0eSPaolo Bonzini fn eq(&self, other: &BqlCell<T>) -> bool { 129*8e194c0eSPaolo Bonzini self.get() == other.get() 130*8e194c0eSPaolo Bonzini } 131*8e194c0eSPaolo Bonzini } 132*8e194c0eSPaolo Bonzini 133*8e194c0eSPaolo Bonzini impl<T: Eq + Copy> Eq for BqlCell<T> {} 134*8e194c0eSPaolo Bonzini 135*8e194c0eSPaolo Bonzini impl<T: PartialOrd + Copy> PartialOrd for BqlCell<T> { 136*8e194c0eSPaolo Bonzini #[inline] 137*8e194c0eSPaolo Bonzini fn partial_cmp(&self, other: &BqlCell<T>) -> Option<Ordering> { 138*8e194c0eSPaolo Bonzini self.get().partial_cmp(&other.get()) 139*8e194c0eSPaolo Bonzini } 140*8e194c0eSPaolo Bonzini } 141*8e194c0eSPaolo Bonzini 142*8e194c0eSPaolo Bonzini impl<T: Ord + Copy> Ord for BqlCell<T> { 143*8e194c0eSPaolo Bonzini #[inline] 144*8e194c0eSPaolo Bonzini fn cmp(&self, other: &BqlCell<T>) -> Ordering { 145*8e194c0eSPaolo Bonzini self.get().cmp(&other.get()) 146*8e194c0eSPaolo Bonzini } 147*8e194c0eSPaolo Bonzini } 148*8e194c0eSPaolo Bonzini 149*8e194c0eSPaolo Bonzini impl<T> From<T> for BqlCell<T> { 150*8e194c0eSPaolo Bonzini /// Creates a new `BqlCell<T>` containing the given value. 151*8e194c0eSPaolo Bonzini fn from(t: T) -> BqlCell<T> { 152*8e194c0eSPaolo Bonzini BqlCell::new(t) 153*8e194c0eSPaolo Bonzini } 154*8e194c0eSPaolo Bonzini } 155*8e194c0eSPaolo Bonzini 156*8e194c0eSPaolo Bonzini impl<T: fmt::Debug + Copy> fmt::Debug for BqlCell<T> { 157*8e194c0eSPaolo Bonzini fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 158*8e194c0eSPaolo Bonzini self.get().fmt(f) 159*8e194c0eSPaolo Bonzini } 160*8e194c0eSPaolo Bonzini } 161*8e194c0eSPaolo Bonzini 162*8e194c0eSPaolo Bonzini impl<T: fmt::Display + Copy> fmt::Display for BqlCell<T> { 163*8e194c0eSPaolo Bonzini fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 164*8e194c0eSPaolo Bonzini self.get().fmt(f) 165*8e194c0eSPaolo Bonzini } 166*8e194c0eSPaolo Bonzini } 167*8e194c0eSPaolo Bonzini 168*8e194c0eSPaolo Bonzini impl<T> BqlCell<T> { 169*8e194c0eSPaolo Bonzini /// Creates a new `BqlCell` containing the given value. 170*8e194c0eSPaolo Bonzini /// 171*8e194c0eSPaolo Bonzini /// # Examples 172*8e194c0eSPaolo Bonzini /// 173*8e194c0eSPaolo Bonzini /// ``` 174*8e194c0eSPaolo Bonzini /// use qemu_api::cell::BqlCell; 175*8e194c0eSPaolo Bonzini /// 176*8e194c0eSPaolo Bonzini /// let c = BqlCell::new(5); 177*8e194c0eSPaolo Bonzini /// ``` 178*8e194c0eSPaolo Bonzini #[inline] 179*8e194c0eSPaolo Bonzini pub const fn new(value: T) -> BqlCell<T> { 180*8e194c0eSPaolo Bonzini BqlCell { 181*8e194c0eSPaolo Bonzini value: UnsafeCell::new(value), 182*8e194c0eSPaolo Bonzini } 183*8e194c0eSPaolo Bonzini } 184*8e194c0eSPaolo Bonzini 185*8e194c0eSPaolo Bonzini /// Sets the contained value. 186*8e194c0eSPaolo Bonzini /// 187*8e194c0eSPaolo Bonzini /// # Examples 188*8e194c0eSPaolo Bonzini /// 189*8e194c0eSPaolo Bonzini /// ``` 190*8e194c0eSPaolo Bonzini /// use qemu_api::cell::BqlCell; 191*8e194c0eSPaolo Bonzini /// 192*8e194c0eSPaolo Bonzini /// let c = BqlCell::new(5); 193*8e194c0eSPaolo Bonzini /// 194*8e194c0eSPaolo Bonzini /// c.set(10); 195*8e194c0eSPaolo Bonzini /// ``` 196*8e194c0eSPaolo Bonzini #[inline] 197*8e194c0eSPaolo Bonzini pub fn set(&self, val: T) { 198*8e194c0eSPaolo Bonzini self.replace(val); 199*8e194c0eSPaolo Bonzini } 200*8e194c0eSPaolo Bonzini 201*8e194c0eSPaolo Bonzini /// Replaces the contained value with `val`, and returns the old contained 202*8e194c0eSPaolo Bonzini /// value. 203*8e194c0eSPaolo Bonzini /// 204*8e194c0eSPaolo Bonzini /// # Examples 205*8e194c0eSPaolo Bonzini /// 206*8e194c0eSPaolo Bonzini /// ``` 207*8e194c0eSPaolo Bonzini /// use qemu_api::cell::BqlCell; 208*8e194c0eSPaolo Bonzini /// 209*8e194c0eSPaolo Bonzini /// let cell = BqlCell::new(5); 210*8e194c0eSPaolo Bonzini /// assert_eq!(cell.get(), 5); 211*8e194c0eSPaolo Bonzini /// assert_eq!(cell.replace(10), 5); 212*8e194c0eSPaolo Bonzini /// assert_eq!(cell.get(), 10); 213*8e194c0eSPaolo Bonzini /// ``` 214*8e194c0eSPaolo Bonzini #[inline] 215*8e194c0eSPaolo Bonzini pub fn replace(&self, val: T) -> T { 216*8e194c0eSPaolo Bonzini assert!(bql_locked()); 217*8e194c0eSPaolo Bonzini // SAFETY: This can cause data races if called from multiple threads, 218*8e194c0eSPaolo Bonzini // but it won't happen as long as C code accesses the value 219*8e194c0eSPaolo Bonzini // under BQL protection only. 220*8e194c0eSPaolo Bonzini mem::replace(unsafe { &mut *self.value.get() }, val) 221*8e194c0eSPaolo Bonzini } 222*8e194c0eSPaolo Bonzini 223*8e194c0eSPaolo Bonzini /// Unwraps the value, consuming the cell. 224*8e194c0eSPaolo Bonzini /// 225*8e194c0eSPaolo Bonzini /// # Examples 226*8e194c0eSPaolo Bonzini /// 227*8e194c0eSPaolo Bonzini /// ``` 228*8e194c0eSPaolo Bonzini /// use qemu_api::cell::BqlCell; 229*8e194c0eSPaolo Bonzini /// 230*8e194c0eSPaolo Bonzini /// let c = BqlCell::new(5); 231*8e194c0eSPaolo Bonzini /// let five = c.into_inner(); 232*8e194c0eSPaolo Bonzini /// 233*8e194c0eSPaolo Bonzini /// assert_eq!(five, 5); 234*8e194c0eSPaolo Bonzini /// ``` 235*8e194c0eSPaolo Bonzini pub fn into_inner(self) -> T { 236*8e194c0eSPaolo Bonzini assert!(bql_locked()); 237*8e194c0eSPaolo Bonzini self.value.into_inner() 238*8e194c0eSPaolo Bonzini } 239*8e194c0eSPaolo Bonzini } 240*8e194c0eSPaolo Bonzini 241*8e194c0eSPaolo Bonzini impl<T: Copy> BqlCell<T> { 242*8e194c0eSPaolo Bonzini /// Returns a copy of the contained value. 243*8e194c0eSPaolo Bonzini /// 244*8e194c0eSPaolo Bonzini /// # Examples 245*8e194c0eSPaolo Bonzini /// 246*8e194c0eSPaolo Bonzini /// ``` 247*8e194c0eSPaolo Bonzini /// use qemu_api::cell::BqlCell; 248*8e194c0eSPaolo Bonzini /// 249*8e194c0eSPaolo Bonzini /// let c = BqlCell::new(5); 250*8e194c0eSPaolo Bonzini /// 251*8e194c0eSPaolo Bonzini /// let five = c.get(); 252*8e194c0eSPaolo Bonzini /// ``` 253*8e194c0eSPaolo Bonzini #[inline] 254*8e194c0eSPaolo Bonzini pub fn get(&self) -> T { 255*8e194c0eSPaolo Bonzini assert!(bql_locked()); 256*8e194c0eSPaolo Bonzini // SAFETY: This can cause data races if called from multiple threads, 257*8e194c0eSPaolo Bonzini // but it won't happen as long as C code accesses the value 258*8e194c0eSPaolo Bonzini // under BQL protection only. 259*8e194c0eSPaolo Bonzini unsafe { *self.value.get() } 260*8e194c0eSPaolo Bonzini } 261*8e194c0eSPaolo Bonzini } 262*8e194c0eSPaolo Bonzini 263*8e194c0eSPaolo Bonzini impl<T> BqlCell<T> { 264*8e194c0eSPaolo Bonzini /// Returns a raw pointer to the underlying data in this cell. 265*8e194c0eSPaolo Bonzini /// 266*8e194c0eSPaolo Bonzini /// # Examples 267*8e194c0eSPaolo Bonzini /// 268*8e194c0eSPaolo Bonzini /// ``` 269*8e194c0eSPaolo Bonzini /// use qemu_api::cell::BqlCell; 270*8e194c0eSPaolo Bonzini /// 271*8e194c0eSPaolo Bonzini /// let c = BqlCell::new(5); 272*8e194c0eSPaolo Bonzini /// 273*8e194c0eSPaolo Bonzini /// let ptr = c.as_ptr(); 274*8e194c0eSPaolo Bonzini /// ``` 275*8e194c0eSPaolo Bonzini #[inline] 276*8e194c0eSPaolo Bonzini pub const fn as_ptr(&self) -> *mut T { 277*8e194c0eSPaolo Bonzini self.value.get() 278*8e194c0eSPaolo Bonzini } 279*8e194c0eSPaolo Bonzini } 280*8e194c0eSPaolo Bonzini 281*8e194c0eSPaolo Bonzini impl<T: Default> BqlCell<T> { 282*8e194c0eSPaolo Bonzini /// Takes the value of the cell, leaving `Default::default()` in its place. 283*8e194c0eSPaolo Bonzini /// 284*8e194c0eSPaolo Bonzini /// # Examples 285*8e194c0eSPaolo Bonzini /// 286*8e194c0eSPaolo Bonzini /// ``` 287*8e194c0eSPaolo Bonzini /// use qemu_api::cell::BqlCell; 288*8e194c0eSPaolo Bonzini /// 289*8e194c0eSPaolo Bonzini /// let c = BqlCell::new(5); 290*8e194c0eSPaolo Bonzini /// let five = c.take(); 291*8e194c0eSPaolo Bonzini /// 292*8e194c0eSPaolo Bonzini /// assert_eq!(five, 5); 293*8e194c0eSPaolo Bonzini /// assert_eq!(c.into_inner(), 0); 294*8e194c0eSPaolo Bonzini /// ``` 295*8e194c0eSPaolo Bonzini pub fn take(&self) -> T { 296*8e194c0eSPaolo Bonzini self.replace(Default::default()) 297*8e194c0eSPaolo Bonzini } 298*8e194c0eSPaolo Bonzini } 299