vfio/pci: Remove the core dependency on driver data

vfio-pci-core currently has runtime functions that interpret pci
driver_data as a pointer to vfio_pci_core_device, and enforce vfio
variant drivers must set vfio_pci_core_device to their pci driver_data.
This constrains variant drivers' private-data layout, including the
typed driver data used by the Rust PCI infrastructure.

Add VFIO_PCI_CORE_DEFINE_CALLBACKS macro to generate wrapper code for
each vfio variant driver, update vfio variant drivers to store their
private structures in driver_data and use generated wrapper to pass the
vfio core device to helpers.

Assisted-by: LLM
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Suggested-by: Alex Williamson <alex.williamson@nvidia.com>
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/all/DLFD2ZDSK9YQ.3A4R66G8UJMD8@kernel.org/
Signed-off-by: Simon Song <xinmengs@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20261005184236.1946167-2-xinmengs@nvidia.com
[VGA chunks and commit log reference dropped with rebase to
commit 93d41424ca ("PCI/VGA: pass a data pointer to be used in the decode callback (v2)")]
Signed-off-by: Alex Williamson <alex@shazbot.org>
This commit is contained in:
Simon Song 2026-10-05 11:42:36 -07:00 committed by Alex Williamson
parent f1b563d3e3
commit 6a5f427bee
12 changed files with 141 additions and 88 deletions

View File

@ -16,6 +16,9 @@
#include "hisi_acc_vfio_pci.h"
VFIO_PCI_CORE_DEFINE_CALLBACKS(hisi_acc_vf, struct hisi_acc_vf_core_device,
core_device)
/* Return 0 on VM acc device ready, -ETIMEDOUT hardware timeout */
static int qm_wait_dev_not_ready(struct hisi_qm *qm)
{
@ -588,10 +591,7 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev,
static struct hisi_acc_vf_core_device *hisi_acc_drvdata(struct pci_dev *pdev)
{
struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
return container_of(core_device, struct hisi_acc_vf_core_device,
core_device);
return pci_get_drvdata(pdev);
}
/* Check the PF's RAS state and Function INT state */
@ -1416,9 +1416,8 @@ static int hisi_acc_vf_debug_check(struct seq_file *seq, struct vfio_device *vde
static int hisi_acc_vf_debug_cmd(struct seq_file *seq, void *data)
{
struct device *vf_dev = seq->private;
struct vfio_pci_core_device *core_device = dev_get_drvdata(vf_dev);
struct vfio_device *vdev = &core_device->vdev;
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(vdev);
struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(vf_dev);
struct vfio_device *vdev = &hisi_acc_vdev->core_device.vdev;
struct hisi_qm *vf_qm = &hisi_acc_vdev->vf_qm;
u64 value;
int ret;
@ -1445,9 +1444,8 @@ static int hisi_acc_vf_debug_cmd(struct seq_file *seq, void *data)
static int hisi_acc_vf_dev_read(struct seq_file *seq, void *data)
{
struct device *vf_dev = seq->private;
struct vfio_pci_core_device *core_device = dev_get_drvdata(vf_dev);
struct vfio_device *vdev = &core_device->vdev;
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(vdev);
struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(vf_dev);
struct vfio_device *vdev = &hisi_acc_vdev->core_device.vdev;
size_t vf_data_sz = offsetofend(struct acc_vf_data, padding);
struct acc_vf_data *vf_data;
int ret;
@ -1492,9 +1490,7 @@ static int hisi_acc_vf_dev_read(struct seq_file *seq, void *data)
static int hisi_acc_vf_migf_read(struct seq_file *seq, void *data)
{
struct device *vf_dev = seq->private;
struct vfio_pci_core_device *core_device = dev_get_drvdata(vf_dev);
struct vfio_device *vdev = &core_device->vdev;
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(vdev);
struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(vf_dev);
size_t vf_data_sz = offsetofend(struct acc_vf_data, padding);
struct hisi_acc_vf_migration_file *debug_migf = hisi_acc_vdev->debug_migf;
@ -1687,7 +1683,7 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
if (IS_ERR(hisi_acc_vdev))
return PTR_ERR(hisi_acc_vdev);
dev_set_drvdata(&pdev->dev, &hisi_acc_vdev->core_device);
dev_set_drvdata(&pdev->dev, hisi_acc_vdev);
ret = vfio_pci_core_register_device(&hisi_acc_vdev->core_device);
if (ret)
goto out_put_vdev;
@ -1721,7 +1717,7 @@ MODULE_DEVICE_TABLE(pci, hisi_acc_vfio_pci_table);
static const struct pci_error_handlers hisi_acc_vf_err_handlers = {
.reset_prepare = hisi_acc_vf_pci_reset_prepare,
.reset_done = hisi_acc_vf_pci_aer_reset_done,
.error_detected = vfio_pci_core_aer_err_detected,
.error_detected = hisi_acc_vf_aer_err_detected,
};
static struct pci_driver hisi_acc_vfio_pci_driver = {
@ -1729,6 +1725,7 @@ static struct pci_driver hisi_acc_vfio_pci_driver = {
.id_table = hisi_acc_vfio_pci_table,
.probe = hisi_acc_vfio_pci_probe,
.remove = hisi_acc_vfio_pci_remove,
.driver = { .pm = pm_ptr(&hisi_acc_vf_pm_ops) },
.err_handler = &hisi_acc_vf_err_handlers,
.driver_managed_dma = true,
};

View File

@ -47,6 +47,9 @@ struct ism_vfio_pci_core_device {
struct kmem_cache *store_block_cache;
};
VFIO_PCI_CORE_DEFINE_CALLBACKS(ism_vfio, struct ism_vfio_pci_core_device,
core_device)
static int ism_vfio_pci_open_device(struct vfio_device *core_vdev)
{
struct ism_vfio_pci_core_device *ivpcd;
@ -363,7 +366,7 @@ static int ism_vfio_pci_probe(struct pci_dev *pdev,
if (IS_ERR(ivpcd))
return PTR_ERR(ivpcd);
dev_set_drvdata(&pdev->dev, &ivpcd->core_device);
dev_set_drvdata(&pdev->dev, ivpcd);
ret = vfio_pci_core_register_device(&ivpcd->core_device);
if (ret)
@ -374,12 +377,7 @@ static int ism_vfio_pci_probe(struct pci_dev *pdev,
static void ism_vfio_pci_remove(struct pci_dev *pdev)
{
struct vfio_pci_core_device *core_device;
struct ism_vfio_pci_core_device *ivpcd;
core_device = dev_get_drvdata(&pdev->dev);
ivpcd = container_of(core_device, struct ism_vfio_pci_core_device,
core_device);
struct ism_vfio_pci_core_device *ivpcd = pci_get_drvdata(pdev);
vfio_pci_core_unregister_device(&ivpcd->core_device);
vfio_put_device(&ivpcd->core_device.vdev);
@ -392,12 +390,17 @@ static const struct pci_device_id ism_device_table[] = {
};
MODULE_DEVICE_TABLE(pci, ism_device_table);
static const struct pci_error_handlers ism_vfio_err_handlers = {
.error_detected = ism_vfio_aer_err_detected,
};
static struct pci_driver ism_vfio_pci_driver = {
.name = KBUILD_MODNAME,
.id_table = ism_device_table,
.probe = ism_vfio_pci_probe,
.remove = ism_vfio_pci_remove,
.err_handler = &vfio_pci_core_err_handlers,
.driver = { .pm = pm_ptr(&ism_vfio_pm_ops) },
.err_handler = &ism_vfio_err_handlers,
.driver_managed_dma = true,
};

View File

@ -21,6 +21,9 @@
#include "cmd.h"
VFIO_PCI_CORE_DEFINE_CALLBACKS(mlx5vf, struct mlx5vf_pci_core_device,
core_device)
/* Device specification max LOAD size */
#define MAX_LOAD_SIZE (BIT_ULL(__mlx5_bit_sz(load_vhca_state_in, size)) - 1)
@ -28,10 +31,7 @@
static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev)
{
struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
return container_of(core_device, struct mlx5vf_pci_core_device,
core_device);
return pci_get_drvdata(pdev);
}
static void mlx5vf_disable_fd(struct mlx5_vf_migration_file *migf)
@ -1415,7 +1415,7 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev,
if (IS_ERR(mvdev))
return PTR_ERR(mvdev);
dev_set_drvdata(&pdev->dev, &mvdev->core_device);
dev_set_drvdata(&pdev->dev, mvdev);
ret = vfio_pci_core_register_device(&mvdev->core_device);
if (ret)
goto out_put_vdev;
@ -1443,7 +1443,7 @@ MODULE_DEVICE_TABLE(pci, mlx5vf_pci_table);
static const struct pci_error_handlers mlx5vf_err_handlers = {
.reset_done = mlx5vf_pci_aer_reset_done,
.error_detected = vfio_pci_core_aer_err_detected,
.error_detected = mlx5vf_aer_err_detected,
};
static struct pci_driver mlx5vf_pci_driver = {
@ -1451,6 +1451,7 @@ static struct pci_driver mlx5vf_pci_driver = {
.id_table = mlx5vf_pci_table,
.probe = mlx5vf_pci_probe,
.remove = mlx5vf_pci_remove,
.driver = { .pm = pm_ptr(&mlx5vf_pm_ops) },
.err_handler = &mlx5vf_err_handlers,
.driver_managed_dma = true,
};

View File

@ -73,6 +73,9 @@ struct nvgrace_gpu_pci_core_device {
int cxl_dvsec;
};
VFIO_PCI_CORE_DEFINE_CALLBACKS(nvgrace_gpu, struct nvgrace_gpu_pci_core_device,
core_device)
static void nvgrace_gpu_init_fake_bar_emu_regs(struct vfio_device *core_vdev)
{
struct nvgrace_gpu_pci_core_device *nvdev =
@ -1341,7 +1344,7 @@ static int nvgrace_gpu_probe(struct pci_dev *pdev,
if (ret)
goto out_put_vdev;
dev_set_drvdata(&pdev->dev, &nvdev->core_device);
dev_set_drvdata(&pdev->dev, nvdev);
if (ops == &nvgrace_gpu_pci_ops) {
nvdev->has_mig_hw_bug = nvgrace_gpu_has_mig_hw_bug(pdev);
@ -1372,10 +1375,10 @@ static int nvgrace_gpu_probe(struct pci_dev *pdev,
static void nvgrace_gpu_remove(struct pci_dev *pdev)
{
struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
struct nvgrace_gpu_pci_core_device *nvdev = pci_get_drvdata(pdev);
vfio_pci_core_unregister_device(core_device);
vfio_put_device(&core_device->vdev);
vfio_pci_core_unregister_device(&nvdev->core_device);
vfio_put_device(&nvdev->core_device.vdev);
}
static const struct pci_device_id nvgrace_gpu_vfio_pci_table[] = {
@ -1407,17 +1410,14 @@ MODULE_DEVICE_TABLE(pci, nvgrace_gpu_vfio_pci_table);
*/
static void nvgrace_gpu_vfio_pci_reset_done(struct pci_dev *pdev)
{
struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
struct nvgrace_gpu_pci_core_device *nvdev =
container_of(core_device, struct nvgrace_gpu_pci_core_device,
core_device);
struct nvgrace_gpu_pci_core_device *nvdev = pci_get_drvdata(pdev);
nvdev->reset_done = true;
}
static const struct pci_error_handlers nvgrace_gpu_vfio_pci_err_handlers = {
.reset_done = nvgrace_gpu_vfio_pci_reset_done,
.error_detected = vfio_pci_core_aer_err_detected,
.error_detected = nvgrace_gpu_aer_err_detected,
};
static struct pci_driver nvgrace_gpu_vfio_pci_driver = {
@ -1425,6 +1425,7 @@ static struct pci_driver nvgrace_gpu_vfio_pci_driver = {
.id_table = nvgrace_gpu_vfio_pci_table,
.probe = nvgrace_gpu_probe,
.remove = nvgrace_gpu_remove,
.driver = { .pm = pm_ptr(&nvgrace_gpu_pm_ops) },
.err_handler = &nvgrace_gpu_vfio_pci_err_handlers,
.driver_managed_dma = true,
};

View File

@ -16,6 +16,9 @@
#include "pci_drv.h"
#include "cmds.h"
VFIO_PCI_CORE_DEFINE_CALLBACKS(pds_vfio, struct pds_vfio_pci_device,
vfio_coredev)
#define PDS_VFIO_DRV_DESCRIPTION "AMD/Pensando VFIO Device Driver"
#define PCI_VENDOR_ID_PENSANDO 0x1dd8
@ -118,7 +121,7 @@ static int pds_vfio_pci_probe(struct pci_dev *pdev,
if (IS_ERR(pds_vfio))
return PTR_ERR(pds_vfio);
dev_set_drvdata(&pdev->dev, &pds_vfio->vfio_coredev);
dev_set_drvdata(&pdev->dev, pds_vfio);
err = vfio_pci_core_register_device(&pds_vfio->vfio_coredev);
if (err)
@ -173,7 +176,7 @@ static void pds_vfio_pci_aer_reset_done(struct pci_dev *pdev)
static const struct pci_error_handlers pds_vfio_pci_err_handlers = {
.reset_done = pds_vfio_pci_aer_reset_done,
.error_detected = vfio_pci_core_aer_err_detected,
.error_detected = pds_vfio_aer_err_detected,
};
static struct pci_driver pds_vfio_pci_driver = {
@ -181,6 +184,7 @@ static struct pci_driver pds_vfio_pci_driver = {
.id_table = pds_vfio_pci_table,
.probe = pds_vfio_pci_probe,
.remove = pds_vfio_pci_remove,
.driver = { .pm = pm_ptr(&pds_vfio_pm_ops) },
.err_handler = &pds_vfio_pci_err_handlers,
.driver_managed_dma = true,
};

View File

@ -20,10 +20,7 @@ struct device *pds_vfio_to_dev(struct pds_vfio_pci_device *pds_vfio)
struct pds_vfio_pci_device *pds_vfio_pci_drvdata(struct pci_dev *pdev)
{
struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
return container_of(core_device, struct pds_vfio_pci_device,
vfio_coredev);
return pci_get_drvdata(pdev);
}
void pds_vfio_reset(struct pds_vfio_pci_device *pds_vfio,

View File

@ -55,6 +55,9 @@ struct qat_vf_core_device {
struct qat_vf_migration_file *saving_migf;
};
VFIO_PCI_CORE_DEFINE_CALLBACKS(qat_vf, struct qat_vf_core_device,
core_device)
static int qat_vf_pci_open_device(struct vfio_device *core_vdev)
{
struct qat_vf_core_device *qat_vdev =
@ -623,9 +626,7 @@ static const struct vfio_device_ops qat_vf_pci_ops = {
static struct qat_vf_core_device *qat_vf_drvdata(struct pci_dev *pdev)
{
struct vfio_pci_core_device *core_device = pci_get_drvdata(pdev);
return container_of(core_device, struct qat_vf_core_device, core_device);
return pci_get_drvdata(pdev);
}
static void qat_vf_pci_aer_reset_done(struct pci_dev *pdev)
@ -651,7 +652,7 @@ qat_vf_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (IS_ERR(qat_vdev))
return PTR_ERR(qat_vdev);
pci_set_drvdata(pdev, &qat_vdev->core_device);
pci_set_drvdata(pdev, qat_vdev);
ret = vfio_pci_core_register_device(&qat_vdev->core_device);
if (ret)
goto out_put_device;
@ -686,7 +687,7 @@ MODULE_DEVICE_TABLE(pci, qat_vf_vfio_pci_table);
static const struct pci_error_handlers qat_vf_err_handlers = {
.reset_done = qat_vf_pci_aer_reset_done,
.error_detected = vfio_pci_core_aer_err_detected,
.error_detected = qat_vf_aer_err_detected,
};
static struct pci_driver qat_vf_vfio_pci_driver = {
@ -694,6 +695,7 @@ static struct pci_driver qat_vf_vfio_pci_driver = {
.id_table = qat_vf_vfio_pci_table,
.probe = qat_vf_vfio_pci_probe,
.remove = qat_vf_vfio_pci_remove,
.driver = { .pm = pm_ptr(&qat_vf_pm_ops) },
.err_handler = &qat_vf_err_handlers,
.driver_managed_dma = true,
};

View File

@ -223,13 +223,44 @@ static const struct pci_device_id vfio_pci_table[] = {
MODULE_DEVICE_TABLE(pci, vfio_pci_table);
static int __maybe_unused vfio_pci_pm_suspend(struct device *dev)
{
struct vfio_pci_core_device *vdev = dev_get_drvdata(dev);
return vfio_pci_core_runtime_suspend(vdev);
}
static int __maybe_unused vfio_pci_pm_resume(struct device *dev)
{
struct vfio_pci_core_device *vdev = dev_get_drvdata(dev);
return vfio_pci_core_runtime_resume(vdev);
}
static const struct dev_pm_ops vfio_pci_pm_ops = {
SET_RUNTIME_PM_OPS(vfio_pci_pm_suspend, vfio_pci_pm_resume, NULL)
};
static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
struct vfio_pci_core_device *vdev = pci_get_drvdata(pdev);
return vfio_pci_core_aer_err_detected(vdev);
}
static const struct pci_error_handlers vfio_pci_err_handlers = {
.error_detected = vfio_pci_aer_err_detected,
};
static struct pci_driver vfio_pci_driver = {
.name = "vfio-pci",
.id_table = vfio_pci_table,
.probe = vfio_pci_probe,
.remove = vfio_pci_remove,
.sriov_configure = vfio_pci_sriov_configure,
.err_handler = &vfio_pci_core_err_handlers,
.err_handler = &vfio_pci_err_handlers,
.driver = { .pm = pm_ptr(&vfio_pci_pm_ops) },
.driver_managed_dma = true,
};

View File

@ -489,10 +489,8 @@ static int vfio_pci_core_pm_exit(struct vfio_pci_core_device *vdev, u32 flags,
}
#ifdef CONFIG_PM
static int vfio_pci_core_runtime_suspend(struct device *dev)
int vfio_pci_core_runtime_suspend(struct vfio_pci_core_device *vdev)
{
struct vfio_pci_core_device *vdev = dev_get_drvdata(dev);
down_write(&vdev->memory_lock);
/*
* The user can move the device into D3hot state before invoking
@ -517,11 +515,10 @@ static int vfio_pci_core_runtime_suspend(struct device *dev)
return 0;
}
EXPORT_SYMBOL_GPL(vfio_pci_core_runtime_suspend);
static int vfio_pci_core_runtime_resume(struct device *dev)
int vfio_pci_core_runtime_resume(struct vfio_pci_core_device *vdev)
{
struct vfio_pci_core_device *vdev = dev_get_drvdata(dev);
/*
* Resume with a pm_wake_eventfd_ctx signals the eventfd and exit
* low power mode.
@ -538,6 +535,7 @@ static int vfio_pci_core_runtime_resume(struct device *dev)
return 0;
}
EXPORT_SYMBOL_GPL(vfio_pci_core_runtime_resume);
#endif /* CONFIG_PM */
/*
@ -577,18 +575,6 @@ static void vfio_pci_core_map_bars(struct vfio_pci_core_device *vdev)
}
}
/*
* The pci-driver core runtime PM routines always save the device state
* before going into suspended state. If the device is going into low power
* state with only with runtime PM ops, then no explicit handling is needed
* for the devices which have NoSoftRst-.
*/
static const struct dev_pm_ops vfio_pci_core_pm_ops = {
SET_RUNTIME_PM_OPS(vfio_pci_core_runtime_suspend,
vfio_pci_core_runtime_resume,
NULL)
};
int vfio_pci_core_enable(struct vfio_pci_core_device *vdev)
{
struct pci_dev *pdev = vdev->pdev;
@ -2222,10 +2208,6 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
struct device *dev = &pdev->dev;
int ret;
/* Drivers must set the vfio_pci_core_device to their drvdata */
if (WARN_ON(vdev != dev_get_drvdata(dev)))
return -EINVAL;
/* Drivers must set a name. Required for sequestering SR-IOV VFs */
if (WARN_ON(!vdev->vdev.ops->name))
return -EINVAL;
@ -2293,7 +2275,6 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
*/
vfio_pci_set_power_state(vdev, PCI_D0);
dev->driver->pm = &vfio_pci_core_pm_ops;
pm_runtime_allow(dev);
if (!vdev->disable_idle_d3)
pm_runtime_put(dev);
@ -2334,10 +2315,8 @@ void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev)
}
EXPORT_SYMBOL_GPL(vfio_pci_core_unregister_device);
pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
pci_channel_state_t state)
pci_ers_result_t vfio_pci_core_aer_err_detected(struct vfio_pci_core_device *vdev)
{
struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
struct vfio_pci_eventfd *eventfd;
rcu_read_lock();
@ -2420,11 +2399,6 @@ int vfio_pci_core_sriov_configure(struct vfio_pci_core_device *vdev,
}
EXPORT_SYMBOL_GPL(vfio_pci_core_sriov_configure);
const struct pci_error_handlers vfio_pci_core_err_handlers = {
.error_detected = vfio_pci_core_aer_err_detected,
};
EXPORT_SYMBOL_GPL(vfio_pci_core_err_handlers);
static bool vfio_dev_in_groups(struct vfio_device *vdev,
struct vfio_pci_group_info *groups)
{

View File

@ -18,6 +18,9 @@
#include "common.h"
VFIO_PCI_CORE_DEFINE_CALLBACKS(virtiovf, struct virtiovf_pci_core_device,
core_device)
static int virtiovf_pci_open_device(struct vfio_device *core_vdev)
{
struct virtiovf_pci_core_device *virtvdev = container_of(core_vdev,
@ -174,7 +177,7 @@ static int virtiovf_pci_probe(struct pci_dev *pdev,
if (sup_lm)
virtiovf_set_migratable(virtvdev);
dev_set_drvdata(&pdev->dev, &virtvdev->core_device);
dev_set_drvdata(&pdev->dev, virtvdev);
ret = vfio_pci_core_register_device(&virtvdev->core_device);
if (ret)
goto out;
@ -211,7 +214,7 @@ static void virtiovf_pci_aer_reset_done(struct pci_dev *pdev)
static const struct pci_error_handlers virtiovf_err_handlers = {
.reset_done = virtiovf_pci_aer_reset_done,
.error_detected = vfio_pci_core_aer_err_detected,
.error_detected = virtiovf_aer_err_detected,
};
static struct pci_driver virtiovf_pci_driver = {
@ -219,6 +222,7 @@ static struct pci_driver virtiovf_pci_driver = {
.id_table = virtiovf_pci_table,
.probe = virtiovf_pci_probe,
.remove = virtiovf_pci_remove,
.driver = { .pm = pm_ptr(&virtiovf_pm_ops) },
.err_handler = &virtiovf_err_handlers,
.driver_managed_dma = true,
};

View File

@ -38,6 +38,9 @@ struct xe_vfio_pci_core_device {
struct xe_vfio_pci_migration_file *migf;
};
VFIO_PCI_CORE_DEFINE_CALLBACKS(xe_vfio, struct xe_vfio_pci_core_device,
core_device)
#define xe_vdev_to_dev(xe_vdev) (&(xe_vdev)->core_device.pdev->dev)
static void xe_vfio_pci_disable_file(struct xe_vfio_pci_migration_file *migf)
@ -140,7 +143,7 @@ static void xe_vfio_pci_reset_done(struct pci_dev *pdev)
static const struct pci_error_handlers xe_vfio_pci_err_handlers = {
.reset_prepare = xe_vfio_pci_reset_prepare,
.reset_done = xe_vfio_pci_reset_done,
.error_detected = vfio_pci_core_aer_err_detected,
.error_detected = xe_vfio_aer_err_detected,
};
static int xe_vfio_pci_open_device(struct vfio_device *core_vdev)
@ -550,7 +553,7 @@ static int xe_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
if (IS_ERR(xe_vdev))
return PTR_ERR(xe_vdev);
dev_set_drvdata(&pdev->dev, &xe_vdev->core_device);
dev_set_drvdata(&pdev->dev, xe_vdev);
ret = vfio_pci_core_register_device(&xe_vdev->core_device);
if (ret) {
@ -586,6 +589,7 @@ static struct pci_driver xe_vfio_pci_driver = {
.id_table = xe_vfio_pci_table,
.probe = xe_vfio_pci_probe,
.remove = xe_vfio_pci_remove,
.driver = { .pm = pm_ptr(&xe_vfio_pm_ops) },
.err_handler = &xe_vfio_pci_err_handlers,
.driver_managed_dma = true,
};

View File

@ -8,6 +8,7 @@
* Author: Tom Lyon, pugs@cisco.com
*/
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/vfio.h>
@ -16,6 +17,7 @@
#include <linux/types.h>
#include <linux/uuid.h>
#include <linux/notifier.h>
#include <linux/pm.h>
#ifndef VFIO_PCI_CORE_H
#define VFIO_PCI_CORE_H
@ -168,7 +170,6 @@ int vfio_pci_core_init_dev(struct vfio_device *core_vdev);
void vfio_pci_core_release_dev(struct vfio_device *core_vdev);
int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev);
void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev);
extern const struct pci_error_handlers vfio_pci_core_err_handlers;
int vfio_pci_core_sriov_configure(struct vfio_pci_core_device *vdev,
int nr_virtfn);
long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
@ -193,8 +194,6 @@ int vfio_pci_core_match_token_uuid(struct vfio_device *core_vdev,
int vfio_pci_core_enable(struct vfio_pci_core_device *vdev);
void vfio_pci_core_disable(struct vfio_pci_core_device *vdev);
void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev);
pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
pci_channel_state_t state);
ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
void __iomem *io, char __user *buf,
loff_t off, size_t count, size_t x_start,
@ -260,4 +259,40 @@ vfio_pci_core_get_iomap(struct vfio_pci_core_device *vdev, unsigned int bar)
int vfio_pci_dma_buf_iommufd_map(struct dma_buf_attachment *attachment,
struct phys_vec *phys);
int vfio_pci_core_runtime_suspend(struct vfio_pci_core_device *vdev);
int vfio_pci_core_runtime_resume(struct vfio_pci_core_device *vdev);
pci_ers_result_t vfio_pci_core_aer_err_detected(struct vfio_pci_core_device *vdev);
/*
* Per-driver PM/AER trampolines. driver_data points to the driver's private
* structure, which embeds a struct vfio_pci_core_device.
*
* @name: prefix for <name>_pm_ops and <name>_aer_err_detected
* @drv_type: type of the driver's private structure, including struct
* @member: member containing the struct vfio_pci_core_device
*/
#define VFIO_PCI_CORE_DEFINE_CALLBACKS(name, drv_type, member) \
static int __maybe_unused name##_pm_suspend(struct device *dev) \
{ \
drv_type *drvdata = dev_get_drvdata(dev); \
\
return vfio_pci_core_runtime_suspend(&drvdata->member); \
} \
static int __maybe_unused name##_pm_resume(struct device *dev) \
{ \
drv_type *drvdata = dev_get_drvdata(dev); \
\
return vfio_pci_core_runtime_resume(&drvdata->member); \
} \
static const struct dev_pm_ops name##_pm_ops = { \
SET_RUNTIME_PM_OPS(name##_pm_suspend, name##_pm_resume, NULL) \
}; \
static pci_ers_result_t name##_aer_err_detected(struct pci_dev *pdev, \
pci_channel_state_t state) \
{ \
drv_type *drvdata = pci_get_drvdata(pdev); \
\
return vfio_pci_core_aer_err_detected(&drvdata->member); \
}
#endif /* VFIO_PCI_CORE_H */