kernel: nvidia-oot: Fix Linux KMD coverity defects

Fix INT30-C, INT08-C, and EXP34-C coverity defects for
cam_fsync.c and cam_cdi_tsc.c.

Jira CAMERASW-30847

Change-Id: I525ed2e0986c3987d062a9baeaefad048715c6c1
Signed-off-by: Hongming Dong <hongmingd@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3280943
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Ankur Pawar <ankurp@nvidia.com>
Reviewed-by: Semi Malinen <smalinen@nvidia.com>
This commit is contained in:
Hongming Dong
2025-01-09 00:00:52 -08:00
committed by Jon Hunter
parent c5fe909fd6
commit ede67c712a
3 changed files with 51 additions and 15 deletions

View File

@@ -516,7 +516,8 @@ static int compute_edge_regs(struct edge_reg_info *info, u64 ticks, bool loop)
while ((ticks > 0U) && (info->count < MAX_EDGE_REGS)) {
u32 const current_ticks = (u32)min(ticks, (u64)EDGE_OFFSET_MASK);
info->regs[info->count++] = current_ticks;
info->regs[info->count] = current_ticks;
info->count++;
ticks -= current_ticks;
}
@@ -528,6 +529,9 @@ static int compute_edge_regs(struct edge_reg_info *info, u64 ticks, bool loop)
if (ticks > 0U)
return -EFAULT;
if (info->count > MAX_EDGE_REGS || info->count < 1U) {
return -EFAULT;
}
/** Update the flags for last edge register */
info->regs[info->count-1] |= flags;
return 0;
@@ -537,19 +541,26 @@ static int cam_fsync_program_group_generator_edges(struct fsync_generator_group
{
struct cam_fsync_generator *generator;
u32 max_freq_hz_lcm = cam_fsync_find_max_freq_hz_lcm(group);
u64 const ticks_per_hz = DIV_ROUND_CLOSEST(NS_PER_SEC, group->features->ns_per_tick);
u32 const ticks_per_hz = DIV_ROUND_CLOSEST(NS_PER_SEC, group->features->ns_per_tick);
bool const can_generate_precise_freq = cam_fsync_can_generate_precise_freq(group);
struct cam_fsync_extra_ticks_and_period extra = {0, 1};
list_for_each_entry(generator, &group->generators, list) {
u64 ref_ticks_in_period = DIV_ROUND_CLOSEST_ULL(ticks_per_hz, max_freq_hz_lcm);
u64 ticks_in_period = ref_ticks_in_period *
(max_freq_hz_lcm / generator->config.freq_hz);
u32 ref_ticks_in_period = DIV_ROUND_CLOSEST(ticks_per_hz, max_freq_hz_lcm);
u64 ticks_in_period = (u64)ref_ticks_in_period *
(u64)(max_freq_hz_lcm / generator->config.freq_hz);
u64 ticks_active = mult_frac(ticks_in_period, generator->config.duty_cycle, 100);
u64 ticks_inactive = ticks_in_period - ticks_active;
u64 ticks_inactive = 0;
struct edge_reg_info edge_info = {0};
u32 i;
if (check_sub_overflow(ticks_in_period, ticks_active, &ticks_inactive)) {
dev_err(group->dev,
"%s: calculate the ticks_inactive due to an underflow\n",
__func__);
return -EINVAL;
}
/**
* Generating a freq with period that is not multiple of TSC unit will
* cause the signal to drift over time. To avoid this, if precise signal
@@ -564,14 +575,21 @@ static int cam_fsync_program_group_generator_edges(struct fsync_generator_group
for (i = 0; i < extra.num_periods; i++) {
int ret;
u64 extra_ticks = (extra.extra_ticks > 0) ? 1 : 0;
u64 tmp_ticks = 0;
if (check_add_overflow(ticks_inactive, extra_ticks, &tmp_ticks)) {
dev_err(group->dev,
"%s: calculate the ticks due to an underflow\n",
__func__);
return -EINVAL;
}
extra.extra_ticks -= (extra_ticks > 0);
ret = compute_edge_regs(&edge_info, ticks_active, false);
if (ret < 0)
return ret;
ret = compute_edge_regs(&edge_info,
ticks_inactive + extra_ticks,
ret = compute_edge_regs(&edge_info, tmp_ticks,
(i == extra.num_periods - 1));
if (ret < 0)
return ret;
@@ -640,7 +658,13 @@ static u64 cam_fsync_get_default_start_ticks(struct cam_fsync_controller *contro
u64 default_start_ticks = mult_frac(
TSC_GENX_START_OFFSET_MS, NS_PER_MS,
controller->features->ns_per_tick);
default_start_ticks += cam_fsync_get_current_tsc_ticks();
u64 current_ticks = cam_fsync_get_current_tsc_ticks();
if (check_add_overflow(default_start_ticks, current_ticks, &default_start_ticks)) {
dev_err(controller->dev,
"%s: calculate the default start ticks due to an overflow\n", __func__);
return 0;
}
return default_start_ticks;
}

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* SPDX-FileCopyrightText: Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
// SPDX-License-Identifier: GPL-2.0
/* SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION. All rights reserved. */
/*
* cam_cdi_tsc.c - tsc driver.
*/
@@ -317,7 +317,14 @@ static int cdi_tsc_program_generator_edges(struct tsc_signal_controller *control
if (controller->features->rational_locking.enforced) {
ticks_in_period = DIV_ROUND_CLOSEST(ticks_per_hz, max_freq_hz_lcm);
ticks_in_period *= max_freq_hz_lcm / generator->config.freq_hz;
if (check_mul_overflow(ticks_in_period,
(max_freq_hz_lcm / generator->config.freq_hz),
&ticks_in_period)) {
dev_err(controller->dev,
"%s: calculate the ticks_in_period due to an overflow\n",
__func__);
return -EINVAL;
}
} else {
ticks_in_period = DIV_ROUND_CLOSEST(ticks_per_hz, generator->config.freq_hz);
}

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2015-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h>
@@ -254,7 +254,12 @@ int cdi_dev_raw_wr(
cdi_dev_dump(__func__, info, offset, val, size);
num_msgs = size / MAX_MSG_SIZE;
num_msgs += (size % MAX_MSG_SIZE) ? 1 : 0;
if (check_add_overflow(num_msgs,
(unsigned int)((size % MAX_MSG_SIZE) ? 1 : 0), &num_msgs)) {
dev_err(info->dev, "%s: calculate the num_msgs due to an overflow\n",
__func__);
return -ENOMEM;
}
i2cmsg = kzalloc((sizeof(struct i2c_msg)*num_msgs), GFP_KERNEL);
if (!i2cmsg) {