aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2022-02-04 13:51:59 +0000
committerGitHub <noreply@github.com>2022-02-04 13:51:59 +0000
commit2d1d87016133b6c2f38e4f6a5fca6be5b820653c (patch)
treef316e6a045a8c08d9d5ab31f29e96b7034d73ea7 /lib
parent314ed91fd991756bef2c87ecdf7feff4016c1d40 (diff)
downloadlibvfio-user-2d1d87016133b6c2f38e4f6a5fca6be5b820653c.zip
libvfio-user-2d1d87016133b6c2f38e4f6a5fca6be5b820653c.tar.gz
libvfio-user-2d1d87016133b6c2f38e4f6a5fca6be5b820653c.tar.bz2
ignore writes to RO MSI-X registers (#642)
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com> Reviewed-by: John Levon <john.levon@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/pci_caps.c51
1 files changed, 19 insertions, 32 deletions
diff --git a/lib/pci_caps.c b/lib/pci_caps.c
index cd91914..e9dc5ac 100644
--- a/lib/pci_caps.c
+++ b/lib/pci_caps.c
@@ -167,49 +167,36 @@ cap_write_pm(vfu_ctx_t *vfu_ctx, struct pci_cap *cap, char * buf,
}
static ssize_t
-handle_mxc_write(vfu_ctx_t *vfu_ctx, struct msixcap *msix,
- const struct mxc *const mxc)
+cap_write_msix(vfu_ctx_t *vfu_ctx, struct pci_cap *cap, char *buf,
+ size_t count, loff_t offset)
{
- assert(msix != NULL);
- assert(mxc != NULL);
+ struct msixcap *msix = cap_data(vfu_ctx, cap);
+ struct msixcap new_msix = *msix;
- if (mxc->mxe != msix->mxc.mxe) {
- vfu_log(vfu_ctx, LOG_DEBUG, "%s MSI-X",
- mxc->mxe ? "enable" : "disable");
- msix->mxc.mxe = mxc->mxe;
- }
+ memcpy((char *)&new_msix + offset - cap->off, buf, count);
+
+ /*
+ * Same as doing &= (PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE), but
+ * prefer to log what's changing.
+ */
- if (mxc->fm != msix->mxc.fm) {
- if (mxc->fm) {
+ if (msix->mxc.fm != new_msix.mxc.fm) {
+ if (new_msix.mxc.fm) {
vfu_log(vfu_ctx, LOG_DEBUG, "all MSI-X vectors masked");
} else {
vfu_log(vfu_ctx, LOG_DEBUG,
"vector's mask bit determines whether vector is masked");
}
- msix->mxc.fm = mxc->fm;
+ msix->mxc.fm = new_msix.mxc.fm;
}
- return sizeof(struct mxc);
-}
-
-static ssize_t
-cap_write_msix(vfu_ctx_t *vfu_ctx, struct pci_cap *cap, char *buf,
- size_t count, loff_t offset)
-{
- struct msixcap *msix = cap_data(vfu_ctx, cap);
-
- if (count == sizeof(struct mxc)) {
- switch (offset - cap->off) {
- case offsetof(struct msixcap, mxc):
- return handle_mxc_write(vfu_ctx, msix, (struct mxc *)buf);
- default:
- vfu_log(vfu_ctx, LOG_ERR,
- "invalid MSI-X write offset %ld", offset);
- return ERROR_INT(EINVAL);
- }
+ if (msix->mxc.mxe != new_msix.mxc.mxe) {
+ vfu_log(vfu_ctx, LOG_DEBUG, "%s MSI-X",
+ msix->mxc.mxe ? "enable" : "disable");
+ msix->mxc.mxe = new_msix.mxc.mxe;
}
- vfu_log(vfu_ctx, LOG_ERR, "invalid MSI-X write size %lu", count);
- return ERROR_INT(EINVAL);
+
+ return count;
}
static int