hv: msix: corrently determine when the guest is changing Message Data/Addr

The guest could write the MSI-X Table fields in DWORD or QWORD. For
example the Message Address could be a QWORD write or two DWORD writes,
the Message Data could be a DWORD write or part of a QWORD write that
is combined with the Vector Control. This patch captures all the
possible combinations when the guest is configuring the MSI-X Table.

Tracked-On: #1568
Signed-off-by: Zide Chen <zide.chen@intel.com>
Reviewed-by: Li, Fei1 <fei1.li@intel.com>
This commit is contained in:
Zide Chen 2018-11-19 15:59:50 -08:00 committed by lijinxia
parent c41c0dab08
commit 3b24c34cbf

View File

@ -217,10 +217,22 @@ static void vmsix_table_rw(struct pci_vdev *vdev, struct mmio_request *mmio, uin
/* Save for comparison */
vector_control = entry->vector_control;
/* Writing different value to Message Data/Addr? */
if (((offsetof(struct msix_table_entry, addr) == entry_offset) && (entry->addr != mmio->value)) ||
((offsetof(struct msix_table_entry, data) == entry_offset) && (entry->data != (uint32_t)mmio->value))) {
message_changed = true;
/*
* Writing different value to Message Data/Addr?
* PCI Spec: Software is permitted to fill in MSI-X Table entry DWORD fields individually
* with DWORD writes, or software in certain cases is permitted to fill in appropriate pairs
* of DWORDs with a single QWORD write
*/
if (entry_offset < offsetof(struct msix_table_entry, data)) {
uint64_t qword_mask = ~0UL;
if (mmio->size == 4U) {
qword_mask = (entry_offset == 0U) ? 0x00000000FFFFFFFFUL : 0xFFFFFFFF00000000UL;
}
message_changed = ((entry->addr & qword_mask) != (mmio->value & qword_mask));
} else {
if (entry_offset == offsetof(struct msix_table_entry, data)) {
message_changed = (entry->data != (uint32_t)mmio->value);
}
}
/* Write to pci_vdev */