mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-21 13:08:42 +00:00
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 <yuan1.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
b09f07e200
commit
9375c634dc
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user