Message ID | 20231202012556.2012281-6-volodymyr_babchuk@epam.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | PCI devices passthrough on Arm, part 3 | expand |
On Sat, Dec 02, 2023 at 01:27:03AM +0000, Volodymyr Babchuk wrote: > From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> > > 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> > diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h > index d743d96a10..75cfb532ee 100644 > --- a/xen/include/xen/vpci.h > +++ b/xen/include/xen/vpci.h > @@ -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 to device. */ Nit: the comment would likely benefit from removing the last device before the full stop. > +int __must_check vpci_assign_device(struct pci_dev *pdev); Thanks, Roger.
On 02.12.2023 02:27, Volodymyr Babchuk wrote: > @@ -886,6 +890,10 @@ static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus, > > pdev->fault.count = 0; > > + write_lock(&target->pci_lock); > + ret = vpci_assign_device(pdev); > + write_unlock(&target->pci_lock); > + > out: > if ( ret ) > printk(XENLOG_G_ERR "%pd: deassign (%pp) failed (%d)\n", Considering the function we're in, I think this "assign" deserves a comment. It's necessary for hwdom only aiui, i.e. particularly not for the more typical case of putting the device in quarantine? Jan
On 12/22/23 03:52, Jan Beulich wrote: > On 02.12.2023 02:27, Volodymyr Babchuk wrote: >> @@ -886,6 +890,10 @@ static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus, >> >> pdev->fault.count = 0; >> >> + write_lock(&target->pci_lock); >> + ret = vpci_assign_device(pdev); >> + write_unlock(&target->pci_lock); >> + >> out: >> if ( ret ) >> printk(XENLOG_G_ERR "%pd: deassign (%pp) failed (%d)\n", > > Considering the function we're in, I think this "assign" deserves a comment. OK, we will add a comment along the lines of: /* Re-assign back to hardware_domain */ > It's necessary for hwdom only aiui, i.e. particularly not for the more > typical case of putting the device in quarantine? Right, since dom_io doesn't have vPCI > > Jan
On 12/21/23 10:21, Roger Pau Monné wrote: > On Sat, Dec 02, 2023 at 01:27:03AM +0000, Volodymyr Babchuk wrote: >> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> >> >> 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> Thanks! > >> diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h >> index d743d96a10..75cfb532ee 100644 >> --- a/xen/include/xen/vpci.h >> +++ b/xen/include/xen/vpci.h >> @@ -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 to device. */ > > Nit: the comment would likely benefit from removing the last device > before the full stop. Will fix > >> +int __must_check vpci_assign_device(struct pci_dev *pdev); > > Thanks, Roger.
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 182da45acb..a3312fdab2 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -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,10 @@ static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus, pdev->fault.count = 0; + write_lock(&target->pci_lock); + 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 +1154,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 +1484,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; @@ -1502,6 +1514,10 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag) pci_to_dev(pdev), flag); } + write_lock(&d->pci_lock); + rc = vpci_assign_device(pdev); + write_unlock(&d->pci_lock); + done: if ( rc ) printk(XENLOG_G_WARNING "%pd: assign (%pp) failed (%d)\n", diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index c86d33d0cd..ec6c93eef6 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -190,7 +190,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); } diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c index 4fec4b26d9..9dacbcf958 100644 --- a/xen/drivers/vpci/vpci.c +++ b/xen/drivers/vpci/vpci.c @@ -36,7 +36,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)); @@ -69,7 +69,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; @@ -103,7 +103,7 @@ int vpci_add_handlers(struct pci_dev *pdev) } if ( rc ) - vpci_remove_device(pdev); + vpci_deassign_device(pdev); return rc; } diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index d743d96a10..75cfb532ee 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -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 to device. */ +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(struct vpci *vpci, @@ -235,12 +235,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) { }