Message ID | 70029e8904170c4f19d9f521847050cd00c6e39d.1603731279.git.rahul.singh@arm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | xen/arm: Make PCI passthrough code non-x86 specific | expand |
On Mon, 26 Oct 2020, Rahul Singh wrote: > passthrough/pci.c file is common for all architecture, but there is x86 > sepcific code in this file. ^ specific > Move x86 specific code to the x86 directory to avoid compilation error > for other architecture. > > No functional change. > > Signed-off-by: Rahul Singh <rahul.singh@arm.com> > --- > xen/drivers/passthrough/pci.c | 75 +-------------------- > xen/drivers/passthrough/x86/Makefile | 1 + > xen/drivers/passthrough/x86/iommu.c | 7 ++ > xen/drivers/passthrough/x86/pci.c | 97 ++++++++++++++++++++++++++++ > xen/include/xen/pci.h | 2 + > 5 files changed, 108 insertions(+), 74 deletions(-) > create mode 100644 xen/drivers/passthrough/x86/pci.c > > diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c > index 2a3bce1462..c6fbb7172c 100644 > --- a/xen/drivers/passthrough/pci.c > +++ b/xen/drivers/passthrough/pci.c > @@ -24,7 +24,6 @@ > #include <xen/irq.h> > #include <xen/param.h> > #include <xen/vm_event.h> > -#include <asm/hvm/irq.h> > #include <xen/delay.h> > #include <xen/keyhandler.h> > #include <xen/event.h> sched.h is not needed anymore among the #include > @@ -847,71 +846,6 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn) > return ret; > } > > -static int pci_clean_dpci_irq(struct domain *d, > - struct hvm_pirq_dpci *pirq_dpci, void *arg) > -{ > - struct dev_intx_gsi_link *digl, *tmp; > - > - pirq_guest_unbind(d, dpci_pirq(pirq_dpci)); > - > - if ( pt_irq_need_timer(pirq_dpci->flags) ) > - kill_timer(&pirq_dpci->timer); > - > - list_for_each_entry_safe ( digl, tmp, &pirq_dpci->digl_list, list ) > - { > - list_del(&digl->list); > - xfree(digl); > - } > - > - radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq); > - > - if ( !pt_pirq_softirq_active(pirq_dpci) ) > - return 0; > - > - domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci; > - > - return -ERESTART; > -} > - > -static int pci_clean_dpci_irqs(struct domain *d) > -{ > - struct hvm_irq_dpci *hvm_irq_dpci = NULL; > - > - if ( !is_iommu_enabled(d) ) > - return 0; > - > - if ( !is_hvm_domain(d) ) > - return 0; > - > - spin_lock(&d->event_lock); > - hvm_irq_dpci = domain_get_irq_dpci(d); > - if ( hvm_irq_dpci != NULL ) > - { > - int ret = 0; > - > - if ( hvm_irq_dpci->pending_pirq_dpci ) > - { > - if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) ) > - ret = -ERESTART; > - else > - hvm_irq_dpci->pending_pirq_dpci = NULL; > - } > - > - if ( !ret ) > - ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); > - if ( ret ) > - { > - spin_unlock(&d->event_lock); > - return ret; > - } > - > - hvm_domain_irq(d)->dpci = NULL; > - free_hvm_irq_dpci(hvm_irq_dpci); > - } > - spin_unlock(&d->event_lock); > - return 0; > -} > - > /* Caller should hold the pcidevs_lock */ > static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus, > uint8_t devfn) > @@ -971,7 +905,7 @@ int pci_release_devices(struct domain *d) > int ret; > > pcidevs_lock(); > - ret = pci_clean_dpci_irqs(d); > + ret = arch_pci_release_devices(d); > if ( ret ) > { > pcidevs_unlock(); > @@ -1375,13 +1309,6 @@ static int __init setup_dump_pcidevs(void) > } > __initcall(setup_dump_pcidevs); > > -int iommu_update_ire_from_msi( > - struct msi_desc *msi_desc, struct msi_msg *msg) > -{ > - return iommu_intremap > - ? iommu_call(&iommu_ops, update_ire_from_msi, msi_desc, msg) : 0; > -} > - > static int iommu_add_device(struct pci_dev *pdev) > { > const struct domain_iommu *hd; > diff --git a/xen/drivers/passthrough/x86/Makefile b/xen/drivers/passthrough/x86/Makefile > index 05e6f51f25..642f673ed2 100644 > --- a/xen/drivers/passthrough/x86/Makefile > +++ b/xen/drivers/passthrough/x86/Makefile > @@ -1,2 +1,3 @@ > obj-$(CONFIG_HAS_PCI_ATS) += ats.o > obj-y += iommu.o > +obj-y += pci.o > diff --git a/xen/drivers/passthrough/x86/iommu.c b/xen/drivers/passthrough/x86/iommu.c > index f17b1820f4..875e67b53b 100644 > --- a/xen/drivers/passthrough/x86/iommu.c > +++ b/xen/drivers/passthrough/x86/iommu.c > @@ -308,6 +308,13 @@ struct page_info *iommu_alloc_pgtable(struct domain *d) > return pg; > } > > +int iommu_update_ire_from_msi( > + struct msi_desc *msi_desc, struct msi_msg *msg) > +{ > + return iommu_intremap > + ? iommu_call(&iommu_ops, update_ire_from_msi, msi_desc, msg) : 0; > +} > + > /* > * Local variables: > * mode: C > diff --git a/xen/drivers/passthrough/x86/pci.c b/xen/drivers/passthrough/x86/pci.c > new file mode 100644 > index 0000000000..443712aa22 > --- /dev/null > +++ b/xen/drivers/passthrough/x86/pci.c > @@ -0,0 +1,97 @@ > +/* > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along with > + * this program; If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <xen/param.h> not needed > +#include <xen/sched.h> > +#include <xen/pci.h> > +#include <xen/pci_regs.h> not needed > +static int pci_clean_dpci_irq(struct domain *d, > + struct hvm_pirq_dpci *pirq_dpci, void *arg) > +{ > + struct dev_intx_gsi_link *digl, *tmp; > + > + pirq_guest_unbind(d, dpci_pirq(pirq_dpci)); > + > + if ( pt_irq_need_timer(pirq_dpci->flags) ) > + kill_timer(&pirq_dpci->timer); > + > + list_for_each_entry_safe ( digl, tmp, &pirq_dpci->digl_list, list ) > + { > + list_del(&digl->list); > + xfree(digl); > + } > + > + radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq); > + > + if ( !pt_pirq_softirq_active(pirq_dpci) ) > + return 0; > + > + domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci; > + > + return -ERESTART; > +} > + > +static int pci_clean_dpci_irqs(struct domain *d) > +{ > + struct hvm_irq_dpci *hvm_irq_dpci = NULL; > + > + if ( !is_iommu_enabled(d) ) > + return 0; > + > + if ( !is_hvm_domain(d) ) > + return 0; > + > + spin_lock(&d->event_lock); > + hvm_irq_dpci = domain_get_irq_dpci(d); > + if ( hvm_irq_dpci != NULL ) > + { > + int ret = 0; > + > + if ( hvm_irq_dpci->pending_pirq_dpci ) > + { > + if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) ) > + ret = -ERESTART; > + else > + hvm_irq_dpci->pending_pirq_dpci = NULL; > + } > + > + if ( !ret ) > + ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); > + if ( ret ) > + { > + spin_unlock(&d->event_lock); > + return ret; > + } > + > + hvm_domain_irq(d)->dpci = NULL; > + free_hvm_irq_dpci(hvm_irq_dpci); > + } > + spin_unlock(&d->event_lock); > + return 0; > +} > + > +int arch_pci_release_devices(struct domain *d) > +{ > + return pci_clean_dpci_irqs(d); > +} > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h > index 2bc4aaf453..13ae7cc2a5 100644 > --- a/xen/include/xen/pci.h > +++ b/xen/include/xen/pci.h > @@ -212,4 +212,6 @@ int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable); > void msixtbl_pt_unregister(struct domain *, struct pirq *); > void msixtbl_pt_cleanup(struct domain *d); > > +int arch_pci_release_devices(struct domain *d); > + > #endif /* __XEN_PCI_H__ */
On 26.10.2020 18:17, Rahul Singh wrote: > passthrough/pci.c file is common for all architecture, but there is x86 > sepcific code in this file. The code you move doesn't look to be x86 specific in the sense that it makes no sense on other architectures, but just because certain pieces are missing on Arm. With this I question whether is it really appropriate to move this code. I do realize that in similar earlier cases my questioning was mostly ignored ... > --- /dev/null > +++ b/xen/drivers/passthrough/x86/pci.c > @@ -0,0 +1,97 @@ > +/* > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along with > + * this program; If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <xen/param.h> > +#include <xen/sched.h> > +#include <xen/pci.h> > +#include <xen/pci_regs.h> > + > +static int pci_clean_dpci_irq(struct domain *d, > + struct hvm_pirq_dpci *pirq_dpci, void *arg) > +{ > + struct dev_intx_gsi_link *digl, *tmp; > + > + pirq_guest_unbind(d, dpci_pirq(pirq_dpci)); > + > + if ( pt_irq_need_timer(pirq_dpci->flags) ) > + kill_timer(&pirq_dpci->timer); > + > + list_for_each_entry_safe ( digl, tmp, &pirq_dpci->digl_list, list ) > + { > + list_del(&digl->list); > + xfree(digl); > + } > + > + radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq); > + > + if ( !pt_pirq_softirq_active(pirq_dpci) ) > + return 0; > + > + domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci; > + > + return -ERESTART; > +} > + > +static int pci_clean_dpci_irqs(struct domain *d) > +{ > + struct hvm_irq_dpci *hvm_irq_dpci = NULL; > + > + if ( !is_iommu_enabled(d) ) > + return 0; > + > + if ( !is_hvm_domain(d) ) > + return 0; > + > + spin_lock(&d->event_lock); > + hvm_irq_dpci = domain_get_irq_dpci(d); > + if ( hvm_irq_dpci != NULL ) > + { > + int ret = 0; > + > + if ( hvm_irq_dpci->pending_pirq_dpci ) > + { > + if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) ) > + ret = -ERESTART; > + else > + hvm_irq_dpci->pending_pirq_dpci = NULL; > + } > + > + if ( !ret ) > + ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); > + if ( ret ) > + { > + spin_unlock(&d->event_lock); > + return ret; > + } > + > + hvm_domain_irq(d)->dpci = NULL; > + free_hvm_irq_dpci(hvm_irq_dpci); > + } > + spin_unlock(&d->event_lock); > + return 0; While moving please add the missing blank line before the main return statement of the function. > +} > + > +int arch_pci_release_devices(struct domain *d) > +{ > + return pci_clean_dpci_irqs(d); > +} Why the extra function layer? Jan
On 28/10/2020 11:51, Jan Beulich wrote: > On 26.10.2020 18:17, Rahul Singh wrote: >> passthrough/pci.c file is common for all architecture, but there is x86 >> sepcific code in this file. > > The code you move doesn't look to be x86 specific in the sense that > it makes no sense on other architectures, but just because certain > pieces are missing on Arm. With this I question whether is it really > appropriate to move this code. I do realize that in similar earlier > cases my questioning was mostly ignored ... There are no plan to get support for PIRQ on Arm. All the interrupts will be properly sent to the guest using a virtual interrupt controller. Regarding the code itself, there are still a few bits that are x86 specific (see struct dev_intx_gsi_link). So I think the right action for now is to move the code to an x86 directory. This can be adjusted in the future if there is another architecture that would require to use PIRQ. Cheers,
Hello Jan, > On 28 Oct 2020, at 11:51 am, Jan Beulich <jbeulich@suse.com> wrote: > > On 26.10.2020 18:17, Rahul Singh wrote: >> passthrough/pci.c file is common for all architecture, but there is x86 >> sepcific code in this file. > > The code you move doesn't look to be x86 specific in the sense that > it makes no sense on other architectures, but just because certain > pieces are missing on Arm. With this I question whether is it really > appropriate to move this code. I do realize that in similar earlier > cases my questioning was mostly ignored ... > >> --- /dev/null >> +++ b/xen/drivers/passthrough/x86/pci.c >> @@ -0,0 +1,97 @@ >> +/* >> + * This program is free software; you can redistribute it and/or modify it >> + * under the terms and conditions of the GNU General Public License, >> + * version 2, as published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope it will be useful, but WITHOUT >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for >> + * more details. >> + * >> + * You should have received a copy of the GNU General Public License along with >> + * this program; If not, see <http://www.gnu.org/licenses/>. >> + */ >> + >> +#include <xen/param.h> >> +#include <xen/sched.h> >> +#include <xen/pci.h> >> +#include <xen/pci_regs.h> >> + >> +static int pci_clean_dpci_irq(struct domain *d, >> + struct hvm_pirq_dpci *pirq_dpci, void *arg) >> +{ >> + struct dev_intx_gsi_link *digl, *tmp; >> + >> + pirq_guest_unbind(d, dpci_pirq(pirq_dpci)); >> + >> + if ( pt_irq_need_timer(pirq_dpci->flags) ) >> + kill_timer(&pirq_dpci->timer); >> + >> + list_for_each_entry_safe ( digl, tmp, &pirq_dpci->digl_list, list ) >> + { >> + list_del(&digl->list); >> + xfree(digl); >> + } >> + >> + radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq); >> + >> + if ( !pt_pirq_softirq_active(pirq_dpci) ) >> + return 0; >> + >> + domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci; >> + >> + return -ERESTART; >> +} >> + >> +static int pci_clean_dpci_irqs(struct domain *d) >> +{ >> + struct hvm_irq_dpci *hvm_irq_dpci = NULL; >> + >> + if ( !is_iommu_enabled(d) ) >> + return 0; >> + >> + if ( !is_hvm_domain(d) ) >> + return 0; >> + >> + spin_lock(&d->event_lock); >> + hvm_irq_dpci = domain_get_irq_dpci(d); >> + if ( hvm_irq_dpci != NULL ) >> + { >> + int ret = 0; >> + >> + if ( hvm_irq_dpci->pending_pirq_dpci ) >> + { >> + if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) ) >> + ret = -ERESTART; >> + else >> + hvm_irq_dpci->pending_pirq_dpci = NULL; >> + } >> + >> + if ( !ret ) >> + ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); >> + if ( ret ) >> + { >> + spin_unlock(&d->event_lock); >> + return ret; >> + } >> + >> + hvm_domain_irq(d)->dpci = NULL; >> + free_hvm_irq_dpci(hvm_irq_dpci); >> + } >> + spin_unlock(&d->event_lock); >> + return 0; > > While moving please add the missing blank line before the main > return statement of the function. Ok I will fix that in next version. > >> +} >> + >> +int arch_pci_release_devices(struct domain *d) >> +{ >> + return pci_clean_dpci_irqs(d); >> +} > > Why the extra function layer? Is that ok if I rename the function pci_clean_dpci_irqs() to arch_pci_clean_pirqs() ? > > Jan > Regards, Rahul
On 28.10.2020 16:20, Rahul Singh wrote: >> On 28 Oct 2020, at 11:51 am, Jan Beulich <jbeulich@suse.com> wrote: >> On 26.10.2020 18:17, Rahul Singh wrote: >>> +int arch_pci_release_devices(struct domain *d) >>> +{ >>> + return pci_clean_dpci_irqs(d); >>> +} >> >> Why the extra function layer? > > Is that ok if I rename the function pci_clean_dpci_irqs() to arch_pci_clean_pirqs() ? I see no problem with you doing so. Jan
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 2a3bce1462..c6fbb7172c 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -24,7 +24,6 @@ #include <xen/irq.h> #include <xen/param.h> #include <xen/vm_event.h> -#include <asm/hvm/irq.h> #include <xen/delay.h> #include <xen/keyhandler.h> #include <xen/event.h> @@ -847,71 +846,6 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn) return ret; } -static int pci_clean_dpci_irq(struct domain *d, - struct hvm_pirq_dpci *pirq_dpci, void *arg) -{ - struct dev_intx_gsi_link *digl, *tmp; - - pirq_guest_unbind(d, dpci_pirq(pirq_dpci)); - - if ( pt_irq_need_timer(pirq_dpci->flags) ) - kill_timer(&pirq_dpci->timer); - - list_for_each_entry_safe ( digl, tmp, &pirq_dpci->digl_list, list ) - { - list_del(&digl->list); - xfree(digl); - } - - radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq); - - if ( !pt_pirq_softirq_active(pirq_dpci) ) - return 0; - - domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci; - - return -ERESTART; -} - -static int pci_clean_dpci_irqs(struct domain *d) -{ - struct hvm_irq_dpci *hvm_irq_dpci = NULL; - - if ( !is_iommu_enabled(d) ) - return 0; - - if ( !is_hvm_domain(d) ) - return 0; - - spin_lock(&d->event_lock); - hvm_irq_dpci = domain_get_irq_dpci(d); - if ( hvm_irq_dpci != NULL ) - { - int ret = 0; - - if ( hvm_irq_dpci->pending_pirq_dpci ) - { - if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) ) - ret = -ERESTART; - else - hvm_irq_dpci->pending_pirq_dpci = NULL; - } - - if ( !ret ) - ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); - if ( ret ) - { - spin_unlock(&d->event_lock); - return ret; - } - - hvm_domain_irq(d)->dpci = NULL; - free_hvm_irq_dpci(hvm_irq_dpci); - } - spin_unlock(&d->event_lock); - return 0; -} - /* Caller should hold the pcidevs_lock */ static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus, uint8_t devfn) @@ -971,7 +905,7 @@ int pci_release_devices(struct domain *d) int ret; pcidevs_lock(); - ret = pci_clean_dpci_irqs(d); + ret = arch_pci_release_devices(d); if ( ret ) { pcidevs_unlock(); @@ -1375,13 +1309,6 @@ static int __init setup_dump_pcidevs(void) } __initcall(setup_dump_pcidevs); -int iommu_update_ire_from_msi( - struct msi_desc *msi_desc, struct msi_msg *msg) -{ - return iommu_intremap - ? iommu_call(&iommu_ops, update_ire_from_msi, msi_desc, msg) : 0; -} - static int iommu_add_device(struct pci_dev *pdev) { const struct domain_iommu *hd; diff --git a/xen/drivers/passthrough/x86/Makefile b/xen/drivers/passthrough/x86/Makefile index 05e6f51f25..642f673ed2 100644 --- a/xen/drivers/passthrough/x86/Makefile +++ b/xen/drivers/passthrough/x86/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_HAS_PCI_ATS) += ats.o obj-y += iommu.o +obj-y += pci.o diff --git a/xen/drivers/passthrough/x86/iommu.c b/xen/drivers/passthrough/x86/iommu.c index f17b1820f4..875e67b53b 100644 --- a/xen/drivers/passthrough/x86/iommu.c +++ b/xen/drivers/passthrough/x86/iommu.c @@ -308,6 +308,13 @@ struct page_info *iommu_alloc_pgtable(struct domain *d) return pg; } +int iommu_update_ire_from_msi( + struct msi_desc *msi_desc, struct msi_msg *msg) +{ + return iommu_intremap + ? iommu_call(&iommu_ops, update_ire_from_msi, msi_desc, msg) : 0; +} + /* * Local variables: * mode: C diff --git a/xen/drivers/passthrough/x86/pci.c b/xen/drivers/passthrough/x86/pci.c new file mode 100644 index 0000000000..443712aa22 --- /dev/null +++ b/xen/drivers/passthrough/x86/pci.c @@ -0,0 +1,97 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; If not, see <http://www.gnu.org/licenses/>. + */ + +#include <xen/param.h> +#include <xen/sched.h> +#include <xen/pci.h> +#include <xen/pci_regs.h> + +static int pci_clean_dpci_irq(struct domain *d, + struct hvm_pirq_dpci *pirq_dpci, void *arg) +{ + struct dev_intx_gsi_link *digl, *tmp; + + pirq_guest_unbind(d, dpci_pirq(pirq_dpci)); + + if ( pt_irq_need_timer(pirq_dpci->flags) ) + kill_timer(&pirq_dpci->timer); + + list_for_each_entry_safe ( digl, tmp, &pirq_dpci->digl_list, list ) + { + list_del(&digl->list); + xfree(digl); + } + + radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq); + + if ( !pt_pirq_softirq_active(pirq_dpci) ) + return 0; + + domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci; + + return -ERESTART; +} + +static int pci_clean_dpci_irqs(struct domain *d) +{ + struct hvm_irq_dpci *hvm_irq_dpci = NULL; + + if ( !is_iommu_enabled(d) ) + return 0; + + if ( !is_hvm_domain(d) ) + return 0; + + spin_lock(&d->event_lock); + hvm_irq_dpci = domain_get_irq_dpci(d); + if ( hvm_irq_dpci != NULL ) + { + int ret = 0; + + if ( hvm_irq_dpci->pending_pirq_dpci ) + { + if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) ) + ret = -ERESTART; + else + hvm_irq_dpci->pending_pirq_dpci = NULL; + } + + if ( !ret ) + ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); + if ( ret ) + { + spin_unlock(&d->event_lock); + return ret; + } + + hvm_domain_irq(d)->dpci = NULL; + free_hvm_irq_dpci(hvm_irq_dpci); + } + spin_unlock(&d->event_lock); + return 0; +} + +int arch_pci_release_devices(struct domain *d) +{ + return pci_clean_dpci_irqs(d); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index 2bc4aaf453..13ae7cc2a5 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -212,4 +212,6 @@ int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable); void msixtbl_pt_unregister(struct domain *, struct pirq *); void msixtbl_pt_cleanup(struct domain *d); +int arch_pci_release_devices(struct domain *d); + #endif /* __XEN_PCI_H__ */
passthrough/pci.c file is common for all architecture, but there is x86 sepcific code in this file. Move x86 specific code to the x86 directory to avoid compilation error for other architecture. No functional change. Signed-off-by: Rahul Singh <rahul.singh@arm.com> --- xen/drivers/passthrough/pci.c | 75 +-------------------- xen/drivers/passthrough/x86/Makefile | 1 + xen/drivers/passthrough/x86/iommu.c | 7 ++ xen/drivers/passthrough/x86/pci.c | 97 ++++++++++++++++++++++++++++ xen/include/xen/pci.h | 2 + 5 files changed, 108 insertions(+), 74 deletions(-) create mode 100644 xen/drivers/passthrough/x86/pci.c