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_state_mutex_unlock(struct pds_vfio_pci_device
*pds_vfio
)
32 spin_lock(&pds_vfio
->reset_lock
);
33 if (pds_vfio
->deferred_reset
) {
34 pds_vfio
->deferred_reset
= false;
35 if (pds_vfio
->state
== VFIO_DEVICE_STATE_ERROR
) {
36 pds_vfio_put_restore_file(pds_vfio
);
37 pds_vfio_put_save_file(pds_vfio
);
38 pds_vfio_dirty_disable(pds_vfio
, false);
40 pds_vfio
->state
= pds_vfio
->deferred_reset_state
;
41 pds_vfio
->deferred_reset_state
= VFIO_DEVICE_STATE_RUNNING
;
42 spin_unlock(&pds_vfio
->reset_lock
);
45 mutex_unlock(&pds_vfio
->state_mutex
);
46 spin_unlock(&pds_vfio
->reset_lock
);
49 void pds_vfio_reset(struct pds_vfio_pci_device
*pds_vfio
)
51 spin_lock(&pds_vfio
->reset_lock
);
52 pds_vfio
->deferred_reset
= true;
53 pds_vfio
->deferred_reset_state
= VFIO_DEVICE_STATE_RUNNING
;
54 if (!mutex_trylock(&pds_vfio
->state_mutex
)) {
55 spin_unlock(&pds_vfio
->reset_lock
);
58 spin_unlock(&pds_vfio
->reset_lock
);
59 pds_vfio_state_mutex_unlock(pds_vfio
);
63 pds_vfio_set_device_state(struct vfio_device
*vdev
,
64 enum vfio_device_mig_state new_state
)
66 struct pds_vfio_pci_device
*pds_vfio
=
67 container_of(vdev
, struct pds_vfio_pci_device
,
69 struct file
*res
= NULL
;
71 mutex_lock(&pds_vfio
->state_mutex
);
73 * only way to transition out of VFIO_DEVICE_STATE_ERROR is via
74 * VFIO_DEVICE_RESET, so prevent the state machine from running since
75 * vfio_mig_get_next_state() will throw a WARN_ON() when transitioning
76 * from VFIO_DEVICE_STATE_ERROR to any other state
78 while (pds_vfio
->state
!= VFIO_DEVICE_STATE_ERROR
&&
79 new_state
!= pds_vfio
->state
) {
80 enum vfio_device_mig_state next_state
;
82 int err
= vfio_mig_get_next_state(vdev
, pds_vfio
->state
,
83 new_state
, &next_state
);
89 res
= pds_vfio_step_device_state_locked(pds_vfio
, next_state
);
93 pds_vfio
->state
= next_state
;
95 if (WARN_ON(res
&& new_state
!= pds_vfio
->state
)) {
96 res
= ERR_PTR(-EINVAL
);
100 pds_vfio_state_mutex_unlock(pds_vfio
);
101 /* still waiting on a deferred_reset */
102 if (pds_vfio
->state
== VFIO_DEVICE_STATE_ERROR
)
108 static int pds_vfio_get_device_state(struct vfio_device
*vdev
,
109 enum vfio_device_mig_state
*current_state
)
111 struct pds_vfio_pci_device
*pds_vfio
=
112 container_of(vdev
, struct pds_vfio_pci_device
,
115 mutex_lock(&pds_vfio
->state_mutex
);
116 *current_state
= pds_vfio
->state
;
117 pds_vfio_state_mutex_unlock(pds_vfio
);
121 static int pds_vfio_get_device_state_size(struct vfio_device
*vdev
,
122 unsigned long *stop_copy_length
)
124 *stop_copy_length
= PDS_LM_DEVICE_STATE_LENGTH
;
128 static const struct vfio_migration_ops pds_vfio_lm_ops
= {
129 .migration_set_state
= pds_vfio_set_device_state
,
130 .migration_get_state
= pds_vfio_get_device_state
,
131 .migration_get_data_size
= pds_vfio_get_device_state_size
134 static const struct vfio_log_ops pds_vfio_log_ops
= {
135 .log_start
= pds_vfio_dma_logging_start
,
136 .log_stop
= pds_vfio_dma_logging_stop
,
137 .log_read_and_clear
= pds_vfio_dma_logging_report
,
140 static int pds_vfio_init_device(struct vfio_device
*vdev
)
142 struct pds_vfio_pci_device
*pds_vfio
=
143 container_of(vdev
, struct pds_vfio_pci_device
,
145 struct pci_dev
*pdev
= to_pci_dev(vdev
->dev
);
146 int err
, vf_id
, pci_id
;
148 vf_id
= pci_iov_vf_id(pdev
);
152 err
= vfio_pci_core_init_dev(vdev
);
156 pds_vfio
->vf_id
= vf_id
;
158 vdev
->migration_flags
= VFIO_MIGRATION_STOP_COPY
| VFIO_MIGRATION_P2P
;
159 vdev
->mig_ops
= &pds_vfio_lm_ops
;
160 vdev
->log_ops
= &pds_vfio_log_ops
;
162 pci_id
= PCI_DEVID(pdev
->bus
->number
, pdev
->devfn
);
164 "%s: PF %#04x VF %#04x vf_id %d domain %d pds_vfio %p\n",
165 __func__
, pci_dev_id(pdev
->physfn
), pci_id
, vf_id
,
166 pci_domain_nr(pdev
->bus
), pds_vfio
);
171 static int pds_vfio_open_device(struct vfio_device
*vdev
)
173 struct pds_vfio_pci_device
*pds_vfio
=
174 container_of(vdev
, struct pds_vfio_pci_device
,
178 err
= vfio_pci_core_enable(&pds_vfio
->vfio_coredev
);
182 mutex_init(&pds_vfio
->state_mutex
);
183 pds_vfio
->state
= VFIO_DEVICE_STATE_RUNNING
;
184 pds_vfio
->deferred_reset_state
= VFIO_DEVICE_STATE_RUNNING
;
186 vfio_pci_core_finish_enable(&pds_vfio
->vfio_coredev
);
191 static void pds_vfio_close_device(struct vfio_device
*vdev
)
193 struct pds_vfio_pci_device
*pds_vfio
=
194 container_of(vdev
, struct pds_vfio_pci_device
,
197 mutex_lock(&pds_vfio
->state_mutex
);
198 pds_vfio_put_restore_file(pds_vfio
);
199 pds_vfio_put_save_file(pds_vfio
);
200 pds_vfio_dirty_disable(pds_vfio
, true);
201 mutex_unlock(&pds_vfio
->state_mutex
);
202 mutex_destroy(&pds_vfio
->state_mutex
);
203 vfio_pci_core_close_device(vdev
);
206 static const struct vfio_device_ops pds_vfio_ops
= {
208 .init
= pds_vfio_init_device
,
209 .release
= vfio_pci_core_release_dev
,
210 .open_device
= pds_vfio_open_device
,
211 .close_device
= pds_vfio_close_device
,
212 .ioctl
= vfio_pci_core_ioctl
,
213 .device_feature
= vfio_pci_core_ioctl_feature
,
214 .read
= vfio_pci_core_read
,
215 .write
= vfio_pci_core_write
,
216 .mmap
= vfio_pci_core_mmap
,
217 .request
= vfio_pci_core_request
,
218 .match
= vfio_pci_core_match
,
219 .bind_iommufd
= vfio_iommufd_physical_bind
,
220 .unbind_iommufd
= vfio_iommufd_physical_unbind
,
221 .attach_ioas
= vfio_iommufd_physical_attach_ioas
,
224 const struct vfio_device_ops
*pds_vfio_ops_info(void)
226 return &pds_vfio_ops
;