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 <fei1.li@intel.com>
This commit is contained in:
Li, Fei1 2019-08-09 22:16:50 +08:00 committed by wenlingz
parent 13de9a4cf6
commit 90480db553
5 changed files with 34 additions and 56 deletions

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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,