From 90480db5532b788a7b346e78e11c4ce1c81c19a6 Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Fri, 9 Aug 2019 22:16:50 +0800 Subject: [PATCH] hv: vpci: split vPCI device from SOS for post-launched VM When assgined a PCI PTDev to post-launched VM from SOS, using a pointer to point to the real struct pci_vdev. When post-launched VM access its PTDev configure space in SOS address space, using this real struct pci_vdev. Tracked-On: #3475 Signed-off-by: Li, Fei1 --- hypervisor/dm/vpci/vdev.c | 24 +-------- hypervisor/dm/vpci/vpci.c | 49 +++++++++---------- hypervisor/dm/vpci/vpci_priv.h | 4 +- hypervisor/include/dm/vpci.h | 5 +- .../scenarios/hybrid/vm_configurations.c | 8 +-- 5 files changed, 34 insertions(+), 56 deletions(-) diff --git a/hypervisor/dm/vpci/vdev.c b/hypervisor/dm/vpci/vdev.c index 01418d370..73a27291c 100644 --- a/hypervisor/dm/vpci/vdev.c +++ b/hypervisor/dm/vpci/vdev.c @@ -74,7 +74,7 @@ void pci_vdev_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, * @pre vpci != NULL * @pre vpci->pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM */ -struct pci_vdev *pci_find_vdev_by_vbdf(const struct acrn_vpci *vpci, union pci_bdf vbdf) +struct pci_vdev *pci_find_vdev(const struct acrn_vpci *vpci, union pci_bdf vbdf) { struct pci_vdev *vdev, *tmp; uint32_t i; @@ -91,25 +91,3 @@ struct pci_vdev *pci_find_vdev_by_vbdf(const struct acrn_vpci *vpci, union pci_b return vdev; } - -/** - * @pre vpci != NULL - * @pre vpci->pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM - */ -struct pci_vdev *pci_find_vdev_by_pbdf(const struct acrn_vpci *vpci, union pci_bdf pbdf) -{ - struct pci_vdev *vdev, *tmp; - uint32_t i; - - vdev = NULL; - for (i = 0U; i < vpci->pci_vdev_cnt; i++) { - tmp = (struct pci_vdev *)&(vpci->pci_vdevs[i]); - - if ((tmp->pdev != NULL) && bdf_is_equal((union pci_bdf *)&(tmp->pdev->bdf), &pbdf)) { - vdev = tmp; - break; - } - } - - return vdev; -} diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index d1fa54b28..6cb1d756e 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -303,7 +303,7 @@ static struct pci_vdev *find_vdev_for_sos(union pci_bdf bdf) vm = get_sos_vm(); - return pci_find_vdev_by_pbdf(&vm->vpci, bdf); + return pci_find_vdev(&vm->vpci, bdf); } /** @@ -312,14 +312,10 @@ static struct pci_vdev *find_vdev_for_sos(union pci_bdf bdf) */ static struct pci_vdev *find_vdev(const struct acrn_vpci *vpci, union pci_bdf bdf) { - struct pci_vdev *vdev; + struct pci_vdev *vdev = pci_find_vdev(vpci, bdf); - if (is_prelaunched_vm(vpci->vm)) { - vdev = pci_find_vdev_by_vbdf(vpci, bdf); - } else if (is_sos_vm(vpci->vm)) { - vdev = find_vdev_for_sos(bdf); - } else { - vdev = NULL; + if ((vdev != NULL) && (vdev->vpci != vpci)) { + vdev = vdev->new_owner; } return vdev; @@ -479,7 +475,7 @@ static void deinit_postlaunched_vm_vpci(const struct acrn_vm *vm) { struct acrn_vm *sos_vm; uint32_t i; - struct pci_vdev *vdev; + struct pci_vdev *vdev, *target_vdev; int32_t ret; /* PCI resources * 1) IOMMU domain switch @@ -498,21 +494,20 @@ static void deinit_postlaunched_vm_vpci(const struct acrn_vm *vm) vdev = (struct pci_vdev *)&(sos_vm->vpci.pci_vdevs[i]); if (vdev->vpci->vm == vm) { - ret = move_pt_device(vm->iommu, sos_vm->iommu, (uint8_t)vdev->pdev->bdf.bits.b, - (uint8_t)(vdev->pdev->bdf.value & 0xFFU)); + target_vdev = vdev->new_owner; + ret = move_pt_device(vm->iommu, sos_vm->iommu, (uint8_t)target_vdev->pdev->bdf.bits.b, + (uint8_t)(target_vdev->pdev->bdf.value & 0xFFU)); if (ret != 0) { panic("failed to assign iommu device!"); } - deinit_vmsi(vdev); + deinit_vmsi(target_vdev); - deinit_vmsix(vdev); + deinit_vmsix(target_vdev); /* Move vdev pointers back to SOS*/ vdev->vpci = (struct acrn_vpci *) &sos_vm->vpci; - - /* vbdf equals to pbdf in sos */ - vdev->bdf.value = vdev->pdev->bdf.value; + vdev->new_owner = NULL; } } } @@ -520,9 +515,10 @@ static void deinit_postlaunched_vm_vpci(const struct acrn_vm *vm) /** * @pre target_vm != NULL */ -void vpci_set_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf) +void vpci_set_ptdev_intr_info(struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf) { - struct pci_vdev *vdev; + struct pci_vdev *vdev, *target_vdev; + struct acrn_vpci *target_vpci; union pci_bdf bdf; bdf.value = pbdf; @@ -531,10 +527,15 @@ void vpci_set_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, ui pr_err("%s, can't find PCI device for vm%d, vbdf (0x%x) pbdf (0x%x)", __func__, target_vm->vm_id, vbdf, pbdf); } else { - /* UOS may do BDF mapping */ - vdev->vpci = (struct acrn_vpci *)&(target_vm->vpci); - vdev->bdf.value = vbdf; - vdev->pdev->bdf.value = pbdf; + target_vpci = &(target_vm->vpci); + vdev->vpci = target_vpci; + + target_vdev = &target_vpci->pci_vdevs[target_vpci->pci_vdev_cnt]; + target_vpci->pci_vdev_cnt++; + (void)memcpy_s((void *)target_vdev, sizeof(struct pci_vdev), (void *)vdev, sizeof(struct pci_vdev)); + target_vdev->bdf.value = vbdf; + + vdev->new_owner = target_vdev; } } @@ -558,9 +559,7 @@ void vpci_reset_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, vm = get_sos_vm(); vdev->vpci = &vm->vpci; - - /* vbdf equals to pbdf in sos */ - vdev->bdf.value = vdev->pdev->bdf.value; + vdev->new_owner = NULL; } } } diff --git a/hypervisor/dm/vpci/vpci_priv.h b/hypervisor/dm/vpci/vpci_priv.h index 6a794a41f..da9eb35be 100644 --- a/hypervisor/dm/vpci/vpci_priv.h +++ b/hypervisor/dm/vpci/vpci_priv.h @@ -143,8 +143,6 @@ void deinit_vmsix(const struct pci_vdev *vdev); uint32_t pci_vdev_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes); void pci_vdev_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val); -struct pci_vdev *pci_find_vdev_by_vbdf(const struct acrn_vpci *vpci, union pci_bdf vbdf); - -struct pci_vdev *pci_find_vdev_by_pbdf(const struct acrn_vpci *vpci, union pci_bdf pbdf); +struct pci_vdev *pci_find_vdev(const struct acrn_vpci *vpci, union pci_bdf vbdf); #endif /* VPCI_PRIV_H_ */ diff --git a/hypervisor/include/dm/vpci.h b/hypervisor/include/dm/vpci.h index 8b3ba2b54..2574e4f82 100644 --- a/hypervisor/include/dm/vpci.h +++ b/hypervisor/include/dm/vpci.h @@ -96,6 +96,9 @@ struct pci_vdev { /* Pointer to corressponding operations */ const struct pci_vdev_ops *vdev_ops; + + /* For SOS, if the device is latterly assigned to a UOS, we use this field to track the new owner. */ + struct pci_vdev *new_owner; }; struct pci_addr_info { @@ -114,7 +117,7 @@ struct acrn_vpci { extern const struct pci_vdev_ops vhostbridge_ops; void vpci_init(struct acrn_vm *vm); void vpci_cleanup(const struct acrn_vm *vm); -void vpci_set_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf); +void vpci_set_ptdev_intr_info(struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf); void vpci_reset_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf); #endif /* VPCI_H_ */ diff --git a/hypervisor/scenarios/hybrid/vm_configurations.c b/hypervisor/scenarios/hybrid/vm_configurations.c index 855a761ba..afce353db 100644 --- a/hypervisor/scenarios/hybrid/vm_configurations.c +++ b/hypervisor/scenarios/hybrid/vm_configurations.c @@ -41,9 +41,7 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = { .irq = COM2_IRQ, .t_vuart.vm_id = 1U, .t_vuart.vuart_id = 1U, - }, - .pci_dev_num = SOS_EMULATED_PCI_DEV_NUM, - .pci_devs = sos_pci_devs, + } }, { /* VM1 */ .load_order = SOS_VM, @@ -72,7 +70,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = { .vuart[1] = { .type = VUART_LEGACY_PIO, .addr.port_base = INVALID_COM_BASE, - } + }, + .pci_dev_num = SOS_EMULATED_PCI_DEV_NUM, + .pci_devs = sos_pci_devs, }, { /* VM2 */ .load_order = POST_LAUNCHED_VM,