// SPDX-License-Identifier: GPL-2.0+
/*
 * Originally from efivars.c
 *
 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
 */

#define pr_fmt(fmt) "efivars: " fmt

#include <linux/types.h>
#include <linux/sizes.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/smp.h>
#include <linux/efi.h>
#include <linux/ucs2_string.h>

/* Private pointer to registered efivars */
static struct efivars *__efivars;

static DEFINE_SEMAPHORE(efivars_lock, 1);

static efi_status_t check_var_size(bool nonblocking, u32 attributes,
				   unsigned long size)
{
	const struct efivar_operations *fops;
	efi_status_t status;

	fops = __efivars->ops;

	if (!fops->query_variable_store)
		status = EFI_UNSUPPORTED;
	else
		status = fops->query_variable_store(attributes, size,
						    nonblocking);
	if (status == EFI_UNSUPPORTED)
		return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
	return status;
}

/**
 * efivar_is_available - check if efivars is available
 *
 * @return true iff evivars is currently registered
 */
bool efivar_is_available(void)
{
	return __efivars != NULL;
}
EXPORT_SYMBOL_GPL(efivar_is_available);

/**
 * efivars_register - register an efivars
 * @efivars: efivars to register
 * @ops: efivars operations
 *
 * Only a single efivars can be registered at any time.
 */
int efivars_register(struct efivars *efivars,
		     const struct efivar_operations *ops)
{
	int rv;
	int event;

	if (down_interruptible(&efivars_lock))
		return -EINTR;

	if (__efivars) {
		pr_warn("efivars already registered\n");
		rv = -EBUSY;
		goto out;
	}

	efivars->ops = ops;

	__efivars = efivars;

	if (efivar_supports_writes())
		event = EFIVAR_OPS_RDWR;
	else
		event = EFIVAR_OPS_RDONLY;

	blocking_notifier_call_chain(&efivar_ops_nh, event, NULL);

	pr_info("Registered efivars operations\n");
	rv = 0;
out:
	up(&efivars_lock);

	return rv;
}
EXPORT_SYMBOL_GPL(efivars_register);

/**
 * efivars_unregister - unregister an efivars
 * @efivars: efivars to unregister
 *
 * The caller must have already removed every entry from the list,
 * failure to do so is an error.
 */
int efivars_unregister(struct efivars *efivars)
{
	int rv;

	if (down_interruptible(&efivars_lock))
		return -EINTR;

	if (!__efivars) {
		pr_err("efivars not registered\n");
		rv = -EINVAL;
		goto out;
	}

	if (__efivars != efivars) {
		rv = -EINVAL;
		goto out;
	}

	pr_info("Unregistered efivars operations\n");
	__efivars = NULL;

	rv = 0;
out:
	up(&efivars_lock);
	return rv;
}
EXPORT_SYMBOL_GPL(efivars_unregister);

bool efivar_supports_writes(void)
{
	return __efivars && __efivars->ops->set_variable;
}
EXPORT_SYMBOL_GPL(efivar_supports_writes);

/*
 * efivar_lock() - obtain the efivar lock, wait for it if needed
 * @return 0 on success, error code on failure
 */
int efivar_lock(void)
{
	if (down_interruptible(&efivars_lock))
		return -EINTR;
	if (!__efivars->ops) {
		up(&efivars_lock);
		return -ENODEV;
	}
	return 0;
}
EXPORT_SYMBOL_NS_GPL(efivar_lock, "EFIVAR");

/*
 * efivar_lock() - obtain the efivar lock if it is free
 * @return 0 on success, error code on failure
 */
int efivar_trylock(void)
{
	if (down_trylock(&efivars_lock))
		 return -EBUSY;
	if (!__efivars->ops) {
		up(&efivars_lock);
		return -ENODEV;
	}
	return 0;
}
EXPORT_SYMBOL_NS_GPL(efivar_trylock, "EFIVAR");

/*
 * efivar_unlock() - release the efivar lock
 */
void efivar_unlock(void)
{
	up(&efivars_lock);
}
EXPORT_SYMBOL_NS_GPL(efivar_unlock, "EFIVAR");

/*
 * efivar_get_variable() - retrieve a variable identified by name/vendor
 *
 * Must be called with efivars_lock held.
 */
efi_status_t efivar_get_variable(efi_char16_t *name, efi_guid_t *vendor,
				 u32 *attr, unsigned long *size, void *data)
{
	return __efivars->ops->get_variable(name, vendor, attr, size, data);
}
EXPORT_SYMBOL_NS_GPL(efivar_get_variable, "EFIVAR");

/*
 * efivar_get_next_variable() - enumerate the next name/vendor pair
 *
 * Must be called with efivars_lock held.
 */
efi_status_t efivar_get_next_variable(unsigned long *name_size,
				      efi_char16_t *name, efi_guid_t *vendor)
{
	return __efivars->ops->get_next_variable(name_size, name, vendor);
}
EXPORT_SYMBOL_NS_GPL(efivar_get_next_variable, "EFIVAR");

/*
 * efivar_set_variable_locked() - set a variable identified by name/vendor
 *
 * Must be called with efivars_lock held. If @nonblocking is set, it will use
 * non-blocking primitives so it is guaranteed not to sleep.
 */
efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
					u32 attr, unsigned long data_size,
					void *data, bool nonblocking)
{
	efi_set_variable_t *setvar;
	efi_status_t status;

	if (data_size > 0) {
		status = check_var_size(nonblocking, attr,
					data_size + ucs2_strsize(name, EFI_VAR_NAME_LEN));
		if (status != EFI_SUCCESS)
			return status;
	}

	/*
	 * If no _nonblocking variant exists, the ordinary one
	 * is assumed to be non-blocking.
	 */
	setvar = __efivars->ops->set_variable_nonblocking;
	if (!setvar || !nonblocking)
		 setvar = __efivars->ops->set_variable;

	return setvar(name, vendor, attr, data_size, data);
}
EXPORT_SYMBOL_NS_GPL(efivar_set_variable_locked, "EFIVAR");

/*
 * efivar_set_variable() - set a variable identified by name/vendor
 *
 * Can be called without holding the efivars_lock. Will sleep on obtaining the
 * lock, or on obtaining other locks that are needed in order to complete the
 * call.
 */
efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor,
				 u32 attr, unsigned long data_size, void *data)
{
	efi_status_t status;

	if (efivar_lock())
		return EFI_ABORTED;

	status = efivar_set_variable_locked(name, vendor, attr, data_size,
					    data, false);
	efivar_unlock();
	return status;
}
EXPORT_SYMBOL_NS_GPL(efivar_set_variable, "EFIVAR");

efi_status_t efivar_query_variable_info(u32 attr,
					u64 *storage_space,
					u64 *remaining_space,
					u64 *max_variable_size)
{
	if (!__efivars->ops->query_variable_info)
		return EFI_UNSUPPORTED;
	return __efivars->ops->query_variable_info(attr, storage_space,
			remaining_space, max_variable_size);
}
EXPORT_SYMBOL_NS_GPL(efivar_query_variable_info, "EFIVAR");
