/*
 * Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#define pr_fmt(fmt) "seemp: %s: " fmt, __func__

#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/seemp_instrumentation.h>
#include <soc/qcom/scm.h>

#include "seemp_logk.h"
#include "seemp_ringbuf.h"

#ifndef VM_RESERVED
#define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
#endif

#define MASK_BUFFER_SIZE 256
#define FOUR_MB 4
#define YEAR_BASE 1900

#define EL2_SCM_ID 0x02001902

static struct seemp_logk_dev *slogk_dev;

static unsigned int ring_sz = FOUR_MB;

/*
 * default is besteffort, apps do not get blocked
 */
static unsigned int block_apps;


/*
 * When this flag is turned on,
 * kmalloc should be used for ring buf allocation
 * otherwise it is vmalloc.
 * default is to use vmalloc
 * kmalloc has a limit of 4MB
 */
unsigned int kmalloc_flag;

static struct class *cl;

static rwlock_t filter_lock;
static struct seemp_source_mask *pmask;
static unsigned int num_sources;

static void *el2_shared_mem;
static struct task_struct *rtic_thread;

static long seemp_logk_reserve_rdblks(
		struct seemp_logk_dev *sdev, unsigned long arg);
static long seemp_logk_set_mask(unsigned long arg);
static long seemp_logk_set_mapping(unsigned long arg);
static long seemp_logk_check_filter(unsigned long arg);
static int seemp_logk_rtic_thread(void *data);

void* (*seemp_logk_kernel_begin)(char **buf);

void (*seemp_logk_kernel_end)(void *blck);

/*
 * the last param is the permission bits *
 * kernel logging is done in three steps:
 * (1)  fetch a block, fill everything except payload.
 * (2)  return payload pointer to the caller.
 * (3)  caller fills its data directly into the payload area.
 * (4)  caller invoked finish_record(), to finish writing.
 */
void *seemp_logk_kernel_start_record(char **buf)
{
	struct seemp_logk_blk *blk;
	struct timespec now;
	struct tm ts;
	int idx;
	int ret;

	DEFINE_WAIT(write_wait);

	ret = 0;
	idx = 0;
	now = current_kernel_time();
	blk = ringbuf_fetch_wr_block(slogk_dev);
	if (!blk) {
		/*
		 * there is no blk to write
		 * if block_apps == 0; quietly return
		 */
		if (!block_apps) {
			*buf = NULL;
			return NULL;
		}
		/*else wait for the blks to be available*/
		while (1) {
			mutex_lock(&slogk_dev->lock);
			prepare_to_wait(&slogk_dev->writers_wq,
				&write_wait, TASK_INTERRUPTIBLE);
			ret = (slogk_dev->num_write_avail_blks <= 0);
			if (!ret) {
				/* don't have to wait*/
				break;
			}
			mutex_unlock(&slogk_dev->lock);
			if (signal_pending(current)) {
				ret = -EINTR;
				break;
			}
			schedule();
		}

		finish_wait(&slogk_dev->writers_wq, &write_wait);
		if (ret)
			return NULL;

		idx = slogk_dev->write_idx;
		slogk_dev->write_idx =
			(slogk_dev->write_idx + 1) % slogk_dev->num_tot_blks;
		slogk_dev->num_write_avail_blks--;
		slogk_dev->num_write_in_prog_blks++;
		slogk_dev->num_writers++;

		blk = &slogk_dev->ring[idx];
		/*mark block invalid*/
		blk->status = 0x0;
		mutex_unlock(&slogk_dev->lock);
	}

	blk->version = OBSERVER_VERSION;
	blk->pid = current->tgid;
	blk->tid = current->pid;
	blk->uid = (current_uid()).val;
	blk->sec = now.tv_sec;
	blk->nsec = now.tv_nsec;
	strlcpy(blk->appname, current->comm, TASK_COMM_LEN);
	time_to_tm(now.tv_sec, 0, &ts);
	ts.tm_year += YEAR_BASE;
	ts.tm_mon += 1;

	snprintf(blk->ts, TS_SIZE, "%04ld-%02d-%02d %02d:%02d:%02d",
			ts.tm_year, ts.tm_mon, ts.tm_mday,
			ts.tm_hour, ts.tm_min, ts.tm_sec);

	*buf = blk->payload.msg;

	return blk;
}

void seemp_logk_kernel_end_record(void *blck)
{
	struct seemp_logk_blk *blk = (struct seemp_logk_blk *)blck;

	if (blk) {
		/*update status at the very end*/
		blk->status |= 0x1;
		blk->uid =  (current_uid()).val;

		ringbuf_finish_writer(slogk_dev, blk);
	}
}

static int seemp_logk_usr_record(const char __user *buf, size_t count)
{
	struct seemp_logk_blk *blk;
	struct seemp_logk_blk usr_blk;
	struct seemp_logk_blk *local_blk;
	struct timespec now;
	struct tm ts;
	int idx, ret;

	DEFINE_WAIT(write_wait);

	if (buf) {
		local_blk = (struct seemp_logk_blk *)buf;
		if (copy_from_user(&usr_blk.pid, &local_blk->pid,
					sizeof(usr_blk.pid)) != 0)
			return -EFAULT;
		if (copy_from_user(&usr_blk.tid, &local_blk->tid,
					sizeof(usr_blk.tid)) != 0)
			return -EFAULT;
		if (copy_from_user(&usr_blk.uid, &local_blk->uid,
					sizeof(usr_blk.uid)) != 0)
			return -EFAULT;
		if (copy_from_user(&usr_blk.len, &local_blk->len,
					sizeof(usr_blk.len)) != 0)
			return -EFAULT;
		if (copy_from_user(&usr_blk.payload, &local_blk->payload,
					sizeof(struct blk_payload)) != 0)
			return -EFAULT;
	} else {
		return -EFAULT;
	}
	idx = ret = 0;
	now = current_kernel_time();
	blk = ringbuf_fetch_wr_block(slogk_dev);
	if (!blk) {
		if (!block_apps)
			return 0;
		while (1) {
			mutex_lock(&slogk_dev->lock);
			prepare_to_wait(&slogk_dev->writers_wq,
					&write_wait,
					TASK_INTERRUPTIBLE);
			ret = (slogk_dev->num_write_avail_blks <= 0);
			if (!ret)
				break;
			mutex_unlock(&slogk_dev->lock);
			if (signal_pending(current)) {
				ret = -EINTR;
				break;
			}
			schedule();
		}
		finish_wait(&slogk_dev->writers_wq, &write_wait);
		if (ret)
			return -EINTR;

		idx = slogk_dev->write_idx;
		slogk_dev->write_idx =
			(slogk_dev->write_idx + 1) % slogk_dev->num_tot_blks;
		slogk_dev->num_write_avail_blks--;
		slogk_dev->num_write_in_prog_blks++;
		slogk_dev->num_writers++;
		blk = &slogk_dev->ring[idx];
		/*mark block invalid*/
		blk->status = 0x0;
		mutex_unlock(&slogk_dev->lock);
	}
	if (usr_blk.len > sizeof(struct blk_payload)-1)
		usr_blk.len = sizeof(struct blk_payload)-1;

	memcpy(&blk->payload, &usr_blk.payload, sizeof(struct blk_payload));
	blk->pid = usr_blk.pid;
	blk->uid = usr_blk.uid;
	blk->tid = usr_blk.tid;
	blk->sec = now.tv_sec;
	blk->nsec = now.tv_nsec;
	time_to_tm(now.tv_sec, 0, &ts);
	ts.tm_year += YEAR_BASE;
	ts.tm_mon += 1;
	snprintf(blk->ts, TS_SIZE, "%02ld-%02d-%02d %02d:%02d:%02d",
			ts.tm_year, ts.tm_mon, ts.tm_mday,
			ts.tm_hour, ts.tm_min, ts.tm_sec);
	strlcpy(blk->appname, current->comm, TASK_COMM_LEN);
	blk->status |= 0x1;
	ringbuf_finish_writer(slogk_dev, blk);
	return ret;
}

static void seemp_logk_attach(void)
{
	seemp_logk_kernel_end = seemp_logk_kernel_end_record;
	seemp_logk_kernel_begin = seemp_logk_kernel_start_record;
}

static void seemp_logk_detach(void)
{
	seemp_logk_kernel_begin = NULL;
	seemp_logk_kernel_end = NULL;
}

static ssize_t
seemp_logk_write(struct file *file, const char __user *buf, size_t count,
		loff_t *ppos)
{
	return seemp_logk_usr_record(buf, count);
}

static int
seemp_logk_open(struct inode *inode, struct file *filp)
{
	int ret;

	/*disallow seeks on this file*/
	ret = nonseekable_open(inode, filp);
	if (ret) {
		pr_err("ret= %d\n", ret);
		return ret;
	}

	slogk_dev->minor = iminor(inode);
	filp->private_data = slogk_dev;

	return 0;
}

static bool seemp_logk_get_bit_from_vector(__u8 *pVec, __u32 index)
{
	unsigned int byte_num = index/8;
	unsigned int bit_num = index%8;
	unsigned char byte;

	if (byte_num >= MASK_BUFFER_SIZE)
		return false;

	byte = pVec[byte_num];

	return !(byte & (1 << bit_num));
}

static long seemp_logk_ioctl(struct file *filp, unsigned int cmd,
		unsigned long arg)
{
	struct seemp_logk_dev *sdev;
	int ret;

	sdev = (struct seemp_logk_dev *) filp->private_data;

	if (cmd == SEEMP_CMD_RESERVE_RDBLKS) {
		return seemp_logk_reserve_rdblks(sdev, arg);
	} else if (cmd == SEEMP_CMD_RELEASE_RDBLKS) {
		mutex_lock(&sdev->lock);
		sdev->read_idx = (sdev->read_idx + sdev->num_read_in_prog_blks)
			% sdev->num_tot_blks;
		sdev->num_write_avail_blks += sdev->num_read_in_prog_blks;
		ret = sdev->num_read_in_prog_blks;
		sdev->num_read_in_prog_blks = 0;
		/*wake up any waiting writers*/
		mutex_unlock(&sdev->lock);
		if (ret && block_apps)
			wake_up_interruptible(&sdev->writers_wq);
	} else if (cmd == SEEMP_CMD_GET_RINGSZ) {
		if (copy_to_user((unsigned int *)arg, &sdev->ring_sz,
				sizeof(unsigned int)))
			return -EFAULT;
	} else if (cmd == SEEMP_CMD_GET_BLKSZ) {
		if (copy_to_user((unsigned int *)arg, &sdev->blk_sz,
				sizeof(unsigned int)))
			return -EFAULT;
	} else if (cmd == SEEMP_CMD_SET_MASK) {
		return seemp_logk_set_mask(arg);
	} else if (cmd == SEEMP_CMD_SET_MAPPING) {
		return seemp_logk_set_mapping(arg);
	} else if (cmd == SEEMP_CMD_CHECK_FILTER) {
		return seemp_logk_check_filter(arg);
	}
	pr_err("Invalid Request %X\n", cmd);
	return -ENOIOCTLCMD;
}

static long seemp_logk_reserve_rdblks(
		struct seemp_logk_dev *sdev, unsigned long arg)
{
	int ret;
	struct read_range rrange;

	DEFINE_WAIT(read_wait);

	mutex_lock(&sdev->lock);
	if (sdev->num_writers > 0 || sdev->num_read_avail_blks <= 0) {
		ret = -EPERM;
		pr_debug("(reserve): blocking, cannot read.\n");
		pr_debug("num_writers=%d num_read_avail_blks=%d\n",
		sdev->num_writers,
				sdev->num_read_avail_blks);
		mutex_unlock(&sdev->lock);
		/*
		 * unlock the device
		 * wait on a wait queue
		 * after wait, grab the dev lock again
		 */
		while (1) {
			mutex_lock(&sdev->lock);
			prepare_to_wait(&sdev->readers_wq, &read_wait,
					TASK_INTERRUPTIBLE);
			ret = (sdev->num_writers > 0 ||
					sdev->num_read_avail_blks <= 0);
			if (!ret) {
				/*don't have to wait*/
				break;
			}
			mutex_unlock(&sdev->lock);
			if (signal_pending(current)) {
				ret = -EINTR;
				break;
			}
			schedule();
		}

		finish_wait(&sdev->readers_wq, &read_wait);
		if (ret)
			return -EINTR;
	}

	/*sdev->lock is held at this point*/
	sdev->num_read_in_prog_blks = sdev->num_read_avail_blks;
	sdev->num_read_avail_blks = 0;
	rrange.start_idx = sdev->read_idx;
	rrange.num = sdev->num_read_in_prog_blks;
	mutex_unlock(&sdev->lock);

	if (copy_to_user((unsigned int *)arg, &rrange,
			sizeof(struct read_range)))
		return -EFAULT;

	return 0;
}

static long seemp_logk_set_mask(unsigned long arg)
{
	__u8 buffer[256];
	int i;
	unsigned int num_elements;

	if (copy_from_user(&num_elements,
		(unsigned int __user *) arg, sizeof(unsigned int)))
		return -EFAULT;

	read_lock(&filter_lock);
	if (num_sources == 0) {
		read_unlock(&filter_lock);
		return -EINVAL;
	}

	if (num_elements == 0 ||
		DIV_ROUND_UP(num_sources, 8) > MASK_BUFFER_SIZE) {
		read_unlock(&filter_lock);
		return -EINVAL;
	}

	if (copy_from_user(buffer,
			(__u8 *)arg, DIV_ROUND_UP(num_sources, 8))) {
		read_unlock(&filter_lock);
		return -EFAULT;
	}

	read_unlock(&filter_lock);
	write_lock(&filter_lock);
	if (num_elements != num_sources) {
		write_unlock(&filter_lock);
		return -EPERM;
	}

	for (i = 0; i < num_sources; i++) {
		pmask[i].isOn =
				seemp_logk_get_bit_from_vector(
					(__u8 *)buffer, i);
	}
	write_unlock(&filter_lock);
	return 0;
}

static long seemp_logk_set_mapping(unsigned long arg)
{
	__u32 num_elements;
	__u32 *pbuffer;
	int i;
	struct seemp_source_mask *pnewmask;

	if (copy_from_user(&num_elements,
					(__u32 __user *)arg, sizeof(__u32)))
		return -EFAULT;

	if ((num_elements == 0) || (num_elements >
		(UINT_MAX / sizeof(struct seemp_source_mask))))
		return -EFAULT;

	write_lock(&filter_lock);
	if (pmask != NULL) {
		/*
		 * Mask is getting set again.
		 * seemp_core was probably restarted.
		 */
		struct seemp_source_mask *ptempmask;

		num_sources = 0;
		ptempmask = pmask;
		pmask = NULL;
		kfree(ptempmask);
	}
	write_unlock(&filter_lock);
	pbuffer = kmalloc(sizeof(struct seemp_source_mask)
				* num_elements, GFP_KERNEL);
	if (pbuffer == NULL)
		return -ENOMEM;

	/*
	 * Use our new table as scratch space for now.
	 * We copy an ordered list of hash values into our buffer.
	 */
	if (copy_from_user(pbuffer, &((__u32 __user *)arg)[1],
					num_elements*sizeof(unsigned int))) {
		kfree(pbuffer);
		return -EFAULT;
	}
	/*
	 * We arrange the user data into a more usable form.
	 * This is done in-place.
	 */
	pnewmask = (struct seemp_source_mask *) pbuffer;
	for (i = num_elements - 1; i >= 0; i--) {
		pnewmask[i].hash = pbuffer[i];
		/* Observer is off by default*/
		pnewmask[i].isOn = 0;
	}
	write_lock(&filter_lock);
	pmask = pnewmask;
	num_sources = num_elements;
	write_unlock(&filter_lock);
	return 0;
}

static long seemp_logk_check_filter(unsigned long arg)
{
	int i;
	unsigned int hash = (unsigned int) arg;

	/*
	 * This lock may be a bit long.
	 * If it is a problem, it can be fixed.
	 */
	read_lock(&filter_lock);
	for (i = 0; i < num_sources; i++) {
		if (hash == pmask[i].hash) {
			int result = pmask[i].isOn;

			read_unlock(&filter_lock);
			return result;
		}
	}
	read_unlock(&filter_lock);
	return 0;
}

static int seemp_logk_mmap(struct file *filp,
		struct vm_area_struct *vma)
{
	int ret;
	char *vptr;
	unsigned long length, pfn;
	unsigned long start = vma->vm_start;

	length = vma->vm_end - vma->vm_start;

	if (length > (unsigned long) slogk_dev->ring_sz) {
		pr_err("len check failed\n");
		return -EIO;
	}

	vma->vm_flags |= VM_RESERVED | VM_SHARED;
	vptr = (char *) slogk_dev->ring;
	ret = 0;

	if (kmalloc_flag) {
		ret = remap_pfn_range(vma,
				start,
				virt_to_phys((void *)
				((unsigned long)slogk_dev->ring)) >> PAGE_SHIFT,
				length,
				vma->vm_page_prot);
		if (ret != 0) {
			pr_err("remap_pfn_range() fails with ret = %d\n",
				ret);
			return -EAGAIN;
		}
	} else {
		while (length > 0) {
			pfn = vmalloc_to_pfn(vptr);

			ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE,
					vma->vm_page_prot);
			if (ret < 0) {
				pr_err("remap_pfn_range() fails with ret = %d\n",
					ret);
				return ret;
			}
			start += PAGE_SIZE;
			vptr += PAGE_SIZE;
			length -= PAGE_SIZE;
		}
	}

	if (!rtic_thread && el2_shared_mem) {
		rtic_thread = kthread_run(seemp_logk_rtic_thread,
				NULL, "seemp_logk_rtic_thread");
		if (IS_ERR(rtic_thread)) {
			pr_err("rtic_thread creation failed");
			rtic_thread = NULL;
		}
	}

	return 0;
}

static const struct file_operations seemp_logk_fops = {
	.write = seemp_logk_write,
	.open = seemp_logk_open,
	.unlocked_ioctl = seemp_logk_ioctl,
	.compat_ioctl = seemp_logk_ioctl,
	.mmap = seemp_logk_mmap,
};

static int seemp_logk_rtic_thread(void *data)
{
	struct el2_report_header_t *header;
	__u64 last_sequence_number = 0;
	int last_pos = -1;
	int i;
	int num_entries = (PAGE_SIZE - sizeof(struct el2_report_header_t))
		/ sizeof(struct el2_report_data_t);
	header = (struct el2_report_header_t *) el2_shared_mem;

	while (!kthread_should_stop()) {
		for (i = 1; i < num_entries + 1; i++) {
			struct el2_report_data_t *report;
			int cur_pos = last_pos + i;

			if (cur_pos >= num_entries)
				cur_pos -= num_entries;

			report = el2_shared_mem +
				sizeof(struct el2_report_header_t) +
				cur_pos * sizeof(struct el2_report_data_t);

			/* determine legitimacy of report */
			if (report->report_valid &&
				(last_sequence_number == 0
					|| report->sequence_number >
						last_sequence_number)) {
				seemp_logk_rtic(report->report_type,
					report->actor,
					/* leave this empty until
					 * asset id is provided
					 */
					"",
					report->asset_category,
					report->response);
				last_sequence_number = report->sequence_number;
			} else {
				last_pos = cur_pos - 1;
				break;
			}
		}

		/* periodically check el2 report every second */
		ssleep(1);
	}

	return 0;
}

__init int seemp_logk_init(void)
{
	int ret;
	int devno = 0;
	struct scm_desc desc = {0};

	num_sources = 0;
	kmalloc_flag = 0;
	block_apps = 0;
	pmask = NULL;

	if (kmalloc_flag && ring_sz > FOUR_MB) {
		pr_err("kmalloc cannot allocate > 4MB\n");
		return -ENOMEM;
	}

	ring_sz = ring_sz * SZ_1M;
	if (ring_sz <= 0) {
		pr_err("Too small a ring_sz=%d\n", ring_sz);
		return -EINVAL;
	}

	slogk_dev = kmalloc(sizeof(*slogk_dev), GFP_KERNEL);
	if (slogk_dev == NULL)
		return -ENOMEM;

	slogk_dev->ring_sz = ring_sz;
	slogk_dev->blk_sz = sizeof(struct seemp_logk_blk);
	/*initialize ping-pong buffers*/
	ret = ringbuf_init(slogk_dev);
	if (ret < 0) {
		pr_err("Init Failed, ret = %d\n", ret);
		goto pingpong_fail;
	}

	ret = alloc_chrdev_region(&devno, 0, seemp_LOGK_NUM_DEVS,
			seemp_LOGK_DEV_NAME);
	if (ret < 0) {
		pr_err("alloc_chrdev_region failed with ret = %d\n",
				ret);
		goto register_fail;
	}

	slogk_dev->major = MAJOR(devno);

	pr_debug("logk: major# = %d\n", slogk_dev->major);

	cl = class_create(THIS_MODULE, seemp_LOGK_DEV_NAME);
	if (cl == NULL) {
		pr_err("class create failed");
		goto cdev_fail;
	}
	if (device_create(cl, NULL, devno, NULL,
			seemp_LOGK_DEV_NAME) == NULL) {
		pr_err("device create failed");
		goto class_destroy_fail;
	}
	cdev_init(&(slogk_dev->cdev), &seemp_logk_fops);

	slogk_dev->cdev.owner = THIS_MODULE;
	ret = cdev_add(&(slogk_dev->cdev), MKDEV(slogk_dev->major, 0), 1);
	if (ret) {
		pr_err("cdev_add failed with ret = %d", ret);
		goto class_destroy_fail;
	}

	seemp_logk_attach();
	mutex_init(&slogk_dev->lock);
	init_waitqueue_head(&slogk_dev->readers_wq);
	init_waitqueue_head(&slogk_dev->writers_wq);
	rwlock_init(&filter_lock);

	el2_shared_mem = (void *) __get_free_page(GFP_KERNEL);
	if (el2_shared_mem) {
		desc.arginfo = SCM_ARGS(2, SCM_RW, SCM_VAL);
		desc.args[0] = (uint64_t) virt_to_phys(el2_shared_mem);
		desc.args[1] = PAGE_SIZE;
		ret = scm_call2(EL2_SCM_ID, &desc);
		if (ret || desc.ret[0] || desc.ret[1]) {
			pr_err("SCM call failed with ret val = %d %d %d",
				ret, (int)desc.ret[0], (int)desc.ret[1]);
			free_page((unsigned long) el2_shared_mem);
			el2_shared_mem = NULL;
		}
	}

	return 0;
class_destroy_fail:
	class_destroy(cl);
cdev_fail:
	unregister_chrdev_region(devno, seemp_LOGK_NUM_DEVS);
register_fail:
	ringbuf_cleanup(slogk_dev);
pingpong_fail:
	kfree(slogk_dev);
	return -EPERM;
}

__exit void seemp_logk_cleanup(void)
{
	dev_t devno = MKDEV(slogk_dev->major, slogk_dev->minor);

	if (rtic_thread) {
		kthread_stop(rtic_thread);
		rtic_thread = NULL;
	}

	seemp_logk_detach();

	cdev_del(&slogk_dev->cdev);

	unregister_chrdev_region(devno, seemp_LOGK_NUM_DEVS);
	ringbuf_cleanup(slogk_dev);
	kfree(slogk_dev);

	if (pmask != NULL) {
		kfree(pmask);
		pmask = NULL;
	}
}

module_init(seemp_logk_init);
module_exit(seemp_logk_cleanup);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("seemp Observer");

