kernel: nvidia-oot: Fix Linux KMD coverity defects

Fix INT30-C and INT08-C coverity defects for
capture-vi.c and tegracam_ctrls.c.

Fix MISSING_LOCK coverity defects for channel.c.

JIRA CAMERASW-30788

Change-Id: I6ad218cb9184f09d04d862a4c8f3f6db35db65cf
Signed-off-by: Bob Zhang <bozhang@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3275901
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Xiaoming Xiang <xxiang@nvidia.com>
Reviewed-by: Anubhav Rai <arai@nvidia.com>
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Ankur Pawar <ankurp@nvidia.com>
This commit is contained in:
Bob Zhang
2025-01-02 01:47:27 +00:00
committed by Jon Hunter
parent 9f909306a0
commit 3aa403fa33
3 changed files with 76 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES.
// All rights reserved.
/**
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c
@@ -1400,14 +1401,24 @@ static uint32_t vi_capture_get_num_progress(
struct vi_capture_req *req)
{
struct vi_capture *capture = chan->capture_data;
struct capture_descriptor* desc = (struct capture_descriptor*)
(capture->requests.va +
req->buffer_index * capture->request_size);
struct vi_channel_config* config = &desc->ch_cfg;
const uint16_t minProgress = 2U;
uint16_t numProgress = minProgress;
struct capture_descriptor *desc;
struct vi_channel_config *config;
unsigned int mul_value = 0;
if (check_mul_overflow(req->buffer_index, capture->request_size, &mul_value)) {
dev_err(chan->dev,
"%s:capture descriptor offset failed due to an overflow\n", __func__);
return minProgress;
}
desc = (struct capture_descriptor *)(capture->requests.va + mul_value);
config = &desc->ch_cfg;
/* Minimum of two progress fences for PXL_SOF and PXL_EOF */
if (config->flush_enable == 0x1UL)
{
@@ -1433,7 +1444,14 @@ static uint32_t vi_capture_get_num_progress(
*/
if (((config->frame.frame_y - config->flush_first) % config->flush) == 0U)
{
numProgress--;
if (numProgress < minProgress) {
dev_err(chan->dev,
"%s:numProgress is less than the minimum value\n",
__func__);
numProgress = minProgress;
} else {
numProgress--;
}
}
}
return (uint32_t)numProgress;
@@ -1446,6 +1464,7 @@ int vi_capture_request(
struct vi_capture *capture = chan->capture_data;
struct CAPTURE_MSG capture_desc;
int err = 0;
uint32_t sum_value = 0;
nv_camera_log(chan->ndev,
__arch_counter_get_cntvct(),
@@ -1495,7 +1514,12 @@ int vi_capture_request(
}
// Progress syncpoints + 1 for status syncpoint
capture->progress_sp.threshold += vi_capture_get_num_progress(chan, req) + 1;
if (check_add_overflow(vi_capture_get_num_progress(chan, req), 1U, &sum_value)) {
dev_err(chan->dev, "%s: check_sub failed due to an overflow\n", __func__);
} else if (check_add_overflow(capture->progress_sp.threshold, sum_value,
&capture->progress_sp.threshold)) {
dev_err(chan->dev, "%s: procress_sp failed due to an overflow\n", __func__);
}
mutex_unlock(&capture->reset_lock);

View File

@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
// SPDX-License-Identifier: GPL-2.0-only
/* SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
*
* tegracam_ctrls - control framework for tegra camera drivers
*
* Copyright (c) 2017-2024, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/nospec.h>
@@ -899,8 +900,35 @@ static int tegracam_check_ctrl_ops(
"ERROR: Can not mix normal and extended sensor controls\n");
return -EINVAL;
}
total_ops = sensor_ops + mode_ops + string_ops + default_ops + compound_ops;
total_ops += sensor_ex_ops + default_ex_ops;
if (check_add_overflow(total_ops, sensor_ops, &total_ops)) {
dev_err(dev, "%s:sensor ops failed due to an overflow\n", __func__);
return -EINVAL;
}
if (check_add_overflow(total_ops, mode_ops, &total_ops)) {
dev_err(dev, "%s:mode ops failed due to an overflow\n", __func__);
return -EINVAL;
}
if (check_add_overflow(total_ops, string_ops, &total_ops)) {
dev_err(dev, "%s:string ops failed due to an overflow\n", __func__);
return -EINVAL;
}
if (check_add_overflow(total_ops, default_ops, &total_ops)) {
dev_err(dev, "%s:default ops failed due to an overflow\n", __func__);
return -EINVAL;
}
if (check_add_overflow(total_ops, compound_ops, &total_ops)) {
dev_err(dev, "%s:compound ops failed due to an overflow\n", __func__);
return -EINVAL;
}
if (check_add_overflow(total_ops, sensor_ex_ops, &total_ops)) {
dev_err(dev, "%s:sensor ex ops failed due to an overflow\n", __func__);
return -EINVAL;
}
if (check_add_overflow(total_ops, default_ex_ops, &total_ops)) {
dev_err(dev, "%s:default ex ops failed due to an overflow\n", __func__);
return -EINVAL;
}
if (total_ops != (ops->numctrls + TEGRACAM_DEF_CTRLS)) {
dev_err(dev,

View File

@@ -411,6 +411,7 @@ void release_buffer(struct tegra_channel *chan,
{
struct vb2_v4l2_buffer *vbuf = &buf->buf;
s64 frame_arrived_ts = 0;
unsigned long flags;
/* release one frame */
vbuf->sequence = chan->sequence;
@@ -423,6 +424,7 @@ void release_buffer(struct tegra_channel *chan,
vb2_set_plane_payload(&vbuf->vb2_buf,
0, chan->format.sizeimage);
spin_lock_irqsave(&chan->capture_state_lock, flags);
/*
* WAR to force buffer state if capture state is not good
* WAR - After sync point timeout or error frame capture
@@ -431,6 +433,7 @@ void release_buffer(struct tegra_channel *chan,
*/
if (chan->capture_state != CAPTURE_GOOD || vbuf->sequence < 2)
buf->state = VB2_BUF_STATE_ERROR;
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
if (chan->sequence == 1) {
/*
@@ -507,6 +510,7 @@ void free_ring_buffers(struct tegra_channel *chan, int frames)
{
struct vb2_v4l2_buffer *vbuf;
s64 frame_arrived_ts = 0;
unsigned long flags;
spin_lock(&chan->buffer_lock);
@@ -529,6 +533,7 @@ void free_ring_buffers(struct tegra_channel *chan, int frames)
vb2_set_plane_payload(&vbuf->vb2_buf,
0, chan->format.sizeimage);
spin_lock_irqsave(&chan->capture_state_lock, flags);
/*
* WAR to force buffer state if capture state is not good
* WAR - After sync point timeout or error frame capture
@@ -540,6 +545,7 @@ void free_ring_buffers(struct tegra_channel *chan, int frames)
chan->released_bufs < 2)
chan->buffer_state[chan->free_index] =
VB2_BUF_STATE_ERROR;
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
if (chan->sequence == 1) {
/*
@@ -587,6 +593,7 @@ static void add_buffer_to_ring(struct tegra_channel *chan,
static void update_state_to_buffer(struct tegra_channel *chan, int state)
{
int save_index = ((int)chan->save_index - PREVIOUS_BUFFER_DEC_INDEX);
unsigned long flags;
/* save index decrements by 2 as 3 bufs are added in ring buffer */
if (save_index < 0)
@@ -594,29 +601,35 @@ static void update_state_to_buffer(struct tegra_channel *chan, int state)
/* update state for the previous buffer */
chan->buffer_state[save_index] = state;
spin_lock_irqsave(&chan->capture_state_lock, flags);
/* for timeout/error case update the current buffer state as well */
if (chan->capture_state != CAPTURE_GOOD)
chan->buffer_state[chan->save_index] = state;
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
}
void tegra_channel_ring_buffer(struct tegra_channel *chan,
struct vb2_v4l2_buffer *vb,
struct timespec64 *ts, int state)
{
unsigned long flags;
if (!chan->bfirst_fstart)
chan->bfirst_fstart = true;
else
update_state_to_buffer(chan, state);
spin_lock_irqsave(&chan->capture_state_lock, flags);
/* Capture state is not GOOD, release all buffers and re-init state */
if (chan->capture_state != CAPTURE_GOOD) {
free_ring_buffers(chan, chan->num_buffers);
tegra_channel_init_ring_buffer(chan);
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
return;
} else {
/* TODO: granular time code information */
vb->timecode.seconds = ts->tv_sec;
}
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
/* release buffer N at N+2 frame start event */
if (chan->num_buffers >= (chan->capture_queue_depth - 1))