diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2016-06-17 03:54:23 -0400 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2016-07-13 10:06:04 -0400 |
commit | f7c72773de88fa3d4b51d4eb2bd2a89b746aaf54 (patch) | |
tree | 05a40dbdf33237547e0d2703027533a65fc12ca7 | |
parent | 5dd0775e502b26b44e5bcb5f504a977a565f2f3e (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.c | 28 |
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 | ||
24 | static 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 | |||
35 | static 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 | } |