Skip to content

Commit 640cf57

Browse files
yliu80wenlingz
authored andcommitted
hv: disable VF device
If a VF instance is disabled, we didn’t remove the vdev instance, only set the vdev as a zombie vdev instance, indicating that it cannot be accessed anymore. Tracked-On: #4433 Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 2a4235f commit 640cf57

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

hypervisor/dm/vpci/vsriov.c

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ static void enable_vf(struct pci_vdev *pf_vdev)
185185
sub_vid = (uint16_t) pci_pdev_read_cfg(vf_bdf, PCIV_SUB_VENDOR_ID, 2U);
186186
if ((sub_vid != 0xFFFFU) && (sub_vid != 0U)) {
187187
uint16_t num_vfs, stride, fst_off;
188+
struct pci_vdev *vf_vdev;
188189

189190
num_vfs = read_sriov_reg(pf_vdev, PCIR_SRIOV_NUMVFS);
190191
fst_off = read_sriov_reg(pf_vdev, PCIR_SRIOV_FST_VF_OFF);
@@ -193,9 +194,20 @@ static void enable_vf(struct pci_vdev *pf_vdev)
193194
vf_bdf.fields.bus = get_vf_bus(pf_vdev, fst_off, stride, idx);
194195
vf_bdf.fields.devfun = get_vf_devfun(pf_vdev, fst_off, stride, idx);
195196

196-
/* if one VF has never been created then create new pdev/vdev for this VF */
197-
if (pci_find_vdev(&pf_vdev->vpci->vm->vpci, vf_bdf) == NULL) {
197+
/*
198+
* If one VF has never been created then create new one including pdev/vdev structures.
199+
*
200+
* The VF maybe have already existed but it is a zombie instance that vf_vdev->vpci
201+
* is NULL, in this case, we need to make the vf_vdev available again in here.
202+
*/
203+
vf_vdev = pci_find_vdev(&pf_vdev->vpci->vm->vpci, vf_bdf);
204+
if (vf_vdev == NULL) {
198205
create_vf(pf_vdev, vf_bdf, idx);
206+
} else {
207+
/* Re-activate a zombie VF */
208+
if (vf_vdev->vpci == NULL) {
209+
vf_vdev->vpci = pf_vdev->vpci;
210+
}
199211
}
200212
}
201213
} else {
@@ -213,8 +225,34 @@ static void enable_vf(struct pci_vdev *pf_vdev)
213225
*/
214226
static void disable_vf(struct pci_vdev *pf_vdev)
215227
{
216-
/* Implementation in next patch */
217-
(void)pf_vdev;
228+
uint16_t idx, num_vfs, stride, first;
229+
struct pci_vdev *vf_vdev;
230+
231+
/*
232+
* PF can disable VFs only when all VFs are not used by any VM or any application
233+
*
234+
* Ideally, VF instances should be deleted after VFs are disabled, but for FuSa reasons,
235+
* we simply set the VF instance status to "zombie" to avoid dynamically adding/removing
236+
* resources
237+
*
238+
* If the VF drivers are still running in SOS or UOS, the MMIO access will return 0xFF.
239+
*
240+
* TODO For security reasons, we need to enforce a return of 0xFF to avoid information leakage.
241+
*/
242+
num_vfs = read_sriov_reg(pf_vdev, PCIR_SRIOV_NUMVFS);
243+
first = read_sriov_reg(pf_vdev, PCIR_SRIOV_FST_VF_OFF);
244+
stride = read_sriov_reg(pf_vdev, PCIR_SRIOV_VF_STRIDE);
245+
for (idx = 0U; idx < num_vfs; idx++) {
246+
union pci_bdf bdf;
247+
248+
bdf.fields.bus = get_vf_bus(pf_vdev, first, stride, idx);
249+
bdf.fields.devfun = get_vf_devfun(pf_vdev, first, stride, idx);
250+
vf_vdev = pci_find_vdev(&pf_vdev->vpci->vm->vpci, bdf);
251+
if (vf_vdev != NULL) {
252+
/* set disabled VF as zombie vdev instance */
253+
vf_vdev->vpci = NULL;
254+
}
255+
}
218256
}
219257

220258
/**

0 commit comments

Comments
 (0)