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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-02-23 11:30:18 +01:00
parent 8846409eab
commit 23fb4fa26d

View File

@ -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)