From: Manish Honap <[email protected]>

vfio-pci-core must stay free of any CXL header dependency, so CXL
Type-2 handling lives in a separate vfio-cxl module that plugs in a set
of callbacks. Add the registration interface: vfio-cxl registers a
single struct vfio_cxl_ops at module_init, and vfio-pci-core stores it
under a mutex.

The owner field lets a later patch pin vfio-cxl for the lifetime of each
bound CXL device. No caller yet; the detection path is added next.

Signed-off-by: Manish Honap <[email protected]>
---
 drivers/vfio/pci/vfio_pci_core.c | 27 +++++++++++++++++++++++++++
 include/linux/vfio_pci_core.h    | 10 ++++++++++
 2 files changed, 37 insertions(+)

diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 3f11a9624b9c..88e68d43af9a 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -2670,6 +2670,33 @@ static void vfio_pci_dev_set_try_reset(struct 
vfio_device_set *dev_set)
        }
 }
 
+static const struct vfio_cxl_ops *vfio_pci_cxl_ops;
+static DEFINE_MUTEX(vfio_pci_cxl_ops_lock);
+
+int vfio_pci_core_register_cxl_ops(const struct vfio_cxl_ops *ops)
+{
+       int ret = 0;
+
+       mutex_lock(&vfio_pci_cxl_ops_lock);
+       if (vfio_pci_cxl_ops)
+               ret = -EBUSY;
+       else
+               vfio_pci_cxl_ops = ops;
+       mutex_unlock(&vfio_pci_cxl_ops_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(vfio_pci_core_register_cxl_ops);
+
+void vfio_pci_core_unregister_cxl_ops(const struct vfio_cxl_ops *ops)
+{
+       mutex_lock(&vfio_pci_cxl_ops_lock);
+       if (vfio_pci_cxl_ops == ops)
+               vfio_pci_cxl_ops = NULL;
+       mutex_unlock(&vfio_pci_cxl_ops_lock);
+}
+EXPORT_SYMBOL_GPL(vfio_pci_core_unregister_cxl_ops);
+
 static void vfio_pci_core_cleanup(void)
 {
        vfio_pci_uninit_perm_bits();
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index 9a1674c152aa..14753972e714 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -66,6 +66,16 @@ struct vfio_pci_device_ops {
                               size_t nr_ranges);
 };
 
+struct vfio_cxl_ops {
+       int     (*init_device)(struct vfio_pci_core_device *vdev);
+       void    (*release_device)(struct vfio_pci_core_device *vdev);
+       /* Pinned per bound CXL device so vfio-cxl cannot unload under usage */
+       struct module *owner;
+};
+
+int vfio_pci_core_register_cxl_ops(const struct vfio_cxl_ops *ops);
+void vfio_pci_core_unregister_cxl_ops(const struct vfio_cxl_ops *ops);
+
 #if IS_ENABLED(CONFIG_VFIO_PCI_DMABUF)
 int vfio_pci_core_fill_phys_vec(struct phys_vec *phys_vec,
                                struct vfio_region_dma_range *dma_ranges,
-- 
2.25.1


Reply via email to