Merge "coresight: byte-cntr: Add the length check in reading data"

This commit is contained in:
qctecmdr 2022-10-26 09:48:13 -07:00 committed by Gerrit - the friendly Code Review server
commit 3c7f6a083d
3 changed files with 76 additions and 22 deletions

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/interrupt.h>
@ -18,7 +18,7 @@
#define CSR_BYTECNTVAL (0x06C)
static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos,
static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, long offset,
size_t bytes, size_t *len, char **bufp)
{
struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
@ -27,12 +27,12 @@ static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos,
if (*len >= bytes)
*len = bytes;
else if (((uint32_t)*ppos % bytes) + *len > bytes)
*len = bytes - ((uint32_t)*ppos % bytes);
else if (((uint32_t)offset % bytes) + *len > bytes)
*len = bytes - ((uint32_t)offset % bytes);
actual = tmc_etr_buf_get_data(etr_buf, *ppos, *len, bufp);
actual = tmc_etr_buf_get_data(etr_buf, offset, *len, bufp);
*len = actual;
if (actual == bytes || (actual + (uint32_t)*ppos) % bytes == 0)
if (actual == bytes || (actual + (uint32_t)offset) % bytes == 0)
atomic_dec(&byte_cntr_data->irq_cnt);
}
@ -50,22 +50,42 @@ static irqreturn_t etr_handler(int irq, void *data)
wake_up(&byte_cntr_data->wq);
}
byte_cntr_data->total_irq++;
return IRQ_HANDLED;
}
static long tmc_etr_flush_remaining_bytes(struct tmc_drvdata *tmcdrvdata, loff_t *ppos,
char **bufpp)
static long tmc_etr_flush_remaining_bytes(struct tmc_drvdata *tmcdrvdata, long offset,
size_t len, char **bufpp)
{
long rwp_offset, req_size, actual = 0;
struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
struct etr_buf *etr_buf;
struct device *dev;
int rc = 0;
if (!tmcdrvdata)
return -EINVAL;
etr_buf = tmcdrvdata->sysfs_buf;
dev = &tmcdrvdata->csdev->dev;
rc = pm_runtime_get_sync(dev->parent);
if (rc < 0) {
pm_runtime_put_noidle(dev->parent);
return rc;
}
rwp_offset = tmc_get_rwp_offset(tmcdrvdata);
req_size = ((rwp_offset < *ppos) ? tmcdrvdata->size : 0) +
rwp_offset - *ppos;
pm_runtime_put(dev->parent);
req_size = ((rwp_offset < offset) ? tmcdrvdata->size : 0) +
rwp_offset - offset;
if (req_size > len)
req_size = len;
if (req_size > 0)
actual = tmc_etr_buf_get_data(etr_buf, *ppos, req_size, bufpp);
actual = tmc_etr_buf_get_data(etr_buf, offset, req_size, bufpp);
return actual;
}
@ -85,7 +105,8 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
mutex_lock(&byte_cntr_data->byte_cntr_lock);
if (!byte_cntr_data->read_active) {
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp);
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
byte_cntr_data->offset, len, &bufp);
if (actual > 0) {
len = actual;
goto copy;
@ -104,7 +125,8 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
return -ERESTARTSYS;
mutex_lock(&byte_cntr_data->byte_cntr_lock);
if (!byte_cntr_data->read_active) {
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp);
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
byte_cntr_data->offset, len, &bufp);
if (actual > 0) {
len = actual;
goto copy;
@ -115,11 +137,12 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
}
}
tmc_etr_read_bytes(byte_cntr_data, ppos,
tmc_etr_read_bytes(byte_cntr_data, byte_cntr_data->offset,
byte_cntr_data->block_size, &len, &bufp);
} else {
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp);
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
byte_cntr_data->offset, len, &bufp);
if (actual > 0) {
len = actual;
goto copy;
@ -137,10 +160,12 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
return -EFAULT;
}
if (*ppos + len >= tmcdrvdata->size)
*ppos = 0;
byte_cntr_data->total_size += len;
if (byte_cntr_data->offset + len >= tmcdrvdata->size)
byte_cntr_data->offset = 0;
else
*ppos += len;
byte_cntr_data->offset += len;
goto out;
@ -192,6 +217,8 @@ EXPORT_SYMBOL(tmc_etr_byte_cntr_stop);
static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp)
{
struct byte_cntr *byte_cntr_data = fp->private_data;
struct device *dev = &byte_cntr_data->tmcdrvdata->csdev->dev;
int rc;
mutex_lock(&byte_cntr_data->byte_cntr_lock);
byte_cntr_data->read_active = false;
@ -203,6 +230,21 @@ static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp)
byte_cntr_data->irqctrl_offset, 0);
disable_irq_wake(byte_cntr_data->byte_cntr_irq);
rc = pm_runtime_get_sync(dev->parent);
if (rc < 0) {
pm_runtime_put_noidle(dev->parent);
} else {
byte_cntr_data->rwp_offset =
tmc_get_rwp_offset(byte_cntr_data->tmcdrvdata);
pm_runtime_put(dev->parent);
}
dev_dbg(dev, "send data total size: %lld bytes, irq_cnt: %lld, offset: %lld rwp_offset: %lld\n",
byte_cntr_data->total_size, byte_cntr_data->total_irq,
byte_cntr_data->offset, byte_cntr_data->rwp_offset);
byte_cntr_data->total_irq = 0;
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
return 0;
@ -239,6 +281,8 @@ static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp)
nonseekable_open(in, fp);
byte_cntr_data->enable = true;
byte_cntr_data->read_active = true;
byte_cntr_data->total_size = 0;
byte_cntr_data->offset = tmc_get_rwp_offset(tmcdrvdata);
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
return 0;
}

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CORESIGHT_BYTE_CNTR_H
@ -34,6 +34,10 @@ struct byte_cntr {
const char *class_name;
int irqctrl_offset;
unsigned long offset;
unsigned long rwp_offset;
uint64_t total_size;
uint64_t total_irq;
};
extern void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data);

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Description: CoreSight TMC USB driver
*/
@ -82,6 +82,7 @@ static int usb_bypass_start(struct byte_cntr *byte_cntr_data)
USB_BLK_SIZE / 8);
atomic_set(&byte_cntr_data->irq_cnt, 0);
byte_cntr_data->total_size = 0;
mutex_unlock(&byte_cntr_data->usb_bypass_lock);
return 0;
@ -102,6 +103,10 @@ static void usb_bypass_stop(struct byte_cntr *byte_cntr_data)
wake_up(&byte_cntr_data->usb_wait_wq);
pr_info("coresight: stop usb bypass\n");
coresight_csr_set_byte_cntr(byte_cntr_data->csr, byte_cntr_data->irqctrl_offset, 0);
dev_dbg(&byte_cntr_data->tmcdrvdata->csdev->dev,
"write to usb data total size: %lld bytes, irq_cnt: %lld, offset: %ld\n",
byte_cntr_data->total_size, byte_cntr_data->total_irq, byte_cntr_data->offset);
byte_cntr_data->total_irq = 0;
mutex_unlock(&byte_cntr_data->usb_bypass_lock);
}
@ -172,7 +177,7 @@ static int usb_transfer_small_packet(struct byte_cntr *drvdata, size_t *small_si
"Write data failed:%d\n", ret);
goto out;
}
drvdata->total_size += actual;
atomic_dec(&drvdata->usb_free_buf);
} else {
dev_dbg(&tmcdrvdata->csdev->dev,
@ -289,6 +294,7 @@ static void usb_read_work_fn(struct work_struct *work)
continue;
return;
}
drvdata->total_size += actual_total;
atomic_dec(&drvdata->usb_free_buf);
} else {