diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index c4d25b761..899623f25 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -388,8 +388,8 @@ void init_vdev_pt(struct pci_vdev *vdev, bool is_pf_vdev) pci_pdev_write_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U, pci_command); } } else { - /* VF is assigned to a UOS */ - if (vdev->vpci != vdev->phyfun->vpci) { + if (!is_own_device(vdev->phyfun->vpci->vm, vdev)) { + /* VF is assigned to a UOS */ uint32_t vid, did; vdev->nr_bars = PCI_BAR_COUNT; @@ -399,6 +399,37 @@ void init_vdev_pt(struct pci_vdev *vdev, bool is_pf_vdev) (vdev->phyfun->sriov.capoff + PCIR_SRIOV_VF_DEV_ID), 2U); pci_vdev_write_vcfg(vdev, PCIR_VENDOR, 2U, vid); pci_vdev_write_vcfg(vdev, PCIR_DEVICE, 2U, did); + } else { + /* VF is unassinged */ + uint32_t bar_idx; + + for (bar_idx = 0U; bar_idx < vdev->nr_bars; bar_idx++) { + vdev_pt_map_mem_vbar(vdev, bar_idx); + } + } + } +} + +/* + * @brief Destruct a specified passthrough vdev structure. + * + * The function deinit_vdev_pt is the destructor corresponding to the function init_vdev_pt. + * + * @param vdev pointer to vdev data structure + * + * @pre vdev != NULL + * + * @return None + */ +void deinit_vdev_pt(struct pci_vdev *vdev) { + + /* Check if the vdev is an unassigned SR-IOV VF device */ + if ((vdev->phyfun != NULL) && (is_own_device(vdev->phyfun->vpci->vm, vdev))) { + uint32_t bar_idx; + + /* Delete VF MMIO from EPT table since the VF physical device has gone */ + for (bar_idx = 0U; bar_idx < vdev->nr_bars; bar_idx++) { + vdev_pt_unmap_mem_vbar(vdev, bar_idx); } } } diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index 2fada8836..e4ac8200e 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -377,6 +377,7 @@ static void vpci_init_pt_dev(struct pci_vdev *vdev) static void vpci_deinit_pt_dev(struct pci_vdev *vdev) { + deinit_vdev_pt(vdev); remove_vdev_pt_iommu_domain(vdev); deinit_vmsix(vdev); deinit_vmsi(vdev); diff --git a/hypervisor/dm/vpci/vpci_priv.h b/hypervisor/dm/vpci/vpci_priv.h index ce6d0e9a5..132dbb137 100644 --- a/hypervisor/dm/vpci/vpci_priv.h +++ b/hypervisor/dm/vpci/vpci_priv.h @@ -102,6 +102,7 @@ static inline bool msicap_access(const struct pci_vdev *vdev, uint32_t offset) } void init_vdev_pt(struct pci_vdev *vdev, bool is_pf_vdev); +void deinit_vdev_pt(struct pci_vdev *vdev); void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val); void vdev_pt_map_msix(struct pci_vdev *vdev, bool hold_lock); diff --git a/hypervisor/dm/vpci/vsriov.c b/hypervisor/dm/vpci/vsriov.c index b8d9bcd04..6e8730f15 100644 --- a/hypervisor/dm/vpci/vsriov.c +++ b/hypervisor/dm/vpci/vsriov.c @@ -239,8 +239,6 @@ static void disable_vfs(struct pci_vdev *pf_vdev) * resources * * If the VF drivers are still running in SOS or UOS, the MMIO access will return 0xFF. - * - * TODO For security reasons, we need to enforce a return of 0xFF to avoid information leakage. */ num_vfs = read_sriov_reg(pf_vdev, PCIR_SRIOV_NUMVFS); first = read_sriov_reg(pf_vdev, PCIR_SRIOV_FST_VF_OFF);