vmm/devices/virtio/mem/
event_handler.rs1use event_manager::{EventOps, Events, MutEventSubscriber};
5use vmm_sys_util::epoll::EventSet;
6
7use crate::devices::virtio::device::VirtioDevice;
8use crate::devices::virtio::mem::MEM_QUEUE;
9use crate::devices::virtio::mem::device::VirtioMem;
10use crate::logger::{error, warn};
11
12impl VirtioMem {
13 const PROCESS_ACTIVATE: u32 = 0;
14 const PROCESS_MEM_QUEUE: u32 = 1;
15
16 fn register_runtime_events(&self, ops: &mut EventOps) {
17 if let Err(err) = ops.add(Events::with_data(
18 &self.queue_events()[MEM_QUEUE],
19 Self::PROCESS_MEM_QUEUE,
20 EventSet::IN,
21 )) {
22 error!("virtio-mem: Failed to register queue event: {err}");
23 }
24 }
25
26 fn register_activate_event(&self, ops: &mut EventOps) {
27 if let Err(err) = ops.add(Events::with_data(
28 self.activate_event(),
29 Self::PROCESS_ACTIVATE,
30 EventSet::IN,
31 )) {
32 error!("virtio-mem: Failed to register activate event: {err}");
33 }
34 }
35
36 fn process_activate_event(&self, ops: &mut EventOps) {
37 if let Err(err) = self.activate_event().read() {
38 error!("virtio-mem: Failed to consume activate event: {err}");
39 }
40
41 self.register_runtime_events(ops);
43
44 if let Err(err) = ops.remove(Events::with_data(
46 self.activate_event(),
47 Self::PROCESS_ACTIVATE,
48 EventSet::IN,
49 )) {
50 error!("virtio-mem: Failed to un-register activate event: {err}");
51 }
52 }
53}
54
55impl MutEventSubscriber for VirtioMem {
56 fn init(&mut self, ops: &mut event_manager::EventOps) {
57 if self.is_activated() {
62 self.register_runtime_events(ops);
63 } else {
64 self.register_activate_event(ops);
65 }
66 }
67
68 fn process(&mut self, events: event_manager::Events, ops: &mut event_manager::EventOps) {
69 let event_set = events.event_set();
70 let source = events.data();
71
72 if !event_set.contains(EventSet::IN) {
73 warn!("virtio-mem: Received unknown event: {event_set:?} from source {source}");
74 return;
75 }
76
77 if !self.is_activated() {
78 warn!("virtio-mem: The device is not activated yet. Spurious event received: {source}");
79 return;
80 }
81
82 match source {
83 Self::PROCESS_ACTIVATE => self.process_activate_event(ops),
84 Self::PROCESS_MEM_QUEUE => self.process_mem_queue_event(),
85
86 _ => {
87 warn!("virtio-mem: Unknown event received: {source}");
88 }
89 }
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use std::sync::{Arc, Mutex};
96
97 use event_manager::{EventManager, SubscriberOps};
98 use vmm_sys_util::epoll::EventSet;
99
100 use super::*;
101 use crate::devices::virtio::ActivateError;
102 use crate::devices::virtio::generated::virtio_mem::VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE;
103 use crate::devices::virtio::mem::device::test_utils::default_virtio_mem;
104 use crate::devices::virtio::test_utils::{VirtQueue, default_interrupt, default_mem};
105 use crate::vstate::memory::GuestAddress;
106
107 #[test]
108 fn test_event_handler_activation() {
109 let mut event_manager = EventManager::new().unwrap();
110 let mut mem_device = default_virtio_mem();
111 let mem = default_mem();
112 let interrupt = default_interrupt();
113
114 let virtq = VirtQueue::new(GuestAddress(0), &mem, 16);
116 mem_device.queues_mut()[MEM_QUEUE] = virtq.create_queue();
117
118 let mem_device = Arc::new(Mutex::new(mem_device));
119 let _id = event_manager.add_subscriber(mem_device.clone());
120
121 assert!(!mem_device.lock().unwrap().is_activated());
123
124 let err = mem_device
126 .lock()
127 .unwrap()
128 .activate(mem.clone(), interrupt.clone())
129 .unwrap_err();
130
131 assert!(matches!(err, ActivateError::RequiredFeatureNotAcked(_)));
132
133 mem_device
135 .lock()
136 .unwrap()
137 .set_acked_features(1 << VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE);
138
139 mem_device.lock().unwrap().activate(mem, interrupt).unwrap();
140
141 let ev_count = event_manager.run_with_timeout(50).unwrap();
143 assert_eq!(ev_count, 1);
144 assert!(mem_device.lock().unwrap().is_activated());
145 }
146
147 #[test]
148 fn test_process_mem_queue_event() {
149 let mut event_manager = EventManager::new().unwrap();
150 let mut mem_device = default_virtio_mem();
151 let mem = default_mem();
152 let interrupt = default_interrupt();
153
154 let virtq = VirtQueue::new(GuestAddress(0), &mem, 16);
156 mem_device.queues_mut()[MEM_QUEUE] = virtq.create_queue();
157 mem_device.set_acked_features(mem_device.avail_features());
158
159 let mem_device = Arc::new(Mutex::new(mem_device));
160 let _id = event_manager.add_subscriber(mem_device.clone());
161
162 mem_device.lock().unwrap().activate(mem, interrupt).unwrap();
164 event_manager.run_with_timeout(50).unwrap(); mem_device.lock().unwrap().queue_events()[MEM_QUEUE]
168 .write(1)
169 .unwrap();
170
171 let ev_count = event_manager.run_with_timeout(50).unwrap();
173 assert_eq!(ev_count, 1);
174 }
175
176 #[test]
177 fn test_spurious_event_before_activation() {
178 let mut event_manager = EventManager::new().unwrap();
179 let mem_device = default_virtio_mem();
180 let mem_device = Arc::new(Mutex::new(mem_device));
181 let _id = event_manager.add_subscriber(mem_device.clone());
182
183 mem_device.lock().unwrap().queue_events()[MEM_QUEUE]
185 .write(1)
186 .unwrap();
187
188 let ev_count = event_manager.run_with_timeout(50).unwrap();
190 assert_eq!(ev_count, 0);
191 }
192}