Skip to content

Commit 6435259

Browse files
yliu80wenlingz
authored andcommitted
hv: unmap SR-IOV VF MMIO when the VF physical device is disabled
To avoid information leakage, we need to ensure that the device is inaccessble when it does not exist. For SR-IOV disabled VF device, we have the following operations. 1. The configuration space accessing will get 0xFFFFFFFF as a return value after set the device state to zombie. 2. The BAR MMIO EPT mapping are removed, the accesssing causes EPT violation. 3. The device will be detached from IOMMU. 4. The IRQ pin and vector are released. Tracked-On: #4433 Signed-off-by: Yuan Liu <[email protected]> Acked-by: Eddie Dong <[email protected]>
1 parent 1d7158c commit 6435259

File tree

4 files changed

+35
-4
lines changed

4 files changed

+35
-4
lines changed

hypervisor/dm/vpci/pci_pt.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,8 @@ void init_vdev_pt(struct pci_vdev *vdev, bool is_pf_vdev)
388388
pci_pdev_write_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U, pci_command);
389389
}
390390
} else {
391-
/* VF is assigned to a UOS */
392-
if (vdev->vpci != vdev->phyfun->vpci) {
391+
if (!is_own_device(vdev->phyfun->vpci->vm, vdev)) {
392+
/* VF is assigned to a UOS */
393393
uint32_t vid, did;
394394

395395
vdev->nr_bars = PCI_BAR_COUNT;
@@ -399,6 +399,37 @@ void init_vdev_pt(struct pci_vdev *vdev, bool is_pf_vdev)
399399
(vdev->phyfun->sriov.capoff + PCIR_SRIOV_VF_DEV_ID), 2U);
400400
pci_vdev_write_vcfg(vdev, PCIR_VENDOR, 2U, vid);
401401
pci_vdev_write_vcfg(vdev, PCIR_DEVICE, 2U, did);
402+
} else {
403+
/* VF is unassinged */
404+
uint32_t bar_idx;
405+
406+
for (bar_idx = 0U; bar_idx < vdev->nr_bars; bar_idx++) {
407+
vdev_pt_map_mem_vbar(vdev, bar_idx);
408+
}
409+
}
410+
}
411+
}
412+
413+
/*
414+
* @brief Destruct a specified passthrough vdev structure.
415+
*
416+
* The function deinit_vdev_pt is the destructor corresponding to the function init_vdev_pt.
417+
*
418+
* @param vdev pointer to vdev data structure
419+
*
420+
* @pre vdev != NULL
421+
*
422+
* @return None
423+
*/
424+
void deinit_vdev_pt(struct pci_vdev *vdev) {
425+
426+
/* Check if the vdev is an unassigned SR-IOV VF device */
427+
if ((vdev->phyfun != NULL) && (is_own_device(vdev->phyfun->vpci->vm, vdev))) {
428+
uint32_t bar_idx;
429+
430+
/* Delete VF MMIO from EPT table since the VF physical device has gone */
431+
for (bar_idx = 0U; bar_idx < vdev->nr_bars; bar_idx++) {
432+
vdev_pt_unmap_mem_vbar(vdev, bar_idx);
402433
}
403434
}
404435
}

hypervisor/dm/vpci/vpci.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ static void vpci_init_pt_dev(struct pci_vdev *vdev)
377377

378378
static void vpci_deinit_pt_dev(struct pci_vdev *vdev)
379379
{
380+
deinit_vdev_pt(vdev);
380381
remove_vdev_pt_iommu_domain(vdev);
381382
deinit_vmsix(vdev);
382383
deinit_vmsi(vdev);

hypervisor/dm/vpci/vpci_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ static inline bool msicap_access(const struct pci_vdev *vdev, uint32_t offset)
102102
}
103103

104104
void init_vdev_pt(struct pci_vdev *vdev, bool is_pf_vdev);
105+
void deinit_vdev_pt(struct pci_vdev *vdev);
105106
void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val);
106107
void vdev_pt_map_msix(struct pci_vdev *vdev, bool hold_lock);
107108

hypervisor/dm/vpci/vsriov.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,6 @@ static void disable_vfs(struct pci_vdev *pf_vdev)
239239
* resources
240240
*
241241
* If the VF drivers are still running in SOS or UOS, the MMIO access will return 0xFF.
242-
*
243-
* TODO For security reasons, we need to enforce a return of 0xFF to avoid information leakage.
244242
*/
245243
num_vfs = read_sriov_reg(pf_vdev, PCIR_SRIOV_NUMVFS);
246244
first = read_sriov_reg(pf_vdev, PCIR_SRIOV_FST_VF_OFF);

0 commit comments

Comments
 (0)