1use super::PciCapability;
7use crate::capabilities::msix::MsiInterrupt;
8use crate::msi::MsiTarget;
9use crate::spec::caps::CapabilityId;
10use crate::spec::caps::msi::MsiCapabilityHeader;
11use chipset_device::pci::ByteEnabledDwordRead;
12use chipset_device::pci::ByteEnabledDwordWrite;
13use inspect::Inspect;
14use inspect::InspectMut;
15use parking_lot::Mutex;
16use std::fmt::Debug;
17use std::sync::Arc;
18use vmcore::interrupt::Interrupt;
19
20#[derive(Debug, Clone, Inspect)]
22pub struct MsiCapability {
23 #[inspect(with = "|x| inspect::adhoc(|req| x.lock().inspect_mut(req))")]
24 state: Arc<Mutex<MsiCapabilityState>>,
25 addr_64bit: bool,
26 per_vector_masking: bool,
27}
28
29#[derive(Debug, InspectMut)]
30struct MsiCapabilityState {
31 enabled: bool,
32 multiple_message_enable: u8, multiple_message_capable: u8, #[inspect(hex)]
35 address: u64,
36 #[inspect(hex)]
37 data: u16,
38 #[inspect(hex)]
39 mask_bits: u32,
40 #[inspect(hex)]
41 pending_bits: u32,
42 interrupt: Option<MsiInterrupt>,
43}
44
45impl MsiCapabilityState {
46 fn new(multiple_message_capable: u8, _addr_64bit: bool, per_vector_masking: bool) -> Self {
47 Self {
48 enabled: false,
49 multiple_message_enable: 0,
50 multiple_message_capable,
51 address: 0,
52 data: 0,
53 mask_bits: if per_vector_masking { 0xFFFFFFFF } else { 0 },
54 pending_bits: 0,
55 interrupt: None,
56 }
57 }
58
59 fn control_register(&self, addr_64bit: bool, per_vector_masking: bool) -> u16 {
60 let mut control = 0u16;
61 control |= (self.multiple_message_capable as u16) << 1; control |= (self.multiple_message_enable as u16) << 4; if addr_64bit {
64 control |= 1 << 7; }
66 if per_vector_masking {
67 control |= 1 << 8; }
69 if self.enabled {
70 control |= 1 << 0; }
72 control
73 }
74
75 fn read(
76 &self,
77 offset: u16,
78 addr_64bit: bool,
79 per_vector_masking: bool,
80 mut value: ByteEnabledDwordRead<'_>,
81 ) {
82 match MsiCapabilityHeader(offset) {
83 MsiCapabilityHeader::CONTROL_CAPS => {
84 value.set_low_high(
85 CapabilityId::MSI.0.into(),
86 self.control_register(addr_64bit, per_vector_masking),
87 );
88 }
89 MsiCapabilityHeader::MSG_ADDR_LO => value.set(self.address as u32),
90 MsiCapabilityHeader::MSG_ADDR_HI if addr_64bit => {
91 value.set((self.address >> 32) as u32)
92 }
93 MsiCapabilityHeader::MSG_DATA_32 if !addr_64bit => value.set_low_high(self.data, 0),
94 MsiCapabilityHeader::MSG_DATA_64 if addr_64bit => value.set_low_high(self.data, 0),
95 MsiCapabilityHeader::MASK_BITS if addr_64bit && per_vector_masking => {
96 value.set(self.mask_bits)
97 }
98 MsiCapabilityHeader::PENDING_BITS if addr_64bit && per_vector_masking => {
99 value.set(self.pending_bits);
100 }
101 _ => {
102 tracelimit::warn_ratelimited!("Unexpected MSI read offset {:#x}", offset);
103 value.set(0);
104 }
105 }
106 }
107}
108
109impl MsiCapability {
110 pub fn new(
118 multiple_message_capable: u8,
119 addr_64bit: bool,
120 per_vector_masking: bool,
121 msi_target: &MsiTarget,
122 ) -> Self {
123 assert!(multiple_message_capable <= 5, "MMC must be 0-5");
124
125 let interrupt = MsiInterrupt::new(msi_target.clone());
126 let state = MsiCapabilityState {
127 interrupt: Some(interrupt),
128 ..MsiCapabilityState::new(multiple_message_capable, addr_64bit, per_vector_masking)
129 };
130
131 Self {
132 state: Arc::new(Mutex::new(state)),
133 addr_64bit,
134 per_vector_masking,
135 }
136 }
137
138 pub fn interrupt(&self) -> Option<Interrupt> {
140 self.state.lock().interrupt.as_mut().map(|i| i.interrupt())
141 }
142
143 fn len_bytes(&self) -> usize {
144 let mut len = 8; if self.addr_64bit {
146 len += 4; }
148 len += 2; if self.per_vector_masking {
150 len += 8; }
152 (len + 3) & !3
154 }
155}
156
157impl PciCapability for MsiCapability {
158 fn label(&self) -> &str {
159 "msi"
160 }
161
162 fn capability_id(&self) -> CapabilityId {
163 CapabilityId::MSI
164 }
165
166 fn len(&self) -> usize {
167 self.len_bytes()
168 }
169
170 fn read(&self, offset: u16, value: ByteEnabledDwordRead<'_>) {
171 self.state
172 .lock()
173 .read(offset, self.addr_64bit, self.per_vector_masking, value);
174 }
175
176 fn write(&mut self, offset: u16, val: ByteEnabledDwordWrite) {
177 let mut state = self.state.lock();
178 match MsiCapabilityHeader(offset) {
179 MsiCapabilityHeader::CONTROL_CAPS => {
180 let control_val = val
181 .merge_high(state.control_register(self.addr_64bit, self.per_vector_masking));
182 let old_enabled = state.enabled;
183 let new_enabled = control_val & 1 != 0;
184 let mme = ((control_val >> 4) & 0x7) as u8;
185
186 state.multiple_message_enable = mme.min(state.multiple_message_capable);
188 state.enabled = new_enabled;
189
190 let address = state.address;
192 let data = state.data as u32;
193 if let Some(ref mut interrupt) = state.interrupt {
194 if new_enabled && !old_enabled {
195 interrupt.enable(address, data, false);
197 } else if !new_enabled && old_enabled {
198 interrupt.disable();
200 }
201 }
202 }
203 MsiCapabilityHeader::MSG_ADDR_LO => {
204 let new_low = val.merge(state.address as u32);
205 state.address = (state.address & 0xFFFFFFFF00000000) | (new_low as u64);
206
207 if state.enabled {
209 let address = state.address;
210 let data = state.data as u32;
211 if let Some(ref mut interrupt) = state.interrupt {
212 interrupt.enable(address, data, false);
213 }
214 }
215 }
216 MsiCapabilityHeader::MSG_ADDR_HI if self.addr_64bit => {
217 let new_high = val.merge((state.address >> 32) as u32);
218 state.address = (state.address & 0xFFFFFFFF) | ((new_high as u64) << 32);
219
220 if state.enabled {
222 let address = state.address;
223 let data = state.data as u32;
224 if let Some(ref mut interrupt) = state.interrupt {
225 interrupt.enable(address, data, false);
226 }
227 }
228 }
229 MsiCapabilityHeader::MSG_DATA_32 if !self.addr_64bit => {
230 state.data = val.merge_low(state.data);
231
232 if state.enabled {
234 let address = state.address;
235 let data = state.data as u32;
236 if let Some(ref mut interrupt) = state.interrupt {
237 interrupt.enable(address, data, false);
238 }
239 }
240 }
241 MsiCapabilityHeader::MSG_DATA_64 if self.addr_64bit => {
242 state.data = val.merge_low(state.data);
243
244 if state.enabled {
246 let address = state.address;
247 let data = state.data as u32;
248 if let Some(ref mut interrupt) = state.interrupt {
249 interrupt.enable(address, data, false);
250 }
251 }
252 }
253 MsiCapabilityHeader::MASK_BITS if self.addr_64bit && self.per_vector_masking => {
254 val.merge_into(&mut state.mask_bits);
255 }
256 MsiCapabilityHeader::PENDING_BITS if self.addr_64bit && self.per_vector_masking => {
257 tracelimit::warn_ratelimited!(
259 "Write to MSI pending bits register (typically read-only)"
260 );
261 }
262 _ => {
263 tracelimit::warn_ratelimited!("Unexpected MSI write offset {:#x}", offset);
264 }
265 }
266 }
267
268 fn reset(&mut self) {
269 let mut state = self.state.lock();
270
271 if state.enabled {
273 if let Some(ref mut interrupt) = state.interrupt {
274 interrupt.disable();
275 }
276 }
277
278 state.enabled = false;
280 state.multiple_message_enable = 0;
281 state.address = 0;
282 state.data = 0;
283 if self.per_vector_masking {
284 state.mask_bits = 0;
285 state.pending_bits = 0;
286 }
287 }
288
289 fn as_msi_cap(&self) -> Option<&MsiCapability> {
290 Some(self)
291 }
292
293 fn as_msi_cap_mut(&mut self) -> Option<&mut MsiCapability> {
294 Some(self)
295 }
296}
297
298mod save_restore {
299 use super::*;
300 use thiserror::Error;
301 use vmcore::save_restore::RestoreError;
302 use vmcore::save_restore::SaveError;
303 use vmcore::save_restore::SaveRestore;
304
305 mod state {
306 use mesh::payload::Protobuf;
307 use vmcore::save_restore::SavedStateRoot;
308
309 #[derive(Debug, Protobuf, SavedStateRoot)]
310 #[mesh(package = "pci.caps.msi")]
311 pub struct SavedState {
312 #[mesh(1)]
313 pub enabled: bool,
314 #[mesh(2)]
315 pub multiple_message_enable: u8,
316 #[mesh(3)]
317 pub address: u64,
318 #[mesh(4)]
319 pub data: u16,
320 #[mesh(5)]
321 pub mask_bits: u32,
322 #[mesh(6)]
323 pub pending_bits: u32,
324 }
325 }
326
327 #[derive(Debug, Error)]
328 enum MsiRestoreError {
329 #[error("invalid multiple message enable value: {0}")]
330 InvalidMultipleMessageEnable(u8),
331 }
332
333 impl SaveRestore for MsiCapability {
334 type SavedState = state::SavedState;
335
336 fn save(&mut self) -> Result<Self::SavedState, SaveError> {
337 let state = self.state.lock();
338 Ok(state::SavedState {
339 enabled: state.enabled,
340 multiple_message_enable: state.multiple_message_enable,
341 address: state.address,
342 data: state.data,
343 mask_bits: state.mask_bits,
344 pending_bits: state.pending_bits,
345 })
346 }
347
348 fn restore(&mut self, saved_state: Self::SavedState) -> Result<(), RestoreError> {
349 let state::SavedState {
350 enabled,
351 multiple_message_enable,
352 address,
353 data,
354 mask_bits,
355 pending_bits,
356 } = saved_state;
357
358 if multiple_message_enable > 5 {
359 return Err(RestoreError::InvalidSavedState(
360 MsiRestoreError::InvalidMultipleMessageEnable(multiple_message_enable).into(),
361 ));
362 }
363
364 let mut state = self.state.lock();
365
366 if state.enabled {
368 if let Some(ref mut interrupt) = state.interrupt {
369 interrupt.disable();
370 }
371 }
372
373 state.enabled = enabled;
375 state.multiple_message_enable =
376 multiple_message_enable.min(state.multiple_message_capable);
377 state.address = address;
378 state.data = data;
379 state.mask_bits = mask_bits;
380 state.pending_bits = pending_bits;
381
382 if state.enabled {
384 let address = state.address;
385 let data = state.data as u32;
386 if let Some(ref mut interrupt) = state.interrupt {
387 interrupt.enable(address, data, false);
388 }
389 }
390
391 Ok(())
392 }
393 }
394}
395
396#[cfg(test)]
397mod tests {
398 use super::*;
399
400 use crate::msi::MsiConnection;
401 use crate::test_helpers::TestPciInterruptController;
402 use crate::test_helpers::read_cap_u32;
403 use crate::test_helpers::write_cap_u32;
404
405 #[test]
406 fn msi_check() {
407 let msi_conn = MsiConnection::new();
408 let mut cap = MsiCapability::new(2, true, false, &msi_conn.target()); let msi_controller = TestPciInterruptController::new();
410 msi_conn.connect(msi_controller.signal_msi());
411
412 assert_eq!(read_cap_u32(&cap, 0), 0x00840005); assert_eq!(read_cap_u32(&cap, 4), 0); assert_eq!(read_cap_u32(&cap, 8), 0); assert_eq!(read_cap_u32(&cap, 12), 0); write_cap_u32(&mut cap, 4, 0x12345678);
423 write_cap_u32(&mut cap, 8, 0x9abcdef0);
424 write_cap_u32(&mut cap, 12, 0x1234);
425
426 assert_eq!(read_cap_u32(&cap, 4), 0x12345678);
427 assert_eq!(read_cap_u32(&cap, 8), 0x9abcdef0);
428 assert_eq!(read_cap_u32(&cap, 12), 0x1234);
429
430 write_cap_u32(&mut cap, 0, 0x00110005); assert_eq!(read_cap_u32(&cap, 0), 0x00950005); cap.reset();
436 assert_eq!(read_cap_u32(&cap, 0), 0x00840005); assert_eq!(read_cap_u32(&cap, 4), 0);
438 assert_eq!(read_cap_u32(&cap, 8), 0);
439 assert_eq!(read_cap_u32(&cap, 12), 0);
440 }
441
442 #[test]
443 fn msi_32bit_check() {
444 let msi_conn = MsiConnection::new();
445 let mut cap = MsiCapability::new(1, false, false, &msi_conn.target()); let msi_controller = TestPciInterruptController::new();
447 msi_conn.connect(msi_controller.signal_msi());
448
449 assert_eq!(read_cap_u32(&cap, 0), 0x00020005); write_cap_u32(&mut cap, 4, 0x12345678); write_cap_u32(&mut cap, 8, 0x1234); assert_eq!(read_cap_u32(&cap, 4), 0x12345678);
457 assert_eq!(read_cap_u32(&cap, 8), 0x1234);
458 }
459
460 #[test]
461 fn test_msi_save_restore() {
462 use vmcore::save_restore::SaveRestore;
463
464 let msi_conn = MsiConnection::new();
465 let mut cap = MsiCapability::new(2, true, false, &msi_conn.target()); let msi_controller = TestPciInterruptController::new();
467 msi_conn.connect(msi_controller.signal_msi());
468
469 write_cap_u32(&mut cap, 4, 0x12345678); write_cap_u32(&mut cap, 8, 0x9abcdef0); write_cap_u32(&mut cap, 12, 0x5678); write_cap_u32(&mut cap, 0, 0x00110001); assert_eq!(read_cap_u32(&cap, 0), 0x00950005); assert_eq!(read_cap_u32(&cap, 4), 0x12345678);
478 assert_eq!(read_cap_u32(&cap, 8), 0x9abcdef0);
479 assert_eq!(read_cap_u32(&cap, 12), 0x5678);
480
481 let saved_state = cap.save().expect("save should succeed");
483
484 cap.reset();
486 assert_eq!(read_cap_u32(&cap, 0), 0x00840005); assert_eq!(read_cap_u32(&cap, 4), 0);
488 assert_eq!(read_cap_u32(&cap, 8), 0);
489 assert_eq!(read_cap_u32(&cap, 12), 0);
490
491 cap.restore(saved_state).expect("restore should succeed");
493
494 assert_eq!(read_cap_u32(&cap, 0), 0x00950005); assert_eq!(read_cap_u32(&cap, 4), 0x12345678);
497 assert_eq!(read_cap_u32(&cap, 8), 0x9abcdef0);
498 assert_eq!(read_cap_u32(&cap, 12), 0x5678);
499 }
500
501 #[test]
502 fn test_msi_save_restore_32bit_with_masking() {
503 use vmcore::save_restore::SaveRestore;
504
505 let msi_conn = MsiConnection::new();
506 let mut cap = MsiCapability::new(3, false, true, &msi_conn.target()); let msi_controller = TestPciInterruptController::new();
508 msi_conn.connect(msi_controller.signal_msi());
509
510 write_cap_u32(&mut cap, 4, 0x87654321); write_cap_u32(&mut cap, 8, 0x1234); write_cap_u32(&mut cap, 12, 0xaaaabbbb); write_cap_u32(&mut cap, 0, 0x00210001); let control_reg = read_cap_u32(&cap, 0);
518 let control_val = (control_reg >> 16) & 0xFFFF;
519 assert!(control_val & 1 != 0); assert_eq!((control_val >> 4) & 0x7, 2); assert_eq!(read_cap_u32(&cap, 4), 0x87654321);
522 assert_eq!(read_cap_u32(&cap, 8), 0x1234);
523
524 let saved_state = cap.save().expect("save should succeed");
526
527 write_cap_u32(&mut cap, 4, 0x11111111);
529 write_cap_u32(&mut cap, 8, 0x9999);
530 write_cap_u32(&mut cap, 12, 0x0000);
531 write_cap_u32(&mut cap, 0, 0x00000005); let control_reg = read_cap_u32(&cap, 0);
535 let control_val = (control_reg >> 16) & 0xFFFF;
536 assert_eq!(control_val & 1, 0); assert_eq!(read_cap_u32(&cap, 4), 0x11111111);
538 assert_eq!(read_cap_u32(&cap, 8), 0x9999);
539
540 cap.restore(saved_state).expect("restore should succeed");
542
543 let control_reg = read_cap_u32(&cap, 0);
545 let control_val = (control_reg >> 16) & 0xFFFF;
546 assert!(control_val & 1 != 0); assert_eq!((control_val >> 4) & 0x7, 2); assert_eq!(read_cap_u32(&cap, 4), 0x87654321);
549 assert_eq!(read_cap_u32(&cap, 8), 0x1234);
550 }
551
552 #[test]
553 fn test_msi_save_restore_mme_clamping() {
554 use vmcore::save_restore::SaveRestore;
555
556 let msi_conn = MsiConnection::new();
557 let mut cap = MsiCapability::new(1, true, false, &msi_conn.target()); let msi_controller = TestPciInterruptController::new();
559 msi_conn.connect(msi_controller.signal_msi());
560
561 write_cap_u32(&mut cap, 4, 0x12345678); write_cap_u32(&mut cap, 8, 0x9abcdef0); write_cap_u32(&mut cap, 12, 0x5678); write_cap_u32(&mut cap, 0, 0x00310001); let control_reg = read_cap_u32(&cap, 0);
569 let control_val = (control_reg >> 16) & 0xFFFF;
570 let mme = (control_val >> 4) & 0x7;
571 assert_eq!(mme, 1); let saved_state = cap.save().expect("save should succeed");
575
576 cap.reset();
578
579 cap.restore(saved_state).expect("restore should succeed");
581
582 let control_reg = read_cap_u32(&cap, 0);
584 let control_val = (control_reg >> 16) & 0xFFFF;
585 let mme = (control_val >> 4) & 0x7;
586 let enabled = control_val & 1 != 0;
587 assert_eq!(mme, 1); assert!(enabled); assert_eq!(read_cap_u32(&cap, 4), 0x12345678);
590 assert_eq!(read_cap_u32(&cap, 8), 0x9abcdef0);
591 assert_eq!(read_cap_u32(&cap, 12), 0x5678);
592 }
593}