vmm/devices/virtio/rng/
event_handler.rs1use event_manager::{EventOps, Events, MutEventSubscriber};
5use vmm_sys_util::epoll::EventSet;
6
7use super::{Entropy, RNG_QUEUE};
8use crate::devices::virtio::device::VirtioDevice;
9use crate::logger::{error, warn};
10
11impl Entropy {
12 const PROCESS_ACTIVATE: u32 = 0;
13 const PROCESS_ENTROPY_QUEUE: u32 = 1;
14 const PROCESS_RATE_LIMITER: u32 = 2;
15
16 fn register_runtime_events(&self, ops: &mut EventOps) {
17 if let Err(err) = ops.add(Events::with_data(
18 &self.queue_events()[RNG_QUEUE],
19 Self::PROCESS_ENTROPY_QUEUE,
20 EventSet::IN,
21 )) {
22 error!("entropy: Failed to register queue event: {err}");
23 }
24 if let Err(err) = ops.add(Events::with_data(
25 self.rate_limiter(),
26 Self::PROCESS_RATE_LIMITER,
27 EventSet::IN,
28 )) {
29 error!("entropy: Failed to register rate-limiter event: {err}");
30 }
31 }
32
33 fn register_activate_event(&self, ops: &mut EventOps) {
34 if let Err(err) = ops.add(Events::with_data(
35 self.activate_event(),
36 Self::PROCESS_ACTIVATE,
37 EventSet::IN,
38 )) {
39 error!("entropy: Failed to register activate event: {err}");
40 }
41 }
42
43 fn process_activate_event(&self, ops: &mut EventOps) {
44 if let Err(err) = self.activate_event().read() {
45 error!("entropy: Failed to consume activate event: {err}");
46 }
47
48 self.register_runtime_events(ops);
50
51 if let Err(err) = ops.remove(Events::with_data(
53 self.activate_event(),
54 Self::PROCESS_ACTIVATE,
55 EventSet::IN,
56 )) {
57 error!("entropy: Failed to un-register activate event: {err}");
58 }
59 }
60}
61
62impl MutEventSubscriber for Entropy {
63 fn init(&mut self, ops: &mut event_manager::EventOps) {
64 if self.is_activated() {
69 self.register_runtime_events(ops);
70 } else {
71 self.register_activate_event(ops);
72 }
73 }
74
75 fn process(&mut self, events: event_manager::Events, ops: &mut event_manager::EventOps) {
76 let event_set = events.event_set();
77 let source = events.data();
78
79 if !event_set.contains(EventSet::IN) {
80 warn!("entropy: Received unknown event: {event_set:?} from source {source}");
81 return;
82 }
83
84 if !self.is_activated() {
85 warn!("entropy: The device is not activated yet. Spurious event received: {source}");
86 return;
87 }
88
89 match source {
90 Self::PROCESS_ACTIVATE => self.process_activate_event(ops),
91 Self::PROCESS_ENTROPY_QUEUE => self.process_entropy_queue_event(),
92 Self::PROCESS_RATE_LIMITER => self.process_rate_limiter_event(),
93 _ => {
94 warn!("entropy: Unknown event received: {source}");
95 }
96 }
97 }
98}