MA-12928 [#imx-1199] Fix kernel panic issue caused by invalid ts_dma_buf pointer.
authorivan.liu <xiaowen.liu@nxp.com>
Thu, 27 Sep 2018 06:28:27 +0000 (14:28 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
There is kernel panic stack which caused by ts_dma_buf pointer.

[  136.041194] [<ffff000008722a8c>] drm_gem_object_init+0x94/0x98
[  136.047028] [<ffff000008748294>] __drm_gem_cma_create+0x40/0xb4
[  136.052950] [<ffff000008748808>] drm_gem_cma_prime_import_sg_table+0x48/0xa8
[  136.060000] [<ffff000008732e0c>] drm_gem_prime_import_dev+0x98/0x134
[  136.066352] [<ffff000008732eb8>] drm_gem_prime_import+0x10/0x18
[  136.072276] [<ffff00000876b144>] dcss_plane_atomic_set_base+0x174/0x2e4
[  136.078889] [<ffff00000876b700>] dcss_plane_atomic_update+0x44c/0x578
[  136.085331] [<ffff0000087134b0>] drm_atomic_helper_commit_planes+0xb4/0x1f0
[  136.092293] [<ffff00000876bea8>] dcss_drm_atomic_commit_tail+0xb4/0xe4
[  136.098820] [<ffff000008716ba8>] commit_tail+0x44/0x84
[  136.103958] [<ffff000008716bf8>] commit_work+0x10/0x18
[  136.109100] [<ffff0000080fa1a4>] process_one_work+0x140/0x3fc
[  136.114846] [<ffff0000080fa598>] worker_thread+0x138/0x3e4
[  136.120334] [<ffff000008101a00>] kthread+0x104/0x130
[  136.125300] [<ffff000008085064>] ret_from_fork+0x10/0x18

ts_dma_buf will become an invalid pointer when user process crashes.
And DRM commit will access invalid ts_dma_buf in kernel thread in async.
Change ts_dma_buf to ts_address to avoid invalid pointer issue.

Signed-off-by: ivan.liu <xiaowen.liu@nxp.com>
Signed-off-by: Arulpandiyan Vadivel <arulpandiyan_vadivel@mentor.com>
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_metadata.h

index 4fef673..a93a256 100644 (file)
@@ -1690,6 +1690,28 @@ gckKERNEL_SetVidMemMetadata(
     }
     else
     {
+#ifdef ANDROID
+        if (nodeObj->metadata.ts_address == 0 && nodeObj->tsNode != NULL)
+        {
+            gctUINT32 Address = 0;
+            gctUINT32 Gid = 0;
+            gctUINT64 PhysicalAddress = 0;
+
+            gcmkONERROR(gckVIDMEM_Lock(Kernel,
+                    nodeObj->tsNode,
+                    gcvFALSE,
+                    &Address,
+                    &Gid,
+                    &PhysicalAddress));
+
+            nodeObj->metadata.ts_address = (
+                    PhysicalAddress + Kernel->hardware->baseAddress);
+            gcmkONERROR(gckVIDMEM_Unlock(Kernel,
+                    nodeObj->tsNode,
+                    gcvSURF_TYPE_UNKNOWN,
+                    gcvNULL));
+        }
+#else
         nodeObj->metadata.ts_fd             = Interface->u.SetVidMemMetadata.ts_fd;
 
         if (nodeObj->metadata.ts_fd >= 0)
@@ -1707,6 +1729,7 @@ gckKERNEL_SetVidMemMetadata(
         {
             nodeObj->metadata.ts_dma_buf    = NULL;
         }
+#endif
 
         nodeObj->metadata.fc_enabled        = Interface->u.SetVidMemMetadata.fc_enabled;
         nodeObj->metadata.fc_value          = Interface->u.SetVidMemMetadata.fc_value;
index 950fda5..719a0b0 100644 (file)
@@ -2619,6 +2619,9 @@ gckVIDMEM_NODE_Allocate(
 
     node->metadata.magic = VIV_VIDMEM_METADATA_MAGIC;
     node->metadata.ts_fd = -1;
+#ifdef ANDROID
+    node->metadata.ts_address = 0;
+#endif
 
     node->node = VideoNode;
     node->kernel = Kernel;
index c617e4f..eae2c17 100644 (file)
@@ -100,6 +100,9 @@ typedef struct _VIV_VIDMEM_METADATA
 
     int32_t  ts_fd;
     void *   ts_dma_buf;
+#ifdef ANDROID
+    dma_addr_t ts_address;
+#endif
 
     uint32_t fc_enabled;
     uint32_t fc_value;