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 fn as_msi_cap(&self) -> Option<&MsiCapability> {
272 Some(self)
273 }
274
275 fn as_msi_cap_mut(&mut self) -> Option<&mut MsiCapability> {
276 Some(self)
277 }
278}
279
280mod save_restore {
281 use super::*;
282 use thiserror::Error;
283 use vmcore::save_restore::RestoreError;
284 use vmcore::save_restore::SaveError;
285 use vmcore::save_restore::SaveRestore;
286
287 mod state {
288 use mesh::payload::Protobuf;
289 use vmcore::save_restore::SavedStateRoot;
290
291 #[derive(Debug, Protobuf, SavedStateRoot)]
292 #[mesh(package = "pci.caps.msi")]
293 pub struct SavedState {
294 #[mesh(1)]
295 pub enabled: bool,
296 #[mesh(2)]
297 pub multiple_message_enable: u8,
298 #[mesh(3)]
299 pub address: u64,
300 #[mesh(4)]
301 pub data: u16,
302 #[mesh(5)]
303 pub mask_bits: u32,
304 #[mesh(6)]
305 pub pending_bits: u32,
306 }
307 }
308
309 #[derive(Debug, Error)]
310 enum MsiRestoreError {
311 #[error("invalid multiple message enable value: {0}")]
312 InvalidMultipleMessageEnable(u8),
313 }
314
315 impl SaveRestore for MsiCapability {
316 type SavedState = state::SavedState;
317
318 fn save(&mut self) -> Result<Self::SavedState, SaveError> {
319 let state = self.state.lock();
320 Ok(state::SavedState {
321 enabled: state.enabled,
322 multiple_message_enable: state.multiple_message_enable,
323 address: state.address,
324 data: state.data,
325 mask_bits: state.mask_bits,
326 pending_bits: state.pending_bits,
327 })
328 }
329
330 fn restore(&mut self, saved_state: Self::SavedState) -> Result<(), RestoreError> {
331 let state::SavedState {
332 enabled,
333 multiple_message_enable,
334 address,
335 data,
336 mask_bits,
337 pending_bits,
338 } = saved_state;
339
340 if multiple_message_enable > 5 {
341 return Err(RestoreError::InvalidSavedState(
342 MsiRestoreError::InvalidMultipleMessageEnable(multiple_message_enable).into(),
343 ));
344 }
345
346 let mut state = self.state.lock();
347
348 if state.enabled {
350 if let Some(ref mut interrupt) = state.interrupt {
351 interrupt.disable();
352 }
353 }
354
355 state.enabled = enabled;
357 state.multiple_message_enable =
358 multiple_message_enable.min(state.multiple_message_capable);
359 state.address = address;
360 state.data = data;
361 state.mask_bits = mask_bits;
362 state.pending_bits = pending_bits;
363
364 if state.enabled {
366 let address = state.address;
367 let data = state.data as u32;
368 if let Some(ref mut interrupt) = state.interrupt {
369 interrupt.enable(address, data, false);
370 }
371 }
372
373 Ok(())
374 }
375 }
376}
377
378#[cfg(test)]
379mod tests {
380 use super::*;
381 use crate::msi::MsiConnection;
382 use crate::test_helpers::TestPciInterruptController;
383
384 #[test]
385 fn msi_check() {
386 let msi_conn = MsiConnection::new();
387 let mut cap = MsiCapability::new(2, true, false, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
389 msi_conn.connect(msi_controller.signal_msi());
390
391 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);
402 cap.write_u32(8, 0x9abcdef0);
403 cap.write_u32(12, 0x1234);
404
405 assert_eq!(cap.read_u32(4), 0x12345678);
406 assert_eq!(cap.read_u32(8), 0x9abcdef0);
407 assert_eq!(cap.read_u32(12), 0x1234);
408
409 cap.write_u32(0, 0x00110005); assert_eq!(cap.read_u32(0), 0x00950005); cap.reset();
415 assert_eq!(cap.read_u32(0), 0x00840005); assert_eq!(cap.read_u32(4), 0);
417 assert_eq!(cap.read_u32(8), 0);
418 assert_eq!(cap.read_u32(12), 0);
419 }
420
421 #[test]
422 fn msi_32bit_check() {
423 let msi_conn = MsiConnection::new();
424 let mut cap = MsiCapability::new(1, false, false, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
426 msi_conn.connect(msi_controller.signal_msi());
427
428 assert_eq!(cap.read_u32(0), 0x00020005); cap.write_u32(4, 0x12345678); cap.write_u32(8, 0x1234); assert_eq!(cap.read_u32(4), 0x12345678);
436 assert_eq!(cap.read_u32(8), 0x1234);
437 }
438
439 #[test]
440 fn test_msi_save_restore() {
441 use vmcore::save_restore::SaveRestore;
442
443 let msi_conn = MsiConnection::new();
444 let mut cap = MsiCapability::new(2, true, false, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
446 msi_conn.connect(msi_controller.signal_msi());
447
448 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);
457 assert_eq!(cap.read_u32(8), 0x9abcdef0);
458 assert_eq!(cap.read_u32(12), 0x5678);
459
460 let saved_state = cap.save().expect("save should succeed");
462
463 cap.reset();
465 assert_eq!(cap.read_u32(0), 0x00840005); assert_eq!(cap.read_u32(4), 0);
467 assert_eq!(cap.read_u32(8), 0);
468 assert_eq!(cap.read_u32(12), 0);
469
470 cap.restore(saved_state).expect("restore should succeed");
472
473 assert_eq!(cap.read_u32(0), 0x00950005); assert_eq!(cap.read_u32(4), 0x12345678);
476 assert_eq!(cap.read_u32(8), 0x9abcdef0);
477 assert_eq!(cap.read_u32(12), 0x5678);
478 }
479
480 #[test]
481 fn test_msi_save_restore_32bit_with_masking() {
482 use vmcore::save_restore::SaveRestore;
483
484 let msi_conn = MsiConnection::new();
485 let mut cap = MsiCapability::new(3, false, true, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
487 msi_conn.connect(msi_controller.signal_msi());
488
489 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);
497 let control_val = (control_reg >> 16) & 0xFFFF;
498 assert!(control_val & 1 != 0); assert_eq!((control_val >> 4) & 0x7, 2); assert_eq!(cap.read_u32(4), 0x87654321);
501 assert_eq!(cap.read_u32(8), 0x1234);
502
503 let saved_state = cap.save().expect("save should succeed");
505
506 cap.write_u32(4, 0x11111111);
508 cap.write_u32(8, 0x9999);
509 cap.write_u32(0, 0x00000005); let control_reg = cap.read_u32(0);
513 let control_val = (control_reg >> 16) & 0xFFFF;
514 assert_eq!(control_val & 1, 0); assert_eq!(cap.read_u32(4), 0x11111111);
516 assert_eq!(cap.read_u32(8), 0x9999);
517
518 cap.restore(saved_state).expect("restore should succeed");
520
521 let control_reg = cap.read_u32(0);
523 let control_val = (control_reg >> 16) & 0xFFFF;
524 assert!(control_val & 1 != 0); assert_eq!((control_val >> 4) & 0x7, 2); assert_eq!(cap.read_u32(4), 0x87654321);
527 assert_eq!(cap.read_u32(8), 0x1234);
528 }
529
530 #[test]
531 fn test_msi_save_restore_mme_clamping() {
532 use vmcore::save_restore::SaveRestore;
533
534 let msi_conn = MsiConnection::new();
535 let mut cap = MsiCapability::new(1, true, false, msi_conn.target()); let msi_controller = TestPciInterruptController::new();
537 msi_conn.connect(msi_controller.signal_msi());
538
539 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);
547 let control_val = (control_reg >> 16) & 0xFFFF;
548 let mme = (control_val >> 4) & 0x7;
549 assert_eq!(mme, 1); let saved_state = cap.save().expect("save should succeed");
553
554 cap.reset();
556
557 cap.restore(saved_state).expect("restore should succeed");
559
560 let control_reg = cap.read_u32(0);
562 let control_val = (control_reg >> 16) & 0xFFFF;
563 let mme = (control_val >> 4) & 0x7;
564 let enabled = control_val & 1 != 0;
565 assert_eq!(mme, 1); assert!(enabled); assert_eq!(cap.read_u32(4), 0x12345678);
568 assert_eq!(cap.read_u32(8), 0x9abcdef0);
569 assert_eq!(cap.read_u32(12), 0x5678);
570 }
571}