From f37f4e27e362629d5c187817104d48d703c380cc Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Tue, 20 Dec 2016 14:11:54 -0800 Subject: [PATCH] gpu: nvgpu: Use perf table only VBIOS supports it We retrieve perf table from VBIOS only if respective HAL op is implemented. Later in code we unconditionally dereference the pointer which can lead to NULL pointer access. Fix by early aborting creation of devinit tables if the perf VBIOS getter is missing. Change-Id: If48aa6dac724056dd1feb2ef520e343736d4db85 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/1279223 GVS: Gerrit_Virtual_Submit Reviewed-by: Thomas Fleury --- drivers/gpu/nvgpu/clk/clk_domain.c | 15 ++++++++------- drivers/gpu/nvgpu/clk/clk_fll.c | 15 ++++++++------- drivers/gpu/nvgpu/clk/clk_vin.c | 15 ++++++++------- drivers/gpu/nvgpu/perf/vfe_equ.c | 18 ++++++++++-------- drivers/gpu/nvgpu/perf/vfe_var.c | 27 ++++++++++++++------------- drivers/gpu/nvgpu/pmgr/pwrdev.c | 15 ++++++++------- drivers/gpu/nvgpu/pmgr/pwrmonitor.c | 15 ++++++++------- drivers/gpu/nvgpu/pmgr/pwrpolicy.c | 15 ++++++++------- drivers/gpu/nvgpu/therm/thrmchannel.c | 15 ++++++++------- drivers/gpu/nvgpu/therm/thrmdev.c | 15 ++++++++------- 10 files changed, 88 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/nvgpu/clk/clk_domain.c b/drivers/gpu/nvgpu/clk/clk_domain.c index fe3db5d63..892437deb 100644 --- a/drivers/gpu/nvgpu/clk/clk_domain.c +++ b/drivers/gpu/nvgpu/clk/clk_domain.c @@ -263,13 +263,14 @@ static u32 devinit_get_clocks_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs) { - clocks_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.clock_token, CLOCKS_TABLE); - if (clocks_table_ptr == NULL) { - status = -EINVAL; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + clocks_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.clock_token, CLOCKS_TABLE); + if (clocks_table_ptr == NULL) { + status = -EINVAL; + goto done; } memcpy(&clocks_table_header, clocks_table_ptr, diff --git a/drivers/gpu/nvgpu/clk/clk_fll.c b/drivers/gpu/nvgpu/clk/clk_fll.c index 0de857f5d..d83f3e155 100644 --- a/drivers/gpu/nvgpu/clk/clk_fll.c +++ b/drivers/gpu/nvgpu/clk/clk_fll.c @@ -236,13 +236,14 @@ static u32 devinit_get_fll_device_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs) { - fll_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.clock_token, FLL_TABLE); - if (fll_table_ptr == NULL) { - status = -1; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + fll_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.clock_token, FLL_TABLE); + if (fll_table_ptr == NULL) { + status = -1; + goto done; } memcpy(&fll_desc_table_header_sz, fll_table_ptr, diff --git a/drivers/gpu/nvgpu/clk/clk_vin.c b/drivers/gpu/nvgpu/clk/clk_vin.c index e8e4b7532..649eb2348 100644 --- a/drivers/gpu/nvgpu/clk/clk_vin.c +++ b/drivers/gpu/nvgpu/clk/clk_vin.c @@ -339,13 +339,14 @@ static u32 devinit_get_vin_device_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs) { - vin_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.clock_token, VIN_TABLE); - if (vin_table_ptr == NULL) { - status = -1; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + vin_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.clock_token, VIN_TABLE); + if (vin_table_ptr == NULL) { + status = -1; + goto done; } memcpy(&vin_desc_table_header, vin_table_ptr, diff --git a/drivers/gpu/nvgpu/perf/vfe_equ.c b/drivers/gpu/nvgpu/perf/vfe_equ.c index 6630fb21e..78a7c57c2 100644 --- a/drivers/gpu/nvgpu/perf/vfe_equ.c +++ b/drivers/gpu/nvgpu/perf/vfe_equ.c @@ -150,14 +150,16 @@ static u32 devinit_get_vfe_equ_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs) { - vfeequs_tbl_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.perf_token, - CONTINUOUS_VIRTUAL_BINNING_TABLE); - if (vfeequs_tbl_ptr == NULL) { - status = -EINVAL; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + vfeequs_tbl_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.perf_token, + CONTINUOUS_VIRTUAL_BINNING_TABLE); + + if (vfeequs_tbl_ptr == NULL) { + status = -EINVAL; + goto done; } memcpy(&vfeequs_tbl_header, vfeequs_tbl_ptr, diff --git a/drivers/gpu/nvgpu/perf/vfe_var.c b/drivers/gpu/nvgpu/perf/vfe_var.c index 4f8dc83be..f4c3f2764 100644 --- a/drivers/gpu/nvgpu/perf/vfe_var.c +++ b/drivers/gpu/nvgpu/perf/vfe_var.c @@ -182,20 +182,21 @@ u32 dev_init_get_vfield_info(struct gk20a *g, u8 *psegmentcount = NULL; u32 status = 0; - if (g->ops.bios.get_perf_table_ptrs) { - vfieldregtableptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.virt_token, VP_FIELD_REGISTER); - if (vfieldregtableptr == NULL) { - status = -EINVAL; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; - vfieldtableptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.virt_token, VP_FIELD_TABLE); - if (vfieldtableptr == NULL) { - status = -EINVAL; - goto done; - } + vfieldregtableptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.virt_token, VP_FIELD_REGISTER); + if (vfieldregtableptr == NULL) { + status = -EINVAL; + goto done; + } + + vfieldtableptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.virt_token, VP_FIELD_TABLE); + if (vfieldtableptr == NULL) { + status = -EINVAL; + goto done; } memcpy(&vregheader, vfieldregtableptr, VFIELD_REG_HEADER_SIZE); diff --git a/drivers/gpu/nvgpu/pmgr/pwrdev.c b/drivers/gpu/nvgpu/pmgr/pwrdev.c index 03e2eb34a..da034b31f 100644 --- a/drivers/gpu/nvgpu/pmgr/pwrdev.c +++ b/drivers/gpu/nvgpu/pmgr/pwrdev.c @@ -140,13 +140,14 @@ static u32 devinit_get_pwr_device_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs != NULL) { - pwr_device_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.perf_token, POWER_SENSORS_TABLE); - if (pwr_device_table_ptr == NULL) { - status = -EINVAL; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + pwr_device_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.perf_token, POWER_SENSORS_TABLE); + if (pwr_device_table_ptr == NULL) { + status = -EINVAL; + goto done; } memcpy(&pwr_sensor_table_header, pwr_device_table_ptr, diff --git a/drivers/gpu/nvgpu/pmgr/pwrmonitor.c b/drivers/gpu/nvgpu/pmgr/pwrmonitor.c index c28751fde..f14bac073 100644 --- a/drivers/gpu/nvgpu/pmgr/pwrmonitor.c +++ b/drivers/gpu/nvgpu/pmgr/pwrmonitor.c @@ -187,13 +187,14 @@ static u32 devinit_get_pwr_topology_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs != NULL) { - pwr_topology_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.perf_token, POWER_TOPOLOGY_TABLE); - if (pwr_topology_table_ptr == NULL) { - status = -EINVAL; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + pwr_topology_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.perf_token, POWER_TOPOLOGY_TABLE); + if (pwr_topology_table_ptr == NULL) { + status = -EINVAL; + goto done; } memcpy(&pwr_topology_table_header, pwr_topology_table_ptr, diff --git a/drivers/gpu/nvgpu/pmgr/pwrpolicy.c b/drivers/gpu/nvgpu/pmgr/pwrpolicy.c index d79267738..cce3bd5ef 100644 --- a/drivers/gpu/nvgpu/pmgr/pwrpolicy.c +++ b/drivers/gpu/nvgpu/pmgr/pwrpolicy.c @@ -466,13 +466,14 @@ static u32 devinit_get_pwr_policy_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs != NULL) { - pwr_policy_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.perf_token, POWER_CAPPING_TABLE); - if (pwr_policy_table_ptr == NULL) { - status = -EINVAL; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + pwr_policy_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.perf_token, POWER_CAPPING_TABLE); + if (pwr_policy_table_ptr == NULL) { + status = -EINVAL; + goto done; } memcpy(&pwr_policy_table_header.version, diff --git a/drivers/gpu/nvgpu/therm/thrmchannel.c b/drivers/gpu/nvgpu/therm/thrmchannel.c index b5a7dfd24..aa40dac88 100644 --- a/drivers/gpu/nvgpu/therm/thrmchannel.c +++ b/drivers/gpu/nvgpu/therm/thrmchannel.c @@ -131,13 +131,14 @@ static u32 devinit_get_therm_channel_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs) { - therm_channel_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.perf_token, THERMAL_CHANNEL_TABLE); - if (therm_channel_table_ptr == NULL) { - status = -EINVAL; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + therm_channel_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.perf_token, THERMAL_CHANNEL_TABLE); + if (therm_channel_table_ptr == NULL) { + status = -EINVAL; + goto done; } memcpy(&therm_channel_table_header, therm_channel_table_ptr, diff --git a/drivers/gpu/nvgpu/therm/thrmdev.c b/drivers/gpu/nvgpu/therm/thrmdev.c index 83ac9739c..9bb77537d 100644 --- a/drivers/gpu/nvgpu/therm/thrmdev.c +++ b/drivers/gpu/nvgpu/therm/thrmdev.c @@ -81,13 +81,14 @@ static u32 devinit_get_therm_device_table(struct gk20a *g, gk20a_dbg_info(""); - if (g->ops.bios.get_perf_table_ptrs) { - therm_device_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, - g->bios.perf_token, THERMAL_DEVICE_TABLE); - if (therm_device_table_ptr == NULL) { - status = -EINVAL; - goto done; - } + if (!g->ops.bios.get_perf_table_ptrs) + return -EINVAL; + + therm_device_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.perf_token, THERMAL_DEVICE_TABLE); + if (therm_device_table_ptr == NULL) { + status = -EINVAL; + goto done; } memcpy(&therm_device_table_header, therm_device_table_ptr,