mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-07 06:32:08 +00:00
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 != NULL
|
||||||
* @pre vpci->pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM
|
* @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;
|
struct pci_vdev *vdev, *tmp;
|
||||||
uint32_t i;
|
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;
|
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();
|
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)
|
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)) {
|
if ((vdev != NULL) && (vdev->vpci != vpci)) {
|
||||||
vdev = pci_find_vdev_by_vbdf(vpci, bdf);
|
vdev = vdev->new_owner;
|
||||||
} else if (is_sos_vm(vpci->vm)) {
|
|
||||||
vdev = find_vdev_for_sos(bdf);
|
|
||||||
} else {
|
|
||||||
vdev = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vdev;
|
return vdev;
|
||||||
@ -479,7 +475,7 @@ static void deinit_postlaunched_vm_vpci(const struct acrn_vm *vm)
|
|||||||
{
|
{
|
||||||
struct acrn_vm *sos_vm;
|
struct acrn_vm *sos_vm;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct pci_vdev *vdev;
|
struct pci_vdev *vdev, *target_vdev;
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
/* PCI resources
|
/* PCI resources
|
||||||
* 1) IOMMU domain switch
|
* 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]);
|
vdev = (struct pci_vdev *)&(sos_vm->vpci.pci_vdevs[i]);
|
||||||
|
|
||||||
if (vdev->vpci->vm == vm) {
|
if (vdev->vpci->vm == vm) {
|
||||||
ret = move_pt_device(vm->iommu, sos_vm->iommu, (uint8_t)vdev->pdev->bdf.bits.b,
|
target_vdev = vdev->new_owner;
|
||||||
(uint8_t)(vdev->pdev->bdf.value & 0xFFU));
|
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) {
|
if (ret != 0) {
|
||||||
panic("failed to assign iommu device!");
|
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*/
|
/* Move vdev pointers back to SOS*/
|
||||||
vdev->vpci = (struct acrn_vpci *) &sos_vm->vpci;
|
vdev->vpci = (struct acrn_vpci *) &sos_vm->vpci;
|
||||||
|
vdev->new_owner = NULL;
|
||||||
/* vbdf equals to pbdf in sos */
|
|
||||||
vdev->bdf.value = vdev->pdev->bdf.value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -520,9 +515,10 @@ static void deinit_postlaunched_vm_vpci(const struct acrn_vm *vm)
|
|||||||
/**
|
/**
|
||||||
* @pre target_vm != NULL
|
* @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;
|
union pci_bdf bdf;
|
||||||
|
|
||||||
bdf.value = pbdf;
|
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__,
|
pr_err("%s, can't find PCI device for vm%d, vbdf (0x%x) pbdf (0x%x)", __func__,
|
||||||
target_vm->vm_id, vbdf, pbdf);
|
target_vm->vm_id, vbdf, pbdf);
|
||||||
} else {
|
} else {
|
||||||
/* UOS may do BDF mapping */
|
target_vpci = &(target_vm->vpci);
|
||||||
vdev->vpci = (struct acrn_vpci *)&(target_vm->vpci);
|
vdev->vpci = target_vpci;
|
||||||
vdev->bdf.value = vbdf;
|
|
||||||
vdev->pdev->bdf.value = pbdf;
|
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();
|
vm = get_sos_vm();
|
||||||
|
|
||||||
vdev->vpci = &vm->vpci;
|
vdev->vpci = &vm->vpci;
|
||||||
|
vdev->new_owner = NULL;
|
||||||
/* vbdf equals to pbdf in sos */
|
|
||||||
vdev->bdf.value = vdev->pdev->bdf.value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
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);
|
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(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);
|
|
||||||
|
|
||||||
#endif /* VPCI_PRIV_H_ */
|
#endif /* VPCI_PRIV_H_ */
|
||||||
|
@ -96,6 +96,9 @@ struct pci_vdev {
|
|||||||
|
|
||||||
/* Pointer to corressponding operations */
|
/* Pointer to corressponding operations */
|
||||||
const struct pci_vdev_ops *vdev_ops;
|
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 {
|
struct pci_addr_info {
|
||||||
@ -114,7 +117,7 @@ struct acrn_vpci {
|
|||||||
extern const struct pci_vdev_ops vhostbridge_ops;
|
extern const struct pci_vdev_ops vhostbridge_ops;
|
||||||
void vpci_init(struct acrn_vm *vm);
|
void vpci_init(struct acrn_vm *vm);
|
||||||
void vpci_cleanup(const 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);
|
void vpci_reset_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf);
|
||||||
|
|
||||||
#endif /* VPCI_H_ */
|
#endif /* VPCI_H_ */
|
||||||
|
@ -41,9 +41,7 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
.irq = COM2_IRQ,
|
.irq = COM2_IRQ,
|
||||||
.t_vuart.vm_id = 1U,
|
.t_vuart.vm_id = 1U,
|
||||||
.t_vuart.vuart_id = 1U,
|
.t_vuart.vuart_id = 1U,
|
||||||
},
|
}
|
||||||
.pci_dev_num = SOS_EMULATED_PCI_DEV_NUM,
|
|
||||||
.pci_devs = sos_pci_devs,
|
|
||||||
},
|
},
|
||||||
{ /* VM1 */
|
{ /* VM1 */
|
||||||
.load_order = SOS_VM,
|
.load_order = SOS_VM,
|
||||||
@ -72,7 +70,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
.vuart[1] = {
|
.vuart[1] = {
|
||||||
.type = VUART_LEGACY_PIO,
|
.type = VUART_LEGACY_PIO,
|
||||||
.addr.port_base = INVALID_COM_BASE,
|
.addr.port_base = INVALID_COM_BASE,
|
||||||
}
|
},
|
||||||
|
.pci_dev_num = SOS_EMULATED_PCI_DEV_NUM,
|
||||||
|
.pci_devs = sos_pci_devs,
|
||||||
},
|
},
|
||||||
{ /* VM2 */
|
{ /* VM2 */
|
||||||
.load_order = POST_LAUNCHED_VM,
|
.load_order = POST_LAUNCHED_VM,
|
||||||
|
Loading…
Reference in New Issue
Block a user