summaryrefslogtreecommitdiff
path: root/drivers/mxc/gpu-viv/hal/os/linux
diff options
context:
space:
mode:
authorXianzhong <xianzhong.li@nxp.com>2019-02-14 23:55:04 +0800
committerXianzhong <xianzhong.li@nxp.com>2019-02-15 13:25:05 +0800
commit3283efbeadbc11cb38146cb7874becfecf27f981 (patch)
treef30ced337607d94d32eef3cfa41b79c651b7d195 /drivers/mxc/gpu-viv/hal/os/linux
parenta7d6f50164039334f371fef1575de7d80d10aa58 (diff)
MGS-4541 [#imx-1334] fix galcore kernel panic in debugfs
Galcore kernel panic when reading from sysfs during modprobe, This issue occurs when gc sysfs entries are read while the modprobe of the galcore module is in progress. Register the GC debugfs attributes in sysfs after the driver data-structures have been initialized, instead of before. Add defensive sanity checks in all _show() functions used by debugfs attributes, to check for NULL pointers before dereferencing them. Return -ENXIO in case of NULL pointers. Signed-off-by: Xianzhong <xianzhong.li@nxp.com>
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/os/linux')
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c60
1 files changed, 43 insertions, 17 deletions
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
index d0a930a12ed6..ad3154b047c8 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
@@ -88,6 +88,9 @@ int gc_info_show(struct seq_file* m, void* data)
gctUINT32 productID = 0;
gctUINT32 ecoID = 0;
+ if (!device)
+ return -ENXIO;
+
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
if (device->irqLines[i] != -1)
@@ -130,6 +133,9 @@ int gc_clients_show(struct seq_file* m, void* data)
gctINT i, pid;
char name[24];
+ if (!kernel)
+ return -ENXIO;
+
seq_printf(m, "%-8s%s\n", "PID", "NAME");
seq_printf(m, "------------------------\n");
@@ -197,6 +203,9 @@ int gc_meminfo_show(struct seq_file* m, void* data)
gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0};
gcsDATABASE_COUNTERS nonPagedCounter = {0, 0, 0};
+ if (!kernel)
+ return -ENXIO;
+
status = gckKERNEL_GetVideoMemoryPool(kernel, gcvPOOL_SYSTEM, &memory);
if (gcmIS_SUCCESS(status))
@@ -488,6 +497,10 @@ gc_db_show(struct seq_file *m, void *data)
gcsINFO_NODE *node = m->private;
gckGALDEVICE device = node->device;
gckKERNEL kernel = _GetValidKernel(device);
+
+ if (!kernel)
+ return -ENXIO;
+
_ShowProcesses(m, kernel);
return 0 ;
}
@@ -499,6 +512,9 @@ gc_version_show(struct seq_file *m, void *data)
gckGALDEVICE device = node->device;
gcsPLATFORM * platform = device->platform;
+ if (!device)
+ return -ENXIO;
+
seq_printf(m, "%s built at %s\n", gcvVERSION_STRING, HOST);
if (platform->name)
@@ -541,6 +557,9 @@ gc_idle_show(struct seq_file *m, void *data)
gctUINT64 idle;
gctUINT64 suspend;
+ if (!kernel)
+ return -ENXIO;
+
gckHARDWARE_QueryStateTimer(kernel->hardware, &start, &end, &on, &off, &idle, &suspend);
/* Idle time since last call */
@@ -588,6 +607,10 @@ gc_dump_trigger_show(struct seq_file *m, void *data)
{
kernel = device->kernels[dumpCore];
}
+
+ if (!kernel)
+ return -ENXIO;
+
#endif
seq_printf(m, gcdDEBUG_FS_WARN);
@@ -618,6 +641,9 @@ static int gc_vidmem_show(struct seq_file *m, void *unused)
gckKERNEL kernel = _GetValidKernel(device);
+ if (!kernel)
+ return -ENXIO;
+
if (dumpProcess == 0)
{
/* Acquire the database mutex. */
@@ -1212,23 +1238,6 @@ gckGALDEVICE_Construct(
device->irqLines[i] = -1;
}
- gcmkONERROR(_DebugfsInit(device));
-
- if (gckDEBUGFS_CreateNode(
- device, LogFileSize, device->debugfsDir.root ,DEBUG_FILE, &(device->dbgNode)))
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Failed to create the debug file system %s/%s \n",
- __FUNCTION__, __LINE__,
- PARENT_FILE, DEBUG_FILE
- );
- }
- else if (LogFileSize)
- {
- gckDEBUGFS_SetCurrentNode(device->dbgNode);
- }
-
_SetupRegisterPhysical(device, Args);
if (IrqLine != -1)
@@ -1586,6 +1595,23 @@ gckGALDEVICE_Construct(
/* Return pointer to the device. */
*Device = galDevice = device;
+ gcmkONERROR(_DebugfsInit(device));
+
+ if (gckDEBUGFS_CreateNode(
+ device, LogFileSize, device->debugfsDir.root ,DEBUG_FILE, &(device->dbgNode)))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to create the debug file system %s/%s \n",
+ __FUNCTION__, __LINE__,
+ PARENT_FILE, DEBUG_FILE
+ );
+ }
+ else if (LogFileSize)
+ {
+ gckDEBUGFS_SetCurrentNode(device->dbgNode);
+ }
+
gcmkFOOTER_ARG("*Device=0x%x", * Device);
return gcvSTATUS_OK;