// SPDX-License-Identifier: GPL-2.0
/*
 * EFI capsule loader driver.
 *
 * Copyright 2015 Intel Corporation
 */

#define pr_fmt(fmt) "efi: " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/efi.h>
#include <linux/vmalloc.h>

#define NO_FURTHER_WRITE_ACTION -1

/**
 * efi_free_all_buff_pages - free all previous allocated buffer pages
 * @cap_info: pointer to current instance of capsule_info structure
 *
 *	In addition to freeing buffer pages, it flags NO_FURTHER_WRITE_ACTION
 *	to cease processing data in subsequent write(2) calls until close(2)
 *	is called.
 **/
static void efi_free_all_buff_pages(struct capsule_info *cap_info)
{
	while (cap_info->index > 0)
		__free_page(cap_info->pages[--cap_info->index]);

	cap_info->index = NO_FURTHER_WRITE_ACTION;
}

int __efi_capsule_setup_info(struct capsule_info *cap_info)
{
	size_t pages_needed;
	int ret;
	void *temp_page;

	pages_needed = ALIGN(cap_info->total_size, PAGE_SIZE) / PAGE_SIZE;

	if (pages_needed == 0) {
		pr_err("invalid capsule size\n");
		return -EINVAL;
	}

	/* Check if the capsule binary supported */
	ret = efi_capsule_supported(cap_info->header.guid,
				    cap_info->header.flags,
				    cap_info->header.imagesize,
				    &cap_info->reset_type);
	if (ret) {
		pr_err("capsule not supported\n");
		return ret;
	}

	temp_page = krealloc(cap_info->pages,
			     pages_needed * sizeof(void *),
			     GFP_KERNEL | __GFP_ZERO);
	if (!temp_page)
		return -ENOMEM;

	cap_info->pages = temp_page;

	temp_page = krealloc(cap_info->phys,
			     pages_needed * sizeof(phys_addr_t *),
			     GFP_KERNEL | __GFP_ZERO);
	if (!temp_page)
		return -ENOMEM;

	cap_info->phys = temp_page;

	return 0;
}

/**
 * efi_capsule_setup_info - obtain the efi capsule header in the binary and
 *			    setup capsule_info structure
 * @cap_info: pointer to current instance of capsule_info structure
 * @kbuff: a mapped first page buffer pointer
 * @hdr_bytes: the total received number of bytes for efi header
 *
 * Platforms with non-standard capsule update mechanisms can override
 * this __weak function so they can perform any required capsule
 * image munging. See quark_quirk_function() for an example.
 **/
int __weak efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff,
				  size_t hdr_bytes)
{
	/* Only process data block that is larger than efi header size */
	if (hdr_bytes < sizeof(efi_capsule_header_t))
		return 0;

	memcpy(&cap_info->header, kbuff, sizeof(cap_info->header));
	cap_info->total_size = cap_info->header.imagesize;

	return __efi_capsule_setup_info(cap_info);
}

/**
 * efi_capsule_submit_update - invoke the efi_capsule_update API once binary
 *			       upload done
 * @cap_info: pointer to current instance of capsule_info structure
 **/
static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
{
	bool do_vunmap = false;
	int ret;

	/*
	 * cap_info->capsule may have been assigned already by a quirk
	 * handler, so only overwrite it if it is NULL
	 */
	if (!cap_info->capsule) {
		cap_info->capsule = vmap(cap_info->pages, cap_info->index,
					 VM_MAP, PAGE_KERNEL);
		if (!cap_info->capsule)
			return -ENOMEM;
		do_vunmap = true;
	}

	ret = efi_capsule_update(cap_info->capsule, cap_info->phys);
	if (do_vunmap)
		vunmap(cap_info->capsule);
	if (ret) {
		pr_err("capsule update failed\n");
		return ret;
	}

	/* Indicate capsule binary uploading is done */
	cap_info->index = NO_FURTHER_WRITE_ACTION;

	if (cap_info->header.flags & EFI_CAPSULE_PERSIST_ACROSS_RESET) {
		pr_info("Successfully uploaded capsule file with reboot type '%s'\n",
			!cap_info->reset_type ? "RESET_COLD" :
			cap_info->reset_type == 1 ? "RESET_WARM" :
			"RESET_SHUTDOWN");
	} else {
		pr_info("Successfully processed capsule file\n");
	}

	return 0;
}

/**
 * efi_capsule_write - store the capsule binary and pass it to
 *		       efi_capsule_update() API
 * @file: file pointer
 * @buff: buffer pointer
 * @count: number of bytes in @buff
 * @offp: not used
 *
 *	Expectation:
 *	- A user space tool should start at the beginning of capsule binary and
 *	  pass data in sequentially.
 *	- Users should close and re-open this file note in order to upload more
 *	  capsules.
 *	- After an error returned, user should close the file and restart the
 *	  operation for the next try otherwise -EIO will be returned until the
 *	  file is closed.
 *	- An EFI capsule header must be located at the beginning of capsule
 *	  binary file and passed in as first block data of write operation.
 **/
static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
				 size_t count, loff_t *offp)
{
	int ret = 0;
	struct capsule_info *cap_info = file->private_data;
	struct page *page;
	void *kbuff = NULL;
	size_t write_byte;

	if (count == 0)
		return 0;

	/* Return error while NO_FURTHER_WRITE_ACTION is flagged */
	if (cap_info->index < 0)
		return -EIO;

	/* Only alloc a new page when previous page is full */
	if (!cap_info->page_bytes_remain) {
		page = alloc_page(GFP_KERNEL);
		if (!page) {
			ret = -ENOMEM;
			goto failed;
		}

		cap_info->pages[cap_info->index] = page;
		cap_info->phys[cap_info->index] = page_to_phys(page);
		cap_info->page_bytes_remain = PAGE_SIZE;
		cap_info->index++;
	} else {
		page = cap_info->pages[cap_info->index - 1];
	}

	kbuff = kmap(page);
	kbuff += PAGE_SIZE - cap_info->page_bytes_remain;

	/* Copy capsule binary data from user space to kernel space buffer */
	write_byte = min_t(size_t, count, cap_info->page_bytes_remain);
	if (copy_from_user(kbuff, buff, write_byte)) {
		ret = -EFAULT;
		goto fail_unmap;
	}
	cap_info->page_bytes_remain -= write_byte;

	/* Setup capsule binary info structure */
	if (cap_info->header.headersize == 0) {
		ret = efi_capsule_setup_info(cap_info, kbuff - cap_info->count,
					     cap_info->count + write_byte);
		if (ret)
			goto fail_unmap;
	}

	cap_info->count += write_byte;
	kunmap(page);

	/* Submit the full binary to efi_capsule_update() API */
	if (cap_info->header.headersize > 0 &&
	    cap_info->count >= cap_info->total_size) {
		if (cap_info->count > cap_info->total_size) {
			pr_err("capsule upload size exceeded header defined size\n");
			ret = -EINVAL;
			goto failed;
		}

		ret = efi_capsule_submit_update(cap_info);
		if (ret)
			goto failed;
	}

	return write_byte;

fail_unmap:
	kunmap(page);
failed:
	efi_free_all_buff_pages(cap_info);
	return ret;
}

/**
 * efi_capsule_flush - called by file close or file flush
 * @file: file pointer
 * @id: not used
 *
 *	If a capsule is being partially uploaded then calling this function
 *	will be treated as upload termination and will free those completed
 *	buffer pages and -ECANCELED will be returned.
 **/
static int efi_capsule_flush(struct file *file, fl_owner_t id)
{
	int ret = 0;
	struct capsule_info *cap_info = file->private_data;

	if (cap_info->index > 0) {
		pr_err("capsule upload not complete\n");
		efi_free_all_buff_pages(cap_info);
		ret = -ECANCELED;
	}

	return ret;
}

/**
 * efi_capsule_release - called by file close
 * @inode: not used
 * @file: file pointer
 *
 *	We will not free successfully submitted pages since efi update
 *	requires data to be maintained across system reboot.
 **/
static int efi_capsule_release(struct inode *inode, struct file *file)
{
	struct capsule_info *cap_info = file->private_data;

	kfree(cap_info->pages);
	kfree(cap_info->phys);
	kfree(file->private_data);
	file->private_data = NULL;
	return 0;
}

/**
 * efi_capsule_open - called by file open
 * @inode: not used
 * @file: file pointer
 *
 *	Will allocate each capsule_info memory for each file open call.
 *	This provided the capability to support multiple file open feature
 *	where user is not needed to wait for others to finish in order to
 *	upload their capsule binary.
 **/
static int efi_capsule_open(struct inode *inode, struct file *file)
{
	struct capsule_info *cap_info;

	cap_info = kzalloc(sizeof(*cap_info), GFP_KERNEL);
	if (!cap_info)
		return -ENOMEM;

	cap_info->pages = kzalloc(sizeof(void *), GFP_KERNEL);
	if (!cap_info->pages) {
		kfree(cap_info);
		return -ENOMEM;
	}

	cap_info->phys = kzalloc(sizeof(void *), GFP_KERNEL);
	if (!cap_info->phys) {
		kfree(cap_info->pages);
		kfree(cap_info);
		return -ENOMEM;
	}

	file->private_data = cap_info;

	return 0;
}

static const struct file_operations efi_capsule_fops = {
	.owner = THIS_MODULE,
	.open = efi_capsule_open,
	.write = efi_capsule_write,
	.flush = efi_capsule_flush,
	.release = efi_capsule_release,
	.llseek = no_llseek,
};

static struct miscdevice efi_capsule_misc = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "efi_capsule_loader",
	.fops = &efi_capsule_fops,
};

static int __init efi_capsule_loader_init(void)
{
	int ret;

	if (!efi_enabled(EFI_RUNTIME_SERVICES))
		return -ENODEV;

	ret = misc_register(&efi_capsule_misc);
	if (ret)
		pr_err("Unable to register capsule loader device\n");

	return ret;
}
module_init(efi_capsule_loader_init);

static void __exit efi_capsule_loader_exit(void)
{
	misc_deregister(&efi_capsule_misc);
}
module_exit(efi_capsule_loader_exit);

MODULE_DESCRIPTION("EFI capsule firmware binary loader");
MODULE_LICENSE("GPL v2");
