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 <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/1279223
GVS: Gerrit_Virtual_Submit
Reviewed-by: Thomas Fleury <tfleury@nvidia.com>
This commit is contained in:
Terje Bergstrom
2016-12-20 14:11:54 -08:00
committed by mobile promotions
parent 2a95a288b2
commit f37f4e27e3
10 changed files with 88 additions and 77 deletions

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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);

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,