xen/arm,arm64: fix xen_dma_ops after 815dd18 "Consolidate get_dma_ops..."
authorStefano Stabellini <sstabellini@kernel.org>
Thu, 13 Apr 2017 21:04:21 +0000 (14:04 -0700)
committerJuergen Gross <jgross@suse.com>
Tue, 2 May 2017 09:14:42 +0000 (11:14 +0200)
The following commit:

  commit 815dd18788fe0d41899f51b91d0560279cf16b0d
  Author: Bart Van Assche <bart.vanassche@sandisk.com>
  Date:   Fri Jan 20 13:04:04 2017 -0800

      treewide: Consolidate get_dma_ops() implementations

rearranges get_dma_ops in a way that xen_dma_ops are not returned when
running on Xen anymore, dev->dma_ops is returned instead (see
arch/arm/include/asm/dma-mapping.h:get_arch_dma_ops and
include/linux/dma-mapping.h:get_dma_ops).

Fix the problem by storing dev->dma_ops in dev_archdata, and setting
dev->dma_ops to xen_dma_ops. This way, xen_dma_ops is returned naturally
by get_dma_ops. The Xen code can retrieve the original dev->dma_ops from
dev_archdata when needed. It also allows us to remove __generic_dma_ops
from common headers.

Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
Tested-by: Julien Grall <julien.grall@arm.com>
Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: <stable@vger.kernel.org> [4.11+]
CC: linux@armlinux.org.uk
CC: catalin.marinas@arm.com
CC: will.deacon@arm.com
CC: boris.ostrovsky@oracle.com
CC: jgross@suse.com
CC: Julien Grall <julien.grall@arm.com>
arch/arm/include/asm/device.h
arch/arm/include/asm/dma-mapping.h
arch/arm/mm/dma-mapping.c
arch/arm64/include/asm/device.h
arch/arm64/include/asm/dma-mapping.h
arch/arm64/mm/dma-mapping.c
include/xen/arm/page-coherent.h

index 220ba207be9130769d3effd8687b19722c32c9ca..36ec9c8f6e161d59d56caafbbe92fe0d2239d3f9 100644 (file)
@@ -15,6 +15,9 @@ struct dev_archdata {
 #endif
 #ifdef CONFIG_ARM_DMA_USE_IOMMU
        struct dma_iommu_mapping        *mapping;
+#endif
+#ifdef CONFIG_XEN
+       const struct dma_map_ops *dev_dma_ops;
 #endif
        bool dma_coherent;
 };
index 71665692597541538c1c04e4475b4d718191cbc3..680d3f3889e72887da6dbc5d0de551c9c8434d8f 100644 (file)
 extern const struct dma_map_ops arm_dma_ops;
 extern const struct dma_map_ops arm_coherent_dma_ops;
 
-static inline const struct dma_map_ops *__generic_dma_ops(struct device *dev)
-{
-       if (dev && dev->dma_ops)
-               return dev->dma_ops;
-       return &arm_dma_ops;
-}
-
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-       if (xen_initial_domain())
-               return xen_dma_ops;
-       else
-               return __generic_dma_ops(NULL);
+       return &arm_dma_ops;
 }
 
 #define HAVE_ARCH_DMA_SUPPORTED 1
index 475811f5383afc40d5e00ab15e03fca6d88d8866..0268584f1fa0a73a8fcef7ffadf5194f23dfe308 100644 (file)
@@ -2414,6 +2414,13 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
                dma_ops = arm_get_dma_map_ops(coherent);
 
        set_dma_ops(dev, dma_ops);
+
+#ifdef CONFIG_XEN
+       if (xen_initial_domain()) {
+               dev->archdata.dev_dma_ops = dev->dma_ops;
+               dev->dma_ops = xen_dma_ops;
+       }
+#endif
 }
 
 void arch_teardown_dma_ops(struct device *dev)
index 73d5bab015ebb3c702daaf80d7f31bc1292b4eb4..5a5fa47a6b18bbd5b29f6dde5fb9201a524ddc2e 100644 (file)
@@ -19,6 +19,9 @@
 struct dev_archdata {
 #ifdef CONFIG_IOMMU_API
        void *iommu;                    /* private IOMMU data */
+#endif
+#ifdef CONFIG_XEN
+       const struct dma_map_ops *dev_dma_ops;
 #endif
        bool dma_coherent;
 };
index 505756cdc67a1deba4ff49491392f95a8290af57..5392dbeffa455ec75043e6dc9067528fa8ae1ea0 100644 (file)
 #define DMA_ERROR_CODE (~(dma_addr_t)0)
 extern const struct dma_map_ops dummy_dma_ops;
 
-static inline const struct dma_map_ops *__generic_dma_ops(struct device *dev)
+static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-       if (dev && dev->dma_ops)
-               return dev->dma_ops;
-
        /*
         * We expect no ISA devices, and all other DMA masters are expected to
         * have someone call arch_setup_dma_ops at device creation time.
@@ -39,14 +36,6 @@ static inline const struct dma_map_ops *__generic_dma_ops(struct device *dev)
        return &dummy_dma_ops;
 }
 
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-       if (xen_initial_domain())
-               return xen_dma_ops;
-       else
-               return __generic_dma_ops(NULL);
-}
-
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
                        const struct iommu_ops *iommu, bool coherent);
 #define arch_setup_dma_ops     arch_setup_dma_ops
index 81cdb2e844ed9fe80e4192315647ccc9245b8003..7f8b37e85a2bdba0c633473e8be1c8f3cb04c96b 100644 (file)
@@ -977,4 +977,11 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 
        dev->archdata.dma_coherent = coherent;
        __iommu_setup_dma_ops(dev, dma_base, size, iommu);
+
+#ifdef CONFIG_XEN
+       if (xen_initial_domain()) {
+               dev->archdata.dev_dma_ops = dev->dma_ops;
+               dev->dma_ops = xen_dma_ops;
+       }
+#endif
 }
index 95ce6ac3a971fb1425d2dc841466defdc850bf9c..b0a2bfc8d64713abcdd1ce475becf44637e8a961 100644 (file)
@@ -2,8 +2,16 @@
 #define _ASM_ARM_XEN_PAGE_COHERENT_H
 
 #include <asm/page.h>
+#include <asm/dma-mapping.h>
 #include <linux/dma-mapping.h>
 
+static inline const struct dma_map_ops *__generic_dma_ops(struct device *dev)
+{
+       if (dev && dev->archdata.dev_dma_ops)
+               return dev->archdata.dev_dma_ops;
+       return get_arch_dma_ops(NULL);
+}
+
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
             dma_addr_t dev_addr, unsigned long offset, size_t size,
             enum dma_data_direction dir, unsigned long attrs);