// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

#include "mali_kbase_timeline_priv.h"
#include "mali_kbase_tlstream.h"
#include "mali_kbase_tracepoints.h"
#include "mali_kbase_timeline.h"

#include <device/mali_kbase_device.h>

#include <linux/poll.h>
#include <linux/version_compat_defs.h>
#include <linux/anon_inodes.h>

#ifndef MALI_STRIP_KBASE_DEVELOPMENT
/* Development builds need to test instrumentation and enable unprivileged
 * processes to acquire timeline streams, in order to avoid complications
 * with configurations across multiple platforms and systems.
 *
 * Release builds, instead, shall deny access to unprivileged processes
 * because there are no use cases where they are allowed to acquire timeline
 * streams, unless they're given special permissions by a privileged process.
 */
static int kbase_unprivileged_global_profiling = 1;
#else
static int kbase_unprivileged_global_profiling;
#endif

/**
 * kbase_unprivileged_global_profiling_set - set permissions for unprivileged processes
 *
 * @val: String containing value to set. Only strings representing positive
 *       integers are accepted as valid; any non-positive integer (including 0)
 *       is rejected.
 * @kp: Module parameter associated with this method.
 *
 * This method can only be used to enable permissions for unprivileged processes,
 * if they are disabled: for this reason, the only values which are accepted are
 * strings representing positive integers. Since it's impossible to disable
 * permissions once they're set, any integer which is non-positive is rejected,
 * including 0.
 *
 * Return: 0 if success, otherwise error code.
 */
static int kbase_unprivileged_global_profiling_set(const char *val, const struct kernel_param *kp)
{
	int new_val;
	int ret = kstrtoint(val, 0, &new_val);

	if (ret == 0) {
		if (new_val < 1)
			return -EINVAL;

		kbase_unprivileged_global_profiling = 1;
	}

	return ret;
}

static const struct kernel_param_ops kbase_global_unprivileged_profiling_ops = {
	.get = param_get_int,
	.set = kbase_unprivileged_global_profiling_set,
};

module_param_cb(kbase_unprivileged_global_profiling, &kbase_global_unprivileged_profiling_ops,
		&kbase_unprivileged_global_profiling, 0600);

/* The timeline stream file operations functions. */
static ssize_t kbasep_timeline_io_read(struct file *filp, char __user *buffer,
				       size_t size, loff_t *f_pos);
static __poll_t kbasep_timeline_io_poll(struct file *filp, poll_table *wait);
static int kbasep_timeline_io_release(struct inode *inode, struct file *filp);
static int kbasep_timeline_io_fsync(struct file *filp, loff_t start, loff_t end,
				    int datasync);

static bool timeline_is_permitted(void)
{
#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE
	return kbase_unprivileged_global_profiling || perfmon_capable();
#else
	return kbase_unprivileged_global_profiling || capable(CAP_SYS_ADMIN);
#endif
}

/**
 * kbasep_timeline_io_packet_pending - check timeline streams for pending
 *                                     packets
 *
 * @timeline:      Timeline instance
 * @ready_stream:  Pointer to variable where stream will be placed
 * @rb_idx_raw:    Pointer to variable where read buffer index will be placed
 *
 * Function checks all streams for pending packets. It will stop as soon as
 * packet ready to be submitted to user space is detected. Variables under
 * pointers, passed as the parameters to this function will be updated with
 * values pointing to right stream and buffer.
 *
 * Return: non-zero if any of timeline streams has at last one packet ready
 */
static int
kbasep_timeline_io_packet_pending(struct kbase_timeline *timeline,
				  struct kbase_tlstream **ready_stream,
				  unsigned int *rb_idx_raw)
{
	enum tl_stream_type i;

	KBASE_DEBUG_ASSERT(ready_stream);
	KBASE_DEBUG_ASSERT(rb_idx_raw);

	for (i = (enum tl_stream_type)0; i < TL_STREAM_TYPE_COUNT; ++i) {
		struct kbase_tlstream *stream = &timeline->streams[i];
		*rb_idx_raw = atomic_read(&stream->rbi);
		/* Read buffer index may be updated by writer in case of
		 * overflow. Read and write buffer indexes must be
		 * loaded in correct order.
		 */
		smp_rmb();
		if (atomic_read(&stream->wbi) != *rb_idx_raw) {
			*ready_stream = stream;
			return 1;
		}
	}

	return 0;
}

/**
 * kbasep_timeline_has_header_data() - check timeline headers for pending
 *                                     packets
 *
 * @timeline:      Timeline instance
 *
 * Return: non-zero if any of timeline headers has at last one packet ready.
 */
static int kbasep_timeline_has_header_data(struct kbase_timeline *timeline)
{
	return timeline->obj_header_btc || timeline->aux_header_btc
#if MALI_USE_CSF
	       || timeline->csf_tl_reader.tl_header.btc
#endif
		;
}

/**
 * copy_stream_header() - copy timeline stream header.
 *
 * @buffer:      Pointer to the buffer provided by user.
 * @size:        Maximum amount of data that can be stored in the buffer.
 * @copy_len:    Pointer to amount of bytes that has been copied already
 *               within the read system call.
 * @hdr:         Pointer to the stream header.
 * @hdr_size:    Header size.
 * @hdr_btc:     Pointer to the remaining number of bytes to copy.
 *
 * Return: 0 if success, -1 otherwise.
 */
static inline int copy_stream_header(char __user *buffer, size_t size,
				     ssize_t *copy_len, const char *hdr,
				     size_t hdr_size, size_t *hdr_btc)
{
	const size_t offset = hdr_size - *hdr_btc;
	const size_t copy_size = MIN(size - *copy_len, *hdr_btc);

	if (!*hdr_btc)
		return 0;

	if (WARN_ON(*hdr_btc > hdr_size))
		return -1;

	if (copy_to_user(&buffer[*copy_len], &hdr[offset], copy_size))
		return -1;

	*hdr_btc -= copy_size;
	*copy_len += copy_size;

	return 0;
}

/**
 * kbasep_timeline_copy_headers - copy timeline headers to the user
 *
 * @timeline:    Timeline instance
 * @buffer:      Pointer to the buffer provided by user
 * @size:        Maximum amount of data that can be stored in the buffer
 * @copy_len:    Pointer to amount of bytes that has been copied already
 *               within the read system call.
 *
 * This helper function checks if timeline headers have not been sent
 * to the user, and if so, sends them. copy_len is respectively
 * updated.
 *
 * Return: 0 if success, -1 if copy_to_user has failed.
 */
static inline int kbasep_timeline_copy_headers(struct kbase_timeline *timeline,
					       char __user *buffer, size_t size,
					       ssize_t *copy_len)
{
	if (copy_stream_header(buffer, size, copy_len, obj_desc_header,
			       obj_desc_header_size, &timeline->obj_header_btc))
		return -1;

	if (copy_stream_header(buffer, size, copy_len, aux_desc_header,
			       aux_desc_header_size, &timeline->aux_header_btc))
		return -1;
#if MALI_USE_CSF
	if (copy_stream_header(buffer, size, copy_len,
			       timeline->csf_tl_reader.tl_header.data,
			       timeline->csf_tl_reader.tl_header.size,
			       &timeline->csf_tl_reader.tl_header.btc))
		return -1;
#endif
	return 0;
}

/**
 * kbasep_timeline_io_read - copy data from streams to buffer provided by user
 *
 * @filp:   Pointer to file structure
 * @buffer: Pointer to the buffer provided by user
 * @size:   Maximum amount of data that can be stored in the buffer
 * @f_pos:  Pointer to file offset (unused)
 *
 * Return: number of bytes stored in the buffer
 */
static ssize_t kbasep_timeline_io_read(struct file *filp, char __user *buffer,
				       size_t size, loff_t *f_pos)
{
	ssize_t copy_len = 0;
	struct kbase_timeline *timeline;

	KBASE_DEBUG_ASSERT(filp);
	KBASE_DEBUG_ASSERT(f_pos);

	if (WARN_ON(!filp->private_data))
		return -EFAULT;

	timeline = (struct kbase_timeline *)filp->private_data;

	if (!buffer)
		return -EINVAL;

	if (*f_pos < 0)
		return -EINVAL;

	mutex_lock(&timeline->reader_lock);

	while (copy_len < size) {
		struct kbase_tlstream *stream = NULL;
		unsigned int rb_idx_raw = 0;
		unsigned int wb_idx_raw;
		unsigned int rb_idx;
		size_t rb_size;

		if (kbasep_timeline_copy_headers(timeline, buffer, size,
						 &copy_len)) {
			copy_len = -EFAULT;
			break;
		}

		/* If we already read some packets and there is no
		 * packet pending then return back to user.
		 * If we don't have any data yet, wait for packet to be
		 * submitted.
		 */
		if (copy_len > 0) {
			if (!kbasep_timeline_io_packet_pending(
				    timeline, &stream, &rb_idx_raw))
				break;
		} else {
			if (wait_event_interruptible(
				    timeline->event_queue,
				    kbasep_timeline_io_packet_pending(
					    timeline, &stream, &rb_idx_raw))) {
				copy_len = -ERESTARTSYS;
				break;
			}
		}

		if (WARN_ON(!stream)) {
			copy_len = -EFAULT;
			break;
		}

		/* Check if this packet fits into the user buffer.
		 * If so copy its content.
		 */
		rb_idx = rb_idx_raw % PACKET_COUNT;
		rb_size = atomic_read(&stream->buffer[rb_idx].size);
		if (rb_size > size - copy_len)
			break;
		if (copy_to_user(&buffer[copy_len], stream->buffer[rb_idx].data,
				 rb_size)) {
			copy_len = -EFAULT;
			break;
		}

		/* If the distance between read buffer index and write
		 * buffer index became more than PACKET_COUNT, then overflow
		 * happened and we need to ignore the last portion of bytes
		 * that we have just sent to user.
		 */
		smp_rmb();
		wb_idx_raw = atomic_read(&stream->wbi);

		if (wb_idx_raw - rb_idx_raw < PACKET_COUNT) {
			copy_len += rb_size;
			atomic_inc(&stream->rbi);
#if MALI_UNIT_TEST
			atomic_add(rb_size, &timeline->bytes_collected);
#endif /* MALI_UNIT_TEST */

		} else {
			const unsigned int new_rb_idx_raw =
				wb_idx_raw - PACKET_COUNT + 1;
			/* Adjust read buffer index to the next valid buffer */
			atomic_set(&stream->rbi, new_rb_idx_raw);
		}
	}

	mutex_unlock(&timeline->reader_lock);

	return copy_len;
}

/**
 * kbasep_timeline_io_poll - poll timeline stream for packets
 * @filp: Pointer to file structure
 * @wait: Pointer to poll table
 *
 * Return: POLLIN if data can be read without blocking, otherwise zero
 */
static __poll_t kbasep_timeline_io_poll(struct file *filp, poll_table *wait)
{
	struct kbase_tlstream *stream;
	unsigned int rb_idx;
	struct kbase_timeline *timeline;

	KBASE_DEBUG_ASSERT(filp);
	KBASE_DEBUG_ASSERT(wait);

	if (WARN_ON(!filp->private_data))
		return (__force __poll_t)-EFAULT;

	timeline = (struct kbase_timeline *)filp->private_data;

	/* If there are header bytes to copy, read will not block */
	if (kbasep_timeline_has_header_data(timeline))
		return (__force __poll_t)POLLIN;

	poll_wait(filp, &timeline->event_queue, wait);
	if (kbasep_timeline_io_packet_pending(timeline, &stream, &rb_idx))
		return (__force __poll_t)POLLIN;
	return 0;
}

int kbase_timeline_io_acquire(struct kbase_device *kbdev, u32 flags)
{
	/* The timeline stream file operations structure. */
	static const struct file_operations kbasep_tlstream_fops = {
		.owner = THIS_MODULE,
		.release = kbasep_timeline_io_release,
		.read = kbasep_timeline_io_read,
		.poll = kbasep_timeline_io_poll,
		.fsync = kbasep_timeline_io_fsync,
	};
	int err;

	if (!timeline_is_permitted())
		return -EPERM;

	if (WARN_ON(!kbdev) || (flags & ~BASE_TLSTREAM_FLAGS_MASK))
		return -EINVAL;

	err = kbase_timeline_acquire(kbdev, flags);
	if (err)
		return err;

	err = anon_inode_getfd("[mali_tlstream]", &kbasep_tlstream_fops, kbdev->timeline,
			       O_RDONLY | O_CLOEXEC);
	if (err < 0)
		kbase_timeline_release(kbdev->timeline);

	return err;
}

#if IS_ENABLED(CONFIG_DEBUG_FS)
static int kbasep_timeline_io_open(struct inode *in, struct file *file)
{
	struct kbase_device *const kbdev = in->i_private;

	if (WARN_ON(!kbdev))
		return -EFAULT;

	file->private_data = kbdev->timeline;
	return kbase_timeline_acquire(kbdev, BASE_TLSTREAM_FLAGS_MASK &
						     ~BASE_TLSTREAM_JOB_DUMPING_ENABLED);
}

void kbase_timeline_io_debugfs_init(struct kbase_device *const kbdev)
{
	static const struct file_operations kbasep_tlstream_debugfs_fops = {
		.owner = THIS_MODULE,
		.open = kbasep_timeline_io_open,
		.release = kbasep_timeline_io_release,
		.read = kbasep_timeline_io_read,
		.poll = kbasep_timeline_io_poll,
		.fsync = kbasep_timeline_io_fsync,
	};
	struct dentry *file;

	if (WARN_ON(!kbdev) || WARN_ON(IS_ERR_OR_NULL(kbdev->mali_debugfs_directory)))
		return;

	file = debugfs_create_file("tlstream", 0400, kbdev->mali_debugfs_directory, kbdev,
				   &kbasep_tlstream_debugfs_fops);

	if (IS_ERR_OR_NULL(file))
		dev_warn(kbdev->dev, "Unable to create timeline debugfs entry");
}
#else
/*
 * Stub function for when debugfs is disabled
 */
void kbase_timeline_io_debugfs_init(struct kbase_device *const kbdev)
{
}
#endif

/**
 * kbasep_timeline_io_release - release timeline stream descriptor
 * @inode: Pointer to inode structure
 * @filp:  Pointer to file structure
 *
 * Return: always return zero
 */
static int kbasep_timeline_io_release(struct inode *inode, struct file *filp)
{
	CSTD_UNUSED(inode);

	kbase_timeline_release(filp->private_data);
	return 0;
}

static int kbasep_timeline_io_fsync(struct file *filp, loff_t start, loff_t end,
				    int datasync)
{
	CSTD_UNUSED(start);
	CSTD_UNUSED(end);
	CSTD_UNUSED(datasync);

	return kbase_timeline_streams_flush(filp->private_data);
}
