1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2023 Advanced Micro Devices, Inc. */
4 #include <linux/vfio.h>
5 #include <linux/vfio_pci_core.h>
11 struct pci_dev
*pds_vfio_to_pci_dev(struct pds_vfio_pci_device
*pds_vfio
)
13 return pds_vfio
->vfio_coredev
.pdev
;
16 struct device
*pds_vfio_to_dev(struct pds_vfio_pci_device
*pds_vfio
)
18 return &pds_vfio_to_pci_dev(pds_vfio
)->dev
;
21 struct pds_vfio_pci_device
*pds_vfio_pci_drvdata(struct pci_dev
*pdev
)
23 struct vfio_pci_core_device
*core_device
= dev_get_drvdata(&pdev
->dev
);
25 return container_of(core_device
, struct pds_vfio_pci_device
,
29 void pds_vfio_reset(struct pds_vfio_pci_device
*pds_vfio
,
30 enum vfio_device_mig_state state
)
32 pds_vfio_put_restore_file(pds_vfio
);
33 pds_vfio_put_save_file(pds_vfio
);
34 if (state
== VFIO_DEVICE_STATE_ERROR
)
35 pds_vfio_dirty_disable(pds_vfio
, false);
36 pds_vfio
->state
= state
;
40 pds_vfio_set_device_state(struct vfio_device
*vdev
,
41 enum vfio_device_mig_state new_state
)
43 struct pds_vfio_pci_device
*pds_vfio
=
44 container_of(vdev
, struct pds_vfio_pci_device
,
46 struct file
*res
= NULL
;
48 mutex_lock(&pds_vfio
->state_mutex
);
50 * only way to transition out of VFIO_DEVICE_STATE_ERROR is via
51 * VFIO_DEVICE_RESET, so prevent the state machine from running since
52 * vfio_mig_get_next_state() will throw a WARN_ON() when transitioning
53 * from VFIO_DEVICE_STATE_ERROR to any other state
55 while (pds_vfio
->state
!= VFIO_DEVICE_STATE_ERROR
&&
56 new_state
!= pds_vfio
->state
) {
57 enum vfio_device_mig_state next_state
;
59 int err
= vfio_mig_get_next_state(vdev
, pds_vfio
->state
,
60 new_state
, &next_state
);
66 res
= pds_vfio_step_device_state_locked(pds_vfio
, next_state
);
70 pds_vfio
->state
= next_state
;
72 if (WARN_ON(res
&& new_state
!= pds_vfio
->state
)) {
73 res
= ERR_PTR(-EINVAL
);
77 mutex_unlock(&pds_vfio
->state_mutex
);
78 if (pds_vfio
->state
== VFIO_DEVICE_STATE_ERROR
)
84 static int pds_vfio_get_device_state(struct vfio_device
*vdev
,
85 enum vfio_device_mig_state
*current_state
)
87 struct pds_vfio_pci_device
*pds_vfio
=
88 container_of(vdev
, struct pds_vfio_pci_device
,
91 mutex_lock(&pds_vfio
->state_mutex
);
92 *current_state
= pds_vfio
->state
;
93 mutex_unlock(&pds_vfio
->state_mutex
);
97 static int pds_vfio_get_device_state_size(struct vfio_device
*vdev
,
98 unsigned long *stop_copy_length
)
100 *stop_copy_length
= PDS_LM_DEVICE_STATE_LENGTH
;
104 static const struct vfio_migration_ops pds_vfio_lm_ops
= {
105 .migration_set_state
= pds_vfio_set_device_state
,
106 .migration_get_state
= pds_vfio_get_device_state
,
107 .migration_get_data_size
= pds_vfio_get_device_state_size
110 static const struct vfio_log_ops pds_vfio_log_ops
= {
111 .log_start
= pds_vfio_dma_logging_start
,
112 .log_stop
= pds_vfio_dma_logging_stop
,
113 .log_read_and_clear
= pds_vfio_dma_logging_report
,
116 static int pds_vfio_init_device(struct vfio_device
*vdev
)
118 struct pds_vfio_pci_device
*pds_vfio
=
119 container_of(vdev
, struct pds_vfio_pci_device
,
121 struct pci_dev
*pdev
= to_pci_dev(vdev
->dev
);
122 int err
, vf_id
, pci_id
;
124 vf_id
= pci_iov_vf_id(pdev
);
128 err
= vfio_pci_core_init_dev(vdev
);
132 pds_vfio
->vf_id
= vf_id
;
134 mutex_init(&pds_vfio
->state_mutex
);
136 vdev
->migration_flags
= VFIO_MIGRATION_STOP_COPY
| VFIO_MIGRATION_P2P
;
137 vdev
->mig_ops
= &pds_vfio_lm_ops
;
138 vdev
->log_ops
= &pds_vfio_log_ops
;
140 pci_id
= PCI_DEVID(pdev
->bus
->number
, pdev
->devfn
);
142 "%s: PF %#04x VF %#04x vf_id %d domain %d pds_vfio %p\n",
143 __func__
, pci_dev_id(pci_physfn(pdev
)), pci_id
, vf_id
,
144 pci_domain_nr(pdev
->bus
), pds_vfio
);
149 static void pds_vfio_release_device(struct vfio_device
*vdev
)
151 struct pds_vfio_pci_device
*pds_vfio
=
152 container_of(vdev
, struct pds_vfio_pci_device
,
155 mutex_destroy(&pds_vfio
->state_mutex
);
156 vfio_pci_core_release_dev(vdev
);
159 static int pds_vfio_open_device(struct vfio_device
*vdev
)
161 struct pds_vfio_pci_device
*pds_vfio
=
162 container_of(vdev
, struct pds_vfio_pci_device
,
166 err
= vfio_pci_core_enable(&pds_vfio
->vfio_coredev
);
170 pds_vfio
->state
= VFIO_DEVICE_STATE_RUNNING
;
172 vfio_pci_core_finish_enable(&pds_vfio
->vfio_coredev
);
177 static void pds_vfio_close_device(struct vfio_device
*vdev
)
179 struct pds_vfio_pci_device
*pds_vfio
=
180 container_of(vdev
, struct pds_vfio_pci_device
,
183 mutex_lock(&pds_vfio
->state_mutex
);
184 pds_vfio_put_restore_file(pds_vfio
);
185 pds_vfio_put_save_file(pds_vfio
);
186 pds_vfio_dirty_disable(pds_vfio
, true);
187 mutex_unlock(&pds_vfio
->state_mutex
);
188 vfio_pci_core_close_device(vdev
);
191 static const struct vfio_device_ops pds_vfio_ops
= {
193 .init
= pds_vfio_init_device
,
194 .release
= pds_vfio_release_device
,
195 .open_device
= pds_vfio_open_device
,
196 .close_device
= pds_vfio_close_device
,
197 .ioctl
= vfio_pci_core_ioctl
,
198 .device_feature
= vfio_pci_core_ioctl_feature
,
199 .read
= vfio_pci_core_read
,
200 .write
= vfio_pci_core_write
,
201 .mmap
= vfio_pci_core_mmap
,
202 .request
= vfio_pci_core_request
,
203 .match
= vfio_pci_core_match
,
204 .bind_iommufd
= vfio_iommufd_physical_bind
,
205 .unbind_iommufd
= vfio_iommufd_physical_unbind
,
206 .attach_ioas
= vfio_iommufd_physical_attach_ioas
,
209 const struct vfio_device_ops
*pds_vfio_ops_info(void)
211 return &pds_vfio_ops
;