diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2025-03-03 16:27:08 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2025-03-06 12:44:46 +0100 |
commit | e8dc87fef2677dc286b3fe72e04d1b763cf98fef (patch) | |
tree | f93280b849aed56d9ebeab044da1aca4695500b6 /rust/hw/timer/hpet/src | |
parent | d7f5ae8b30cc9652a4ddcfeb52076f5aef6d78b6 (diff) | |
download | qemu-e8dc87fef2677dc286b3fe72e04d1b763cf98fef.zip qemu-e8dc87fef2677dc286b3fe72e04d1b763cf98fef.tar.gz qemu-e8dc87fef2677dc286b3fe72e04d1b763cf98fef.tar.bz2 |
rust: hpet: embed Timer without the Option and Box indirection
This simplifies things for migration, since Option<Box<QEMUTimer>> does not
implement VMState.
This also shows a soundness issue because Timer::new() will leave a NULL
timer list pointer, which can then be dereferenced by Timer::modify(). It
will be fixed shortly.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'rust/hw/timer/hpet/src')
-rw-r--r-- | rust/hw/timer/hpet/src/hpet.rs | 61 |
1 files changed, 29 insertions, 32 deletions
diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index be27eb0..02c81ae 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -151,14 +151,14 @@ fn timer_handler(timer_cell: &BqlRefCell<HPETTimer>) { /// HPET Timer Abstraction #[repr(C)] -#[derive(Debug, Default, qemu_api_macros::offsets)] +#[derive(Debug, qemu_api_macros::offsets)] pub struct HPETTimer { /// timer N index within the timer block (`HPETState`) #[doc(alias = "tn")] index: usize, - qemu_timer: Option<Box<Timer>>, + qemu_timer: Timer, /// timer block abstraction containing this timer - state: Option<NonNull<HPETState>>, + state: NonNull<HPETState>, // Memory-mapped, software visible timer registers /// Timer N Configuration and Capability Register @@ -181,32 +181,34 @@ pub struct HPETTimer { } impl HPETTimer { - fn init(&mut self, index: usize, state_ptr: *mut HPETState) -> &mut Self { - *self = HPETTimer::default(); - self.index = index; - self.state = NonNull::new(state_ptr); - self - } - - fn init_timer_with_state(&mut self) { - self.qemu_timer = Some(Box::new({ - let mut t = Timer::new(); - t.init_full( - None, - CLOCK_VIRTUAL, - Timer::NS, - 0, - timer_handler, - &self.get_state().timers[self.index], - ); - t - })); + fn init(&mut self, index: usize, state: &HPETState) { + *self = HPETTimer { + index, + qemu_timer: Timer::new(), + state: NonNull::new(state as *const _ as *mut _).unwrap(), + config: 0, + cmp: 0, + fsb: 0, + cmp64: 0, + period: 0, + wrap_flag: 0, + last: 0, + }; + + self.qemu_timer.init_full( + None, + CLOCK_VIRTUAL, + Timer::NS, + 0, + timer_handler, + &state.timers[self.index], + ) } fn get_state(&self) -> &HPETState { // SAFETY: // the pointer is convertible to a reference - unsafe { self.state.unwrap().as_ref() } + unsafe { self.state.as_ref() } } fn is_int_active(&self) -> bool { @@ -330,7 +332,7 @@ impl HPETTimer { } self.last = ns; - self.qemu_timer.as_ref().unwrap().modify(self.last); + self.qemu_timer.modify(self.last); } fn set_timer(&mut self) { @@ -353,7 +355,7 @@ impl HPETTimer { fn del_timer(&mut self) { // Just remove the timer from the timer_list without destroying // this timer instance. - self.qemu_timer.as_ref().unwrap().delete(); + self.qemu_timer.delete(); if self.is_int_active() { // For level-triggered interrupt, this leaves interrupt status @@ -581,13 +583,8 @@ impl HPETState { } fn init_timer(&self) { - let raw_ptr: *mut HPETState = self as *const HPETState as *mut HPETState; - for (index, timer) in self.timers.iter().enumerate() { - timer - .borrow_mut() - .init(index, raw_ptr) - .init_timer_with_state(); + timer.borrow_mut().init(index, self); } } |