From: <mhonap@nvidia.com>
To: <alex@shazbot.org>, <jgg@ziepe.ca>, <ankita@nvidia.com>,
<jic23@kernel.org>, <dave.jiang@intel.com>,
<alejandro.lucero-palau@amd.com>, <smadhavan@nvidia.com>,
<corbet@lwn.net>, <skhan@linuxfoundation.org>,
<dave@stgolabs.net>, <alison.schofield@intel.com>,
<vishal.l.verma@intel.com>, <iweiny@kernel.org>,
<ming.li@zohomail.com>, <yishaih@nvidia.com>,
<skolothumtho@nvidia.com>, <kevin.tian@intel.com>,
<bhelgaas@google.com>, <dmatlack@google.com>, <kees@kernel.org>,
<gustavoars@kernel.org>
Cc: <cjia@nvidia.com>, <kjaju@nvidia.com>, <vsethi@nvidia.com>,
<zhiw@nvidia.com>, <mhonap@nvidia.com>,
<linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<kvm@vger.kernel.org>, <linux-cxl@vger.kernel.org>,
<linux-pci@vger.kernel.org>, <linux-kselftest@vger.kernel.org>,
<linux-hardening@vger.kernel.org>
Subject: [PATCH v6 19/31] vfio/cxl: Create the CXL memdev and set media ready at bind
Date: Fri, 16 Oct 2026 21:48:26 +0530 [thread overview]
Message-ID: <20261016161839.2765592-20-mhonap@nvidia.com> (raw)
In-Reply-To: <20261016161839.2765592-1-mhonap@nvidia.com>
From: Manish Honap <mhonap@nvidia.com>
At bind, build the CXL memory device for the passed-through Type-2
accelerator so it joins the CXL topology and its HDM region resolves to a
host physical range. A Type-2 device has no mailbox, so there is no
media-ready register to poll: set media ready directly once the component
registers validate (mirroring drivers/net/ethernet/sfc/efx_cxl.c)
As per current vfio-cxl support, reject a device with:
- more than one HDM decoder
- interleaving enabled
- whose reset the host cannot service, including the CPU cache
invalidation that the reset needs
The CXL-core allocations are grouped with devres, in a helper that
returns on the first error, so a failed bind unwinds them: a failed init
leaves the device bound without CXL support, so devm would otherwise hold
them until unbind.
The device is not kept in D0. Low power loses the committed HDM
decoder, and the host restores the decoder configuration when the device
returns to D0. The contents of device memory across low power are the
user's to keep.
Take the bind-time copy of the cached HDM state with
pci_cxl_hdm_snapshot(), which needs no device lock: probe may run in
a worker on the device's NUMA node that does not own the lock.
Assisted-by: LLM
Signed-off-by: Manish Honap <mhonap@nvidia.com>
---
drivers/vfio/pci/cxl/vfio_cxl_core.c | 135 +++++++++++++++++++++++++++
1 file changed, 135 insertions(+)
diff --git a/drivers/vfio/pci/cxl/vfio_cxl_core.c b/drivers/vfio/pci/cxl/vfio_cxl_core.c
index ee49d68d689c..ef1fc715020e 100644
--- a/drivers/vfio/pci/cxl/vfio_cxl_core.c
+++ b/drivers/vfio/pci/cxl/vfio_cxl_core.c
@@ -5,17 +5,151 @@
* Copyright (c) 2026 NVIDIA Corporation & Affiliates
*/
+#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/range.h>
+#include <linux/slab.h>
#include <linux/vfio_pci_core.h>
+#include <cxl/cxl.h>
+#include <cxl/hdm.h>
+#include <cxl/pci.h>
+
+/**
+ * struct vfio_cxl_state - per-device state for a vfio-cxl device
+ * @cxlds: CXL device state; kept first for devm_cxl_dev_state_create()
+ * @cxlmd: memory device joined to the CXL topology at bind
+ * @hpa_range: host physical range of the HDM region
+ * @hdm: copy of the HDM state cached at PCI enumeration, taken at bind
+ */
+struct vfio_cxl_state {
+ struct cxl_dev_state cxlds;
+ struct cxl_memdev *cxlmd;
+ struct range hpa_range;
+ struct cxl_hdm_info *hdm;
+};
+
+/*
+ * Create the CXL device state and join the device to the CXL topology. The
+ * caller groups these devres allocations, so return on the first error.
+ */
+static struct vfio_cxl_state *vfio_cxl_create_memdev(struct pci_dev *pdev,
+ u64 hdm_size)
+{
+ struct vfio_cxl_state *cxl;
+ struct cxl_memdev *cxlmd;
+ u64 serial;
+ u16 dvsec;
+ int ret;
+
+ dvsec = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
+ PCI_DVSEC_CXL_DEVICE);
+ serial = pci_get_dsn(pdev);
+
+ cxl = devm_cxl_dev_state_create(&pdev->dev, CXL_DEVTYPE_DEVMEM, serial,
+ dvsec, struct vfio_cxl_state, cxlds,
+ false);
+ if (!cxl)
+ return ERR_PTR(-ENOMEM);
+
+ ret = cxl_pci_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT,
+ &cxl->cxlds.reg_map);
+ if (ret) {
+ pci_err(pdev, "vfio-cxl: no component registers\n");
+ return ERR_PTR(ret);
+ }
+
+ if (!cxl->cxlds.reg_map.component_map.hdm_decoder.valid) {
+ pci_err(pdev, "vfio-cxl: HDM decoder registers not found\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ /*
+ * A Type-2 accelerator has no mailbox and no media-ready register, so
+ * set media ready directly.
+ */
+ cxl->cxlds.media_ready = true;
+
+ ret = cxl_set_capacity(&cxl->cxlds, hdm_size);
+ if (ret)
+ return ERR_PTR(ret);
+
+ cxlmd = devm_cxl_probe_mem(&cxl->cxlds, &cxl->hpa_range);
+ if (IS_ERR(cxlmd))
+ return ERR_CAST(cxlmd);
+
+ cxl->cxlmd = cxlmd;
+ return cxl;
+}
static int vfio_cxl_init_device(struct vfio_pci_core_device *vdev)
{
+ struct pci_dev *pdev = vdev->pdev;
+ struct cxl_hdm_info *hdm __free(kfree) = NULL;
+ struct vfio_cxl_state *cxl;
+ u64 hdm_size;
+
+ /*
+ * pdev->hdm is cached at PCI enumeration, before any driver binds, so a
+ * device without it has no usable HDM decoder. Continue without CXL
+ * support rather than defer the bind forever. The cache belongs to the
+ * CXL core, so work from a copy. Probe may run in a worker on the
+ * device's NUMA node that does not own the device lock, so take the
+ * copy that needs none.
+ */
+ hdm = pci_cxl_hdm_snapshot(pdev);
+ if (IS_ERR(hdm))
+ return PTR_ERR(hdm);
+ if (!hdm)
+ return -ENODEV;
+
+ /* The guest drives one virtual decoder; multiple are unsupported. */
+ if (hdm->decoder_count != 1)
+ return -EOPNOTSUPP;
+
+ /* An interleaved decoder cannot be mapped 1:1 to the guest. */
+ if (hdm->settings[0].config.interleave_ways != 1)
+ return -EOPNOTSUPP;
+
+ /*
+ * The guest drives resets through the CXL Device DVSEC and polls the
+ * shadow for completion. If the host cannot service a function-scoped
+ * CXL reset, that request could never complete, so refuse the device
+ * rather than advertise a reset the guest would poll on forever. The
+ * check includes the CPU cache invalidation that the reset needs.
+ */
+ if (!pci_cxl_reset_capable(pdev))
+ return -EOPNOTSUPP;
+
+ hdm_size = range_len(&hdm->settings[0].config.hpa_range);
+ if (!hdm_size)
+ return -ENXIO;
+
+ /*
+ * Group the CXL-core allocations so a failure unwinds them here. A
+ * failed init leaves the device bound without CXL support, so devm
+ * would otherwise hold them until unbind.
+ */
+ if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
+ return -ENOMEM;
+
+ cxl = vfio_cxl_create_memdev(pdev, hdm_size);
+ if (IS_ERR(cxl)) {
+ devres_release_group(&pdev->dev, NULL);
+ return PTR_ERR(cxl);
+ }
+ devres_close_group(&pdev->dev, NULL);
+
+ cxl->hdm = no_free_ptr(hdm);
+ vdev->cxl = cxl;
+
return 0;
}
static void vfio_cxl_release_device(struct vfio_pci_core_device *vdev)
{
+ kfree(vdev->cxl->hdm);
+ vdev->cxl = NULL;
}
static int vfio_cxl_open_device(struct vfio_pci_core_device *vdev)
@@ -80,3 +214,4 @@ module_exit(vfio_cxl_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("VFIO support for CXL Type-2 devices");
+MODULE_IMPORT_NS("CXL");
--
2.53.0
next prev parent reply other threads:[~2026-10-16 16:22 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-16 16:18 [PATCH v6 00/31] vfio/pci: Add CXL Type-2 device passthrough support mhonap
2026-10-16 16:18 ` [PATCH v6 01/31] cxl/regs: Split the BAR block request and ioremap helpers mhonap
2026-10-16 16:18 ` [PATCH v6 02/31] cxl/regs: Let a BAR-owning driver own the component register block mhonap
2026-10-16 16:18 ` [PATCH v6 03/31] cxl: Move component register defines to uapi/cxl/cxl_regs.h mhonap
2026-10-16 16:18 ` [PATCH v6 04/31] PCI/CXL: Let the driver that owns the HDM range run CXL Reset mhonap
2026-10-16 16:18 ` [PATCH v6 05/31] PCI: Refuse bus and slot reset below a CXL port with SBR masked mhonap
2026-10-16 16:18 ` [PATCH v6 06/31] vfio/pci: Add the CXL provider ops registration interface mhonap
2026-10-16 16:18 ` [PATCH v6 07/31] vfio/pci: Detect CXL devices and load the CXL provider on demand mhonap
2026-10-16 16:18 ` [PATCH v6 08/31] vfio/pci: Add a generic excluded-range list mhonap
2026-10-16 16:18 ` [PATCH v6 09/31] vfio/pci: Advertise the mmap areas around excluded ranges mhonap
2026-10-16 16:18 ` [PATCH v6 10/31] vfio/pci: Refuse ioeventfds and dma-buf exports over " mhonap
2026-10-16 16:18 ` [PATCH v6 11/31] vfio/pci: Virtualize the CXL DVSEC in vfio_pci_config.c mhonap
2026-10-16 16:18 ` [PATCH v6 12/31] vfio/pci: Call the CXL open and close hooks around device use mhonap
2026-10-16 16:18 ` [PATCH v6 13/31] vfio/pci: Bracket PCI resets with the CXL reset hooks mhonap
2026-10-16 16:18 ` [PATCH v6 14/31] vfio/pci: Provide an opt-out for the CXL Type-2 extensions mhonap
2026-10-16 16:18 ` [PATCH v6 15/31] vfio/pci: Route every reset point through a try-reset helper mhonap
2026-10-16 16:18 ` [PATCH v6 16/31] vfio/pci: Revoke and re-arm one device-specific region mhonap
2026-10-16 16:18 ` [PATCH v6 17/31] vfio/pci: Call the device provider across low-power transitions mhonap
2026-10-16 16:18 ` [PATCH v6 18/31] vfio/cxl: Add the vfio-cxl provider module skeleton mhonap
2026-10-16 16:18 ` mhonap [this message]
2026-10-16 16:18 ` [PATCH v6 20/31] vfio/cxl: Own the whole component register BAR mhonap
2026-10-16 16:18 ` [PATCH v6 21/31] vfio/cxl: Expose the HDM memory region to the guest mhonap
2026-10-16 16:18 ` [PATCH v6 22/31] vfio/cxl: Allow mmap of the HDM memory region mhonap
2026-10-16 16:18 ` [PATCH v6 23/31] vfio/cxl: Contain HDM memory errors with memory_failure() mhonap
2026-10-16 16:18 ` [PATCH v6 24/31] vfio/cxl: Expose the HDM decoder registers read-only to the guest mhonap
2026-10-16 16:18 ` [PATCH v6 25/31] vfio/cxl: Exclude the HDM decoder registers from direct BAR access mhonap
2026-10-16 16:18 ` [PATCH v6 26/31] vfio/cxl: Restore the HDM decoder after a hot reset mhonap
2026-10-16 16:18 ` [PATCH v6 27/31] vfio/cxl: Describe the CXL device and decoder geometry to userspace mhonap
2026-10-16 16:18 ` [PATCH v6 28/31] vfio/cxl: Export the HDM memory region as a dma-buf mhonap
2026-10-16 16:18 ` [PATCH v6 29/31] vfio/cxl: Run the CXL reset at the vfio reset points mhonap
2026-10-16 16:18 ` [PATCH v6 30/31] Documentation: vfio-pci: Document CXL Type-2 device passthrough mhonap
2026-10-16 16:18 ` [PATCH v6 31/31] selftests/vfio: Add CXL Type-2 passthrough tests mhonap
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=20261016161839.2765592-20-mhonap@nvidia.com \
--to=mhonap@nvidia.com \
--cc=alejandro.lucero-palau@amd.com \
--cc=alex@shazbot.org \
--cc=alison.schofield@intel.com \
--cc=ankita@nvidia.com \
--cc=bhelgaas@google.com \
--cc=cjia@nvidia.com \
--cc=corbet@lwn.net \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=dmatlack@google.com \
--cc=gustavoars@kernel.org \
--cc=iweiny@kernel.org \
--cc=jgg@ziepe.ca \
--cc=jic23@kernel.org \
--cc=kees@kernel.org \
--cc=kevin.tian@intel.com \
--cc=kjaju@nvidia.com \
--cc=kvm@vger.kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=ming.li@zohomail.com \
--cc=skhan@linuxfoundation.org \
--cc=skolothumtho@nvidia.com \
--cc=smadhavan@nvidia.com \
--cc=vishal.l.verma@intel.com \
--cc=vsethi@nvidia.com \
--cc=yishaih@nvidia.com \
--cc=zhiw@nvidia.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox