From d2349b32ec35a4f89a9d88f4876c83616292556a Mon Sep 17 00:00:00 2001 From: mkumbar Date: Wed, 12 May 2021 20:50:29 +0530 Subject: [PATCH] gpu: nvgpu: update SSMD array size -Update SSMD array size to hold all supported super-surface members -Handle the error and report if invalid SSMD ID is found. issue: At present SSMD array size set to 32 but overall 33 super-surface members are supported, when 33rd member accessed system crash happened due to overflow access, so fixing it by setting the SSMD array size to actual number of super-surface members supported Bug 200721968 Bug 200721966 Change-Id: I5ba1084a661d7497056f13a053d2fc79d50f595c Signed-off-by: mkumbar Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2528569 Tested-by: mobile promotions Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c | 5 ++++- .../common/pmu/super_surface/super_surface.c | 22 ++++++++++++++++--- .../pmu/super_surface/super_surface_priv.h | 7 +++--- .../nvgpu/include/nvgpu/pmu/super_surface.h | 4 ++-- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c b/drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c index 8cfd0ea1f..7bed652f8 100644 --- a/drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c +++ b/drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c @@ -475,8 +475,11 @@ static int pmu_process_init_msg(struct nvgpu_pmu *pmu, nvgpu_pmu_allocator_dmem_init(g, pmu, &pmu->dmem, init); if (nvgpu_is_enabled(g, NVGPU_SUPPORT_PMU_SUPER_SURFACE)) { - nvgpu_pmu_ss_create_ssmd_lookup_table(g, + err = nvgpu_pmu_ss_create_ssmd_lookup_table(g, pmu, pmu->super_surface); + if (err != 0) { + goto exit; + } } nvgpu_pmu_set_fw_ready(g, pmu, true); diff --git a/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface.c b/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface.c index 73670b3c3..876adb6cc 100644 --- a/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface.c +++ b/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -76,18 +76,20 @@ struct nvgpu_mem *nvgpu_pmu_super_surface_mem(struct gk20a *g, * table, i.e one table is for SET ID TYPE & second table for * GET_STATUS ID_TYPE. */ -void nvgpu_pmu_ss_create_ssmd_lookup_table(struct gk20a *g, +int nvgpu_pmu_ss_create_ssmd_lookup_table(struct gk20a *g, struct nvgpu_pmu *pmu, struct nvgpu_pmu_super_surface *ss) { struct super_surface_member_descriptor ssmd; u32 ssmd_size = (u32) sizeof(struct super_surface_member_descriptor); u32 idx = 0U; + int err = 0; nvgpu_log_fn(g, " "); if (ss == NULL) { - return; + nvgpu_err(g, "SS not allocated"); + return -ENOMEM; } for (idx = 0U; idx < NV_PMU_SUPER_SURFACE_MEMBER_DESCRIPTOR_COUNT; @@ -109,6 +111,12 @@ void nvgpu_pmu_ss_create_ssmd_lookup_table(struct gk20a *g, * during member info fetch. */ ssmd.id &= 0xFFFFU; + if (ssmd.id >= NV_PMU_SUPER_SURFACE_MEMBER_COUNT) { + nvgpu_err(g, "incorrect ssmd id %d", ssmd.id); + nvgpu_err(g, "Failed to create SSMD table"); + err = -EINVAL; + break; + } /*use member ID as index for lookup table too*/ (void) memcpy(&ss->ssmd_set[ssmd.id], &ssmd, ssmd_size); @@ -121,6 +129,12 @@ void nvgpu_pmu_ss_create_ssmd_lookup_table(struct gk20a *g, * during member info fetch. */ ssmd.id &= 0xFFFFU; + if (ssmd.id >= NV_PMU_SUPER_SURFACE_MEMBER_COUNT) { + nvgpu_err(g, "incorrect ssmd id %d", ssmd.id); + nvgpu_err(g, "failed to create SSMD table"); + err = -EINVAL; + break; + } /*use member ID as index for lookup table too*/ (void) memcpy(&ss->ssmd_get_status[ssmd.id], &ssmd, ssmd_size); @@ -128,6 +142,8 @@ void nvgpu_pmu_ss_create_ssmd_lookup_table(struct gk20a *g, continue; } } + + return err; } u32 nvgpu_pmu_get_ss_member_set_offset(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface_priv.h b/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface_priv.h index 9c61ec0c4..9662b2f38 100644 --- a/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface_priv.h +++ b/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface_priv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -27,6 +27,7 @@ #include #include #include +#include struct nvgpu_mem; @@ -103,10 +104,10 @@ struct nvgpu_pmu_super_surface { struct nvgpu_mem super_surface_buf; struct super_surface_member_descriptor - ssmd_set[NV_PMU_SUPER_SURFACE_MEMBER_DESCRIPTOR_COUNT]; + ssmd_set[NV_PMU_SUPER_SURFACE_MEMBER_COUNT]; struct super_surface_member_descriptor - ssmd_get_status[NV_PMU_SUPER_SURFACE_MEMBER_DESCRIPTOR_COUNT]; + ssmd_get_status[NV_PMU_SUPER_SURFACE_MEMBER_COUNT]; }; #endif /* SUPER_SURFACE_PRIV_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/super_surface.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/super_surface.h index 6e7d3b138..e360be133 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu/super_surface.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/super_surface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -63,7 +63,7 @@ u32 nvgpu_pmu_get_ss_member_get_status_offset(struct gk20a *g, struct nvgpu_pmu *pmu, u32 member_id); u32 nvgpu_pmu_get_ss_member_get_status_size(struct gk20a *g, struct nvgpu_pmu *pmu, u32 member_id); -void nvgpu_pmu_ss_create_ssmd_lookup_table(struct gk20a *g, +int nvgpu_pmu_ss_create_ssmd_lookup_table(struct gk20a *g, struct nvgpu_pmu *pmu, struct nvgpu_pmu_super_surface *ss); struct nvgpu_mem *nvgpu_pmu_super_surface_mem(struct gk20a *g, struct nvgpu_pmu *pmu, struct nvgpu_pmu_super_surface *ss);