]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
x86/iommu: introduce a cache sync hook
authorRoger Pau Monné <roger.pau@citrix.com>
Tue, 7 Jul 2020 12:38:34 +0000 (14:38 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 7 Jul 2020 12:38:34 +0000 (14:38 +0200)
The hook is only implemented for VT-d and it uses the already existing
iommu_sync_cache function present in VT-d code. The new hook is
added so that the cache can be flushed by code outside of VT-d when
using shared page tables.

Note that alloc_pgtable_maddr must use the now locally defined
sync_cache function, because IOMMU ops are not yet setup the first
time the function gets called during IOMMU initialization.

No functional change intended.

This is part of XSA-321.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/drivers/passthrough/vtd/extern.h
xen/drivers/passthrough/vtd/iommu.c
xen/include/asm-x86/iommu.h
xen/include/xen/iommu.h

index 52b5e1c60d078ec88739459f7b89f4ed3dc78108..f15947af1ff4d7d368ebc9965ee419bf5f77feb8 100644 (file)
@@ -43,7 +43,6 @@ void disable_qinval(struct vtd_iommu *iommu);
 int enable_intremap(struct vtd_iommu *iommu, int eim);
 void disable_intremap(struct vtd_iommu *iommu);
 
-void iommu_sync_cache(const void *addr, unsigned int size);
 int iommu_alloc(struct acpi_drhd_unit *drhd);
 void iommu_free(struct acpi_drhd_unit *drhd);
 
index 55eb140033b70a8b789e64571caecb1eaae27b37..93bcd72f848d502d253e0b7b419abb4ffd8fb892 100644 (file)
@@ -147,7 +147,7 @@ static int context_get_domain_id(struct context_entry *context,
 
 static int iommus_incoherent;
 
-void iommu_sync_cache(const void *addr, unsigned int size)
+static void sync_cache(const void *addr, unsigned int size)
 {
     int i;
     static unsigned int clflush_size = 0;
@@ -180,7 +180,7 @@ uint64_t alloc_pgtable_maddr(unsigned long npages, nodeid_t node)
         vaddr = __map_domain_page(cur_pg);
         memset(vaddr, 0, PAGE_SIZE);
 
-        iommu_sync_cache(vaddr, PAGE_SIZE);
+        sync_cache(vaddr, PAGE_SIZE);
         unmap_domain_page(vaddr);
         cur_pg++;
     }
@@ -2778,6 +2778,7 @@ const struct iommu_ops __initconstrel intel_iommu_ops = {
     .iotlb_flush_all = iommu_flush_iotlb_all,
     .get_reserved_device_memory = intel_iommu_get_reserved_device_memory,
     .dump_p2m_table = vtd_dump_p2m_table,
+    .sync_cache = sync_cache,
 };
 
 const struct iommu_init_ops __initconstrel intel_iommu_init_ops = {
index 85741f7c9647798887fa4602df62454c9e6e81c5..864e0250784a96a8aa85da527702b451f72bbcbf 100644 (file)
@@ -121,6 +121,13 @@ extern bool untrusted_msi;
 int pi_update_irte(const struct pi_desc *pi_desc, const struct pirq *pirq,
                    const uint8_t gvec);
 
+#define iommu_sync_cache(addr, size) ({                 \
+    const struct iommu_ops *ops = iommu_get_ops();      \
+                                                        \
+    if ( ops->sync_cache )                              \
+        iommu_vcall(ops, sync_cache, addr, size);       \
+})
+
 #endif /* !__ARCH_X86_IOMMU_H__ */
 /*
  * Local variables:
index 6264d3d07f3ac3c253e6893ac116033e1268a365..32728749580ec87230caa03f92a99525189a1e3a 100644 (file)
@@ -275,6 +275,7 @@ struct iommu_ops {
     int (*setup_hpet_msi)(struct msi_desc *);
 
     int (*adjust_irq_affinities)(void);
+    void (*sync_cache)(const void *addr, unsigned int size);
 #endif /* CONFIG_X86 */
 
     int __must_check (*suspend)(void);