]> git.ipfire.org Git - thirdparty/qemu.git/commit
rust: timer: wrap QEMUTimer with Opaque<> and express pinning requirements
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 14 Feb 2025 11:06:13 +0000 (12:06 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 6 Mar 2025 11:44:46 +0000 (12:44 +0100)
commita32b239699377f09bba08b2e8ae0d167c1488b1f
treec2c5eda3f56d647b3f67645aace572d65853e13f
parente8dc87fef2677dc286b3fe72e04d1b763cf98fef
rust: timer: wrap QEMUTimer with Opaque<> and express pinning requirements

Timers must be pinned in memory, because modify() stores a pointer to them
in the TimerList.  To express this requirement, change init_full() to take
a pinned reference.  Because the only way to obtain a Timer is through
Timer::new(), which is unsafe, modify() can assume that the timer it got
was later initialized; and because the initialization takes a Pin<&mut
Timer> modify() can assume that the timer is pinned.  In the future the
pinning requirement will be expressed through the pin_init crate instead.

Note that Timer is a bit different from other users of Opaque, in that
it is created in Rust code rather than C code.  This is why it has to
use the unsafe constructors provided by Opaque; and in fact Timer::new()
is also unsafe, because it leaves it to the caller to invoke init_full()
before modify().  Without a call to init_full(), modify() will cause a
NULL pointer dereference.

An alternative could be to combine new() + init_full() by returning a
pinned box; however, using a reference makes it easier to express
the requirement that the opaque outlives the timer.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
meson.build
rust/hw/timer/hpet/src/hpet.rs
rust/qemu-api/src/timer.rs