aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2016-06-17 03:54:23 -0400
committerInki Dae <daeinki@gmail.com>2016-07-13 10:06:04 -0400
commitf7c72773de88fa3d4b51d4eb2bd2a89b746aaf54 (patch)
tree05a40dbdf33237547e0d2703027533a65fc12ca7
parent5dd0775e502b26b44e5bcb5f504a977a565f2f3e (diff)
drm/exynos: iommu: move dma_params configuration code to separate functions
Move code for managing DMA max segment size parameter to separate functions. This patch also replaces devm_kzalloc() with kzalloc() and adds proper kfree call. devm_kzalloc() cannot be used for dma_params structure, because it will be freed on driver remove not on device release. This means in case of Exynos DRM being compiled as module and loaded 2 times, a user-after-free issue will happen. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_iommu.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index 7ca09ee19656..1e82529e0c41 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -21,6 +21,23 @@
21#include "exynos_drm_drv.h" 21#include "exynos_drm_drv.h"
22#include "exynos_drm_iommu.h" 22#include "exynos_drm_iommu.h"
23 23
24static inline int configure_dma_max_seg_size(struct device *dev)
25{
26 if (!dev->dma_parms)
27 dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL);
28 if (!dev->dma_parms)
29 return -ENOMEM;
30
31 dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
32 return 0;
33}
34
35static inline void clear_dma_max_seg_size(struct device *dev)
36{
37 kfree(dev->dma_parms);
38 dev->dma_parms = NULL;
39}
40
24/* 41/*
25 * drm_create_iommu_mapping - create a mapping structure 42 * drm_create_iommu_mapping - create a mapping structure
26 * 43 *
@@ -80,13 +97,10 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,
80 if (!priv->mapping) 97 if (!priv->mapping)
81 return 0; 98 return 0;
82 99
83 subdrv_dev->dma_parms = devm_kzalloc(subdrv_dev,
84 sizeof(*subdrv_dev->dma_parms),
85 GFP_KERNEL);
86 if (!subdrv_dev->dma_parms)
87 return -ENOMEM;
88 100
89 dma_set_max_seg_size(subdrv_dev, 0xffffffffu); 101 ret = configure_dma_max_seg_size(subdrv_dev);
102 if (ret)
103 return ret;
90 104
91 if (subdrv_dev->archdata.mapping) 105 if (subdrv_dev->archdata.mapping)
92 arm_iommu_detach_device(subdrv_dev); 106 arm_iommu_detach_device(subdrv_dev);
@@ -94,6 +108,7 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,
94 ret = arm_iommu_attach_device(subdrv_dev, priv->mapping); 108 ret = arm_iommu_attach_device(subdrv_dev, priv->mapping);
95 if (ret < 0) { 109 if (ret < 0) {
96 DRM_DEBUG_KMS("failed iommu attach.\n"); 110 DRM_DEBUG_KMS("failed iommu attach.\n");
111 clear_dma_max_seg_size(subdrv_dev);
97 return ret; 112 return ret;
98 } 113 }
99 114
@@ -119,4 +134,5 @@ void drm_iommu_detach_device(struct drm_device *drm_dev,
119 return; 134 return;
120 135
121 arm_iommu_detach_device(subdrv_dev); 136 arm_iommu_detach_device(subdrv_dev);
137 clear_dma_max_seg_size(subdrv_dev);
122} 138}