// SPDX-License-Identifier: GPL-2.0-only

#define pr_fmt(fmt) "papr-vpd: " fmt

#include <linux/anon_inodes.h>
#include <linux/build_bug.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/lockdep.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/string_helpers.h>
#include <linux/uaccess.h>
#include <asm/machdep.h>
#include <asm/papr-vpd.h>
#include <asm/rtas-work-area.h>
#include <asm/rtas.h>
#include <uapi/asm/papr-vpd.h>

/*
 * Function-specific return values for ibm,get-vpd, derived from PAPR+
 * v2.13 7.3.20 "ibm,get-vpd RTAS Call".
 */
#define RTAS_IBM_GET_VPD_COMPLETE    0 /* All VPD has been retrieved. */
#define RTAS_IBM_GET_VPD_MORE_DATA   1 /* More VPD is available. */
#define RTAS_IBM_GET_VPD_START_OVER -4 /* VPD changed, restart call sequence. */

/**
 * struct rtas_ibm_get_vpd_params - Parameters (in and out) for ibm,get-vpd.
 * @loc_code:  In: Caller-provided location code buffer. Must be RTAS-addressable.
 * @work_area: In: Caller-provided work area buffer for results.
 * @sequence:  In: Sequence number. Out: Next sequence number.
 * @written:   Out: Bytes written by ibm,get-vpd to @work_area.
 * @status:    Out: RTAS call status.
 */
struct rtas_ibm_get_vpd_params {
	const struct papr_location_code *loc_code;
	struct rtas_work_area *work_area;
	u32 sequence;
	u32 written;
	s32 status;
};

/**
 * rtas_ibm_get_vpd() - Call ibm,get-vpd to fill a work area buffer.
 * @params: See &struct rtas_ibm_get_vpd_params.
 *
 * Calls ibm,get-vpd until it errors or successfully deposits data
 * into the supplied work area. Handles RTAS retry statuses. Maps RTAS
 * error statuses to reasonable errno values.
 *
 * The caller is expected to invoke rtas_ibm_get_vpd() multiple times
 * to retrieve all the VPD for the provided location code. Only one
 * sequence should be in progress at any time; starting a new sequence
 * will disrupt any sequence already in progress. Serialization of VPD
 * retrieval sequences is the responsibility of the caller.
 *
 * The caller should inspect @params.status to determine whether more
 * calls are needed to complete the sequence.
 *
 * Context: May sleep.
 * Return: -ve on error, 0 otherwise.
 */
static int rtas_ibm_get_vpd(struct rtas_ibm_get_vpd_params *params)
{
	const struct papr_location_code *loc_code = params->loc_code;
	struct rtas_work_area *work_area = params->work_area;
	u32 rets[2];
	s32 fwrc;
	int ret;

	lockdep_assert_held(&rtas_ibm_get_vpd_lock);

	do {
		fwrc = rtas_call(rtas_function_token(RTAS_FN_IBM_GET_VPD), 4, 3,
				 rets,
				 __pa(loc_code),
				 rtas_work_area_phys(work_area),
				 rtas_work_area_size(work_area),
				 params->sequence);
	} while (rtas_busy_delay(fwrc));

	switch (fwrc) {
	case RTAS_HARDWARE_ERROR:
		ret = -EIO;
		break;
	case RTAS_INVALID_PARAMETER:
		ret = -EINVAL;
		break;
	case RTAS_IBM_GET_VPD_START_OVER:
		ret = -EAGAIN;
		break;
	case RTAS_IBM_GET_VPD_MORE_DATA:
		params->sequence = rets[0];
		fallthrough;
	case RTAS_IBM_GET_VPD_COMPLETE:
		params->written = rets[1];
		/*
		 * Kernel or firmware bug, do not continue.
		 */
		if (WARN(params->written > rtas_work_area_size(work_area),
			 "possible write beyond end of work area"))
			ret = -EFAULT;
		else
			ret = 0;
		break;
	default:
		ret = -EIO;
		pr_err_ratelimited("unexpected ibm,get-vpd status %d\n", fwrc);
		break;
	}

	params->status = fwrc;
	return ret;
}

/*
 * Internal VPD "blob" APIs for accumulating ibm,get-vpd results into
 * an immutable buffer to be attached to a file descriptor.
 */
struct vpd_blob {
	const char *data;
	size_t len;
};

static bool vpd_blob_has_data(const struct vpd_blob *blob)
{
	return blob->data && blob->len;
}

static void vpd_blob_free(const struct vpd_blob *blob)
{
	if (blob) {
		kvfree(blob->data);
		kfree(blob);
	}
}

/**
 * vpd_blob_extend() - Append data to a &struct vpd_blob.
 * @blob: The blob to extend.
 * @data: The new data to append to @blob.
 * @len:  The length of @data.
 *
 * Context: May sleep.
 * Return: -ENOMEM on allocation failure, 0 otherwise.
 */
static int vpd_blob_extend(struct vpd_blob *blob, const char *data, size_t len)
{
	const size_t new_len = blob->len + len;
	const size_t old_len = blob->len;
	const char *old_ptr = blob->data;
	char *new_ptr;

	new_ptr = old_ptr ?
		kvrealloc(old_ptr, old_len, new_len, GFP_KERNEL_ACCOUNT) :
		kvmalloc(len, GFP_KERNEL_ACCOUNT);

	if (!new_ptr)
		return -ENOMEM;

	memcpy(&new_ptr[old_len], data, len);
	blob->data = new_ptr;
	blob->len = new_len;
	return 0;
}

/**
 * vpd_blob_generate() - Construct a new &struct vpd_blob.
 * @generator: Function that supplies the blob data.
 * @arg:       Context pointer supplied by caller, passed to @generator.
 *
 * The @generator callback is invoked until it returns NULL. @arg is
 * passed to @generator in its first argument on each call. When
 * @generator returns data, it should store the data length in its
 * second argument.
 *
 * Context: May sleep.
 * Return: A completely populated &struct vpd_blob, or NULL on error.
 */
static const struct vpd_blob *
vpd_blob_generate(const char * (*generator)(void *, size_t *), void *arg)
{
	struct vpd_blob *blob;
	const char *buf;
	size_t len;
	int err = 0;

	blob  = kzalloc(sizeof(*blob), GFP_KERNEL_ACCOUNT);
	if (!blob)
		return NULL;

	while (err == 0 && (buf = generator(arg, &len)))
		err = vpd_blob_extend(blob, buf, len);

	if (err != 0 || !vpd_blob_has_data(blob))
		goto free_blob;

	return blob;
free_blob:
	vpd_blob_free(blob);
	return NULL;
}

/*
 * Internal VPD sequence APIs. A VPD sequence is a series of calls to
 * ibm,get-vpd for a given location code. The sequence ends when an
 * error is encountered or all VPD for the location code has been
 * returned.
 */

/**
 * struct vpd_sequence - State for managing a VPD sequence.
 * @error:  Shall be zero as long as the sequence has not encountered an error,
 *          -ve errno otherwise. Use vpd_sequence_set_err() to update this.
 * @params: Parameter block to pass to rtas_ibm_get_vpd().
 */
struct vpd_sequence {
	int error;
	struct rtas_ibm_get_vpd_params params;
};

/**
 * vpd_sequence_begin() - Begin a VPD retrieval sequence.
 * @seq:      Uninitialized sequence state.
 * @loc_code: Location code that defines the scope of the VPD to return.
 *
 * Initializes @seq with the resources necessary to carry out a VPD
 * sequence. Callers must pass @seq to vpd_sequence_end() regardless
 * of whether the sequence succeeds.
 *
 * Context: May sleep.
 */
static void vpd_sequence_begin(struct vpd_sequence *seq,
			       const struct papr_location_code *loc_code)
{
	/*
	 * Use a static data structure for the location code passed to
	 * RTAS to ensure it's in the RMA and avoid a separate work
	 * area allocation. Guarded by the function lock.
	 */
	static struct papr_location_code static_loc_code;

	/*
	 * We could allocate the work area before acquiring the
	 * function lock, but that would allow concurrent requests to
	 * exhaust the limited work area pool for no benefit. So
	 * allocate the work area under the lock.
	 */
	mutex_lock(&rtas_ibm_get_vpd_lock);
	static_loc_code = *loc_code;
	*seq = (struct vpd_sequence) {
		.params = {
			.work_area = rtas_work_area_alloc(SZ_4K),
			.loc_code = &static_loc_code,
			.sequence = 1,
		},
	};
}

/**
 * vpd_sequence_end() - Finalize a VPD retrieval sequence.
 * @seq: Sequence state.
 *
 * Releases resources obtained by vpd_sequence_begin().
 */
static void vpd_sequence_end(struct vpd_sequence *seq)
{
	rtas_work_area_free(seq->params.work_area);
	mutex_unlock(&rtas_ibm_get_vpd_lock);
}

/**
 * vpd_sequence_should_stop() - Determine whether a VPD retrieval sequence
 *                              should continue.
 * @seq: VPD sequence state.
 *
 * Examines the sequence error state and outputs of the last call to
 * ibm,get-vpd to determine whether the sequence in progress should
 * continue or stop.
 *
 * Return: True if the sequence has encountered an error or if all VPD for
 *         this sequence has been retrieved. False otherwise.
 */
static bool vpd_sequence_should_stop(const struct vpd_sequence *seq)
{
	bool done;

	if (seq->error)
		return true;

	switch (seq->params.status) {
	case 0:
		if (seq->params.written == 0)
			done = false; /* Initial state. */
		else
			done = true; /* All data consumed. */
		break;
	case 1:
		done = false; /* More data available. */
		break;
	default:
		done = true; /* Error encountered. */
		break;
	}

	return done;
}

static int vpd_sequence_set_err(struct vpd_sequence *seq, int err)
{
	/* Preserve the first error recorded. */
	if (seq->error == 0)
		seq->error = err;

	return seq->error;
}

/*
 * Generator function to be passed to vpd_blob_generate().
 */
static const char *vpd_sequence_fill_work_area(void *arg, size_t *len)
{
	struct vpd_sequence *seq = arg;
	struct rtas_ibm_get_vpd_params *p = &seq->params;

	if (vpd_sequence_should_stop(seq))
		return NULL;
	if (vpd_sequence_set_err(seq, rtas_ibm_get_vpd(p)))
		return NULL;
	*len = p->written;
	return rtas_work_area_raw_buf(p->work_area);
}

/*
 * Higher-level VPD retrieval code below. These functions use the
 * vpd_blob_* and vpd_sequence_* APIs defined above to create fd-based
 * VPD handles for consumption by user space.
 */

/**
 * papr_vpd_run_sequence() - Run a single VPD retrieval sequence.
 * @loc_code: Location code that defines the scope of VPD to return.
 *
 * Context: May sleep. Holds a mutex and an RTAS work area for its
 *          duration. Typically performs multiple sleepable slab
 *          allocations.
 *
 * Return: A populated &struct vpd_blob on success. Encoded error
 * pointer otherwise.
 */
static const struct vpd_blob *papr_vpd_run_sequence(const struct papr_location_code *loc_code)
{
	const struct vpd_blob *blob;
	struct vpd_sequence seq;

	vpd_sequence_begin(&seq, loc_code);
	blob = vpd_blob_generate(vpd_sequence_fill_work_area, &seq);
	if (!blob)
		vpd_sequence_set_err(&seq, -ENOMEM);
	vpd_sequence_end(&seq);

	if (seq.error) {
		vpd_blob_free(blob);
		return ERR_PTR(seq.error);
	}

	return blob;
}

/**
 * papr_vpd_retrieve() - Return the VPD for a location code.
 * @loc_code: Location code that defines the scope of VPD to return.
 *
 * Run VPD sequences against @loc_code until a blob is successfully
 * instantiated, or a hard error is encountered, or a fatal signal is
 * pending.
 *
 * Context: May sleep.
 * Return: A fully populated VPD blob when successful. Encoded error
 * pointer otherwise.
 */
static const struct vpd_blob *papr_vpd_retrieve(const struct papr_location_code *loc_code)
{
	const struct vpd_blob *blob;

	/*
	 * EAGAIN means the sequence errored with a -4 (VPD changed)
	 * status from ibm,get-vpd, and we should attempt a new
	 * sequence. PAPR+ v2.13 R1–7.3.20–5 indicates that this
	 * should be a transient condition, not something that happens
	 * continuously. But we'll stop trying on a fatal signal.
	 */
	do {
		blob = papr_vpd_run_sequence(loc_code);
		if (!IS_ERR(blob)) /* Success. */
			break;
		if (PTR_ERR(blob) != -EAGAIN) /* Hard error. */
			break;
		pr_info_ratelimited("VPD changed during retrieval, retrying\n");
		cond_resched();
	} while (!fatal_signal_pending(current));

	return blob;
}

static ssize_t papr_vpd_handle_read(struct file *file, char __user *buf, size_t size, loff_t *off)
{
	const struct vpd_blob *blob = file->private_data;

	/* bug: we should not instantiate a handle without any data attached. */
	if (!vpd_blob_has_data(blob)) {
		pr_err_once("handle without data\n");
		return -EIO;
	}

	return simple_read_from_buffer(buf, size, off, blob->data, blob->len);
}

static int papr_vpd_handle_release(struct inode *inode, struct file *file)
{
	const struct vpd_blob *blob = file->private_data;

	vpd_blob_free(blob);

	return 0;
}

static loff_t papr_vpd_handle_seek(struct file *file, loff_t off, int whence)
{
	const struct vpd_blob *blob = file->private_data;

	return fixed_size_llseek(file, off, whence, blob->len);
}


static const struct file_operations papr_vpd_handle_ops = {
	.read = papr_vpd_handle_read,
	.llseek = papr_vpd_handle_seek,
	.release = papr_vpd_handle_release,
};

/**
 * papr_vpd_create_handle() - Create a fd-based handle for reading VPD.
 * @ulc: Location code in user memory; defines the scope of the VPD to
 *       retrieve.
 *
 * Handler for PAPR_VPD_IOC_CREATE_HANDLE ioctl command. Validates
 * @ulc and instantiates an immutable VPD "blob" for it. The blob is
 * attached to a file descriptor for reading by user space. The memory
 * backing the blob is freed when the file is released.
 *
 * The entire requested VPD is retrieved by this call and all
 * necessary RTAS interactions are performed before returning the fd
 * to user space. This keeps the read handler simple and ensures that
 * the kernel can prevent interleaving of ibm,get-vpd call sequences.
 *
 * Return: The installed fd number if successful, -ve errno otherwise.
 */
static long papr_vpd_create_handle(struct papr_location_code __user *ulc)
{
	struct papr_location_code klc;
	const struct vpd_blob *blob;
	struct file *file;
	long err;
	int fd;

	if (copy_from_user(&klc, ulc, sizeof(klc)))
		return -EFAULT;

	if (!string_is_terminated(klc.str, ARRAY_SIZE(klc.str)))
		return -EINVAL;

	blob = papr_vpd_retrieve(&klc);
	if (IS_ERR(blob))
		return PTR_ERR(blob);

	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
	if (fd < 0) {
		err = fd;
		goto free_blob;
	}

	file = anon_inode_getfile("[papr-vpd]", &papr_vpd_handle_ops,
				  (void *)blob, O_RDONLY);
	if (IS_ERR(file)) {
		err = PTR_ERR(file);
		goto put_fd;
	}

	file->f_mode |= FMODE_LSEEK | FMODE_PREAD;
	fd_install(fd, file);
	return fd;
put_fd:
	put_unused_fd(fd);
free_blob:
	vpd_blob_free(blob);
	return err;
}

/*
 * Top-level ioctl handler for /dev/papr-vpd.
 */
static long papr_vpd_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
{
	void __user *argp = (__force void __user *)arg;
	long ret;

	switch (ioctl) {
	case PAPR_VPD_IOC_CREATE_HANDLE:
		ret = papr_vpd_create_handle(argp);
		break;
	default:
		ret = -ENOIOCTLCMD;
		break;
	}
	return ret;
}

static const struct file_operations papr_vpd_ops = {
	.unlocked_ioctl = papr_vpd_dev_ioctl,
};

static struct miscdevice papr_vpd_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "papr-vpd",
	.fops = &papr_vpd_ops,
};

static __init int papr_vpd_init(void)
{
	if (!rtas_function_implemented(RTAS_FN_IBM_GET_VPD))
		return -ENODEV;

	return misc_register(&papr_vpd_dev);
}
machine_device_initcall(pseries, papr_vpd_init);
