summaryrefslogtreecommitdiff
path: root/5f046cca-x86-IOMMU-introduce-cache-sync-hook.patch
diff options
context:
space:
mode:
Diffstat (limited to '5f046cca-x86-IOMMU-introduce-cache-sync-hook.patch')
-rw-r--r--5f046cca-x86-IOMMU-introduce-cache-sync-hook.patch86
1 files changed, 86 insertions, 0 deletions
diff --git a/5f046cca-x86-IOMMU-introduce-cache-sync-hook.patch b/5f046cca-x86-IOMMU-introduce-cache-sync-hook.patch
new file mode 100644
index 0000000..f2ad08f
--- /dev/null
+++ b/5f046cca-x86-IOMMU-introduce-cache-sync-hook.patch
@@ -0,0 +1,86 @@
+# Commit 91526b460e5009fc56edbd6809e66c327281faba
+# Date 2020-07-07 14:38:34 +0200
+# Author Roger Pau Monné <roger.pau@citrix.com>
+# Committer Jan Beulich <jbeulich@suse.com>
+x86/iommu: introduce a cache sync hook
+
+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>
+
+--- a/xen/drivers/passthrough/vtd/extern.h
++++ b/xen/drivers/passthrough/vtd/extern.h
+@@ -43,7 +43,6 @@ void disable_qinval(struct vtd_iommu *io
+ 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);
+
+--- a/xen/drivers/passthrough/vtd/iommu.c
++++ b/xen/drivers/passthrough/vtd/iommu.c
+@@ -141,7 +141,7 @@ static int context_get_domain_id(struct
+
+ 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;
+@@ -174,7 +174,7 @@ uint64_t alloc_pgtable_maddr(unsigned lo
+ 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++;
+ }
+@@ -2763,6 +2763,7 @@ const struct iommu_ops __initconstrel in
+ .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 = {
+--- a/xen/include/asm-x86/iommu.h
++++ b/xen/include/asm-x86/iommu.h
+@@ -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:
+--- a/xen/include/xen/iommu.h
++++ b/xen/include/xen/iommu.h
+@@ -250,6 +250,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);