1use super::PciCapability;
7use crate::capabilities::msix::MsiInterrupt;
8use crate::msi::MsiTarget;
9use crate::spec::caps::CapabilityId;
10use crate::spec::caps::msi::MsiCapabilityHeader;
11use inspect::Inspect;
12use inspect::InspectMut;
13use parking_lot::Mutex;
14use std::fmt::Debug;
15use std::sync::Arc;
16use vmcore::interrupt::Interrupt;
17
18#[derive(Debug, Inspect)]
20pub struct MsiCapability {
21 #[inspect(with = "|x| inspect::adhoc(|req| x.lock().inspect_mut(req))")]
22 state: Arc<Mutex<MsiCapabilityState>>,
23 addr_64bit: bool,
24 per_vector_masking: bool,
25}
26
27#[derive(Debug, InspectMut)]
28struct MsiCapabilityState {
29 enabled: bool,
30 multiple_message_enable: u8, multiple_message_capable: u8, #[inspect(hex)]
33 address: u64,
34 #[inspect(hex)]
35 data: u16,
36 #[inspect(hex)]
37 mask_bits: u32,
38 #[inspect(hex)]
39 pending_bits: u32,
40 interrupt: Option<MsiInterrupt>,
41}
42
43impl MsiCapabilityState {
44 fn new(multiple_message_capable: u8, _addr_64bit: bool, per_vector_masking: bool) -> Self {
45 Self {
46 enabled: false,
47 multiple_message_enable: 0,
48 multiple_message_capable,
49 address: 0,
50 data: 0,
51 mask_bits: if per_vector_masking { 0xFFFFFFFF } else { 0 },
52 pending_bits: 0,
53 interrupt: None,
54 }
55 }
56
57 fn control_register(&self, addr_64bit: bool, per_vector_masking: bool) -> u32 {
58 let mut control = 0u32;
59 control |= (self.multiple_message_capable as u32) << 1; control |= (self.multiple_message_enable as u32) << 4; if addr_64bit {
62 control |= 1 << 7; }
64 if per_vector_masking {
65 control |= 1 << 8; }
67 if self.enabled {
68 control |= 1 << 0; }
70 control
71 }
72}
73
74impl MsiCapability {
75 pub fn new(
83 multiple_message_capable: u8,
84 addr_64bit: bool,
85 per_vector_masking: bool,
86 msi_target: &MsiTarget,
87 ) -> Self {
88 assert!(multiple_message_capable <= 5, "MMC must be 0-5");
89
90 let interrupt = MsiInterrupt::new(msi_target.clone());
91 let state = MsiCapabilityState {
92 interrupt: Some(interrupt),
93 ..MsiCapabilityState::new(multiple_message_capable, addr_64bit, per_vector_masking)
94 };
95
96 Self {
97 state: Arc::new(Mutex::new(state)),
98 addr_64bit,
99 per_vector_masking,
100 }
101 }
102
103 pub fn interrupt(&self) -> Option<Interrupt> {
105 self.state.lock().interrupt.as_mut().map(|i| i.interrupt())
106 }
107
108 fn len_bytes(&self) -> usize {
109 let mut len = 8; if self.addr_64bit {
111 len += 4; }
113 len += 2; if self.per_vector_masking {
115 len += 8; }
117 (len + 3) & !3
119 }
120}
121
122impl PciCapability for MsiCapability {
123 fn label(&self) -> &str {
124 "msi"
125 }
126
127 fn capability_id(&self) -> CapabilityId {
128 CapabilityId::MSI
129 }
130
131 fn len(&self) -> usize {
132 self.len_bytes()
133 }
134
135 fn read_u32(&self, offset: u16) -> u32 {
136 let state = self.state.lock();
137
138 match MsiCapabilityHeader(offset) {
139 MsiCapabilityHeader::CONTROL_CAPS => {
140 let control_reg = state.control_register(self.addr_64bit, self.per_vector_masking);
141 CapabilityId::MSI.0 as u32 | (control_reg << 16)
142 }
143 MsiCapabilityHeader::MSG_ADDR_LO => state.address as u32,
144 MsiCapabilityHeader::MSG_ADDR_HI if self.addr_64bit => (state.address >> 32) as u32,
145 MsiCapabilityHeader::MSG_DATA_32 if !self.addr_64bit => state.data as u32,
146 MsiCapabilityHeader::MSG_DATA_64 if self.addr_64bit => state.data as u32,
147 MsiCapabilityHeader::MASK_BITS if self.addr_64bit && self.per_vector_masking => {
148 state.mask_bits
149 }
150 MsiCapabilityHeader::PENDING_BITS if self.addr_64bit && self.per_vector_masking => {
151 state.pending_bits
152 }
153 _ => {
154 tracelimit::warn_ratelimited!("Unexpected MSI read offset {:#x}", offset);
155 0
156 }
157 }
158 }
159
160 fn write_u32(&mut self, offset: u16, val: u32) {
161 let mut state = self.state.lock();
162
163 match MsiCapabilityHeader(offset) {
164 MsiCapabilityHeader::CONTROL_CAPS => {
165 let control_val = (val >> 16) & 0xFFFF;
166 let old_enabled = state.enabled;
167 let new_enabled = control_val & 1 != 0;
168 let mme = ((control_val >> 4) & 0x7) as u8;
169
170 state.multiple_message_enable = mme.min(state.multiple_message_capable);
172 state.enabled = new_enabled;
173
174 let address = state.address;
176 let data = state.data as u32;
177 if let Some(ref mut interrupt) = state.interrupt {
178 if new_enabled && !old_enabled {
179 interrupt.enable(address, data, false);
181 } else if !new_enabled && old_enabled {
182 interrupt.disable();
184 }
185 }
186 }
187 MsiCapabilityHeader::MSG_ADDR_LO => {
188 state.address = (state.address & 0xFFFFFFFF00000000) | (val as u64);
189
190 if state.enabled {
192 let address = state.address;
193 let data = state.data as u32;
194 if let Some(ref mut interrupt) = state.interrupt {
195 interrupt.enable(address, data, false);
196 }
197 }
198 }
199 MsiCapabilityHeader::MSG_ADDR_HI if self.addr_64bit => {
200 state.address = (state.address & 0xFFFFFFFF) | ((val as u64) << 32);
201
202 if state.enabled {
204 let address = state.address;
205 let data = state.data as u32;
206 if let Some(ref mut interrupt) = state.interrupt {
207 interrupt.enable(address, data, false);
208 }
209 }
210 }
211 MsiCapabilityHeader::MSG_DATA_32 if !self.addr_64bit => {
212 state.data = val as u16;
213
214 if state.enabled {
216 let address = state.address;
217 let data = state.data as u32;
218 if let Some(ref mut interrupt) = state.interrupt {
219 interrupt.enable(address, data, false);
220 }
221 }
222 }
223 MsiCapabilityHeader::MSG_DATA_64 if self.addr_64bit => {
224 state.data = val as u16;
225
226 if state.enabled {
228 let address = state.address;
229 let data = state.data as u32;
230 if let Some(ref mut interrupt) = state.interrupt {
231 interrupt.enable(address, data, false);
232 }
233 }
234 }
235 MsiCapabilityHeader::MASK_BITS if self.addr_64bit && self.per_vector_masking => {
236 state.mask_bits = val;
237 }
238 MsiCapabilityHeader::PENDING_BITS if self.addr_64bit && self.per_vector_masking => {
239 tracelimit::warn_ratelimited!(
241 "Write to MSI pending bits register (typically read-only)"
242 );
243 }
244 _ => {
245 tracelimit::warn_ratelimited!("Unexpected MSI write offset {:#x}", offset);
246 }
247 }
248 }
249
250 fn reset(&mut self) {
251 let mut state = self.state.lock();
252
253 if state.enabled {
255 if let Some(ref mut interrupt) = state.interrupt {
256 interrupt.disable();
257 }
258 }
259
260 state.enabled = false;
262 state.multiple_message_enable = 0;
263 state.address = 0;
264 state.data = 0;
265 if self.per_vector_masking {
266 state.mask_bits = 0;
267 state.pending_bits = 0;
268 }
269 }
270}
271
272mod save_restore {
273 use super::*;
274 use thiserror::Error;
275 use vmcore::save_restore::RestoreError;
276 use vmcore::save_restore::SaveError;
277 use vmcore::save_restore::SaveRestore;
278
279 mod state {
280 use mesh::payload::Protobuf;
281 use vmcore::save_restore::SavedStateRoot;
282
283 #[derive(Debug, Protobuf, SavedStateRoot)]
284 #[mesh(package = "pci.caps.msi")]
285 pub struct SavedState {
286 #[mesh(1)]
287 pub enabled: bool,
288 #[mesh(2)]
289 pub multiple_message_enable: u8,
290 #[mesh(3)]
291 pub address: u64,
292 #[mesh(4)]
293 pub data: u16,
294 #[mesh(5)]
295 pub mask_bits: u32,
296 #[mesh(6)]
297 pub pending_bits: u32,
298 }
299 }
300
301 #[derive(Debug, Error)]
302 enum MsiRestoreError {
303 #[error("invalid multiple message enable value: {0}")]
304 InvalidMultipleMessageEnable(u8),
305 }
306
307 impl SaveRestore for MsiCapability {
308 type SavedState = state::SavedState;
309
310 fn save(&mut self) -> Result<Self::SavedState, SaveError> {
311 let state = self.state.lock();
312 Ok(state::SavedState {
313 enabled: state.enabled,
314 multiple_message_enable: state.multiple_message_enable,
315 address: state.address,
316 data: state.data,
317 mask_bits: state.mask_bits,
318 pending_bits: state.pending_bits,
319 })
320 }
321
322 fn restore(&mut self, saved_state: Self::SavedState) -> Result<(), RestoreError> {
323 let state::SavedState {
324 enabled,
325 multiple_message_enable,
326 address,
327 data,
328 mask_bits,
329 pending_bits,
330 } = saved_state;
331
332 if multiple_message_enable > 5 {
333 return Err(RestoreError::InvalidSavedState(
334 MsiRestoreError::InvalidMultipleMessageEnable(multiple_message_enable).into(),
335 ));
336 }
337
338 let mut state = self.state.lock();
339
340 if state.enabled {
342 if let Some(ref mut interrupt) = state.interrupt {
343 interrupt.disable();
344 }
345 }
346
347 state.enabled = enabled;
349 state.multiple_message_enable =
350 multiple_message_enable.min(state.multiple_message_capable);
351 state.address = address;
352 state.data = data;
353 state.mask_bits = mask_bits;
354 state.pending_bits = pending_bits;
355
356 if state.enabled {
358 let address = state.address;
359 let data = state.data as u32;
360 if let Some(ref mut interrupt) = state.interrupt {
361 interrupt.enable(address, data, false);
362 }
363 }
364
365 Ok(())
366 }
367 }
368}
369
370#[cfg(test)]
371mod tests {
372 use super::*;
373 use crate::msi::MsiConnection;
374 use crate::test_helpers::TestPciInterruptController;
375
376 #[test]
377 fn msi_check() {
378 let msi_conn = MsiConnection::new();
379 let mut cap = MsiCapability::new(2, true, false, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
381 msi_conn.connect(msi_controller.signal_msi());
382
383 assert_eq!(cap.read_u32(0), 0x00840005); assert_eq!(cap.read_u32(4), 0); assert_eq!(cap.read_u32(8), 0); assert_eq!(cap.read_u32(12), 0); cap.write_u32(4, 0x12345678);
394 cap.write_u32(8, 0x9abcdef0);
395 cap.write_u32(12, 0x1234);
396
397 assert_eq!(cap.read_u32(4), 0x12345678);
398 assert_eq!(cap.read_u32(8), 0x9abcdef0);
399 assert_eq!(cap.read_u32(12), 0x1234);
400
401 cap.write_u32(0, 0x00110005); assert_eq!(cap.read_u32(0), 0x00950005); cap.reset();
407 assert_eq!(cap.read_u32(0), 0x00840005); assert_eq!(cap.read_u32(4), 0);
409 assert_eq!(cap.read_u32(8), 0);
410 assert_eq!(cap.read_u32(12), 0);
411 }
412
413 #[test]
414 fn msi_32bit_check() {
415 let msi_conn = MsiConnection::new();
416 let mut cap = MsiCapability::new(1, false, false, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
418 msi_conn.connect(msi_controller.signal_msi());
419
420 assert_eq!(cap.read_u32(0), 0x00020005); cap.write_u32(4, 0x12345678); cap.write_u32(8, 0x1234); assert_eq!(cap.read_u32(4), 0x12345678);
428 assert_eq!(cap.read_u32(8), 0x1234);
429 }
430
431 #[test]
432 fn test_msi_save_restore() {
433 use vmcore::save_restore::SaveRestore;
434
435 let msi_conn = MsiConnection::new();
436 let mut cap = MsiCapability::new(2, true, false, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
438 msi_conn.connect(msi_controller.signal_msi());
439
440 cap.write_u32(4, 0x12345678); cap.write_u32(8, 0x9abcdef0); cap.write_u32(12, 0x5678); cap.write_u32(0, 0x00110001); assert_eq!(cap.read_u32(0), 0x00950005); assert_eq!(cap.read_u32(4), 0x12345678);
449 assert_eq!(cap.read_u32(8), 0x9abcdef0);
450 assert_eq!(cap.read_u32(12), 0x5678);
451
452 let saved_state = cap.save().expect("save should succeed");
454
455 cap.reset();
457 assert_eq!(cap.read_u32(0), 0x00840005); assert_eq!(cap.read_u32(4), 0);
459 assert_eq!(cap.read_u32(8), 0);
460 assert_eq!(cap.read_u32(12), 0);
461
462 cap.restore(saved_state).expect("restore should succeed");
464
465 assert_eq!(cap.read_u32(0), 0x00950005); assert_eq!(cap.read_u32(4), 0x12345678);
468 assert_eq!(cap.read_u32(8), 0x9abcdef0);
469 assert_eq!(cap.read_u32(12), 0x5678);
470 }
471
472 #[test]
473 fn test_msi_save_restore_32bit_with_masking() {
474 use vmcore::save_restore::SaveRestore;
475
476 let msi_conn = MsiConnection::new();
477 let mut cap = MsiCapability::new(3, false, true, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
479 msi_conn.connect(msi_controller.signal_msi());
480
481 cap.write_u32(4, 0x87654321); cap.write_u32(8, 0x1234); cap.write_u32(12, 0xaaaabbbb); cap.write_u32(0, 0x00210001); let control_reg = cap.read_u32(0);
489 let control_val = (control_reg >> 16) & 0xFFFF;
490 assert!(control_val & 1 != 0); assert_eq!((control_val >> 4) & 0x7, 2); assert_eq!(cap.read_u32(4), 0x87654321);
493 assert_eq!(cap.read_u32(8), 0x1234);
494
495 let saved_state = cap.save().expect("save should succeed");
497
498 cap.write_u32(4, 0x11111111);
500 cap.write_u32(8, 0x9999);
501 cap.write_u32(0, 0x00000005); let control_reg = cap.read_u32(0);
505 let control_val = (control_reg >> 16) & 0xFFFF;
506 assert_eq!(control_val & 1, 0); assert_eq!(cap.read_u32(4), 0x11111111);
508 assert_eq!(cap.read_u32(8), 0x9999);
509
510 cap.restore(saved_state).expect("restore should succeed");
512
513 let control_reg = cap.read_u32(0);
515 let control_val = (control_reg >> 16) & 0xFFFF;
516 assert!(control_val & 1 != 0); assert_eq!((control_val >> 4) & 0x7, 2); assert_eq!(cap.read_u32(4), 0x87654321);
519 assert_eq!(cap.read_u32(8), 0x1234);
520 }
521
522 #[test]
523 fn test_msi_save_restore_mme_clamping() {
524 use vmcore::save_restore::SaveRestore;
525
526 let msi_conn = MsiConnection::new();
527 let mut cap = MsiCapability::new(1, true, false, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
529 msi_conn.connect(msi_controller.signal_msi());
530
531 cap.write_u32(4, 0x12345678); cap.write_u32(8, 0x9abcdef0); cap.write_u32(12, 0x5678); cap.write_u32(0, 0x00310001); let control_reg = cap.read_u32(0);
539 let control_val = (control_reg >> 16) & 0xFFFF;
540 let mme = (control_val >> 4) & 0x7;
541 assert_eq!(mme, 1); let saved_state = cap.save().expect("save should succeed");
545
546 cap.reset();
548
549 cap.restore(saved_state).expect("restore should succeed");
551
552 let control_reg = cap.read_u32(0);
554 let control_val = (control_reg >> 16) & 0xFFFF;
555 let mme = (control_val >> 4) & 0x7;
556 let enabled = control_val & 1 != 0;
557 assert_eq!(mme, 1); assert!(enabled); assert_eq!(cap.read_u32(4), 0x12345678);
560 assert_eq!(cap.read_u32(8), 0x9abcdef0);
561 assert_eq!(cap.read_u32(12), 0x5678);
562 }
563}