mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
vpci: add hooks for PCI device assign/de-assign
When a PCI device gets assigned/de-assigned we need to initialize/de-initialize vPCI state for the device. Also, rename vpci_add_handlers() to vpci_assign_device() and vpci_remove_device() to vpci_deassign_device() to better reflect role of the functions. Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> Signed-off-by: Stewart Hildebrand <stewart.hildebrand@amd.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
80b0eb095a
commit
f20dde9259
4 files changed
+33
-13
No files matched your search
@@ -755,7 +755,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
|
||||
* For devices not discovered by Xen during boot, add vPCI handlers
|
||||
* when Dom0 first informs Xen about such devices.
|
||||
*/
|
||||
ret = vpci_add_handlers(pdev);
|
||||
ret = vpci_assign_device(pdev);
|
||||
if ( ret )
|
||||
{
|
||||
list_del(&pdev->domain_list);
|
||||
@@ -769,7 +769,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
|
||||
if ( ret )
|
||||
{
|
||||
write_lock(&hardware_domain->pci_lock);
|
||||
vpci_remove_device(pdev);
|
||||
vpci_deassign_device(pdev);
|
||||
list_del(&pdev->domain_list);
|
||||
write_unlock(&hardware_domain->pci_lock);
|
||||
pdev->domain = NULL;
|
||||
@@ -817,7 +817,7 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
|
||||
list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
|
||||
if ( pdev->bus == bus && pdev->devfn == devfn )
|
||||
{
|
||||
vpci_remove_device(pdev);
|
||||
vpci_deassign_device(pdev);
|
||||
pci_cleanup_msi(pdev);
|
||||
ret = iommu_remove_device(pdev);
|
||||
if ( pdev->domain )
|
||||
@@ -875,6 +875,10 @@ static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus,
|
||||
goto out;
|
||||
}
|
||||
|
||||
write_lock(&d->pci_lock);
|
||||
vpci_deassign_device(pdev);
|
||||
write_unlock(&d->pci_lock);
|
||||
|
||||
devfn = pdev->devfn;
|
||||
ret = iommu_call(hd->platform_ops, reassign_device, d, target, devfn,
|
||||
pci_to_dev(pdev));
|
||||
@@ -886,6 +890,11 @@ static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus,
|
||||
|
||||
pdev->fault.count = 0;
|
||||
|
||||
write_lock(&target->pci_lock);
|
||||
/* Re-assign back to hardware_domain */
|
||||
ret = vpci_assign_device(pdev);
|
||||
write_unlock(&target->pci_lock);
|
||||
|
||||
out:
|
||||
if ( ret )
|
||||
printk(XENLOG_G_ERR "%pd: deassign (%pp) failed (%d)\n",
|
||||
@@ -1146,7 +1155,7 @@ static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt,
|
||||
PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
|
||||
|
||||
write_lock(&ctxt->d->pci_lock);
|
||||
err = vpci_add_handlers(pdev);
|
||||
err = vpci_assign_device(pdev);
|
||||
write_unlock(&ctxt->d->pci_lock);
|
||||
if ( err )
|
||||
printk(XENLOG_ERR "setup of vPCI for d%d failed: %d\n",
|
||||
@@ -1476,6 +1485,10 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag)
|
||||
if ( pdev->broken && d != hardware_domain && d != dom_io )
|
||||
goto done;
|
||||
|
||||
write_lock(&pdev->domain->pci_lock);
|
||||
vpci_deassign_device(pdev);
|
||||
write_unlock(&pdev->domain->pci_lock);
|
||||
|
||||
rc = pdev_msix_assign(d, pdev);
|
||||
if ( rc )
|
||||
goto done;
|
||||
@@ -1501,6 +1514,13 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag)
|
||||
pci_to_dev(pdev), flag);
|
||||
}
|
||||
|
||||
if ( rc )
|
||||
goto done;
|
||||
|
||||
write_lock(&d->pci_lock);
|
||||
rc = vpci_assign_device(pdev);
|
||||
write_unlock(&d->pci_lock);
|
||||
|
||||
done:
|
||||
if ( rc )
|
||||
{
|
||||
|
||||
@@ -191,7 +191,7 @@ bool vpci_process_pending(struct vcpu *v)
|
||||
* killed in order to avoid leaking stale p2m mappings on
|
||||
* failure.
|
||||
*/
|
||||
vpci_remove_device(v->vpci.pdev);
|
||||
vpci_deassign_device(v->vpci.pdev);
|
||||
write_unlock(&v->domain->pci_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ extern vpci_register_init_t *const __start_vpci_array[];
|
||||
extern vpci_register_init_t *const __end_vpci_array[];
|
||||
#define NUM_VPCI_INIT (__end_vpci_array - __start_vpci_array)
|
||||
|
||||
void vpci_remove_device(struct pci_dev *pdev)
|
||||
void vpci_deassign_device(struct pci_dev *pdev)
|
||||
{
|
||||
ASSERT(rw_is_write_locked(&pdev->domain->pci_lock));
|
||||
|
||||
@@ -73,7 +73,7 @@ void vpci_remove_device(struct pci_dev *pdev)
|
||||
pdev->vpci = NULL;
|
||||
}
|
||||
|
||||
int vpci_add_handlers(struct pci_dev *pdev)
|
||||
int vpci_assign_device(struct pci_dev *pdev)
|
||||
{
|
||||
unsigned int i;
|
||||
const unsigned long *ro_map;
|
||||
@@ -107,7 +107,7 @@ int vpci_add_handlers(struct pci_dev *pdev)
|
||||
}
|
||||
|
||||
if ( rc )
|
||||
vpci_remove_device(pdev);
|
||||
vpci_deassign_device(pdev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ typedef int vpci_register_init_t(struct pci_dev *dev);
|
||||
static vpci_register_init_t *const x##_entry \
|
||||
__used_section(".data.vpci." p) = x
|
||||
|
||||
/* Add vPCI handlers to device. */
|
||||
int __must_check vpci_add_handlers(struct pci_dev *pdev);
|
||||
/* Assign vPCI to device by adding handlers. */
|
||||
int __must_check vpci_assign_device(struct pci_dev *pdev);
|
||||
|
||||
/* Remove all handlers and free vpci related structures. */
|
||||
void vpci_remove_device(struct pci_dev *pdev);
|
||||
void vpci_deassign_device(struct pci_dev *pdev);
|
||||
|
||||
/* Add/remove a register handler. */
|
||||
int __must_check vpci_add_register_mask(struct vpci *vpci,
|
||||
@@ -255,12 +255,12 @@ bool vpci_ecam_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int len,
|
||||
#else /* !CONFIG_HAS_VPCI */
|
||||
struct vpci_vcpu {};
|
||||
|
||||
static inline int vpci_add_handlers(struct pci_dev *pdev)
|
||||
static inline int vpci_assign_device(struct pci_dev *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void vpci_remove_device(struct pci_dev *pdev) { }
|
||||
static inline void vpci_deassign_device(struct pci_dev *pdev) { }
|
||||
|
||||
static inline void vpci_dump_msi(void) { }
|
||||
|
||||
|
||||