mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-11 05:39:45 +00:00
hv: passthrough a VF device
Emulate Device ID, Vendor ID and MSE(Memory Space Enable) bit in configuration space for an assigned VF, initialize assgined VF Bars. The Device ID comes from PF's SRIOV capability The Vendor ID comes from PF's Vendor ID The PCI MSE bit always be set when VM reads from an assigned VF. 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:
@@ -387,5 +387,18 @@ void init_vdev_pt(struct pci_vdev *vdev, bool is_pf_vdev)
|
||||
pci_command |= 0x400U;
|
||||
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) {
|
||||
uint32_t vid, did;
|
||||
|
||||
vdev->nr_bars = PCI_BAR_COUNT;
|
||||
/* SRIOV VF Vendor ID and Device ID initialization */
|
||||
vid = pci_pdev_read_cfg(vdev->phyfun->bdf, PCIR_VENDOR, 2U);
|
||||
did = pci_pdev_read_cfg(vdev->phyfun->bdf,
|
||||
(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -425,6 +425,12 @@ static void read_cfg_header(const struct pci_vdev *vdev,
|
||||
} else {
|
||||
if (bitmap32_test(((uint16_t)offset) >> 2U, &cfg_hdr_perm.pt_mask)) {
|
||||
*val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes);
|
||||
|
||||
/* MSE(Memory Space Enable) bit always be set for an assigned VF */
|
||||
if ((vdev->phyfun != NULL) && (offset == PCIR_COMMAND) &&
|
||||
(vdev->vpci != vdev->phyfun->vpci)) {
|
||||
*val |= PCIM_CMD_MEMEN;
|
||||
}
|
||||
} else {
|
||||
*val = pci_vdev_read_vcfg(vdev, offset, bytes);
|
||||
}
|
||||
@@ -721,10 +727,18 @@ int32_t vpci_assign_pcidev(struct acrn_vm *tgt_vm, struct acrn_assign_pcidev *pc
|
||||
vdev_in_sos->vpci = vpci;
|
||||
|
||||
spinlock_obtain(&tgt_vm->vpci.lock);
|
||||
vdev = vpci_init_vdev(vpci, vdev_in_sos->pci_dev_config, NULL);
|
||||
vdev = vpci_init_vdev(vpci, vdev_in_sos->pci_dev_config, vdev_in_sos->phyfun);
|
||||
pci_vdev_write_vcfg(vdev, PCIR_INTERRUPT_LINE, 1U, pcidev->intr_line);
|
||||
pci_vdev_write_vcfg(vdev, PCIR_INTERRUPT_PIN, 1U, pcidev->intr_pin);
|
||||
for (idx = 0U; idx < vdev->nr_bars; idx++) {
|
||||
/* VF is assigned to a UOS */
|
||||
if (vdev->phyfun != NULL) {
|
||||
vdev->vbars[idx] = vdev_in_sos->vbars[idx];
|
||||
if (has_msix_cap(vdev) && (idx == vdev->msix.table_bar)) {
|
||||
vdev->msix.mmio_hpa = vdev->vbars[idx].base_hpa;
|
||||
vdev->msix.mmio_size = vdev->vbars[idx].size;
|
||||
}
|
||||
}
|
||||
pci_vdev_write_vbar(vdev, idx, pcidev->bar[idx]);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user