mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
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:
@@ -1,5 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES.
|
// SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES.
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c
|
* @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_req *req)
|
||||||
{
|
{
|
||||||
struct vi_capture *capture = chan->capture_data;
|
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;
|
const uint16_t minProgress = 2U;
|
||||||
uint16_t numProgress = minProgress;
|
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 */
|
/* Minimum of two progress fences for PXL_SOF and PXL_EOF */
|
||||||
if (config->flush_enable == 0x1UL)
|
if (config->flush_enable == 0x1UL)
|
||||||
{
|
{
|
||||||
@@ -1433,9 +1444,16 @@ static uint32_t vi_capture_get_num_progress(
|
|||||||
*/
|
*/
|
||||||
if (((config->frame.frame_y - config->flush_first) % config->flush) == 0U)
|
if (((config->frame.frame_y - config->flush_first) % config->flush) == 0U)
|
||||||
{
|
{
|
||||||
|
if (numProgress < minProgress) {
|
||||||
|
dev_err(chan->dev,
|
||||||
|
"%s:numProgress is less than the minimum value\n",
|
||||||
|
__func__);
|
||||||
|
numProgress = minProgress;
|
||||||
|
} else {
|
||||||
numProgress--;
|
numProgress--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return (uint32_t)numProgress;
|
return (uint32_t)numProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1446,6 +1464,7 @@ int vi_capture_request(
|
|||||||
struct vi_capture *capture = chan->capture_data;
|
struct vi_capture *capture = chan->capture_data;
|
||||||
struct CAPTURE_MSG capture_desc;
|
struct CAPTURE_MSG capture_desc;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
uint32_t sum_value = 0;
|
||||||
|
|
||||||
nv_camera_log(chan->ndev,
|
nv_camera_log(chan->ndev,
|
||||||
__arch_counter_get_cntvct(),
|
__arch_counter_get_cntvct(),
|
||||||
@@ -1495,7 +1514,12 @@ int vi_capture_request(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Progress syncpoints + 1 for status syncpoint
|
// 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);
|
mutex_unlock(&capture->reset_lock);
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
* tegracam_ctrls - control framework for tegra camera drivers
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017-2024, NVIDIA CORPORATION. All rights reserved.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/nospec.h>
|
#include <linux/nospec.h>
|
||||||
@@ -899,8 +900,35 @@ static int tegracam_check_ctrl_ops(
|
|||||||
"ERROR: Can not mix normal and extended sensor controls\n");
|
"ERROR: Can not mix normal and extended sensor controls\n");
|
||||||
return -EINVAL;
|
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)) {
|
if (total_ops != (ops->numctrls + TEGRACAM_DEF_CTRLS)) {
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
|
|||||||
@@ -411,6 +411,7 @@ void release_buffer(struct tegra_channel *chan,
|
|||||||
{
|
{
|
||||||
struct vb2_v4l2_buffer *vbuf = &buf->buf;
|
struct vb2_v4l2_buffer *vbuf = &buf->buf;
|
||||||
s64 frame_arrived_ts = 0;
|
s64 frame_arrived_ts = 0;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
/* release one frame */
|
/* release one frame */
|
||||||
vbuf->sequence = chan->sequence;
|
vbuf->sequence = chan->sequence;
|
||||||
@@ -423,6 +424,7 @@ void release_buffer(struct tegra_channel *chan,
|
|||||||
vb2_set_plane_payload(&vbuf->vb2_buf,
|
vb2_set_plane_payload(&vbuf->vb2_buf,
|
||||||
0, chan->format.sizeimage);
|
0, chan->format.sizeimage);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&chan->capture_state_lock, flags);
|
||||||
/*
|
/*
|
||||||
* WAR to force buffer state if capture state is not good
|
* WAR to force buffer state if capture state is not good
|
||||||
* WAR - After sync point timeout or error frame capture
|
* 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)
|
if (chan->capture_state != CAPTURE_GOOD || vbuf->sequence < 2)
|
||||||
buf->state = VB2_BUF_STATE_ERROR;
|
buf->state = VB2_BUF_STATE_ERROR;
|
||||||
|
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
|
||||||
|
|
||||||
if (chan->sequence == 1) {
|
if (chan->sequence == 1) {
|
||||||
/*
|
/*
|
||||||
@@ -507,6 +510,7 @@ void free_ring_buffers(struct tegra_channel *chan, int frames)
|
|||||||
{
|
{
|
||||||
struct vb2_v4l2_buffer *vbuf;
|
struct vb2_v4l2_buffer *vbuf;
|
||||||
s64 frame_arrived_ts = 0;
|
s64 frame_arrived_ts = 0;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock(&chan->buffer_lock);
|
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,
|
vb2_set_plane_payload(&vbuf->vb2_buf,
|
||||||
0, chan->format.sizeimage);
|
0, chan->format.sizeimage);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&chan->capture_state_lock, flags);
|
||||||
/*
|
/*
|
||||||
* WAR to force buffer state if capture state is not good
|
* WAR to force buffer state if capture state is not good
|
||||||
* WAR - After sync point timeout or error frame capture
|
* 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->released_bufs < 2)
|
||||||
chan->buffer_state[chan->free_index] =
|
chan->buffer_state[chan->free_index] =
|
||||||
VB2_BUF_STATE_ERROR;
|
VB2_BUF_STATE_ERROR;
|
||||||
|
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
|
||||||
|
|
||||||
if (chan->sequence == 1) {
|
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)
|
static void update_state_to_buffer(struct tegra_channel *chan, int state)
|
||||||
{
|
{
|
||||||
int save_index = ((int)chan->save_index - PREVIOUS_BUFFER_DEC_INDEX);
|
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 */
|
/* save index decrements by 2 as 3 bufs are added in ring buffer */
|
||||||
if (save_index < 0)
|
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 */
|
/* update state for the previous buffer */
|
||||||
chan->buffer_state[save_index] = state;
|
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 */
|
/* for timeout/error case update the current buffer state as well */
|
||||||
if (chan->capture_state != CAPTURE_GOOD)
|
if (chan->capture_state != CAPTURE_GOOD)
|
||||||
chan->buffer_state[chan->save_index] = state;
|
chan->buffer_state[chan->save_index] = state;
|
||||||
|
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tegra_channel_ring_buffer(struct tegra_channel *chan,
|
void tegra_channel_ring_buffer(struct tegra_channel *chan,
|
||||||
struct vb2_v4l2_buffer *vb,
|
struct vb2_v4l2_buffer *vb,
|
||||||
struct timespec64 *ts, int state)
|
struct timespec64 *ts, int state)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
if (!chan->bfirst_fstart)
|
if (!chan->bfirst_fstart)
|
||||||
chan->bfirst_fstart = true;
|
chan->bfirst_fstart = true;
|
||||||
else
|
else
|
||||||
update_state_to_buffer(chan, state);
|
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 */
|
/* Capture state is not GOOD, release all buffers and re-init state */
|
||||||
if (chan->capture_state != CAPTURE_GOOD) {
|
if (chan->capture_state != CAPTURE_GOOD) {
|
||||||
free_ring_buffers(chan, chan->num_buffers);
|
free_ring_buffers(chan, chan->num_buffers);
|
||||||
tegra_channel_init_ring_buffer(chan);
|
tegra_channel_init_ring_buffer(chan);
|
||||||
|
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/* TODO: granular time code information */
|
/* TODO: granular time code information */
|
||||||
vb->timecode.seconds = ts->tv_sec;
|
vb->timecode.seconds = ts->tv_sec;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
|
||||||
|
|
||||||
/* release buffer N at N+2 frame start event */
|
/* release buffer N at N+2 frame start event */
|
||||||
if (chan->num_buffers >= (chan->capture_queue_depth - 1))
|
if (chan->num_buffers >= (chan->capture_queue_depth - 1))
|
||||||
|
|||||||
Reference in New Issue
Block a user