diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index cd6174d..9c62861 100644 --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -301,6 +301,26 @@ int iommu_unmap_page(struct domain *d, unsigned long gfn) return hd->platform_ops->unmap_page(d, gfn); } +void iommu_iotlb_flush(struct domain *d, unsigned long gfn, unsigned int page_count) +{ + struct hvm_iommu *hd = domain_hvm_iommu(d); + + if ( !iommu_enabled || !hd->platform_ops || !hd->platform_ops->iotlb_flush ) + return; + + hd->platform_ops->iotlb_flush(d, gfn, page_count); +} + +void iommu_iotlb_flush_all(struct domain *d) +{ + struct hvm_iommu *hd = domain_hvm_iommu(d); + + if ( !iommu_enabled || !hd->platform_ops ) + return; + + hd->platform_ops->iotlb_flush_all(d); +} + /* caller should hold the pcidevs_lock */ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn) { diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 5a5b6be..7ec9541 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -619,6 +619,16 @@ static void __intel_iommu_iotlb_flush(struct domain *d, unsigned long gfn, } } +static void intel_iommu_iotlb_flush(struct domain *d, unsigned long gfn, unsigned int page_count) +{ + __intel_iommu_iotlb_flush(d, gfn, 1, page_count); +} + +static void intel_iommu_iotlb_flush_all(struct domain *d) +{ + __intel_iommu_iotlb_flush(d, 0, 0, 0); +} + /* clear one page's page table */ static void dma_pte_clear_one(struct domain *domain, u64 addr) { @@ -2329,6 +2339,8 @@ const struct iommu_ops intel_iommu_ops = { .resume = vtd_resume, .share_p2m = iommu_set_pgd, .crash_shutdown = vtd_crash_shutdown, + .iotlb_flush = intel_iommu_iotlb_flush, + .iotlb_flush_all = intel_iommu_iotlb_flush_all, }; /* diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index 837e60d..a1034df 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -139,6 +139,8 @@ struct iommu_ops { void (*resume)(void); void (*share_p2m)(struct domain *d); void (*crash_shutdown)(void); + void (*iotlb_flush)(struct domain *d, unsigned long gfn, unsigned int page_count); + void (*iotlb_flush_all)(struct domain *d); }; void iommu_update_ire_from_apic(unsigned int apic, unsigned int reg, unsigned int value); @@ -155,4 +157,7 @@ void iommu_share_p2m_table(struct domain *d); int iommu_do_domctl(struct xen_domctl *, XEN_GUEST_HANDLE(xen_domctl_t)); +void iommu_iotlb_flush(struct domain *d, unsigned long gfn, unsigned int page_count); +void iommu_iotlb_flush_all(struct domain *d); + #endif /* _IOMMU_H_ */