From 23fb4fa26d24132f8edc7014563f6a2cfdd698bb Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 23 Feb 2022 11:30:18 +0100 Subject: [PATCH] pci: Allow only writable bits for MSI message control register The same way we mask the writes coming from the guest to the message control register related to MSI-X capability, let's do the same for MSI. The point is to prevent the guest from writing to read-only bits. The correct writable bits for MSI are only bits 0, 4, 5 and 6 of 2nd 16-bit word. Those are: * MSI Enable: 0 * Multiple Message Enable: 6-4 See "Table 7-39 Message Control Register for MSI" from "NCB-PCI_Express_Base_5.0r1.0-2019-05-22.pdf". Signed-off-by: Sebastien Boeuf --- pci/src/configuration.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pci/src/configuration.rs b/pci/src/configuration.rs index 6e53fd12d..9e4a1dd93 100644 --- a/pci/src/configuration.rs +++ b/pci/src/configuration.rs @@ -21,6 +21,7 @@ const ROM_BAR_REG: usize = 12; const BAR_IO_ADDR_MASK: u32 = 0xffff_fffc; const BAR_MEM_ADDR_MASK: u32 = 0xffff_fff0; const ROM_BAR_ADDR_MASK: u32 = 0xffff_f800; +const MSI_CAPABILITY_REGISTER_MASK: u32 = 0x0071_0000; const MSIX_CAPABILITY_REGISTER_MASK: u32 = 0xc000_0000; const NUM_BAR_REGS: usize = 6; const CAPABILITY_LIST_HEAD_OFFSET: usize = 0x34; @@ -715,9 +716,15 @@ impl PciConfiguration { } self.last_capability = Some((cap_offset, total_len)); - if cap_data.id() == PciCapabilityId::MsiX { - self.msix_cap_reg_idx = Some(cap_offset / 4); - self.writable_bits[self.msix_cap_reg_idx.unwrap()] = MSIX_CAPABILITY_REGISTER_MASK; + match cap_data.id() { + PciCapabilityId::MessageSignalledInterrupts => { + self.writable_bits[cap_offset / 4] = MSI_CAPABILITY_REGISTER_MASK; + } + PciCapabilityId::MsiX => { + self.msix_cap_reg_idx = Some(cap_offset / 4); + self.writable_bits[self.msix_cap_reg_idx.unwrap()] = MSIX_CAPABILITY_REGISTER_MASK; + } + _ => {} } Ok(cap_offset)