aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2020-05-14 19:09:00 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2020-05-14 19:09:00 +0000
commitf89903d63f71890746a348bb546b5dbc4dba623e (patch)
tree9d46d190d5b462e0f14d4bbf5b358490d9c014fc
parent62863d44bbe90719bf229f63402910def81f49cd (diff)
downloadsrc-f89903d63f71890746a348bb546b5dbc4dba623e.tar.gz
src-f89903d63f71890746a348bb546b5dbc4dba623e.zip
MF11 361041:
Update the cached MSI state when any MSI capability register is written. bhyve uses cached copies of the MSI capability registers to generate MSI interrupts for device models. Previously, these cached fields were only set when the MSI capability control register was updated. The Linux kernel recently adopted a change to deal with races in MSI interrupt delivery that writes to the MSI capability address and data registers to alter the destination of MSI interrupts without writing to the MSI capability control register. bhyve was not updating its cached registers for these writes and continued to send interrupts with the old data value to the old address. Fix this by recomputing the cached values for every write to any MSI capability register. Approved by: re (gjb)
Notes
Notes: svn path=/releng/11.4/; revision=361045
-rw-r--r--usr.sbin/bhyve/pci_emul.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index aad653bf19f7..81b0102313a4 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -898,26 +898,26 @@ msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
msgctrl &= ~rwmask;
msgctrl |= val & rwmask;
val = msgctrl;
-
- addrlo = pci_get_cfgdata32(pi, capoff + 4);
- if (msgctrl & PCIM_MSICTRL_64BIT)
- msgdata = pci_get_cfgdata16(pi, capoff + 12);
- else
- msgdata = pci_get_cfgdata16(pi, capoff + 8);
-
- mme = msgctrl & PCIM_MSICTRL_MME_MASK;
- pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0;
- if (pi->pi_msi.enabled) {
- pi->pi_msi.addr = addrlo;
- pi->pi_msi.msg_data = msgdata;
- pi->pi_msi.maxmsgnum = 1 << (mme >> 4);
- } else {
- pi->pi_msi.maxmsgnum = 0;
- }
- pci_lintr_update(pi);
}
-
CFGWRITE(pi, offset, val, bytes);
+
+ msgctrl = pci_get_cfgdata16(pi, capoff + 2);
+ addrlo = pci_get_cfgdata32(pi, capoff + 4);
+ if (msgctrl & PCIM_MSICTRL_64BIT)
+ msgdata = pci_get_cfgdata16(pi, capoff + 12);
+ else
+ msgdata = pci_get_cfgdata16(pi, capoff + 8);
+
+ mme = msgctrl & PCIM_MSICTRL_MME_MASK;
+ pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0;
+ if (pi->pi_msi.enabled) {
+ pi->pi_msi.addr = addrlo;
+ pi->pi_msi.msg_data = msgdata;
+ pi->pi_msi.maxmsgnum = 1 << (mme >> 4);
+ } else {
+ pi->pi_msi.maxmsgnum = 0;
+ }
+ pci_lintr_update(pi);
}
void