mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
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:
committed by
mobile promotions
parent
3a956a573d
commit
ea1b69d3f5
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) <<
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user