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:
parent
13de9a4cf6
commit
90480db553
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue