From bf3292ca31ef4eedd6aa070b04321178a60e4b8f Mon Sep 17 00:00:00 2001 From: Jean Guyader Date: Fri, 18 Nov 2011 13:40:56 +0000 Subject: [PATCH] iommu: Introduce iommu_flush and iommu_flush_all. Signed-off-by: Jean Guyader Committed-by: Keir Fraser --- xen/drivers/passthrough/iommu.c | 20 ++++++++++++++++++++ xen/drivers/passthrough/vtd/iommu.c | 12 ++++++++++++ xen/include/xen/iommu.h | 5 +++++ 3 files changed, 37 insertions(+) diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index cd6174df17..ca7b37b6c6 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 || !hd->platform_ops->iotlb_flush_all ) + 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 9cf91b0931..73ebeb57f0 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -622,6 +622,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) { @@ -2343,6 +2353,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 a905a47d5b..82d4cc4605 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -143,6 +143,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); @@ -159,4 +161,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_ */ -- 2.30.2