gpu: nvgpu: Fix crash on read fail of mc_boot_0_r

This CL handles
- erroneous use of boot_0 function pointer
before being assigned in __nvgpu_check_gpu_state
- And proper handling of error returned from gk20a_readl
in gk20a_mc_boot_0
With these fixes crash is not seen in case mc_boot_0 read
returns 0 in gk20a_mc_boot_0
- And also this handles the recursion caused by mc.boot_0()
calling nvgpu_readl and nvgpu_readl in turn
calling mc.boot_0 in case of read failure

Bug 2010966

Change-Id: Ia087811c67d88948b7fc5fff35e0fabc6ea91989
Signed-off-by: Supriya <ssharatkumar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1616274
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Supriya
2017-11-02 11:54:03 +05:30
committed by mobile promotions
parent 3a956a573d
commit ea1b69d3f5
4 changed files with 24 additions and 6 deletions

View File

@@ -32,6 +32,16 @@ void nvgpu_writel(struct gk20a *g, u32 r, u32 v)
}
u32 nvgpu_readl(struct gk20a *g, u32 r)
{
u32 v = __nvgpu_readl(g, r);
if (v == 0xffffffff)
__nvgpu_check_gpu_state(g);
return v;
}
u32 __nvgpu_readl(struct gk20a *g, u32 r)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
u32 v = 0xffffffff;
@@ -41,8 +51,6 @@ u32 nvgpu_readl(struct gk20a *g, u32 r)
gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v);
} else {
v = readl(l->regs + r);
if (v == 0xffffffff)
__nvgpu_check_gpu_state(g);
gk20a_dbg(gpu_dbg_reg, "r=0x%x v=0x%x", r, v);
}

View File

@@ -54,11 +54,17 @@
void __nvgpu_check_gpu_state(struct gk20a *g)
{
u32 boot_0 = g->ops.mc.boot_0(g, NULL, NULL, NULL);
u32 boot_0 = 0xffffffff;
if (!g->ops.mc.boot_0) {
nvgpu_err(g, "Can't determine GPU state, mc.boot_0 unset");
return;
}
boot_0 = g->ops.mc.boot_0(g, NULL, NULL, NULL);
if (boot_0 == 0xffffffff) {
pr_err("nvgpu: GPU has disappeared from bus!!\n");
pr_err("nvgpu: Rebooting system!!\n");
nvgpu_err(g, "GPU has disappeared from bus!!");
nvgpu_err(g, "Rebooting system!!");
kernel_restart(NULL);
}
}

View File

@@ -200,7 +200,10 @@ void gk20a_mc_reset(struct gk20a *g, u32 units)
u32 gk20a_mc_boot_0(struct gk20a *g, u32 *arch, u32 *impl, u32 *rev)
{
u32 val = gk20a_readl(g, mc_boot_0_r());
u32 val = __nvgpu_readl(g, mc_boot_0_r());
if (val == 0xffffffff)
return val;
if (arch)
*arch = mc_boot_0_architecture_v(val) <<

View File

@@ -40,6 +40,7 @@ struct gk20a;
void nvgpu_writel(struct gk20a *g, u32 r, u32 v);
u32 nvgpu_readl(struct gk20a *g, u32 r);
u32 __nvgpu_readl(struct gk20a *g, u32 r);
void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v);
void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v);
u32 nvgpu_bar1_readl(struct gk20a *g, u32 b);