From: "Cédric Le Goater" <clg@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Richard Henderson" <richard.henderson@linaro.org>,
"Alex Williamson" <alex.williamson@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Robin Voetter" <robin@streamhpc.com>,
"Cédric Le Goater" <clg@redhat.com>
Subject: [PULL 11/11] vfio/pci: Enable AtomicOps completers on root ports
Date: Mon, 10 Jul 2023 09:48:48 +0200 [thread overview]
Message-ID: <20230710074848.456453-12-clg@redhat.com> (raw)
In-Reply-To: <20230710074848.456453-1-clg@redhat.com>
From: Alex Williamson <alex.williamson@redhat.com>
Dynamically enable Atomic Ops completer support around realize/exit of
vfio-pci devices reporting host support for these accesses and adhering
to a minimal configuration standard. While the Atomic Ops completer
bits in the root port device capabilities2 register are read-only, the
PCIe spec does allow RO bits to change to reflect hardware state. We
take advantage of that here around the realize and exit functions of
the vfio-pci device.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Robin Voetter <robin@streamhpc.com>
Tested-by: Robin Voetter <robin@streamhpc.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/vfio/pci.h | 1 +
hw/vfio/pci.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 2674476d6c77..a2771b9ff3cc 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -174,6 +174,7 @@ struct VFIOPCIDevice {
bool no_vfio_ioeventfd;
bool enable_ramfb;
bool defer_kvm_irq_routing;
+ bool clear_parent_atomics_on_exit;
VFIODisplay *dpy;
Notifier irqchip_change_notifier;
};
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index c89fdf7ae6c2..a205c6b1130f 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1828,6 +1828,81 @@ static void vfio_add_emulated_long(VFIOPCIDevice *vdev, int pos,
vfio_set_long_bits(vdev->emulated_config_bits + pos, mask, mask);
}
+static void vfio_pci_enable_rp_atomics(VFIOPCIDevice *vdev)
+{
+ struct vfio_device_info_cap_pci_atomic_comp *cap;
+ g_autofree struct vfio_device_info *info = NULL;
+ PCIBus *bus = pci_get_bus(&vdev->pdev);
+ PCIDevice *parent = bus->parent_dev;
+ struct vfio_info_cap_header *hdr;
+ uint32_t mask = 0;
+ uint8_t *pos;
+
+ /*
+ * PCIe Atomic Ops completer support is only added automatically for single
+ * function devices downstream of a root port supporting DEVCAP2. Support
+ * is added during realize and, if added, removed during device exit. The
+ * single function requirement avoids conflicting requirements should a
+ * slot be composed of multiple devices with differing capabilities.
+ */
+ if (pci_bus_is_root(bus) || !parent || !parent->exp.exp_cap ||
+ pcie_cap_get_type(parent) != PCI_EXP_TYPE_ROOT_PORT ||
+ pcie_cap_get_version(parent) != PCI_EXP_FLAGS_VER2 ||
+ vdev->pdev.devfn ||
+ vdev->pdev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
+ return;
+ }
+
+ pos = parent->config + parent->exp.exp_cap + PCI_EXP_DEVCAP2;
+
+ /* Abort if there'a already an Atomic Ops configuration on the root port */
+ if (pci_get_long(pos) & (PCI_EXP_DEVCAP2_ATOMIC_COMP32 |
+ PCI_EXP_DEVCAP2_ATOMIC_COMP64 |
+ PCI_EXP_DEVCAP2_ATOMIC_COMP128)) {
+ return;
+ }
+
+ info = vfio_get_device_info(vdev->vbasedev.fd);
+ if (!info) {
+ return;
+ }
+
+ hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP);
+ if (!hdr) {
+ return;
+ }
+
+ cap = (void *)hdr;
+ if (cap->flags & VFIO_PCI_ATOMIC_COMP32) {
+ mask |= PCI_EXP_DEVCAP2_ATOMIC_COMP32;
+ }
+ if (cap->flags & VFIO_PCI_ATOMIC_COMP64) {
+ mask |= PCI_EXP_DEVCAP2_ATOMIC_COMP64;
+ }
+ if (cap->flags & VFIO_PCI_ATOMIC_COMP128) {
+ mask |= PCI_EXP_DEVCAP2_ATOMIC_COMP128;
+ }
+
+ if (!mask) {
+ return;
+ }
+
+ pci_long_test_and_set_mask(pos, mask);
+ vdev->clear_parent_atomics_on_exit = true;
+}
+
+static void vfio_pci_disable_rp_atomics(VFIOPCIDevice *vdev)
+{
+ if (vdev->clear_parent_atomics_on_exit) {
+ PCIDevice *parent = pci_get_bus(&vdev->pdev)->parent_dev;
+ uint8_t *pos = parent->config + parent->exp.exp_cap + PCI_EXP_DEVCAP2;
+
+ pci_long_test_and_clear_mask(pos, PCI_EXP_DEVCAP2_ATOMIC_COMP32 |
+ PCI_EXP_DEVCAP2_ATOMIC_COMP64 |
+ PCI_EXP_DEVCAP2_ATOMIC_COMP128);
+ }
+}
+
static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
Error **errp)
{
@@ -1931,6 +2006,8 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
QEMU_PCI_EXP_LNKCAP_MLS(QEMU_PCI_EXP_LNK_2_5GT), ~0);
vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL, 0, ~0);
}
+
+ vfio_pci_enable_rp_atomics(vdev);
}
/*
@@ -3273,6 +3350,7 @@ static void vfio_exitfn(PCIDevice *pdev)
timer_free(vdev->intx.mmap_timer);
}
vfio_teardown_msi(vdev);
+ vfio_pci_disable_rp_atomics(vdev);
vfio_bars_exit(vdev);
vfio_migration_exit(&vdev->vbasedev);
}
--
2.41.0
next prev parent reply other threads:[~2023-07-10 7:50 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-10 7:48 [PULL 00/11] vfio queue Cédric Le Goater
2023-07-10 7:48 ` [PULL 01/11] hw/vfio/pci-quirks: Sanitize capability pointer Cédric Le Goater
2023-07-10 7:48 ` [PULL 02/11] vfio/pci: Disable INTx in vfio_realize error path Cédric Le Goater
2023-07-10 7:48 ` [PULL 03/11] vfio/migration: Change vIOMMU blocker from global to per device Cédric Le Goater
2023-07-10 7:48 ` [PULL 04/11] vfio/migration: Free resources when vfio_migration_realize fails Cédric Le Goater
2023-07-10 7:48 ` [PULL 05/11] vfio/migration: Remove print of "Migration disabled" Cédric Le Goater
2023-07-10 7:48 ` [PULL 06/11] vfio/migration: Return bool type for vfio_migration_realize() Cédric Le Goater
2023-07-10 7:48 ` [PULL 07/11] vfio: Fix null pointer dereference bug in vfio_bars_finalize() Cédric Le Goater
2023-07-10 14:36 ` Michael Tokarev
2023-07-10 7:48 ` [PULL 08/11] linux-headers: update to v6.5-rc1 Cédric Le Goater
2023-07-10 7:48 ` [PULL 09/11] s390x/ap: Wire up the device request notifier interface Cédric Le Goater
2023-07-10 7:48 ` [PULL 10/11] pcie: Add a PCIe capability version helper Cédric Le Goater
2023-07-10 7:48 ` Cédric Le Goater [this message]
2023-07-10 7:55 ` [PULL 00/11] vfio queue Cédric Le Goater
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230710074848.456453-12-clg@redhat.com \
--to=clg@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=robin@streamhpc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.