// SPDX-License-Identifier: GPL-2.0-only
/*
 * AMD Secure Encrypted Virtualization (SEV) interface
 *
 * Copyright (C) 2016,2019 Advanced Micro Devices, Inc.
 *
 * Author: Brijesh Singh <brijesh.singh@amd.com>
 */

#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/spinlock_types.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/hw_random.h>
#include <linux/ccp.h>
#include <linux/firmware.h>
#include <linux/panic_notifier.h>
#include <linux/gfp.h>
#include <linux/cpufeature.h>
#include <linux/fs.h>
#include <linux/fs_struct.h>
#include <linux/psp.h>
#include <linux/amd-iommu.h>
#include <linux/crash_dump.h>

#include <asm/smp.h>
#include <asm/cacheflush.h>
#include <asm/e820/types.h>
#include <asm/sev.h>
#include <asm/msr.h>

#include "psp-dev.h"
#include "sev-dev.h"

#define DEVICE_NAME		"sev"
#define SEV_FW_FILE		"amd/sev.fw"
#define SEV_FW_NAME_SIZE	64

/* Minimum firmware version required for the SEV-SNP support */
#define SNP_MIN_API_MAJOR	1
#define SNP_MIN_API_MINOR	51

/*
 * Maximum number of firmware-writable buffers that might be specified
 * in the parameters of a legacy SEV command buffer.
 */
#define CMD_BUF_FW_WRITABLE_MAX 2

/* Leave room in the descriptor array for an end-of-list indicator. */
#define CMD_BUF_DESC_MAX (CMD_BUF_FW_WRITABLE_MAX + 1)

static DEFINE_MUTEX(sev_cmd_mutex);
static struct sev_misc_dev *misc_dev;

static int psp_cmd_timeout = 100;
module_param(psp_cmd_timeout, int, 0644);
MODULE_PARM_DESC(psp_cmd_timeout, " default timeout value, in seconds, for PSP commands");

static int psp_probe_timeout = 5;
module_param(psp_probe_timeout, int, 0644);
MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe");

static char *init_ex_path;
module_param(init_ex_path, charp, 0444);
MODULE_PARM_DESC(init_ex_path, " Path for INIT_EX data; if set try INIT_EX");

static bool psp_init_on_probe = true;
module_param(psp_init_on_probe, bool, 0444);
MODULE_PARM_DESC(psp_init_on_probe, "  if true, the PSP will be initialized on module init. Else the PSP will be initialized on the first command requiring it");

#if IS_ENABLED(CONFIG_PCI_TSM)
static bool sev_tio_enabled = true;
module_param_named(tio, sev_tio_enabled, bool, 0444);
MODULE_PARM_DESC(tio, "Enables TIO in SNP_INIT_EX");
#else
static const bool sev_tio_enabled = false;
#endif

MODULE_FIRMWARE("amd/amd_sev_fam17h_model0xh.sbin"); /* 1st gen EPYC */
MODULE_FIRMWARE("amd/amd_sev_fam17h_model3xh.sbin"); /* 2nd gen EPYC */
MODULE_FIRMWARE("amd/amd_sev_fam19h_model0xh.sbin"); /* 3rd gen EPYC */
MODULE_FIRMWARE("amd/amd_sev_fam19h_model1xh.sbin"); /* 4th gen EPYC */

static bool psp_dead;
static int psp_timeout;

enum snp_hv_fixed_pages_state {
	ALLOCATED,
	HV_FIXED,
};

struct snp_hv_fixed_pages_entry {
	struct list_head list;
	struct page *page;
	unsigned int order;
	bool free;
	enum snp_hv_fixed_pages_state page_state;
};

static LIST_HEAD(snp_hv_fixed_pages);

/* Trusted Memory Region (TMR):
 *   The TMR is a 1MB area that must be 1MB aligned.  Use the page allocator
 *   to allocate the memory, which will return aligned memory for the specified
 *   allocation order.
 *
 * When SEV-SNP is enabled the TMR needs to be 2MB aligned and 2MB sized.
 */
#define SEV_TMR_SIZE		(1024 * 1024)
#define SNP_TMR_SIZE		(2 * 1024 * 1024)

static void *sev_es_tmr;
static size_t sev_es_tmr_size = SEV_TMR_SIZE;

/* INIT_EX NV Storage:
 *   The NV Storage is a 32Kb area and must be 4Kb page aligned.  Use the page
 *   allocator to allocate the memory, which will return aligned memory for the
 *   specified allocation order.
 */
#define NV_LENGTH (32 * 1024)
static void *sev_init_ex_buffer;

static void __sev_firmware_shutdown(struct sev_device *sev, bool panic);

static int snp_shutdown_on_panic(struct notifier_block *nb,
				 unsigned long reason, void *arg);

static struct notifier_block snp_panic_notifier = {
	.notifier_call = snp_shutdown_on_panic,
};

static inline bool sev_version_greater_or_equal(u8 maj, u8 min)
{
	struct sev_device *sev = psp_master->sev_data;

	if (sev->api_major > maj)
		return true;

	if (sev->api_major == maj && sev->api_minor >= min)
		return true;

	return false;
}

static void sev_irq_handler(int irq, void *data, unsigned int status)
{
	struct sev_device *sev = data;
	int reg;

	/* Check if it is command completion: */
	if (!(status & SEV_CMD_COMPLETE))
		return;

	/* Check if it is SEV command completion: */
	reg = ioread32(sev->io_regs + sev->vdata->cmdresp_reg);
	if (FIELD_GET(PSP_CMDRESP_RESP, reg)) {
		sev->int_rcvd = 1;
		wake_up(&sev->int_queue);
	}
}

static int sev_wait_cmd_ioc(struct sev_device *sev,
			    unsigned int *reg, unsigned int timeout)
{
	int ret;

	/*
	 * If invoked during panic handling, local interrupts are disabled,
	 * so the PSP command completion interrupt can't be used. Poll for
	 * PSP command completion instead.
	 */
	if (irqs_disabled()) {
		unsigned long timeout_usecs = (timeout * USEC_PER_SEC) / 10;

		/* Poll for SEV command completion: */
		while (timeout_usecs--) {
			*reg = ioread32(sev->io_regs + sev->vdata->cmdresp_reg);
			if (*reg & PSP_CMDRESP_RESP)
				return 0;

			udelay(10);
		}
		return -ETIMEDOUT;
	}

	ret = wait_event_timeout(sev->int_queue,
			sev->int_rcvd, timeout * HZ);
	if (!ret)
		return -ETIMEDOUT;

	*reg = ioread32(sev->io_regs + sev->vdata->cmdresp_reg);

	return 0;
}

static int sev_cmd_buffer_len(int cmd)
{
	switch (cmd) {
	case SEV_CMD_INIT:			return sizeof(struct sev_data_init);
	case SEV_CMD_INIT_EX:                   return sizeof(struct sev_data_init_ex);
	case SEV_CMD_SNP_SHUTDOWN_EX:		return sizeof(struct sev_data_snp_shutdown_ex);
	case SEV_CMD_SNP_INIT_EX:		return sizeof(struct sev_data_snp_init_ex);
	case SEV_CMD_PLATFORM_STATUS:		return sizeof(struct sev_user_data_status);
	case SEV_CMD_PEK_CSR:			return sizeof(struct sev_data_pek_csr);
	case SEV_CMD_PEK_CERT_IMPORT:		return sizeof(struct sev_data_pek_cert_import);
	case SEV_CMD_PDH_CERT_EXPORT:		return sizeof(struct sev_data_pdh_cert_export);
	case SEV_CMD_LAUNCH_START:		return sizeof(struct sev_data_launch_start);
	case SEV_CMD_LAUNCH_UPDATE_DATA:	return sizeof(struct sev_data_launch_update_data);
	case SEV_CMD_LAUNCH_UPDATE_VMSA:	return sizeof(struct sev_data_launch_update_vmsa);
	case SEV_CMD_LAUNCH_FINISH:		return sizeof(struct sev_data_launch_finish);
	case SEV_CMD_LAUNCH_MEASURE:		return sizeof(struct sev_data_launch_measure);
	case SEV_CMD_ACTIVATE:			return sizeof(struct sev_data_activate);
	case SEV_CMD_DEACTIVATE:		return sizeof(struct sev_data_deactivate);
	case SEV_CMD_DECOMMISSION:		return sizeof(struct sev_data_decommission);
	case SEV_CMD_GUEST_STATUS:		return sizeof(struct sev_data_guest_status);
	case SEV_CMD_DBG_DECRYPT:		return sizeof(struct sev_data_dbg);
	case SEV_CMD_DBG_ENCRYPT:		return sizeof(struct sev_data_dbg);
	case SEV_CMD_SEND_START:		return sizeof(struct sev_data_send_start);
	case SEV_CMD_SEND_UPDATE_DATA:		return sizeof(struct sev_data_send_update_data);
	case SEV_CMD_SEND_UPDATE_VMSA:		return sizeof(struct sev_data_send_update_vmsa);
	case SEV_CMD_SEND_FINISH:		return sizeof(struct sev_data_send_finish);
	case SEV_CMD_RECEIVE_START:		return sizeof(struct sev_data_receive_start);
	case SEV_CMD_RECEIVE_FINISH:		return sizeof(struct sev_data_receive_finish);
	case SEV_CMD_RECEIVE_UPDATE_DATA:	return sizeof(struct sev_data_receive_update_data);
	case SEV_CMD_RECEIVE_UPDATE_VMSA:	return sizeof(struct sev_data_receive_update_vmsa);
	case SEV_CMD_LAUNCH_UPDATE_SECRET:	return sizeof(struct sev_data_launch_secret);
	case SEV_CMD_DOWNLOAD_FIRMWARE:		return sizeof(struct sev_data_download_firmware);
	case SEV_CMD_GET_ID:			return sizeof(struct sev_data_get_id);
	case SEV_CMD_ATTESTATION_REPORT:	return sizeof(struct sev_data_attestation_report);
	case SEV_CMD_SEND_CANCEL:		return sizeof(struct sev_data_send_cancel);
	case SEV_CMD_SNP_GCTX_CREATE:		return sizeof(struct sev_data_snp_addr);
	case SEV_CMD_SNP_LAUNCH_START:		return sizeof(struct sev_data_snp_launch_start);
	case SEV_CMD_SNP_LAUNCH_UPDATE:		return sizeof(struct sev_data_snp_launch_update);
	case SEV_CMD_SNP_ACTIVATE:		return sizeof(struct sev_data_snp_activate);
	case SEV_CMD_SNP_DECOMMISSION:		return sizeof(struct sev_data_snp_addr);
	case SEV_CMD_SNP_PAGE_RECLAIM:		return sizeof(struct sev_data_snp_page_reclaim);
	case SEV_CMD_SNP_GUEST_STATUS:		return sizeof(struct sev_data_snp_guest_status);
	case SEV_CMD_SNP_LAUNCH_FINISH:		return sizeof(struct sev_data_snp_launch_finish);
	case SEV_CMD_SNP_DBG_DECRYPT:		return sizeof(struct sev_data_snp_dbg);
	case SEV_CMD_SNP_DBG_ENCRYPT:		return sizeof(struct sev_data_snp_dbg);
	case SEV_CMD_SNP_PAGE_UNSMASH:		return sizeof(struct sev_data_snp_page_unsmash);
	case SEV_CMD_SNP_PLATFORM_STATUS:	return sizeof(struct sev_data_snp_addr);
	case SEV_CMD_SNP_GUEST_REQUEST:		return sizeof(struct sev_data_snp_guest_request);
	case SEV_CMD_SNP_CONFIG:		return sizeof(struct sev_user_data_snp_config);
	case SEV_CMD_SNP_COMMIT:		return sizeof(struct sev_data_snp_commit);
	case SEV_CMD_SNP_FEATURE_INFO:		return sizeof(struct sev_data_snp_feature_info);
	case SEV_CMD_SNP_VLEK_LOAD:		return sizeof(struct sev_user_data_snp_vlek_load);
	default:				return sev_tio_cmd_buffer_len(cmd);
	}

	return 0;
}

static struct file *open_file_as_root(const char *filename, int flags, umode_t mode)
{
	struct path root __free(path_put) = {};

	task_lock(&init_task);
	get_fs_root(init_task.fs, &root);
	task_unlock(&init_task);

	CLASS(prepare_creds, cred)();
	if (!cred)
		return ERR_PTR(-ENOMEM);

	cred->fsuid = GLOBAL_ROOT_UID;

	scoped_with_creds(cred)
		return file_open_root(&root, filename, flags, mode);
}

static int sev_read_init_ex_file(void)
{
	struct sev_device *sev = psp_master->sev_data;
	struct file *fp;
	ssize_t nread;

	lockdep_assert_held(&sev_cmd_mutex);

	if (!sev_init_ex_buffer)
		return -EOPNOTSUPP;

	fp = open_file_as_root(init_ex_path, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		int ret = PTR_ERR(fp);

		if (ret == -ENOENT) {
			dev_info(sev->dev,
				"SEV: %s does not exist and will be created later.\n",
				init_ex_path);
			ret = 0;
		} else {
			dev_err(sev->dev,
				"SEV: could not open %s for read, error %d\n",
				init_ex_path, ret);
		}
		return ret;
	}

	nread = kernel_read(fp, sev_init_ex_buffer, NV_LENGTH, NULL);
	if (nread != NV_LENGTH) {
		dev_info(sev->dev,
			"SEV: could not read %u bytes to non volatile memory area, ret %ld\n",
			NV_LENGTH, nread);
	}

	dev_dbg(sev->dev, "SEV: read %ld bytes from NV file\n", nread);
	filp_close(fp, NULL);

	return 0;
}

static int sev_write_init_ex_file(void)
{
	struct sev_device *sev = psp_master->sev_data;
	struct file *fp;
	loff_t offset = 0;
	ssize_t nwrite;

	lockdep_assert_held(&sev_cmd_mutex);

	if (!sev_init_ex_buffer)
		return 0;

	fp = open_file_as_root(init_ex_path, O_CREAT | O_WRONLY, 0600);
	if (IS_ERR(fp)) {
		int ret = PTR_ERR(fp);

		dev_err(sev->dev,
			"SEV: could not open file for write, error %d\n",
			ret);
		return ret;
	}

	nwrite = kernel_write(fp, sev_init_ex_buffer, NV_LENGTH, &offset);
	vfs_fsync(fp, 0);
	filp_close(fp, NULL);

	if (nwrite != NV_LENGTH) {
		dev_err(sev->dev,
			"SEV: failed to write %u bytes to non volatile memory area, ret %ld\n",
			NV_LENGTH, nwrite);
		return -EIO;
	}

	dev_dbg(sev->dev, "SEV: write successful to NV file\n");

	return 0;
}

static int sev_write_init_ex_file_if_required(int cmd_id)
{
	lockdep_assert_held(&sev_cmd_mutex);

	if (!sev_init_ex_buffer)
		return 0;

	/*
	 * Only a few platform commands modify the SPI/NV area, but none of the
	 * non-platform commands do. Only INIT(_EX), PLATFORM_RESET, PEK_GEN,
	 * PEK_CERT_IMPORT, and PDH_GEN do.
	 */
	switch (cmd_id) {
	case SEV_CMD_FACTORY_RESET:
	case SEV_CMD_INIT_EX:
	case SEV_CMD_PDH_GEN:
	case SEV_CMD_PEK_CERT_IMPORT:
	case SEV_CMD_PEK_GEN:
		break;
	default:
		return 0;
	}

	return sev_write_init_ex_file();
}

int snp_reclaim_pages(unsigned long paddr, unsigned int npages, bool locked)
{
	int ret, err, i;

	paddr = __sme_clr(ALIGN_DOWN(paddr, PAGE_SIZE));

	for (i = 0; i < npages; i++, paddr += PAGE_SIZE) {
		struct sev_data_snp_page_reclaim data = {0};

		data.paddr = paddr;

		if (locked)
			ret = __sev_do_cmd_locked(SEV_CMD_SNP_PAGE_RECLAIM, &data, &err);
		else
			ret = sev_do_cmd(SEV_CMD_SNP_PAGE_RECLAIM, &data, &err);

		if (ret)
			goto cleanup;

		ret = rmp_make_shared(__phys_to_pfn(paddr), PG_LEVEL_4K);
		if (ret)
			goto cleanup;
	}

	return 0;

cleanup:
	/*
	 * If there was a failure reclaiming the page then it is no longer safe
	 * to release it back to the system; leak it instead.
	 */
	snp_leak_pages(__phys_to_pfn(paddr), npages - i);
	return ret;
}
EXPORT_SYMBOL_GPL(snp_reclaim_pages);

static int rmp_mark_pages_firmware(unsigned long paddr, unsigned int npages, bool locked)
{
	unsigned long pfn = __sme_clr(paddr) >> PAGE_SHIFT;
	int rc, i;

	for (i = 0; i < npages; i++, pfn++) {
		rc = rmp_make_private(pfn, 0, PG_LEVEL_4K, 0, true);
		if (rc)
			goto cleanup;
	}

	return 0;

cleanup:
	/*
	 * Try unrolling the firmware state changes by
	 * reclaiming the pages which were already changed to the
	 * firmware state.
	 */
	snp_reclaim_pages(paddr, i, locked);

	return rc;
}

static struct page *__snp_alloc_firmware_pages(gfp_t gfp_mask, int order, bool locked)
{
	unsigned long npages = 1ul << order, paddr;
	struct sev_device *sev;
	struct page *page;

	if (!psp_master || !psp_master->sev_data)
		return NULL;

	page = alloc_pages(gfp_mask, order);
	if (!page)
		return NULL;

	/* If SEV-SNP is initialized then add the page in RMP table. */
	sev = psp_master->sev_data;
	if (!sev->snp_initialized)
		return page;

	paddr = __pa((unsigned long)page_address(page));
	if (rmp_mark_pages_firmware(paddr, npages, locked))
		return NULL;

	return page;
}

void *snp_alloc_firmware_page(gfp_t gfp_mask)
{
	struct page *page;

	page = __snp_alloc_firmware_pages(gfp_mask, 0, false);

	return page ? page_address(page) : NULL;
}
EXPORT_SYMBOL_GPL(snp_alloc_firmware_page);

static void __snp_free_firmware_pages(struct page *page, int order, bool locked)
{
	struct sev_device *sev = psp_master->sev_data;
	unsigned long paddr, npages = 1ul << order;

	if (!page)
		return;

	paddr = __pa((unsigned long)page_address(page));
	if (sev->snp_initialized &&
	    snp_reclaim_pages(paddr, npages, locked))
		return;

	__free_pages(page, order);
}

void snp_free_firmware_page(void *addr)
{
	if (!addr)
		return;

	__snp_free_firmware_pages(virt_to_page(addr), 0, false);
}
EXPORT_SYMBOL_GPL(snp_free_firmware_page);

static void *sev_fw_alloc(unsigned long len)
{
	struct page *page;

	page = __snp_alloc_firmware_pages(GFP_KERNEL, get_order(len), true);
	if (!page)
		return NULL;

	return page_address(page);
}

/**
 * struct cmd_buf_desc - descriptors for managing legacy SEV command address
 * parameters corresponding to buffers that may be written to by firmware.
 *
 * @paddr_ptr:  pointer to the address parameter in the command buffer which may
 *              need to be saved/restored depending on whether a bounce buffer
 *              is used. In the case of a bounce buffer, the command buffer
 *              needs to be updated with the address of the new bounce buffer
 *              snp_map_cmd_buf_desc() has allocated specifically for it. Must
 *              be NULL if this descriptor is only an end-of-list indicator.
 *
 * @paddr_orig: storage for the original address parameter, which can be used to
 *              restore the original value in @paddr_ptr in cases where it is
 *              replaced with the address of a bounce buffer.
 *
 * @len: length of buffer located at the address originally stored at @paddr_ptr
 *
 * @guest_owned: true if the address corresponds to guest-owned pages, in which
 *               case bounce buffers are not needed.
 */
struct cmd_buf_desc {
	u64 *paddr_ptr;
	u64 paddr_orig;
	u32 len;
	bool guest_owned;
};

/*
 * If a legacy SEV command parameter is a memory address, those pages in
 * turn need to be transitioned to/from firmware-owned before/after
 * executing the firmware command.
 *
 * Additionally, in cases where those pages are not guest-owned, a bounce
 * buffer is needed in place of the original memory address parameter.
 *
 * A set of descriptors are used to keep track of this handling, and
 * initialized here based on the specific commands being executed.
 */
static void snp_populate_cmd_buf_desc_list(int cmd, void *cmd_buf,
					   struct cmd_buf_desc *desc_list)
{
	switch (cmd) {
	case SEV_CMD_PDH_CERT_EXPORT: {
		struct sev_data_pdh_cert_export *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->pdh_cert_address;
		desc_list[0].len = data->pdh_cert_len;
		desc_list[1].paddr_ptr = &data->cert_chain_address;
		desc_list[1].len = data->cert_chain_len;
		break;
	}
	case SEV_CMD_GET_ID: {
		struct sev_data_get_id *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->address;
		desc_list[0].len = data->len;
		break;
	}
	case SEV_CMD_PEK_CSR: {
		struct sev_data_pek_csr *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->address;
		desc_list[0].len = data->len;
		break;
	}
	case SEV_CMD_LAUNCH_UPDATE_DATA: {
		struct sev_data_launch_update_data *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->address;
		desc_list[0].len = data->len;
		desc_list[0].guest_owned = true;
		break;
	}
	case SEV_CMD_LAUNCH_UPDATE_VMSA: {
		struct sev_data_launch_update_vmsa *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->address;
		desc_list[0].len = data->len;
		desc_list[0].guest_owned = true;
		break;
	}
	case SEV_CMD_LAUNCH_MEASURE: {
		struct sev_data_launch_measure *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->address;
		desc_list[0].len = data->len;
		break;
	}
	case SEV_CMD_LAUNCH_UPDATE_SECRET: {
		struct sev_data_launch_secret *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->guest_address;
		desc_list[0].len = data->guest_len;
		desc_list[0].guest_owned = true;
		break;
	}
	case SEV_CMD_DBG_DECRYPT: {
		struct sev_data_dbg *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->dst_addr;
		desc_list[0].len = data->len;
		desc_list[0].guest_owned = true;
		break;
	}
	case SEV_CMD_DBG_ENCRYPT: {
		struct sev_data_dbg *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->dst_addr;
		desc_list[0].len = data->len;
		desc_list[0].guest_owned = true;
		break;
	}
	case SEV_CMD_ATTESTATION_REPORT: {
		struct sev_data_attestation_report *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->address;
		desc_list[0].len = data->len;
		break;
	}
	case SEV_CMD_SEND_START: {
		struct sev_data_send_start *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->session_address;
		desc_list[0].len = data->session_len;
		break;
	}
	case SEV_CMD_SEND_UPDATE_DATA: {
		struct sev_data_send_update_data *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->hdr_address;
		desc_list[0].len = data->hdr_len;
		desc_list[1].paddr_ptr = &data->trans_address;
		desc_list[1].len = data->trans_len;
		break;
	}
	case SEV_CMD_SEND_UPDATE_VMSA: {
		struct sev_data_send_update_vmsa *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->hdr_address;
		desc_list[0].len = data->hdr_len;
		desc_list[1].paddr_ptr = &data->trans_address;
		desc_list[1].len = data->trans_len;
		break;
	}
	case SEV_CMD_RECEIVE_UPDATE_DATA: {
		struct sev_data_receive_update_data *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->guest_address;
		desc_list[0].len = data->guest_len;
		desc_list[0].guest_owned = true;
		break;
	}
	case SEV_CMD_RECEIVE_UPDATE_VMSA: {
		struct sev_data_receive_update_vmsa *data = cmd_buf;

		desc_list[0].paddr_ptr = &data->guest_address;
		desc_list[0].len = data->guest_len;
		desc_list[0].guest_owned = true;
		break;
	}
	default:
		break;
	}
}

static int snp_map_cmd_buf_desc(struct cmd_buf_desc *desc)
{
	unsigned int npages;

	if (!desc->len)
		return 0;

	/* Allocate a bounce buffer if this isn't a guest owned page. */
	if (!desc->guest_owned) {
		struct page *page;

		page = alloc_pages(GFP_KERNEL_ACCOUNT, get_order(desc->len));
		if (!page) {
			pr_warn("Failed to allocate bounce buffer for SEV legacy command.\n");
			return -ENOMEM;
		}

		desc->paddr_orig = *desc->paddr_ptr;
		*desc->paddr_ptr = __psp_pa(page_to_virt(page));
	}

	npages = PAGE_ALIGN(desc->len) >> PAGE_SHIFT;

	/* Transition the buffer to firmware-owned. */
	if (rmp_mark_pages_firmware(*desc->paddr_ptr, npages, true)) {
		pr_warn("Error moving pages to firmware-owned state for SEV legacy command.\n");
		return -EFAULT;
	}

	return 0;
}

static int snp_unmap_cmd_buf_desc(struct cmd_buf_desc *desc)
{
	unsigned int npages;

	if (!desc->len)
		return 0;

	npages = PAGE_ALIGN(desc->len) >> PAGE_SHIFT;

	/* Transition the buffers back to hypervisor-owned. */
	if (snp_reclaim_pages(*desc->paddr_ptr, npages, true)) {
		pr_warn("Failed to reclaim firmware-owned pages while issuing SEV legacy command.\n");
		return -EFAULT;
	}

	/* Copy data from bounce buffer and then free it. */
	if (!desc->guest_owned) {
		void *bounce_buf = __va(__sme_clr(*desc->paddr_ptr));
		void *dst_buf = __va(__sme_clr(desc->paddr_orig));

		memcpy(dst_buf, bounce_buf, desc->len);
		__free_pages(virt_to_page(bounce_buf), get_order(desc->len));

		/* Restore the original address in the command buffer. */
		*desc->paddr_ptr = desc->paddr_orig;
	}

	return 0;
}

static int snp_map_cmd_buf_desc_list(int cmd, void *cmd_buf, struct cmd_buf_desc *desc_list)
{
	int i;

	snp_populate_cmd_buf_desc_list(cmd, cmd_buf, desc_list);

	for (i = 0; i < CMD_BUF_DESC_MAX; i++) {
		struct cmd_buf_desc *desc = &desc_list[i];

		if (!desc->paddr_ptr)
			break;

		if (snp_map_cmd_buf_desc(desc))
			goto err_unmap;
	}

	return 0;

err_unmap:
	for (i--; i >= 0; i--)
		snp_unmap_cmd_buf_desc(&desc_list[i]);

	return -EFAULT;
}

static int snp_unmap_cmd_buf_desc_list(struct cmd_buf_desc *desc_list)
{
	int i, ret = 0;

	for (i = 0; i < CMD_BUF_DESC_MAX; i++) {
		struct cmd_buf_desc *desc = &desc_list[i];

		if (!desc->paddr_ptr)
			break;

		if (snp_unmap_cmd_buf_desc(&desc_list[i]))
			ret = -EFAULT;
	}

	return ret;
}

static bool sev_cmd_buf_writable(int cmd)
{
	switch (cmd) {
	case SEV_CMD_PLATFORM_STATUS:
	case SEV_CMD_GUEST_STATUS:
	case SEV_CMD_LAUNCH_START:
	case SEV_CMD_RECEIVE_START:
	case SEV_CMD_LAUNCH_MEASURE:
	case SEV_CMD_SEND_START:
	case SEV_CMD_SEND_UPDATE_DATA:
	case SEV_CMD_SEND_UPDATE_VMSA:
	case SEV_CMD_PEK_CSR:
	case SEV_CMD_PDH_CERT_EXPORT:
	case SEV_CMD_GET_ID:
	case SEV_CMD_ATTESTATION_REPORT:
		return true;
	default:
		return false;
	}
}

/* After SNP is INIT'ed, the behavior of legacy SEV commands is changed. */
static bool snp_legacy_handling_needed(int cmd)
{
	struct sev_device *sev = psp_master->sev_data;

	return cmd < SEV_CMD_SNP_INIT && sev->snp_initialized;
}

static int snp_prep_cmd_buf(int cmd, void *cmd_buf, struct cmd_buf_desc *desc_list)
{
	if (!snp_legacy_handling_needed(cmd))
		return 0;

	if (snp_map_cmd_buf_desc_list(cmd, cmd_buf, desc_list))
		return -EFAULT;

	/*
	 * Before command execution, the command buffer needs to be put into
	 * the firmware-owned state.
	 */
	if (sev_cmd_buf_writable(cmd)) {
		if (rmp_mark_pages_firmware(__pa(cmd_buf), 1, true))
			return -EFAULT;
	}

	return 0;
}

static int snp_reclaim_cmd_buf(int cmd, void *cmd_buf)
{
	if (!snp_legacy_handling_needed(cmd))
		return 0;

	/*
	 * After command completion, the command buffer needs to be put back
	 * into the hypervisor-owned state.
	 */
	if (sev_cmd_buf_writable(cmd))
		if (snp_reclaim_pages(__pa(cmd_buf), 1, true))
			return -EFAULT;

	return 0;
}

int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
{
	struct cmd_buf_desc desc_list[CMD_BUF_DESC_MAX] = {0};
	struct psp_device *psp = psp_master;
	struct sev_device *sev;
	unsigned int cmdbuff_hi, cmdbuff_lo;
	unsigned int phys_lsb, phys_msb;
	unsigned int reg;
	void *cmd_buf;
	int buf_len;
	int ret = 0;

	if (!psp || !psp->sev_data)
		return -ENODEV;

	if (psp_dead)
		return -EBUSY;

	sev = psp->sev_data;

	buf_len = sev_cmd_buffer_len(cmd);
	if (WARN_ON_ONCE(!data != !buf_len))
		return -EINVAL;

	/*
	 * Copy the incoming data to driver's scratch buffer as __pa() will not
	 * work for some memory, e.g. vmalloc'd addresses, and @data may not be
	 * physically contiguous.
	 */
	if (data) {
		/*
		 * Commands are generally issued one at a time and require the
		 * sev_cmd_mutex, but there could be recursive firmware requests
		 * due to SEV_CMD_SNP_PAGE_RECLAIM needing to be issued while
		 * preparing buffers for another command. This is the only known
		 * case of nesting in the current code, so exactly one
		 * additional command buffer is available for that purpose.
		 */
		if (!sev->cmd_buf_active) {
			cmd_buf = sev->cmd_buf;
			sev->cmd_buf_active = true;
		} else if (!sev->cmd_buf_backup_active) {
			cmd_buf = sev->cmd_buf_backup;
			sev->cmd_buf_backup_active = true;
		} else {
			dev_err(sev->dev,
				"SEV: too many firmware commands in progress, no command buffers available.\n");
			return -EBUSY;
		}

		memcpy(cmd_buf, data, buf_len);

		/*
		 * The behavior of the SEV-legacy commands is altered when the
		 * SNP firmware is in the INIT state.
		 */
		ret = snp_prep_cmd_buf(cmd, cmd_buf, desc_list);
		if (ret) {
			dev_err(sev->dev,
				"SEV: failed to prepare buffer for legacy command 0x%x. Error: %d\n",
				cmd, ret);
			return ret;
		}
	} else {
		cmd_buf = sev->cmd_buf;
	}

	/* Get the physical address of the command buffer */
	phys_lsb = data ? lower_32_bits(__psp_pa(cmd_buf)) : 0;
	phys_msb = data ? upper_32_bits(__psp_pa(cmd_buf)) : 0;

	dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n",
		cmd, phys_msb, phys_lsb, psp_timeout);

	print_hex_dump_debug("(in):  ", DUMP_PREFIX_OFFSET, 16, 2, data,
			     buf_len, false);

	iowrite32(phys_lsb, sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg);
	iowrite32(phys_msb, sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg);

	sev->int_rcvd = 0;

	reg = FIELD_PREP(SEV_CMDRESP_CMD, cmd);

	/*
	 * If invoked during panic handling, local interrupts are disabled so
	 * the PSP command completion interrupt can't be used.
	 * sev_wait_cmd_ioc() already checks for interrupts disabled and
	 * polls for PSP command completion.  Ensure we do not request an
	 * interrupt from the PSP if irqs disabled.
	 */
	if (!irqs_disabled())
		reg |= SEV_CMDRESP_IOC;

	iowrite32(reg, sev->io_regs + sev->vdata->cmdresp_reg);

	/* wait for command completion */
	ret = sev_wait_cmd_ioc(sev, &reg, psp_timeout);
	if (ret) {
		if (psp_ret)
			*psp_ret = 0;

		dev_err(sev->dev, "sev command %#x timed out, disabling PSP\n", cmd);
		psp_dead = true;

		return ret;
	}

	psp_timeout = psp_cmd_timeout;

	if (psp_ret)
		*psp_ret = FIELD_GET(PSP_CMDRESP_STS, reg);

	if (FIELD_GET(PSP_CMDRESP_STS, reg)) {
		dev_dbg(sev->dev, "sev command %#x failed (%#010lx)\n",
			cmd, FIELD_GET(PSP_CMDRESP_STS, reg));

		/*
		 * PSP firmware may report additional error information in the
		 * command buffer registers on error. Print contents of command
		 * buffer registers if they changed.
		 */
		cmdbuff_hi = ioread32(sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg);
		cmdbuff_lo = ioread32(sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg);
		if (cmdbuff_hi != phys_msb || cmdbuff_lo != phys_lsb) {
			dev_dbg(sev->dev, "Additional error information reported in cmdbuff:");
			dev_dbg(sev->dev, "  cmdbuff hi: %#010x\n", cmdbuff_hi);
			dev_dbg(sev->dev, "  cmdbuff lo: %#010x\n", cmdbuff_lo);
		}
		ret = -EIO;
	} else {
		ret = sev_write_init_ex_file_if_required(cmd);
	}

	/*
	 * Copy potential output from the PSP back to data.  Do this even on
	 * failure in case the caller wants to glean something from the error.
	 */
	if (data) {
		int ret_reclaim;
		/*
		 * Restore the page state after the command completes.
		 */
		ret_reclaim = snp_reclaim_cmd_buf(cmd, cmd_buf);
		if (ret_reclaim) {
			dev_err(sev->dev,
				"SEV: failed to reclaim buffer for legacy command %#x. Error: %d\n",
				cmd, ret_reclaim);
			return ret_reclaim;
		}

		memcpy(data, cmd_buf, buf_len);

		if (sev->cmd_buf_backup_active)
			sev->cmd_buf_backup_active = false;
		else
			sev->cmd_buf_active = false;

		if (snp_unmap_cmd_buf_desc_list(desc_list))
			return -EFAULT;
	}

	print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
			     buf_len, false);

	return ret;
}

int sev_do_cmd(int cmd, void *data, int *psp_ret)
{
	int rc;

	mutex_lock(&sev_cmd_mutex);
	rc = __sev_do_cmd_locked(cmd, data, psp_ret);
	mutex_unlock(&sev_cmd_mutex);

	return rc;
}
EXPORT_SYMBOL_GPL(sev_do_cmd);

static int __sev_init_locked(int *error)
{
	struct sev_data_init data;

	memset(&data, 0, sizeof(data));
	if (sev_es_tmr) {
		/*
		 * Do not include the encryption mask on the physical
		 * address of the TMR (firmware should clear it anyway).
		 */
		data.tmr_address = __pa(sev_es_tmr);

		data.flags |= SEV_INIT_FLAGS_SEV_ES;
		data.tmr_len = sev_es_tmr_size;
	}

	return __sev_do_cmd_locked(SEV_CMD_INIT, &data, error);
}

static int __sev_init_ex_locked(int *error)
{
	struct sev_data_init_ex data;

	memset(&data, 0, sizeof(data));
	data.length = sizeof(data);
	data.nv_address = __psp_pa(sev_init_ex_buffer);
	data.nv_len = NV_LENGTH;

	if (sev_es_tmr) {
		/*
		 * Do not include the encryption mask on the physical
		 * address of the TMR (firmware should clear it anyway).
		 */
		data.tmr_address = __pa(sev_es_tmr);

		data.flags |= SEV_INIT_FLAGS_SEV_ES;
		data.tmr_len = sev_es_tmr_size;
	}

	return __sev_do_cmd_locked(SEV_CMD_INIT_EX, &data, error);
}

static inline int __sev_do_init_locked(int *psp_ret)
{
	if (sev_init_ex_buffer)
		return __sev_init_ex_locked(psp_ret);
	else
		return __sev_init_locked(psp_ret);
}

/* Hypervisor Fixed pages API interface */
static void snp_hv_fixed_pages_state_update(struct sev_device *sev,
					    enum snp_hv_fixed_pages_state page_state)
{
	struct snp_hv_fixed_pages_entry *entry;

	/* List is protected by sev_cmd_mutex */
	lockdep_assert_held(&sev_cmd_mutex);

	if (list_empty(&snp_hv_fixed_pages))
		return;

	list_for_each_entry(entry, &snp_hv_fixed_pages, list)
		entry->page_state = page_state;
}

/*
 * Allocate HV_FIXED pages in 2MB aligned sizes to ensure the whole
 * 2MB pages are marked as HV_FIXED.
 */
struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages)
{
	struct psp_device *psp_master = psp_get_master_device();
	struct snp_hv_fixed_pages_entry *entry;
	unsigned int order;
	struct page *page;

	if (!psp_master)
		return NULL;

	order = get_order(PMD_SIZE * num_2mb_pages);

	/*
	 * SNP_INIT_EX is protected by sev_cmd_mutex, therefore this list
	 * also needs to be protected using the same mutex.
	 */
	guard(mutex)(&sev_cmd_mutex);

	/*
	 * This API uses SNP_INIT_EX to transition allocated pages to HV_Fixed
	 * page state, fail if SNP is already initialized.
	 */
	if (psp_master->sev_data &&
	    ((struct sev_device *)psp_master->sev_data)->snp_initialized)
		return NULL;

	/* Re-use freed pages that match the request */
	list_for_each_entry(entry, &snp_hv_fixed_pages, list) {
		/* Hypervisor fixed page allocator implements exact fit policy */
		if (entry->order == order && entry->free) {
			entry->free = false;
			memset(page_address(entry->page), 0,
			       (1 << entry->order) * PAGE_SIZE);
			return entry->page;
		}
	}

	page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
	if (!page)
		return NULL;

	entry = kzalloc_obj(*entry);
	if (!entry) {
		__free_pages(page, order);
		return NULL;
	}

	entry->page = page;
	entry->order = order;
	list_add_tail(&entry->list, &snp_hv_fixed_pages);

	return page;
}

void snp_free_hv_fixed_pages(struct page *page)
{
	struct psp_device *psp_master = psp_get_master_device();
	struct snp_hv_fixed_pages_entry *entry, *nentry;

	if (!psp_master)
		return;

	/*
	 * SNP_INIT_EX is protected by sev_cmd_mutex, therefore this list
	 * also needs to be protected using the same mutex.
	 */
	guard(mutex)(&sev_cmd_mutex);

	list_for_each_entry_safe(entry, nentry, &snp_hv_fixed_pages, list) {
		if (entry->page != page)
			continue;

		/*
		 * HV_FIXED page state cannot be changed until reboot
		 * and they cannot be used by an SNP guest, so they cannot
		 * be returned back to the page allocator.
		 * Mark the pages as free internally to allow possible re-use.
		 */
		if (entry->page_state == HV_FIXED) {
			entry->free = true;
		} else {
			__free_pages(page, entry->order);
			list_del(&entry->list);
			kfree(entry);
		}
		return;
	}
}

static void snp_add_hv_fixed_pages(struct sev_device *sev, struct sev_data_range_list *range_list)
{
	struct snp_hv_fixed_pages_entry *entry;
	struct sev_data_range *range;
	int num_elements;

	lockdep_assert_held(&sev_cmd_mutex);

	if (list_empty(&snp_hv_fixed_pages))
		return;

	num_elements = list_count_nodes(&snp_hv_fixed_pages) +
		       range_list->num_elements;

	/*
	 * Ensure the list of HV_FIXED pages that will be passed to firmware
	 * do not exceed the page-sized argument buffer.
	 */
	if (num_elements * sizeof(*range) + sizeof(*range_list) > PAGE_SIZE) {
		dev_warn(sev->dev, "Additional HV_Fixed pages cannot be accommodated, omitting\n");
		return;
	}

	range = &range_list->ranges[range_list->num_elements];
	list_for_each_entry(entry, &snp_hv_fixed_pages, list) {
		range->base = page_to_pfn(entry->page) << PAGE_SHIFT;
		range->page_count = 1 << entry->order;
		range++;
	}
	range_list->num_elements = num_elements;
}

static void snp_leak_hv_fixed_pages(void)
{
	struct snp_hv_fixed_pages_entry *entry, *nentry;

	/* List is protected by sev_cmd_mutex */
	lockdep_assert_held(&sev_cmd_mutex);

	if (list_empty(&snp_hv_fixed_pages))
		return;

	list_for_each_entry_safe(entry, nentry, &snp_hv_fixed_pages, list) {
		if (entry->free && entry->page_state != HV_FIXED)
			__free_pages(entry->page, entry->order);
		else
			__snp_leak_pages(page_to_pfn(entry->page),
					 1 << entry->order, false);

		list_del(&entry->list);
		kfree(entry);
	}
}

bool sev_is_snp_ciphertext_hiding_supported(void)
{
	struct psp_device *psp = psp_master;
	struct sev_device *sev;

	if (!psp || !psp->sev_data)
		return false;

	sev = psp->sev_data;

	/*
	 * Feature information indicates if CipherTextHiding feature is
	 * supported by the SEV firmware and additionally platform status
	 * indicates if CipherTextHiding feature is enabled in the
	 * Platform BIOS.
	 */
	return ((sev->snp_feat_info_0.ecx & SNP_CIPHER_TEXT_HIDING_SUPPORTED) &&
		 sev->snp_plat_status.ciphertext_hiding_cap);
}
EXPORT_SYMBOL_GPL(sev_is_snp_ciphertext_hiding_supported);

static int snp_get_platform_data(struct sev_device *sev, int *error)
{
	struct sev_data_snp_feature_info snp_feat_info;
	struct snp_feature_info *feat_info;
	struct sev_data_snp_addr buf;
	struct page *page;
	int rc;

	/*
	 * This function is expected to be called before SNP is
	 * initialized.
	 */
	if (sev->snp_initialized)
		return -EINVAL;

	buf.address = __psp_pa(&sev->snp_plat_status);
	rc = sev_do_cmd(SEV_CMD_SNP_PLATFORM_STATUS, &buf, error);
	if (rc) {
		dev_err(sev->dev, "SNP PLATFORM_STATUS command failed, ret = %d, error = %#x\n",
			rc, *error);
		return rc;
	}

	sev->api_major = sev->snp_plat_status.api_major;
	sev->api_minor = sev->snp_plat_status.api_minor;
	sev->build = sev->snp_plat_status.build_id;

	/*
	 * Do feature discovery of the currently loaded firmware,
	 * and cache feature information from CPUID 0x8000_0024,
	 * sub-function 0.
	 */
	if (!sev->snp_plat_status.feature_info)
		return 0;

	/*
	 * Use dynamically allocated structure for the SNP_FEATURE_INFO
	 * command to ensure structure is 8-byte aligned, and does not
	 * cross a page boundary.
	 */
	page = alloc_page(GFP_KERNEL);
	if (!page)
		return -ENOMEM;

	feat_info = page_address(page);
	snp_feat_info.length = sizeof(snp_feat_info);
	snp_feat_info.ecx_in = 0;
	snp_feat_info.feature_info_paddr = __psp_pa(feat_info);

	rc = sev_do_cmd(SEV_CMD_SNP_FEATURE_INFO, &snp_feat_info, error);
	if (!rc)
		sev->snp_feat_info_0 = *feat_info;
	else
		dev_err(sev->dev, "SNP FEATURE_INFO command failed, ret = %d, error = %#x\n",
			rc, *error);

	__free_page(page);

	return rc;
}

static int snp_filter_reserved_mem_regions(struct resource *rs, void *arg)
{
	struct sev_data_range_list *range_list = arg;
	struct sev_data_range *range = &range_list->ranges[range_list->num_elements];
	size_t size;

	/*
	 * Ensure the list of HV_FIXED pages that will be passed to firmware
	 * do not exceed the page-sized argument buffer.
	 */
	if ((range_list->num_elements * sizeof(struct sev_data_range) +
	     sizeof(struct sev_data_range_list)) > PAGE_SIZE)
		return -E2BIG;

	switch (rs->desc) {
	case E820_TYPE_RESERVED:
	case E820_TYPE_PMEM:
	case E820_TYPE_ACPI:
		range->base = rs->start & PAGE_MASK;
		size = PAGE_ALIGN((rs->end + 1) - rs->start);
		range->page_count = size >> PAGE_SHIFT;
		range_list->num_elements++;
		break;
	default:
		break;
	}

	return 0;
}

static int __sev_snp_init_locked(int *error, unsigned int max_snp_asid)
{
	struct sev_data_range_list *snp_range_list __free(kfree) = NULL;
	struct psp_device *psp = psp_master;
	struct sev_data_snp_init_ex data;
	struct sev_device *sev;
	void *arg = &data;
	int cmd, rc = 0;

	if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
		return -ENODEV;

	sev = psp->sev_data;

	if (sev->snp_initialized)
		return 0;

	if (!sev_version_greater_or_equal(SNP_MIN_API_MAJOR, SNP_MIN_API_MINOR)) {
		dev_dbg(sev->dev, "SEV-SNP support requires firmware version >= %d:%d\n",
			SNP_MIN_API_MAJOR, SNP_MIN_API_MINOR);
		return -EOPNOTSUPP;
	}

	snp_prepare();

	/*
	 * Starting in SNP firmware v1.52, the SNP_INIT_EX command takes a list
	 * of system physical address ranges to convert into HV-fixed page
	 * states during the RMP initialization.  For instance, the memory that
	 * UEFI reserves should be included in the that list. This allows system
	 * components that occasionally write to memory (e.g. logging to UEFI
	 * reserved regions) to not fail due to RMP initialization and SNP
	 * enablement.
	 *
	 */
	if (sev_version_greater_or_equal(SNP_MIN_API_MAJOR, 52)) {
		bool tio_supp = !!(sev->snp_feat_info_0.ebx & SNP_SEV_TIO_SUPPORTED);

		/*
		 * Firmware checks that the pages containing the ranges enumerated
		 * in the RANGES structure are either in the default page state or in the
		 * firmware page state.
		 */
		snp_range_list = kzalloc(PAGE_SIZE, GFP_KERNEL);
		if (!snp_range_list) {
			dev_err(sev->dev,
				"SEV: SNP_INIT_EX range list memory allocation failed\n");
			return -ENOMEM;
		}

		/*
		 * Retrieve all reserved memory regions from the e820 memory map
		 * to be setup as HV-fixed pages.
		 */
		rc = walk_iomem_res_desc(IORES_DESC_NONE, IORESOURCE_MEM, 0, ~0,
					 snp_range_list, snp_filter_reserved_mem_regions);
		if (rc) {
			dev_err(sev->dev,
				"SEV: SNP_INIT_EX walk_iomem_res_desc failed rc = %d\n", rc);
			return rc;
		}

		/*
		 * Add HV_Fixed pages from other PSP sub-devices, such as SFS to the
		 * HV_Fixed page list.
		 */
		snp_add_hv_fixed_pages(sev, snp_range_list);

		memset(&data, 0, sizeof(data));

		if (max_snp_asid) {
			data.ciphertext_hiding_en = 1;
			data.max_snp_asid = max_snp_asid;
		}

		data.init_rmp = 1;
		data.list_paddr_en = 1;
		data.list_paddr = __psp_pa(snp_range_list);

		data.tio_en = tio_supp && sev_tio_enabled && amd_iommu_sev_tio_supported();

		/*
		 * When psp_init_on_probe is disabled, the userspace calling
		 * SEV ioctl can inadvertently shut down SNP and SEV-TIO causing
		 * unexpected state loss.
		 */
		if (data.tio_en && !psp_init_on_probe)
			dev_warn(sev->dev, "SEV-TIO as incompatible with psp_init_on_probe=0\n");

		cmd = SEV_CMD_SNP_INIT_EX;
	} else {
		cmd = SEV_CMD_SNP_INIT;
		arg = NULL;
	}

	/*
	 * The following sequence must be issued before launching the first SNP
	 * guest to ensure all dirty cache lines are flushed, including from
	 * updates to the RMP table itself via the RMPUPDATE instruction:
	 *
	 * - WBINVD on all running CPUs
	 * - SEV_CMD_SNP_INIT[_EX] firmware command
	 * - WBINVD on all running CPUs
	 * - SEV_CMD_SNP_DF_FLUSH firmware command
	 */
	wbinvd_on_all_cpus();

	rc = __sev_do_cmd_locked(cmd, arg, error);
	if (rc) {
		dev_err(sev->dev, "SEV-SNP: %s failed rc %d, error %#x\n",
			cmd == SEV_CMD_SNP_INIT_EX ? "SNP_INIT_EX" : "SNP_INIT",
			rc, *error);
		return rc;
	}

	/* Prepare for first SNP guest launch after INIT. */
	wbinvd_on_all_cpus();
	rc = __sev_do_cmd_locked(SEV_CMD_SNP_DF_FLUSH, NULL, error);
	if (rc) {
		dev_err(sev->dev, "SEV-SNP: SNP_DF_FLUSH failed rc %d, error %#x\n",
			rc, *error);
		return rc;
	}

	snp_hv_fixed_pages_state_update(sev, HV_FIXED);
	sev->snp_initialized = true;
	dev_dbg(sev->dev, "SEV-SNP firmware initialized, SEV-TIO is %s\n",
		data.tio_en ? "enabled" : "disabled");

	dev_info(sev->dev, "SEV-SNP API:%d.%d build:%d\n", sev->api_major,
		 sev->api_minor, sev->build);

	atomic_notifier_chain_register(&panic_notifier_list,
				       &snp_panic_notifier);

	if (data.tio_en) {
		/*
		 * This executes with the sev_cmd_mutex held so down the stack
		 * snp_reclaim_pages(locked=false) might be needed (which is extremely
		 * unlikely) but will cause a deadlock.
		 * Instead of exporting __snp_alloc_firmware_pages(), allocate a page
		 * for this one call here.
		 */
		void *tio_status = page_address(__snp_alloc_firmware_pages(
			GFP_KERNEL_ACCOUNT | __GFP_ZERO, 0, true));

		if (tio_status) {
			sev_tsm_init_locked(sev, tio_status);
			__snp_free_firmware_pages(virt_to_page(tio_status), 0, true);
		}
	}

	sev_es_tmr_size = SNP_TMR_SIZE;

	return 0;
}

static void __sev_platform_init_handle_tmr(struct sev_device *sev)
{
	if (sev_es_tmr)
		return;

	/* Obtain the TMR memory area for SEV-ES use */
	sev_es_tmr = sev_fw_alloc(sev_es_tmr_size);
	if (sev_es_tmr) {
		/* Must flush the cache before giving it to the firmware */
		if (!sev->snp_initialized)
			clflush_cache_range(sev_es_tmr, sev_es_tmr_size);
	} else {
			dev_warn(sev->dev, "SEV: TMR allocation failed, SEV-ES support unavailable\n");
	}
}

/*
 * If an init_ex_path is provided allocate a buffer for the file and
 * read in the contents. Additionally, if SNP is initialized, convert
 * the buffer pages to firmware pages.
 */
static int __sev_platform_init_handle_init_ex_path(struct sev_device *sev)
{
	struct page *page;
	int rc;

	if (!init_ex_path)
		return 0;

	if (sev_init_ex_buffer)
		return 0;

	page = alloc_pages(GFP_KERNEL, get_order(NV_LENGTH));
	if (!page) {
		dev_err(sev->dev, "SEV: INIT_EX NV memory allocation failed\n");
		return -ENOMEM;
	}

	sev_init_ex_buffer = page_address(page);

	rc = sev_read_init_ex_file();
	if (rc)
		return rc;

	/* If SEV-SNP is initialized, transition to firmware page. */
	if (sev->snp_initialized) {
		unsigned long npages;

		npages = 1UL << get_order(NV_LENGTH);
		if (rmp_mark_pages_firmware(__pa(sev_init_ex_buffer), npages, false)) {
			dev_err(sev->dev, "SEV: INIT_EX NV memory page state change failed.\n");
			return -ENOMEM;
		}
	}

	return 0;
}

static int __sev_platform_init_locked(int *error)
{
	int rc, psp_ret, dfflush_error;
	struct sev_device *sev;

	psp_ret = dfflush_error = SEV_RET_NO_FW_CALL;

	if (!psp_master || !psp_master->sev_data)
		return -ENODEV;

	sev = psp_master->sev_data;

	if (sev->sev_plat_status.state == SEV_STATE_INIT)
		return 0;

	__sev_platform_init_handle_tmr(sev);

	rc = __sev_platform_init_handle_init_ex_path(sev);
	if (rc)
		return rc;

	rc = __sev_do_init_locked(&psp_ret);
	if (rc && psp_ret == SEV_RET_SECURE_DATA_INVALID) {
		/*
		 * Initialization command returned an integrity check failure
		 * status code, meaning that firmware load and validation of SEV
		 * related persistent data has failed. Retrying the
		 * initialization function should succeed by replacing the state
		 * with a reset state.
		 */
		dev_err(sev->dev,
"SEV: retrying INIT command because of SECURE_DATA_INVALID error. Retrying once to reset PSP SEV state.");
		rc = __sev_do_init_locked(&psp_ret);
	}

	if (error)
		*error = psp_ret;

	if (rc) {
		dev_err(sev->dev, "SEV: %s failed %#x, rc %d\n",
			sev_init_ex_buffer ? "INIT_EX" : "INIT", psp_ret, rc);
		return rc;
	}

	sev->sev_plat_status.state = SEV_STATE_INIT;

	/* Prepare for first SEV guest launch after INIT */
	wbinvd_on_all_cpus();
	rc = __sev_do_cmd_locked(SEV_CMD_DF_FLUSH, NULL, &dfflush_error);
	if (rc) {
		dev_err(sev->dev, "SEV: DF_FLUSH failed %#x, rc %d\n",
			dfflush_error, rc);
		return rc;
	}

	dev_dbg(sev->dev, "SEV firmware initialized\n");

	dev_info(sev->dev, "SEV API:%d.%d build:%d\n", sev->api_major,
		 sev->api_minor, sev->build);

	return 0;
}

static int _sev_platform_init_locked(struct sev_platform_init_args *args)
{
	struct sev_device *sev;
	int rc;

	if (!psp_master || !psp_master->sev_data)
		return -ENODEV;

	/*
	 * Skip SNP/SEV initialization under a kdump kernel as SEV/SNP
	 * may already be initialized in the previous kernel. Since no
	 * SNP/SEV guests are run under a kdump kernel, there is no
	 * need to initialize SNP or SEV during kdump boot.
	 */
	if (is_kdump_kernel())
		return 0;

	sev = psp_master->sev_data;

	if (sev->sev_plat_status.state == SEV_STATE_INIT)
		return 0;

	rc = __sev_snp_init_locked(&args->error, args->max_snp_asid);
	if (rc && rc != -ENODEV)
		return rc;

	/* Defer legacy SEV/SEV-ES support if allowed by caller/module. */
	if (args->probe && !psp_init_on_probe)
		return 0;

	return __sev_platform_init_locked(&args->error);
}

int sev_platform_init(struct sev_platform_init_args *args)
{
	int rc;

	mutex_lock(&sev_cmd_mutex);
	rc = _sev_platform_init_locked(args);
	mutex_unlock(&sev_cmd_mutex);

	return rc;
}
EXPORT_SYMBOL_GPL(sev_platform_init);

static int __sev_platform_shutdown_locked(int *error)
{
	struct psp_device *psp = psp_master;
	struct sev_device *sev;
	int ret;

	if (!psp || !psp->sev_data)
		return 0;

	sev = psp->sev_data;

	if (sev->sev_plat_status.state == SEV_STATE_UNINIT)
		return 0;

	ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error);
	if (ret) {
		dev_err(sev->dev, "SEV: failed to SHUTDOWN error %#x, rc %d\n",
			*error, ret);
		return ret;
	}

	sev->sev_plat_status.state = SEV_STATE_UNINIT;
	dev_dbg(sev->dev, "SEV firmware shutdown\n");

	return ret;
}

static int sev_get_platform_state(int *state, int *error)
{
	struct sev_user_data_status data;
	int rc;

	rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, error);
	if (rc)
		return rc;

	*state = data.state;
	return rc;
}

static int sev_move_to_init_state(struct sev_issue_cmd *argp, bool *shutdown_required)
{
	struct sev_platform_init_args init_args = {0};
	int rc;

	rc = _sev_platform_init_locked(&init_args);
	if (rc) {
		argp->error = SEV_RET_INVALID_PLATFORM_STATE;
		return rc;
	}

	*shutdown_required = true;

	return 0;
}

static int snp_move_to_init_state(struct sev_issue_cmd *argp, bool *shutdown_required)
{
	int error, rc;

	rc = __sev_snp_init_locked(&error, 0);
	if (rc) {
		argp->error = SEV_RET_INVALID_PLATFORM_STATE;
		return rc;
	}

	*shutdown_required = true;

	return 0;
}

static int sev_ioctl_do_reset(struct sev_issue_cmd *argp, bool writable)
{
	int state, rc;

	if (!writable)
		return -EPERM;

	/*
	 * The SEV spec requires that FACTORY_RESET must be issued in
	 * UNINIT state. Before we go further lets check if any guest is
	 * active.
	 *
	 * If FW is in WORKING state then deny the request otherwise issue
	 * SHUTDOWN command do INIT -> UNINIT before issuing the FACTORY_RESET.
	 *
	 */
	rc = sev_get_platform_state(&state, &argp->error);
	if (rc)
		return rc;

	if (state == SEV_STATE_WORKING)
		return -EBUSY;

	if (state == SEV_STATE_INIT) {
		rc = __sev_platform_shutdown_locked(&argp->error);
		if (rc)
			return rc;
	}

	return __sev_do_cmd_locked(SEV_CMD_FACTORY_RESET, NULL, &argp->error);
}

static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)
{
	struct sev_user_data_status data;
	int ret;

	memset(&data, 0, sizeof(data));

	ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error);
	if (ret)
		return ret;

	if (copy_to_user((void __user *)argp->data, &data, sizeof(data)))
		ret = -EFAULT;

	return ret;
}

static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp, bool writable)
{
	struct sev_device *sev = psp_master->sev_data;
	bool shutdown_required = false;
	int rc;

	if (!writable)
		return -EPERM;

	if (sev->sev_plat_status.state == SEV_STATE_UNINIT) {
		rc = sev_move_to_init_state(argp, &shutdown_required);
		if (rc)
			return rc;
	}

	rc = __sev_do_cmd_locked(cmd, NULL, &argp->error);

	if (shutdown_required)
		__sev_firmware_shutdown(sev, false);

	return rc;
}

static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
{
	struct sev_device *sev = psp_master->sev_data;
	struct sev_user_data_pek_csr input;
	bool shutdown_required = false;
	struct sev_data_pek_csr data;
	void __user *input_address;
	void *blob = NULL;
	int ret;

	if (!writable)
		return -EPERM;

	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
		return -EFAULT;

	memset(&data, 0, sizeof(data));

	/* userspace wants to query CSR length */
	if (!input.address || !input.length)
		goto cmd;

	/* allocate a physically contiguous buffer to store the CSR blob */
	input_address = (void __user *)input.address;
	if (input.length > SEV_FW_BLOB_MAX_SIZE)
		return -EFAULT;

	blob = kzalloc(input.length, GFP_KERNEL);
	if (!blob)
		return -ENOMEM;

	data.address = __psp_pa(blob);
	data.len = input.length;

cmd:
	if (sev->sev_plat_status.state == SEV_STATE_UNINIT) {
		ret = sev_move_to_init_state(argp, &shutdown_required);
		if (ret)
			goto e_free_blob;
	}

	ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, &data, &argp->error);

	/*
	 * Firmware will returns the length of the CSR blob (either the minimum
	 * required length or the actual length written), return it to the user.
	 */
	input.length = data.len;

	if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
		ret = -EFAULT;
		goto e_free_blob;
	}

	if (ret || WARN_ON_ONCE(argp->error))
		goto e_free_blob;

	if (blob) {
		if (copy_to_user(input_address, blob, input.length))
			ret = -EFAULT;
	}

e_free_blob:
	if (shutdown_required)
		__sev_firmware_shutdown(sev, false);

	kfree(blob);
	return ret;
}

void *psp_copy_user_blob(u64 uaddr, u32 len)
{
	if (!uaddr || !len)
		return ERR_PTR(-EINVAL);

	/* verify that blob length does not exceed our limit */
	if (len > SEV_FW_BLOB_MAX_SIZE)
		return ERR_PTR(-EINVAL);

	return memdup_user((void __user *)uaddr, len);
}
EXPORT_SYMBOL_GPL(psp_copy_user_blob);

static int sev_get_api_version(void)
{
	struct sev_device *sev = psp_master->sev_data;
	struct sev_user_data_status status;
	int error = 0, ret;

	/*
	 * Cache SNP platform status and SNP feature information
	 * if SNP is available.
	 */
	if (cc_platform_has(CC_ATTR_HOST_SEV_SNP)) {
		ret = snp_get_platform_data(sev, &error);
		if (ret)
			return 1;
	}

	ret = sev_platform_status(&status, &error);
	if (ret) {
		dev_err(sev->dev,
			"SEV: failed to get status. Error: %#x\n", error);
		return 1;
	}

	/* Cache SEV platform status */
	sev->sev_plat_status = status;

	sev->api_major = status.api_major;
	sev->api_minor = status.api_minor;
	sev->build = status.build;

	return 0;
}

static int sev_get_firmware(struct device *dev,
			    const struct firmware **firmware)
{
	char fw_name_specific[SEV_FW_NAME_SIZE];
	char fw_name_subset[SEV_FW_NAME_SIZE];

	snprintf(fw_name_specific, sizeof(fw_name_specific),
		 "amd/amd_sev_fam%.2xh_model%.2xh.sbin",
		 boot_cpu_data.x86, boot_cpu_data.x86_model);

	snprintf(fw_name_subset, sizeof(fw_name_subset),
		 "amd/amd_sev_fam%.2xh_model%.1xxh.sbin",
		 boot_cpu_data.x86, (boot_cpu_data.x86_model & 0xf0) >> 4);

	/* Check for SEV FW for a particular model.
	 * Ex. amd_sev_fam17h_model00h.sbin for Family 17h Model 00h
	 *
	 * or
	 *
	 * Check for SEV FW common to a subset of models.
	 * Ex. amd_sev_fam17h_model0xh.sbin for
	 *     Family 17h Model 00h -- Family 17h Model 0Fh
	 *
	 * or
	 *
	 * Fall-back to using generic name: sev.fw
	 */
	if ((firmware_request_nowarn(firmware, fw_name_specific, dev) >= 0) ||
	    (firmware_request_nowarn(firmware, fw_name_subset, dev) >= 0) ||
	    (firmware_request_nowarn(firmware, SEV_FW_FILE, dev) >= 0))
		return 0;

	return -ENOENT;
}

/* Don't fail if SEV FW couldn't be updated. Continue with existing SEV FW */
static int sev_update_firmware(struct device *dev)
{
	struct sev_data_download_firmware data;
	const struct firmware *firmware;
	int ret, error, order;
	struct page *p;
	void *fw_blob;

	if (!sev_version_greater_or_equal(0, 15)) {
		dev_dbg(dev, "DOWNLOAD_FIRMWARE not supported\n");
		return -1;
	}

	if (sev_get_firmware(dev, &firmware) == -ENOENT) {
		dev_dbg(dev, "No SEV firmware file present\n");
		return -1;
	}

	order = get_order(firmware->size);
	p = alloc_pages(GFP_KERNEL, order);
	if (!p) {
		ret = -1;
		goto fw_err;
	}

	/*
	 * Copy firmware data to a kernel allocated contiguous
	 * memory region.
	 */
	fw_blob = page_address(p);
	memcpy(fw_blob, firmware->data, firmware->size);

	data.address = __psp_pa(fw_blob);
	data.len = firmware->size;

	ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, &data, &error);

	/*
	 * A quirk for fixing the committed TCB version, when upgrading from
	 * earlier firmware version than 1.50.
	 */
	if (!ret && !sev_version_greater_or_equal(1, 50))
		ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, &data, &error);

	if (ret)
		dev_dbg(dev, "Failed to update SEV firmware: %#x\n", error);

	__free_pages(p, order);

fw_err:
	release_firmware(firmware);

	return ret;
}

static int __sev_snp_shutdown_locked(int *error, bool panic)
{
	struct psp_device *psp = psp_master;
	struct sev_device *sev;
	struct sev_data_snp_shutdown_ex data;
	int ret;

	if (!psp || !psp->sev_data)
		return 0;

	sev = psp->sev_data;

	if (!sev->snp_initialized)
		return 0;

	memset(&data, 0, sizeof(data));
	data.len = sizeof(data);
	data.iommu_snp_shutdown = 1;
	if (sev->snp_feat_info_0.ecx & SNP_X86_SHUTDOWN_SUPPORTED)
		data.x86_snp_shutdown = 1;

	/*
	 * If invoked during panic handling, local interrupts are disabled
	 * and all CPUs are stopped, so wbinvd_on_all_cpus() can't be called.
	 * In that case, a wbinvd() is done on remote CPUs via the NMI
	 * callback, so only a local wbinvd() is needed here.
	 */
	if (!panic)
		wbinvd_on_all_cpus();
	else
		wbinvd();

	ret = __sev_do_cmd_locked(SEV_CMD_SNP_SHUTDOWN_EX, &data, error);
	/* SHUTDOWN may require DF_FLUSH */
	if (*error == SEV_RET_DFFLUSH_REQUIRED) {
		int dfflush_error = SEV_RET_NO_FW_CALL;

		ret = __sev_do_cmd_locked(SEV_CMD_SNP_DF_FLUSH, NULL, &dfflush_error);
		if (ret) {
			dev_err(sev->dev, "SEV-SNP DF_FLUSH failed, ret = %d, error = %#x\n",
				ret, dfflush_error);
			return ret;
		}
		/* reissue the shutdown command */
		ret = __sev_do_cmd_locked(SEV_CMD_SNP_SHUTDOWN_EX, &data,
					  error);
	}
	if (ret) {
		dev_err(sev->dev, "SEV-SNP firmware shutdown failed, rc %d, error %#x\n",
			ret, *error);
		return ret;
	}

	if (data.x86_snp_shutdown) {
		if (!panic)
			snp_shutdown();
		snp_hv_fixed_pages_state_update(sev, ALLOCATED);
	} else {
		/*
		 * SNP_SHUTDOWN_EX with IOMMU_SNP_SHUTDOWN set to 1 disables SNP
		 * enforcement by the IOMMU and also transitions all pages
		 * associated with the IOMMU to the Reclaim state.
		 * Firmware was transitioning the IOMMU pages to Hypervisor state
		 * before version 1.53. But, accounting for the number of assigned
		 * 4kB pages in a 2M page was done incorrectly by not transitioning
		 * to the Reclaim state. This resulted in RMP #PF when later accessing
		 * the 2M page containing those pages during kexec boot. Hence, the
		 * firmware now transitions these pages to Reclaim state and hypervisor
		 * needs to transition these pages to shared state. SNP Firmware
		 * version 1.53 and above are needed for kexec boot.
		 */
		ret = amd_iommu_snp_disable();
		if (ret) {
			dev_err(sev->dev, "SNP IOMMU shutdown failed\n");
			return ret;
		}
	}

	snp_leak_hv_fixed_pages();
	sev->snp_initialized = false;
	dev_dbg(sev->dev, "SEV-SNP firmware shutdown\n");

	/*
	 * __sev_snp_shutdown_locked() deadlocks when it tries to unregister
	 * itself during panic as the panic notifier is called with RCU read
	 * lock held and notifier unregistration does RCU synchronization.
	 */
	if (!panic)
		atomic_notifier_chain_unregister(&panic_notifier_list,
						 &snp_panic_notifier);

	/* Reset TMR size back to default */
	sev_es_tmr_size = SEV_TMR_SIZE;

	return ret;
}

static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
{
	struct sev_device *sev = psp_master->sev_data;
	struct sev_user_data_pek_cert_import input;
	struct sev_data_pek_cert_import data;
	bool shutdown_required = false;
	void *pek_blob, *oca_blob;
	int ret;

	if (!writable)
		return -EPERM;

	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
		return -EFAULT;

	/* copy PEK certificate blobs from userspace */
	pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len);
	if (IS_ERR(pek_blob))
		return PTR_ERR(pek_blob);

	data.reserved = 0;
	data.pek_cert_address = __psp_pa(pek_blob);
	data.pek_cert_len = input.pek_cert_len;

	/* copy PEK certificate blobs from userspace */
	oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len);
	if (IS_ERR(oca_blob)) {
		ret = PTR_ERR(oca_blob);
		goto e_free_pek;
	}

	data.oca_cert_address = __psp_pa(oca_blob);
	data.oca_cert_len = input.oca_cert_len;

	/* If platform is not in INIT state then transition it to INIT */
	if (sev->sev_plat_status.state != SEV_STATE_INIT) {
		ret = sev_move_to_init_state(argp, &shutdown_required);
		if (ret)
			goto e_free_oca;
	}

	ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, &data, &argp->error);

e_free_oca:
	if (shutdown_required)
		__sev_firmware_shutdown(sev, false);

	kfree(oca_blob);
e_free_pek:
	kfree(pek_blob);
	return ret;
}

static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
{
	struct sev_user_data_get_id2 input;
	struct sev_data_get_id data;
	void __user *input_address;
	void *id_blob = NULL;
	int ret;

	/* SEV GET_ID is available from SEV API v0.16 and up */
	if (!sev_version_greater_or_equal(0, 16))
		return -ENOTSUPP;

	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
		return -EFAULT;

	input_address = (void __user *)input.address;

	if (input.address && input.length) {
		/*
		 * The length of the ID shouldn't be assumed by software since
		 * it may change in the future.  The allocation size is limited
		 * to 1 << (PAGE_SHIFT + MAX_PAGE_ORDER) by the page allocator.
		 * If the allocation fails, simply return ENOMEM rather than
		 * warning in the kernel log.
		 */
		id_blob = kzalloc(input.length, GFP_KERNEL | __GFP_NOWARN);
		if (!id_blob)
			return -ENOMEM;

		data.address = __psp_pa(id_blob);
		data.len = input.length;
	} else {
		data.address = 0;
		data.len = 0;
	}

	ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, &data, &argp->error);

	/*
	 * Firmware will return the length of the ID value (either the minimum
	 * required length or the actual length written), return it to the user.
	 */
	input.length = data.len;

	if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
		ret = -EFAULT;
		goto e_free;
	}

	if (ret || WARN_ON_ONCE(argp->error))
		goto e_free;

	if (id_blob) {
		if (copy_to_user(input_address, id_blob, data.len)) {
			ret = -EFAULT;
			goto e_free;
		}
	}

e_free:
	kfree(id_blob);

	return ret;
}

static int sev_ioctl_do_get_id(struct sev_issue_cmd *argp)
{
	struct sev_data_get_id *data;
	u64 data_size, user_size;
	void *id_blob, *mem;
	int ret;

	/* SEV GET_ID available from SEV API v0.16 and up */
	if (!sev_version_greater_or_equal(0, 16))
		return -ENOTSUPP;

	/* SEV FW expects the buffer it fills with the ID to be
	 * 8-byte aligned. Memory allocated should be enough to
	 * hold data structure + alignment padding + memory
	 * where SEV FW writes the ID.
	 */
	data_size = ALIGN(sizeof(struct sev_data_get_id), 8);
	user_size = sizeof(struct sev_user_data_get_id);

	mem = kzalloc(data_size + user_size, GFP_KERNEL);
	if (!mem)
		return -ENOMEM;

	data = mem;
	id_blob = mem + data_size;

	data->address = __psp_pa(id_blob);
	data->len = user_size;

	ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, data, &argp->error);
	if (!ret) {
		if (copy_to_user((void __user *)argp->data, id_blob, data->len))
			ret = -EFAULT;
	}

	kfree(mem);

	return ret;
}

static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
{
	struct sev_device *sev = psp_master->sev_data;
	struct sev_user_data_pdh_cert_export input;
	void *pdh_blob = NULL, *cert_blob = NULL;
	struct sev_data_pdh_cert_export data;
	void __user *input_cert_chain_address;
	void __user *input_pdh_cert_address;
	bool shutdown_required = false;
	int ret;

	if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
		return -EFAULT;

	memset(&data, 0, sizeof(data));

	input_pdh_cert_address = (void __user *)input.pdh_cert_address;
	input_cert_chain_address = (void __user *)input.cert_chain_address;

	/* Userspace wants to query the certificate length. */
	if (!input.pdh_cert_address ||
	    !input.pdh_cert_len ||
	    !input.cert_chain_address)
		goto cmd;

	/* Allocate a physically contiguous buffer to store the PDH blob. */
	if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE)
		return -EFAULT;

	/* Allocate a physically contiguous buffer to store the cert chain blob. */
	if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE)
		return -EFAULT;

	pdh_blob = kzalloc(input.pdh_cert_len, GFP_KERNEL);
	if (!pdh_blob)
		return -ENOMEM;

	data.pdh_cert_address = __psp_pa(pdh_blob);
	data.pdh_cert_len = input.pdh_cert_len;

	cert_blob = kzalloc(input.cert_chain_len, GFP_KERNEL);
	if (!cert_blob) {
		ret = -ENOMEM;
		goto e_free_pdh;
	}

	data.cert_chain_address = __psp_pa(cert_blob);
	data.cert_chain_len = input.cert_chain_len;

cmd:
	/* If platform is not in INIT state then transition it to INIT. */
	if (sev->sev_plat_status.state != SEV_STATE_INIT) {
		if (!writable) {
			ret = -EPERM;
			goto e_free_cert;
		}
		ret = sev_move_to_init_state(argp, &shutdown_required);
		if (ret)
			goto e_free_cert;
	}

	ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, &data, &argp->error);

	/*
	 * Firmware will return the length of the blobs (either the minimum
	 * required length or the actual length written), return 'em to the user.
	 */
	input.cert_chain_len = data.cert_chain_len;
	input.pdh_cert_len = data.pdh_cert_len;

	if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) {
		ret = -EFAULT;
		goto e_free_cert;
	}

	if (ret || WARN_ON_ONCE(argp->error))
		goto e_free_cert;

	if (pdh_blob) {
		if (copy_to_user(input_pdh_cert_address,
				 pdh_blob, input.pdh_cert_len)) {
			ret = -EFAULT;
			goto e_free_cert;
		}
	}

	if (cert_blob) {
		if (copy_to_user(input_cert_chain_address,
				 cert_blob, input.cert_chain_len))
			ret = -EFAULT;
	}

e_free_cert:
	if (shutdown_required)
		__sev_firmware_shutdown(sev, false);

	kfree(cert_blob);
e_free_pdh:
	kfree(pdh_blob);
	return ret;
}

static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp)
{
	struct sev_device *sev = psp_master->sev_data;
	struct sev_data_snp_addr buf;
	struct page *status_page;
	void *data;
	int ret;

	if (!argp->data)
		return -EINVAL;

	status_page = alloc_page(GFP_KERNEL_ACCOUNT);
	if (!status_page)
		return -ENOMEM;

	data = page_address(status_page);

	/*
	 * SNP_PLATFORM_STATUS can be executed in any SNP state. But if executed
	 * when SNP has been initialized, the status page must be firmware-owned.
	 */
	if (sev->snp_initialized) {
		/*
		 * Firmware expects the status page to be in Firmware state,
		 * otherwise it will report an error INVALID_PAGE_STATE.
		 */
		if (rmp_mark_pages_firmware(__pa(data), 1, true)) {
			ret = -EFAULT;
			goto cleanup;
		}
	}

	buf.address = __psp_pa(data);
	ret = __sev_do_cmd_locked(SEV_CMD_SNP_PLATFORM_STATUS, &buf, &argp->error);

	if (sev->snp_initialized) {
		/*
		 * The status page will be in Reclaim state on success, or left
		 * in Firmware state on failure. Use snp_reclaim_pages() to
		 * transition either case back to Hypervisor-owned state.
		 */
		if (snp_reclaim_pages(__pa(data), 1, true))
			return -EFAULT;
	}

	if (ret)
		goto cleanup;

	if (copy_to_user((void __user *)argp->data, data,
			 sizeof(struct sev_user_data_snp_status)))
		ret = -EFAULT;

cleanup:
	__free_pages(status_page, 0);
	return ret;
}

static int sev_ioctl_do_snp_commit(struct sev_issue_cmd *argp)
{
	struct sev_device *sev = psp_master->sev_data;
	struct sev_data_snp_commit buf;
	bool shutdown_required = false;
	int ret, error;

	if (!sev->snp_initialized) {
		ret = snp_move_to_init_state(argp, &shutdown_required);
		if (ret)
			return ret;
	}

	buf.len = sizeof(buf);

	ret = __sev_do_cmd_locked(SEV_CMD_SNP_COMMIT, &buf, &argp->error);

	if (shutdown_required)
		__sev_snp_shutdown_locked(&error, false);

	return ret;
}

static int sev_ioctl_do_snp_set_config(struct sev_issue_cmd *argp, bool writable)
{
	struct sev_device *sev = psp_master->sev_data;
	struct sev_user_data_snp_config config;
	bool shutdown_required = false;
	int ret, error;

	if (!argp->data)
		return -EINVAL;

	if (!writable)
		return -EPERM;

	if (copy_from_user(&config, (void __user *)argp->data, sizeof(config)))
		return -EFAULT;

	if (!sev->snp_initialized) {
		ret = snp_move_to_init_state(argp, &shutdown_required);
		if (ret)
			return ret;
	}

	ret = __sev_do_cmd_locked(SEV_CMD_SNP_CONFIG, &config, &argp->error);

	if (shutdown_required)
		__sev_snp_shutdown_locked(&error, false);

	return ret;
}

static int sev_ioctl_do_snp_vlek_load(struct sev_issue_cmd *argp, bool writable)
{
	struct sev_device *sev = psp_master->sev_data;
	struct sev_user_data_snp_vlek_load input;
	bool shutdown_required = false;
	int ret, error;
	void *blob;

	if (!argp->data)
		return -EINVAL;

	if (!writable)
		return -EPERM;

	if (copy_from_user(&input, u64_to_user_ptr(argp->data), sizeof(input)))
		return -EFAULT;

	if (input.len != sizeof(input) || input.vlek_wrapped_version != 0)
		return -EINVAL;

	blob = psp_copy_user_blob(input.vlek_wrapped_address,
				  sizeof(struct sev_user_data_snp_wrapped_vlek_hashstick));
	if (IS_ERR(blob))
		return PTR_ERR(blob);

	input.vlek_wrapped_address = __psp_pa(blob);

	if (!sev->snp_initialized) {
		ret = snp_move_to_init_state(argp, &shutdown_required);
		if (ret)
			goto cleanup;
	}

	ret = __sev_do_cmd_locked(SEV_CMD_SNP_VLEK_LOAD, &input, &argp->error);

	if (shutdown_required)
		__sev_snp_shutdown_locked(&error, false);

cleanup:
	kfree(blob);

	return ret;
}

static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	struct sev_issue_cmd input;
	int ret = -EFAULT;
	bool writable = file->f_mode & FMODE_WRITE;

	if (!psp_master || !psp_master->sev_data)
		return -ENODEV;

	if (ioctl != SEV_ISSUE_CMD)
		return -EINVAL;

	if (copy_from_user(&input, argp, sizeof(struct sev_issue_cmd)))
		return -EFAULT;

	if (input.cmd > SEV_MAX)
		return -EINVAL;

	mutex_lock(&sev_cmd_mutex);

	switch (input.cmd) {

	case SEV_FACTORY_RESET:
		ret = sev_ioctl_do_reset(&input, writable);
		break;
	case SEV_PLATFORM_STATUS:
		ret = sev_ioctl_do_platform_status(&input);
		break;
	case SEV_PEK_GEN:
		ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PEK_GEN, &input, writable);
		break;
	case SEV_PDH_GEN:
		ret = sev_ioctl_do_pek_pdh_gen(SEV_CMD_PDH_GEN, &input, writable);
		break;
	case SEV_PEK_CSR:
		ret = sev_ioctl_do_pek_csr(&input, writable);
		break;
	case SEV_PEK_CERT_IMPORT:
		ret = sev_ioctl_do_pek_import(&input, writable);
		break;
	case SEV_PDH_CERT_EXPORT:
		ret = sev_ioctl_do_pdh_export(&input, writable);
		break;
	case SEV_GET_ID:
		pr_warn_once("SEV_GET_ID command is deprecated, use SEV_GET_ID2\n");
		ret = sev_ioctl_do_get_id(&input);
		break;
	case SEV_GET_ID2:
		ret = sev_ioctl_do_get_id2(&input);
		break;
	case SNP_PLATFORM_STATUS:
		ret = sev_ioctl_do_snp_platform_status(&input);
		break;
	case SNP_COMMIT:
		ret = sev_ioctl_do_snp_commit(&input);
		break;
	case SNP_SET_CONFIG:
		ret = sev_ioctl_do_snp_set_config(&input, writable);
		break;
	case SNP_VLEK_LOAD:
		ret = sev_ioctl_do_snp_vlek_load(&input, writable);
		break;
	default:
		ret = -EINVAL;
		goto out;
	}

	if (copy_to_user(argp, &input, sizeof(struct sev_issue_cmd)))
		ret = -EFAULT;
out:
	mutex_unlock(&sev_cmd_mutex);

	return ret;
}

static const struct file_operations sev_fops = {
	.owner	= THIS_MODULE,
	.unlocked_ioctl = sev_ioctl,
};

int sev_platform_status(struct sev_user_data_status *data, int *error)
{
	return sev_do_cmd(SEV_CMD_PLATFORM_STATUS, data, error);
}
EXPORT_SYMBOL_GPL(sev_platform_status);

int sev_guest_deactivate(struct sev_data_deactivate *data, int *error)
{
	return sev_do_cmd(SEV_CMD_DEACTIVATE, data, error);
}
EXPORT_SYMBOL_GPL(sev_guest_deactivate);

int sev_guest_activate(struct sev_data_activate *data, int *error)
{
	return sev_do_cmd(SEV_CMD_ACTIVATE, data, error);
}
EXPORT_SYMBOL_GPL(sev_guest_activate);

int sev_guest_decommission(struct sev_data_decommission *data, int *error)
{
	return sev_do_cmd(SEV_CMD_DECOMMISSION, data, error);
}
EXPORT_SYMBOL_GPL(sev_guest_decommission);

int sev_guest_df_flush(int *error)
{
	return sev_do_cmd(SEV_CMD_DF_FLUSH, NULL, error);
}
EXPORT_SYMBOL_GPL(sev_guest_df_flush);

static void sev_exit(struct kref *ref)
{
	misc_deregister(&misc_dev->misc);
	kfree(misc_dev);
	misc_dev = NULL;
}

static int sev_misc_init(struct sev_device *sev)
{
	struct device *dev = sev->dev;
	int ret;

	/*
	 * SEV feature support can be detected on multiple devices but the SEV
	 * FW commands must be issued on the master. During probe, we do not
	 * know the master hence we create /dev/sev on the first device probe.
	 * sev_do_cmd() finds the right master device to which to issue the
	 * command to the firmware.
	 */
	if (!misc_dev) {
		struct miscdevice *misc;

		misc_dev = kzalloc_obj(*misc_dev);
		if (!misc_dev)
			return -ENOMEM;

		misc = &misc_dev->misc;
		misc->minor = MISC_DYNAMIC_MINOR;
		misc->name = DEVICE_NAME;
		misc->fops = &sev_fops;

		ret = misc_register(misc);
		if (ret)
			return ret;

		kref_init(&misc_dev->refcount);
	} else {
		kref_get(&misc_dev->refcount);
	}

	init_waitqueue_head(&sev->int_queue);
	sev->misc = misc_dev;
	dev_dbg(dev, "registered SEV device\n");

	return 0;
}

int sev_dev_init(struct psp_device *psp)
{
	struct device *dev = psp->dev;
	struct sev_device *sev;
	int ret = -ENOMEM;

	if (!boot_cpu_has(X86_FEATURE_SEV)) {
		dev_info_once(dev, "SEV: memory encryption not enabled by BIOS\n");
		return 0;
	}

	sev = devm_kzalloc(dev, sizeof(*sev), GFP_KERNEL);
	if (!sev)
		goto e_err;

	sev->cmd_buf = (void *)devm_get_free_pages(dev, GFP_KERNEL, 1);
	if (!sev->cmd_buf)
		goto e_sev;

	sev->cmd_buf_backup = (uint8_t *)sev->cmd_buf + PAGE_SIZE;

	psp->sev_data = sev;

	sev->dev = dev;
	sev->psp = psp;

	sev->io_regs = psp->io_regs;

	sev->vdata = (struct sev_vdata *)psp->vdata->sev;
	if (!sev->vdata) {
		ret = -ENODEV;
		dev_err(dev, "sev: missing driver data\n");
		goto e_buf;
	}

	psp_set_sev_irq_handler(psp, sev_irq_handler, sev);

	ret = sev_misc_init(sev);
	if (ret)
		goto e_irq;

	dev_notice(dev, "sev enabled\n");

	return 0;

e_irq:
	psp_clear_sev_irq_handler(psp);
e_buf:
	devm_free_pages(dev, (unsigned long)sev->cmd_buf);
e_sev:
	devm_kfree(dev, sev);
e_err:
	psp->sev_data = NULL;

	dev_notice(dev, "sev initialization failed\n");

	return ret;
}

static void __sev_firmware_shutdown(struct sev_device *sev, bool panic)
{
	int error;

	__sev_platform_shutdown_locked(&error);

	if (sev_es_tmr) {
		/*
		 * The TMR area was encrypted, flush it from the cache.
		 *
		 * If invoked during panic handling, local interrupts are
		 * disabled and all CPUs are stopped, so wbinvd_on_all_cpus()
		 * can't be used. In that case, wbinvd() is done on remote CPUs
		 * via the NMI callback, and done for this CPU later during
		 * SNP shutdown, so wbinvd_on_all_cpus() can be skipped.
		 */
		if (!panic)
			wbinvd_on_all_cpus();

		__snp_free_firmware_pages(virt_to_page(sev_es_tmr),
					  get_order(sev_es_tmr_size),
					  true);
		sev_es_tmr = NULL;
	}

	if (sev_init_ex_buffer) {
		__snp_free_firmware_pages(virt_to_page(sev_init_ex_buffer),
					  get_order(NV_LENGTH),
					  true);
		sev_init_ex_buffer = NULL;
	}

	__sev_snp_shutdown_locked(&error, panic);
}

static void sev_firmware_shutdown(struct sev_device *sev)
{
	/*
	 * Calling without sev_cmd_mutex held as TSM will likely try disconnecting
	 * IDE and this ends up calling sev_do_cmd() which locks sev_cmd_mutex.
	 */
	if (sev->tio_status)
		sev_tsm_uninit(sev);

	mutex_lock(&sev_cmd_mutex);

	__sev_firmware_shutdown(sev, false);

	kfree(sev->tio_status);
	sev->tio_status = NULL;

	mutex_unlock(&sev_cmd_mutex);
}

void sev_platform_shutdown(void)
{
	if (!psp_master || !psp_master->sev_data)
		return;

	sev_firmware_shutdown(psp_master->sev_data);
}
EXPORT_SYMBOL_GPL(sev_platform_shutdown);

u64 sev_get_snp_policy_bits(void)
{
	struct psp_device *psp = psp_master;
	struct sev_device *sev;
	u64 policy_bits;

	if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
		return 0;

	if (!psp || !psp->sev_data)
		return 0;

	sev = psp->sev_data;

	policy_bits = SNP_POLICY_MASK_BASE;

	if (sev->snp_plat_status.feature_info) {
		if (sev->snp_feat_info_0.ecx & SNP_RAPL_DISABLE_SUPPORTED)
			policy_bits |= SNP_POLICY_MASK_RAPL_DIS;

		if (sev->snp_feat_info_0.ecx & SNP_CIPHER_TEXT_HIDING_SUPPORTED)
			policy_bits |= SNP_POLICY_MASK_CIPHERTEXT_HIDING_DRAM;

		if (sev->snp_feat_info_0.ecx & SNP_AES_256_XTS_POLICY_SUPPORTED)
			policy_bits |= SNP_POLICY_MASK_MEM_AES_256_XTS;

		if (sev->snp_feat_info_0.ecx & SNP_CXL_ALLOW_POLICY_SUPPORTED)
			policy_bits |= SNP_POLICY_MASK_CXL_ALLOW;

		if (sev_version_greater_or_equal(1, 58))
			policy_bits |= SNP_POLICY_MASK_PAGE_SWAP_DISABLE;
	}

	return policy_bits;
}
EXPORT_SYMBOL_GPL(sev_get_snp_policy_bits);

void sev_dev_destroy(struct psp_device *psp)
{
	struct sev_device *sev = psp->sev_data;

	if (!sev)
		return;

	sev_firmware_shutdown(sev);

	if (sev->misc)
		kref_put(&misc_dev->refcount, sev_exit);

	psp_clear_sev_irq_handler(psp);
}

static int snp_shutdown_on_panic(struct notifier_block *nb,
				 unsigned long reason, void *arg)
{
	struct sev_device *sev = psp_master->sev_data;

	/*
	 * If sev_cmd_mutex is already acquired, then it's likely
	 * another PSP command is in flight and issuing a shutdown
	 * would fail in unexpected ways. Rather than create even
	 * more confusion during a panic, just bail out here.
	 */
	if (mutex_is_locked(&sev_cmd_mutex))
		return NOTIFY_DONE;

	__sev_firmware_shutdown(sev, true);

	return NOTIFY_DONE;
}

int sev_issue_cmd_external_user(struct file *filep, unsigned int cmd,
				void *data, int *error)
{
	if (!filep || filep->f_op != &sev_fops)
		return -EBADF;

	return sev_do_cmd(cmd, data, error);
}
EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user);

void sev_pci_init(void)
{
	struct sev_device *sev = psp_master->sev_data;
	u8 api_major, api_minor, build;

	if (!sev)
		return;

	psp_timeout = psp_probe_timeout;

	if (sev_get_api_version())
		goto err;

	api_major = sev->api_major;
	api_minor = sev->api_minor;
	build     = sev->build;

	if (sev_update_firmware(sev->dev) == 0)
		sev_get_api_version();

	if (api_major != sev->api_major || api_minor != sev->api_minor ||
	    build != sev->build)
		dev_info(sev->dev, "SEV firmware updated from %d.%d.%d to %d.%d.%d\n",
			 api_major, api_minor, build,
			 sev->api_major, sev->api_minor, sev->build);

	return;

err:
	sev_dev_destroy(psp_master);

	psp_master->sev_data = NULL;
}

void sev_pci_exit(void)
{
	struct sev_device *sev = psp_master->sev_data;

	if (!sev)
		return;

	sev_firmware_shutdown(sev);
}
