// SPDX-License-Identifier: GPL-2.0
/*
 *   S/390 debug facility
 *
 *    Copyright IBM Corp. 1999, 2020
 *
 *    Author(s): Michael Holzheu (holzheu@de.ibm.com),
 *		 Holger Smolinski (Holger.Smolinski@de.ibm.com)
 *
 *    Bugreports to: <Linux390@de.ibm.com>
 */

#define KMSG_COMPONENT "s390dbf"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/sysctl.h>
#include <linux/uaccess.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/minmax.h>
#include <linux/debugfs.h>

#include <asm/debug.h>

#define DEBUG_PROLOG_ENTRY -1

#define ALL_AREAS 0 /* copy all debug areas */
#define NO_AREAS  1 /* copy no debug areas */

/* typedefs */

typedef struct file_private_info {
	loff_t offset;			/* offset of last read in file */
	int    act_area;		/* number of last formated area */
	int    act_page;		/* act page in given area */
	int    act_entry;		/* last formated entry (offset */
					/* relative to beginning of last */
					/* formated page) */
	size_t act_entry_offset;	/* up to this offset we copied */
					/* in last read the last formated */
					/* entry to userland */
	char   temp_buf[2048];		/* buffer for output */
	debug_info_t *debug_info_org;	/* original debug information */
	debug_info_t *debug_info_snap;	/* snapshot of debug information */
	struct debug_view *view;	/* used view of debug info */
} file_private_info_t;

typedef struct {
	char *string;
	/*
	 * This assumes that all args are converted into longs
	 * on L/390 this is the case for all types of parameter
	 * except of floats, and long long (32 bit)
	 *
	 */
	long args[];
} debug_sprintf_entry_t;

/* internal function prototyes */

static int debug_init(void);
static ssize_t debug_output(struct file *file, char __user *user_buf,
			    size_t user_len, loff_t *offset);
static ssize_t debug_input(struct file *file, const char __user *user_buf,
			   size_t user_len, loff_t *offset);
static int debug_open(struct inode *inode, struct file *file);
static int debug_close(struct inode *inode, struct file *file);
static debug_info_t *debug_info_create(const char *name, int pages_per_area,
				       int nr_areas, int buf_size, umode_t mode);
static void debug_info_get(debug_info_t *);
static void debug_info_put(debug_info_t *);
static int debug_prolog_level_fn(debug_info_t *id,
				 struct debug_view *view, char *out_buf);
static int debug_input_level_fn(debug_info_t *id, struct debug_view *view,
				struct file *file, const char __user *user_buf,
				size_t user_buf_size, loff_t *offset);
static int debug_prolog_pages_fn(debug_info_t *id,
				 struct debug_view *view, char *out_buf);
static int debug_input_pages_fn(debug_info_t *id, struct debug_view *view,
				struct file *file, const char __user *user_buf,
				size_t user_buf_size, loff_t *offset);
static int debug_input_flush_fn(debug_info_t *id, struct debug_view *view,
				struct file *file, const char __user *user_buf,
				size_t user_buf_size, loff_t *offset);
static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view,
				     char *out_buf, const char *in_buf);
static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view,
				   char *out_buf, const char *inbuf);
static void debug_areas_swap(debug_info_t *a, debug_info_t *b);
static void debug_events_append(debug_info_t *dest, debug_info_t *src);

/* globals */

struct debug_view debug_hex_ascii_view = {
	"hex_ascii",
	NULL,
	&debug_dflt_header_fn,
	&debug_hex_ascii_format_fn,
	NULL,
	NULL
};
EXPORT_SYMBOL(debug_hex_ascii_view);

static struct debug_view debug_level_view = {
	"level",
	&debug_prolog_level_fn,
	NULL,
	NULL,
	&debug_input_level_fn,
	NULL
};

static struct debug_view debug_pages_view = {
	"pages",
	&debug_prolog_pages_fn,
	NULL,
	NULL,
	&debug_input_pages_fn,
	NULL
};

static struct debug_view debug_flush_view = {
	"flush",
	NULL,
	NULL,
	NULL,
	&debug_input_flush_fn,
	NULL
};

struct debug_view debug_sprintf_view = {
	"sprintf",
	NULL,
	&debug_dflt_header_fn,
	&debug_sprintf_format_fn,
	NULL,
	NULL
};
EXPORT_SYMBOL(debug_sprintf_view);

/* used by dump analysis tools to determine version of debug feature */
static unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION;

/* static globals */

static debug_info_t *debug_area_first;
static debug_info_t *debug_area_last;
static DEFINE_MUTEX(debug_mutex);

static int initialized;
static int debug_critical;

static const struct file_operations debug_file_ops = {
	.owner	 = THIS_MODULE,
	.read	 = debug_output,
	.write	 = debug_input,
	.open	 = debug_open,
	.release = debug_close,
	.llseek  = no_llseek,
};

static struct dentry *debug_debugfs_root_entry;

/* functions */

/*
 * debug_areas_alloc
 * - Debug areas are implemented as a threedimensonal array:
 *   areas[areanumber][pagenumber][pageoffset]
 */

static debug_entry_t ***debug_areas_alloc(int pages_per_area, int nr_areas)
{
	debug_entry_t ***areas;
	int i, j;

	areas = kmalloc_array(nr_areas, sizeof(debug_entry_t **), GFP_KERNEL);
	if (!areas)
		goto fail_malloc_areas;
	for (i = 0; i < nr_areas; i++) {
		/* GFP_NOWARN to avoid user triggerable WARN, we handle fails */
		areas[i] = kmalloc_array(pages_per_area,
					 sizeof(debug_entry_t *),
					 GFP_KERNEL | __GFP_NOWARN);
		if (!areas[i])
			goto fail_malloc_areas2;
		for (j = 0; j < pages_per_area; j++) {
			areas[i][j] = kzalloc(PAGE_SIZE, GFP_KERNEL);
			if (!areas[i][j]) {
				for (j--; j >= 0 ; j--)
					kfree(areas[i][j]);
				kfree(areas[i]);
				goto fail_malloc_areas2;
			}
		}
	}
	return areas;

fail_malloc_areas2:
	for (i--; i >= 0; i--) {
		for (j = 0; j < pages_per_area; j++)
			kfree(areas[i][j]);
		kfree(areas[i]);
	}
	kfree(areas);
fail_malloc_areas:
	return NULL;
}

/*
 * debug_info_alloc
 * - alloc new debug-info
 */
static debug_info_t *debug_info_alloc(const char *name, int pages_per_area,
				      int nr_areas, int buf_size, int level,
				      int mode)
{
	debug_info_t *rc;

	/* alloc everything */
	rc = kmalloc(sizeof(debug_info_t), GFP_KERNEL);
	if (!rc)
		goto fail_malloc_rc;
	rc->active_entries = kcalloc(nr_areas, sizeof(int), GFP_KERNEL);
	if (!rc->active_entries)
		goto fail_malloc_active_entries;
	rc->active_pages = kcalloc(nr_areas, sizeof(int), GFP_KERNEL);
	if (!rc->active_pages)
		goto fail_malloc_active_pages;
	if ((mode == ALL_AREAS) && (pages_per_area != 0)) {
		rc->areas = debug_areas_alloc(pages_per_area, nr_areas);
		if (!rc->areas)
			goto fail_malloc_areas;
	} else {
		rc->areas = NULL;
	}

	/* initialize members */
	spin_lock_init(&rc->lock);
	rc->pages_per_area = pages_per_area;
	rc->nr_areas	   = nr_areas;
	rc->active_area    = 0;
	rc->level	   = level;
	rc->buf_size	   = buf_size;
	rc->entry_size	   = sizeof(debug_entry_t) + buf_size;
	strscpy(rc->name, name, sizeof(rc->name));
	memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *));
	memset(rc->debugfs_entries, 0, DEBUG_MAX_VIEWS * sizeof(struct dentry *));
	refcount_set(&(rc->ref_count), 0);

	return rc;

fail_malloc_areas:
	kfree(rc->active_pages);
fail_malloc_active_pages:
	kfree(rc->active_entries);
fail_malloc_active_entries:
	kfree(rc);
fail_malloc_rc:
	return NULL;
}

/*
 * debug_areas_free
 * - free all debug areas
 */
static void debug_areas_free(debug_info_t *db_info)
{
	int i, j;

	if (!db_info->areas)
		return;
	for (i = 0; i < db_info->nr_areas; i++) {
		for (j = 0; j < db_info->pages_per_area; j++)
			kfree(db_info->areas[i][j]);
		kfree(db_info->areas[i]);
	}
	kfree(db_info->areas);
	db_info->areas = NULL;
}

/*
 * debug_info_free
 * - free memory debug-info
 */
static void debug_info_free(debug_info_t *db_info)
{
	debug_areas_free(db_info);
	kfree(db_info->active_entries);
	kfree(db_info->active_pages);
	kfree(db_info);
}

/*
 * debug_info_create
 * - create new debug-info
 */

static debug_info_t *debug_info_create(const char *name, int pages_per_area,
				       int nr_areas, int buf_size, umode_t mode)
{
	debug_info_t *rc;

	rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size,
			      DEBUG_DEFAULT_LEVEL, ALL_AREAS);
	if (!rc)
		goto out;

	rc->mode = mode & ~S_IFMT;
	refcount_set(&rc->ref_count, 1);
out:
	return rc;
}

/*
 * debug_info_copy
 * - copy debug-info
 */
static debug_info_t *debug_info_copy(debug_info_t *in, int mode)
{
	unsigned long flags;
	debug_info_t *rc;
	int i, j;

	/* get a consistent copy of the debug areas */
	do {
		rc = debug_info_alloc(in->name, in->pages_per_area,
			in->nr_areas, in->buf_size, in->level, mode);
		spin_lock_irqsave(&in->lock, flags);
		if (!rc)
			goto out;
		/* has something changed in the meantime ? */
		if ((rc->pages_per_area == in->pages_per_area) &&
		    (rc->nr_areas == in->nr_areas)) {
			break;
		}
		spin_unlock_irqrestore(&in->lock, flags);
		debug_info_free(rc);
	} while (1);

	if (mode == NO_AREAS)
		goto out;

	for (i = 0; i < in->nr_areas; i++) {
		for (j = 0; j < in->pages_per_area; j++)
			memcpy(rc->areas[i][j], in->areas[i][j], PAGE_SIZE);
	}
out:
	spin_unlock_irqrestore(&in->lock, flags);
	return rc;
}

/*
 * debug_info_get
 * - increments reference count for debug-info
 */
static void debug_info_get(debug_info_t *db_info)
{
	if (db_info)
		refcount_inc(&db_info->ref_count);
}

/*
 * debug_info_put:
 * - decreases reference count for debug-info and frees it if necessary
 */
static void debug_info_put(debug_info_t *db_info)
{
	if (!db_info)
		return;
	if (refcount_dec_and_test(&db_info->ref_count))
		debug_info_free(db_info);
}

/*
 * debug_format_entry:
 * - format one debug entry and return size of formated data
 */
static int debug_format_entry(file_private_info_t *p_info)
{
	debug_info_t *id_snap	= p_info->debug_info_snap;
	struct debug_view *view = p_info->view;
	debug_entry_t *act_entry;
	size_t len = 0;

	if (p_info->act_entry == DEBUG_PROLOG_ENTRY) {
		/* print prolog */
		if (view->prolog_proc)
			len += view->prolog_proc(id_snap, view, p_info->temp_buf);
		goto out;
	}
	if (!id_snap->areas) /* this is true, if we have a prolog only view */
		goto out;    /* or if 'pages_per_area' is 0 */
	act_entry = (debug_entry_t *) ((char *)id_snap->areas[p_info->act_area]
				       [p_info->act_page] + p_info->act_entry);

	if (act_entry->clock == 0LL)
		goto out; /* empty entry */
	if (view->header_proc)
		len += view->header_proc(id_snap, view, p_info->act_area,
					 act_entry, p_info->temp_buf + len);
	if (view->format_proc)
		len += view->format_proc(id_snap, view, p_info->temp_buf + len,
					 DEBUG_DATA(act_entry));
out:
	return len;
}

/*
 * debug_next_entry:
 * - goto next entry in p_info
 */
static inline int debug_next_entry(file_private_info_t *p_info)
{
	debug_info_t *id;

	id = p_info->debug_info_snap;
	if (p_info->act_entry == DEBUG_PROLOG_ENTRY) {
		p_info->act_entry = 0;
		p_info->act_page  = 0;
		goto out;
	}
	if (!id->areas)
		return 1;
	p_info->act_entry += id->entry_size;
	/* switch to next page, if we reached the end of the page  */
	if (p_info->act_entry > (PAGE_SIZE - id->entry_size)) {
		/* next page */
		p_info->act_entry = 0;
		p_info->act_page += 1;
		if ((p_info->act_page % id->pages_per_area) == 0) {
			/* next area */
			p_info->act_area++;
			p_info->act_page = 0;
		}
		if (p_info->act_area >= id->nr_areas)
			return 1;
	}
out:
	return 0;
}

/*
 * debug_output:
 * - called for user read()
 * - copies formated debug entries to the user buffer
 */
static ssize_t debug_output(struct file *file,		/* file descriptor */
			    char __user *user_buf,	/* user buffer */
			    size_t len,			/* length of buffer */
			    loff_t *offset)		/* offset in the file */
{
	size_t count = 0;
	size_t entry_offset;
	file_private_info_t *p_info;

	p_info = (file_private_info_t *) file->private_data;
	if (*offset != p_info->offset)
		return -EPIPE;
	if (p_info->act_area >= p_info->debug_info_snap->nr_areas)
		return 0;
	entry_offset = p_info->act_entry_offset;
	while (count < len) {
		int formatted_line_residue;
		int formatted_line_size;
		int user_buf_residue;
		size_t copy_size;

		formatted_line_size = debug_format_entry(p_info);
		formatted_line_residue = formatted_line_size - entry_offset;
		user_buf_residue = len-count;
		copy_size = min(user_buf_residue, formatted_line_residue);
		if (copy_size) {
			if (copy_to_user(user_buf + count, p_info->temp_buf
					 + entry_offset, copy_size))
				return -EFAULT;
			count += copy_size;
			entry_offset += copy_size;
		}
		if (copy_size == formatted_line_residue) {
			entry_offset = 0;
			if (debug_next_entry(p_info))
				goto out;
		}
	}
out:
	p_info->offset		 = *offset + count;
	p_info->act_entry_offset = entry_offset;
	*offset = p_info->offset;
	return count;
}

/*
 * debug_input:
 * - called for user write()
 * - calls input function of view
 */
static ssize_t debug_input(struct file *file, const char __user *user_buf,
			   size_t length, loff_t *offset)
{
	file_private_info_t *p_info;
	int rc = 0;

	mutex_lock(&debug_mutex);
	p_info = ((file_private_info_t *) file->private_data);
	if (p_info->view->input_proc) {
		rc = p_info->view->input_proc(p_info->debug_info_org,
					      p_info->view, file, user_buf,
					      length, offset);
	} else {
		rc = -EPERM;
	}
	mutex_unlock(&debug_mutex);
	return rc; /* number of input characters */
}

/*
 * debug_open:
 * - called for user open()
 * - copies formated output to private_data area of the file
 *   handle
 */
static int debug_open(struct inode *inode, struct file *file)
{
	debug_info_t *debug_info, *debug_info_snapshot;
	file_private_info_t *p_info;
	int i, rc = 0;

	mutex_lock(&debug_mutex);
	debug_info = file_inode(file)->i_private;
	/* find debug view */
	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
		if (!debug_info->views[i])
			continue;
		else if (debug_info->debugfs_entries[i] == file->f_path.dentry)
			goto found; /* found view ! */
	}
	/* no entry found */
	rc = -EINVAL;
	goto out;

found:

	/* Make snapshot of current debug areas to get it consistent.	  */
	/* To copy all the areas is only needed, if we have a view which  */
	/* formats the debug areas. */

	if (!debug_info->views[i]->format_proc && !debug_info->views[i]->header_proc)
		debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS);
	else
		debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS);

	if (!debug_info_snapshot) {
		rc = -ENOMEM;
		goto out;
	}
	p_info = kmalloc(sizeof(file_private_info_t), GFP_KERNEL);
	if (!p_info) {
		debug_info_free(debug_info_snapshot);
		rc = -ENOMEM;
		goto out;
	}
	p_info->offset = 0;
	p_info->debug_info_snap = debug_info_snapshot;
	p_info->debug_info_org	= debug_info;
	p_info->view = debug_info->views[i];
	p_info->act_area = 0;
	p_info->act_page = 0;
	p_info->act_entry = DEBUG_PROLOG_ENTRY;
	p_info->act_entry_offset = 0;
	file->private_data = p_info;
	debug_info_get(debug_info);
	nonseekable_open(inode, file);
out:
	mutex_unlock(&debug_mutex);
	return rc;
}

/*
 * debug_close:
 * - called for user close()
 * - deletes  private_data area of the file handle
 */
static int debug_close(struct inode *inode, struct file *file)
{
	file_private_info_t *p_info;

	p_info = (file_private_info_t *) file->private_data;
	if (p_info->debug_info_snap)
		debug_info_free(p_info->debug_info_snap);
	debug_info_put(p_info->debug_info_org);
	kfree(file->private_data);
	return 0; /* success */
}

/* Create debugfs entries and add to internal list. */
static void _debug_register(debug_info_t *id)
{
	/* create root directory */
	id->debugfs_root_entry = debugfs_create_dir(id->name,
						    debug_debugfs_root_entry);

	/* append new element to linked list */
	if (!debug_area_first) {
		/* first element in list */
		debug_area_first = id;
		id->prev = NULL;
	} else {
		/* append element to end of list */
		debug_area_last->next = id;
		id->prev = debug_area_last;
	}
	debug_area_last = id;
	id->next = NULL;

	debug_register_view(id, &debug_level_view);
	debug_register_view(id, &debug_flush_view);
	debug_register_view(id, &debug_pages_view);
}

/**
 * debug_register_mode() - creates and initializes debug area.
 *
 * @name:	Name of debug log (e.g. used for debugfs entry)
 * @pages_per_area:	Number of pages, which will be allocated per area
 * @nr_areas:	Number of debug areas
 * @buf_size:	Size of data area in each debug entry
 * @mode:	File mode for debugfs files. E.g. S_IRWXUGO
 * @uid:	User ID for debugfs files. Currently only 0 is supported.
 * @gid:	Group ID for debugfs files. Currently only 0 is supported.
 *
 * Return:
 * - Handle for generated debug area
 * - %NULL if register failed
 *
 * Allocates memory for a debug log.
 * Must not be called within an interrupt handler.
 */
debug_info_t *debug_register_mode(const char *name, int pages_per_area,
				  int nr_areas, int buf_size, umode_t mode,
				  uid_t uid, gid_t gid)
{
	debug_info_t *rc = NULL;

	/* Since debugfs currently does not support uid/gid other than root, */
	/* we do not allow gid/uid != 0 until we get support for that. */
	if ((uid != 0) || (gid != 0))
		pr_warn("Root becomes the owner of all s390dbf files in sysfs\n");
	BUG_ON(!initialized);

	/* create new debug_info */
	rc = debug_info_create(name, pages_per_area, nr_areas, buf_size, mode);
	if (rc) {
		mutex_lock(&debug_mutex);
		_debug_register(rc);
		mutex_unlock(&debug_mutex);
	} else {
		pr_err("Registering debug feature %s failed\n", name);
	}
	return rc;
}
EXPORT_SYMBOL(debug_register_mode);

/**
 * debug_register() - creates and initializes debug area with default file mode.
 *
 * @name:	Name of debug log (e.g. used for debugfs entry)
 * @pages_per_area:	Number of pages, which will be allocated per area
 * @nr_areas:	Number of debug areas
 * @buf_size:	Size of data area in each debug entry
 *
 * Return:
 * - Handle for generated debug area
 * - %NULL if register failed
 *
 * Allocates memory for a debug log.
 * The debugfs file mode access permissions are read and write for user.
 * Must not be called within an interrupt handler.
 */
debug_info_t *debug_register(const char *name, int pages_per_area,
			     int nr_areas, int buf_size)
{
	return debug_register_mode(name, pages_per_area, nr_areas, buf_size,
				   S_IRUSR | S_IWUSR, 0, 0);
}
EXPORT_SYMBOL(debug_register);

/**
 * debug_register_static() - registers a static debug area
 *
 * @id: Handle for static debug area
 * @pages_per_area: Number of pages per area
 * @nr_areas: Number of debug areas
 *
 * Register debug_info_t defined using DEFINE_STATIC_DEBUG_INFO.
 *
 * Note: This function is called automatically via an initcall generated by
 *	 DEFINE_STATIC_DEBUG_INFO.
 */
void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
{
	unsigned long flags;
	debug_info_t *copy;

	if (!initialized) {
		pr_err("Tried to register debug feature %s too early\n",
		       id->name);
		return;
	}

	copy = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size,
				id->level, ALL_AREAS);
	if (!copy) {
		pr_err("Registering debug feature %s failed\n", id->name);

		/* Clear pointers to prevent tracing into released initdata. */
		spin_lock_irqsave(&id->lock, flags);
		id->areas = NULL;
		id->active_pages = NULL;
		id->active_entries = NULL;
		spin_unlock_irqrestore(&id->lock, flags);

		return;
	}

	/* Replace static trace area with dynamic copy. */
	spin_lock_irqsave(&id->lock, flags);
	debug_events_append(copy, id);
	debug_areas_swap(id, copy);
	spin_unlock_irqrestore(&id->lock, flags);

	/* Clear pointers to initdata and discard copy. */
	copy->areas = NULL;
	copy->active_pages = NULL;
	copy->active_entries = NULL;
	debug_info_free(copy);

	mutex_lock(&debug_mutex);
	_debug_register(id);
	mutex_unlock(&debug_mutex);
}

/* Remove debugfs entries and remove from internal list. */
static void _debug_unregister(debug_info_t *id)
{
	int i;

	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
		if (!id->views[i])
			continue;
		debugfs_remove(id->debugfs_entries[i]);
	}
	debugfs_remove(id->debugfs_root_entry);
	if (id == debug_area_first)
		debug_area_first = id->next;
	if (id == debug_area_last)
		debug_area_last = id->prev;
	if (id->prev)
		id->prev->next = id->next;
	if (id->next)
		id->next->prev = id->prev;
}

/**
 * debug_unregister() - give back debug area.
 *
 * @id:		handle for debug log
 *
 * Return:
 *    none
 */
void debug_unregister(debug_info_t *id)
{
	if (!id)
		return;
	mutex_lock(&debug_mutex);
	_debug_unregister(id);
	mutex_unlock(&debug_mutex);

	debug_info_put(id);
}
EXPORT_SYMBOL(debug_unregister);

/*
 * debug_set_size:
 * - set area size (number of pages) and number of areas
 */
static int debug_set_size(debug_info_t *id, int nr_areas, int pages_per_area)
{
	debug_info_t *new_id;
	unsigned long flags;

	if (!id || (nr_areas <= 0) || (pages_per_area < 0))
		return -EINVAL;

	new_id = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size,
				  id->level, ALL_AREAS);
	if (!new_id) {
		pr_info("Allocating memory for %i pages failed\n",
			pages_per_area);
		return -ENOMEM;
	}

	spin_lock_irqsave(&id->lock, flags);
	debug_events_append(new_id, id);
	debug_areas_swap(new_id, id);
	debug_info_free(new_id);
	spin_unlock_irqrestore(&id->lock, flags);
	pr_info("%s: set new size (%i pages)\n", id->name, pages_per_area);

	return 0;
}

/**
 * debug_set_level() - Sets new actual debug level if new_level is valid.
 *
 * @id:		handle for debug log
 * @new_level:	new debug level
 *
 * Return:
 *    none
 */
void debug_set_level(debug_info_t *id, int new_level)
{
	unsigned long flags;

	if (!id)
		return;

	if (new_level == DEBUG_OFF_LEVEL) {
		pr_info("%s: switched off\n", id->name);
	} else if ((new_level > DEBUG_MAX_LEVEL) || (new_level < 0)) {
		pr_info("%s: level %i is out of range (%i - %i)\n",
			id->name, new_level, 0, DEBUG_MAX_LEVEL);
		return;
	}

	spin_lock_irqsave(&id->lock, flags);
	id->level = new_level;
	spin_unlock_irqrestore(&id->lock, flags);
}
EXPORT_SYMBOL(debug_set_level);

/*
 * proceed_active_entry:
 * - set active entry to next in the ring buffer
 */
static inline void proceed_active_entry(debug_info_t *id)
{
	if ((id->active_entries[id->active_area] += id->entry_size)
	    > (PAGE_SIZE - id->entry_size)) {
		id->active_entries[id->active_area] = 0;
		id->active_pages[id->active_area] =
			(id->active_pages[id->active_area] + 1) %
			id->pages_per_area;
	}
}

/*
 * proceed_active_area:
 * - set active area to next in the ring buffer
 */
static inline void proceed_active_area(debug_info_t *id)
{
	id->active_area++;
	id->active_area = id->active_area % id->nr_areas;
}

/*
 * get_active_entry:
 */
static inline debug_entry_t *get_active_entry(debug_info_t *id)
{
	return (debug_entry_t *) (((char *) id->areas[id->active_area]
				   [id->active_pages[id->active_area]]) +
				  id->active_entries[id->active_area]);
}

/* Swap debug areas of a and b. */
static void debug_areas_swap(debug_info_t *a, debug_info_t *b)
{
	swap(a->nr_areas, b->nr_areas);
	swap(a->pages_per_area, b->pages_per_area);
	swap(a->areas, b->areas);
	swap(a->active_area, b->active_area);
	swap(a->active_pages, b->active_pages);
	swap(a->active_entries, b->active_entries);
}

/* Append all debug events in active area from source to destination log. */
static void debug_events_append(debug_info_t *dest, debug_info_t *src)
{
	debug_entry_t *from, *to, *last;

	if (!src->areas || !dest->areas)
		return;

	/* Loop over all entries in src, starting with oldest. */
	from = get_active_entry(src);
	last = from;
	do {
		if (from->clock != 0LL) {
			to = get_active_entry(dest);
			memset(to, 0, dest->entry_size);
			memcpy(to, from, min(src->entry_size,
					     dest->entry_size));
			proceed_active_entry(dest);
		}

		proceed_active_entry(src);
		from = get_active_entry(src);
	} while (from != last);
}

/*
 * debug_finish_entry:
 * - set timestamp, caller address, cpu number etc.
 */

static inline void debug_finish_entry(debug_info_t *id, debug_entry_t *active,
				      int level, int exception)
{
	unsigned long timestamp;
	union tod_clock clk;

	store_tod_clock_ext(&clk);
	timestamp = clk.us;
	timestamp -= TOD_UNIX_EPOCH >> 12;
	active->clock = timestamp;
	active->cpu = smp_processor_id();
	active->caller = __builtin_return_address(0);
	active->exception = exception;
	active->level = level;
	proceed_active_entry(id);
	if (exception)
		proceed_active_area(id);
}

static int debug_stoppable = 1;
static int debug_active = 1;

#define CTL_S390DBF_STOPPABLE 5678
#define CTL_S390DBF_ACTIVE 5679

/*
 * proc handler for the running debug_active sysctl
 * always allow read, allow write only if debug_stoppable is set or
 * if debug_active is already off
 */
static int s390dbf_procactive(struct ctl_table *table, int write,
			      void *buffer, size_t *lenp, loff_t *ppos)
{
	if (!write || debug_stoppable || !debug_active)
		return proc_dointvec(table, write, buffer, lenp, ppos);
	else
		return 0;
}

static struct ctl_table s390dbf_table[] = {
	{
		.procname	= "debug_stoppable",
		.data		= &debug_stoppable,
		.maxlen		= sizeof(int),
		.mode		= S_IRUGO | S_IWUSR,
		.proc_handler	= proc_dointvec,
	},
	{
		.procname	= "debug_active",
		.data		= &debug_active,
		.maxlen		= sizeof(int),
		.mode		= S_IRUGO | S_IWUSR,
		.proc_handler	= s390dbf_procactive,
	},
	{ }
};

static struct ctl_table_header *s390dbf_sysctl_header;

/**
 * debug_stop_all() - stops the debug feature if stopping is allowed.
 *
 * Return:
 * -   none
 *
 * Currently used in case of a kernel oops.
 */
void debug_stop_all(void)
{
	if (debug_stoppable)
		debug_active = 0;
}
EXPORT_SYMBOL(debug_stop_all);

/**
 * debug_set_critical() - event/exception functions try lock instead of spin.
 *
 * Return:
 * -   none
 *
 * Currently used in case of stopping all CPUs but the current one.
 * Once in this state, functions to write a debug entry for an
 * event or exception no longer spin on the debug area lock,
 * but only try to get it and fail if they do not get the lock.
 */
void debug_set_critical(void)
{
	debug_critical = 1;
}

/*
 * debug_event_common:
 * - write debug entry with given size
 */
debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf,
				  int len)
{
	debug_entry_t *active;
	unsigned long flags;

	if (!debug_active || !id->areas)
		return NULL;
	if (debug_critical) {
		if (!spin_trylock_irqsave(&id->lock, flags))
			return NULL;
	} else {
		spin_lock_irqsave(&id->lock, flags);
	}
	do {
		active = get_active_entry(id);
		memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
		if (len < id->buf_size)
			memset((DEBUG_DATA(active)) + len, 0, id->buf_size - len);
		debug_finish_entry(id, active, level, 0);
		len -= id->buf_size;
		buf += id->buf_size;
	} while (len > 0);

	spin_unlock_irqrestore(&id->lock, flags);
	return active;
}
EXPORT_SYMBOL(debug_event_common);

/*
 * debug_exception_common:
 * - write debug entry with given size and switch to next debug area
 */
debug_entry_t *debug_exception_common(debug_info_t *id, int level,
				      const void *buf, int len)
{
	debug_entry_t *active;
	unsigned long flags;

	if (!debug_active || !id->areas)
		return NULL;
	if (debug_critical) {
		if (!spin_trylock_irqsave(&id->lock, flags))
			return NULL;
	} else {
		spin_lock_irqsave(&id->lock, flags);
	}
	do {
		active = get_active_entry(id);
		memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
		if (len < id->buf_size)
			memset((DEBUG_DATA(active)) + len, 0, id->buf_size - len);
		debug_finish_entry(id, active, level, len <= id->buf_size);
		len -= id->buf_size;
		buf += id->buf_size;
	} while (len > 0);

	spin_unlock_irqrestore(&id->lock, flags);
	return active;
}
EXPORT_SYMBOL(debug_exception_common);

/*
 * counts arguments in format string for sprintf view
 */
static inline int debug_count_numargs(char *string)
{
	int numargs = 0;

	while (*string) {
		if (*string++ == '%')
			numargs++;
	}
	return numargs;
}

/*
 * debug_sprintf_event:
 */
debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
{
	debug_sprintf_entry_t *curr_event;
	debug_entry_t *active;
	unsigned long flags;
	int numargs, idx;
	va_list ap;

	if (!debug_active || !id->areas)
		return NULL;
	numargs = debug_count_numargs(string);

	if (debug_critical) {
		if (!spin_trylock_irqsave(&id->lock, flags))
			return NULL;
	} else {
		spin_lock_irqsave(&id->lock, flags);
	}
	active = get_active_entry(id);
	curr_event = (debug_sprintf_entry_t *) DEBUG_DATA(active);
	va_start(ap, string);
	curr_event->string = string;
	for (idx = 0; idx < min(numargs, (int)(id->buf_size / sizeof(long)) - 1); idx++)
		curr_event->args[idx] = va_arg(ap, long);
	va_end(ap);
	debug_finish_entry(id, active, level, 0);
	spin_unlock_irqrestore(&id->lock, flags);

	return active;
}
EXPORT_SYMBOL(__debug_sprintf_event);

/*
 * debug_sprintf_exception:
 */
debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
{
	debug_sprintf_entry_t *curr_event;
	debug_entry_t *active;
	unsigned long flags;
	int numargs, idx;
	va_list ap;

	if (!debug_active || !id->areas)
		return NULL;

	numargs = debug_count_numargs(string);

	if (debug_critical) {
		if (!spin_trylock_irqsave(&id->lock, flags))
			return NULL;
	} else {
		spin_lock_irqsave(&id->lock, flags);
	}
	active = get_active_entry(id);
	curr_event = (debug_sprintf_entry_t *)DEBUG_DATA(active);
	va_start(ap, string);
	curr_event->string = string;
	for (idx = 0; idx < min(numargs, (int)(id->buf_size / sizeof(long)) - 1); idx++)
		curr_event->args[idx] = va_arg(ap, long);
	va_end(ap);
	debug_finish_entry(id, active, level, 1);
	spin_unlock_irqrestore(&id->lock, flags);

	return active;
}
EXPORT_SYMBOL(__debug_sprintf_exception);

/**
 * debug_register_view() - registers new debug view and creates debugfs
 *			   dir entry
 *
 * @id:		handle for debug log
 * @view:	pointer to debug view struct
 *
 * Return:
 * -   0  : ok
 * -   < 0: Error
 */
int debug_register_view(debug_info_t *id, struct debug_view *view)
{
	unsigned long flags;
	struct dentry *pde;
	umode_t mode;
	int rc = 0;
	int i;

	if (!id)
		goto out;
	mode = (id->mode | S_IFREG) & ~S_IXUGO;
	if (!(view->prolog_proc || view->format_proc || view->header_proc))
		mode &= ~(S_IRUSR | S_IRGRP | S_IROTH);
	if (!view->input_proc)
		mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
	pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry,
				  id, &debug_file_ops);
	spin_lock_irqsave(&id->lock, flags);
	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
		if (!id->views[i])
			break;
	}
	if (i == DEBUG_MAX_VIEWS) {
		rc = -1;
	} else {
		id->views[i] = view;
		id->debugfs_entries[i] = pde;
	}
	spin_unlock_irqrestore(&id->lock, flags);
	if (rc) {
		pr_err("Registering view %s/%s would exceed the maximum "
		       "number of views %i\n", id->name, view->name, i);
		debugfs_remove(pde);
	}
out:
	return rc;
}
EXPORT_SYMBOL(debug_register_view);

/**
 * debug_unregister_view() - unregisters debug view and removes debugfs
 *			     dir entry
 *
 * @id:		handle for debug log
 * @view:	pointer to debug view struct
 *
 * Return:
 * -   0  : ok
 * -   < 0: Error
 */
int debug_unregister_view(debug_info_t *id, struct debug_view *view)
{
	struct dentry *dentry = NULL;
	unsigned long flags;
	int i, rc = 0;

	if (!id)
		goto out;
	spin_lock_irqsave(&id->lock, flags);
	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
		if (id->views[i] == view)
			break;
	}
	if (i == DEBUG_MAX_VIEWS) {
		rc = -1;
	} else {
		dentry = id->debugfs_entries[i];
		id->views[i] = NULL;
		id->debugfs_entries[i] = NULL;
	}
	spin_unlock_irqrestore(&id->lock, flags);
	debugfs_remove(dentry);
out:
	return rc;
}
EXPORT_SYMBOL(debug_unregister_view);

static inline char *debug_get_user_string(const char __user *user_buf,
					  size_t user_len)
{
	char *buffer;

	buffer = kmalloc(user_len + 1, GFP_KERNEL);
	if (!buffer)
		return ERR_PTR(-ENOMEM);
	if (copy_from_user(buffer, user_buf, user_len) != 0) {
		kfree(buffer);
		return ERR_PTR(-EFAULT);
	}
	/* got the string, now strip linefeed. */
	if (buffer[user_len - 1] == '\n')
		buffer[user_len - 1] = 0;
	else
		buffer[user_len] = 0;
	return buffer;
}

static inline int debug_get_uint(char *buf)
{
	int rc;

	buf = skip_spaces(buf);
	rc = simple_strtoul(buf, &buf, 10);
	if (*buf)
		rc = -EINVAL;
	return rc;
}

/*
 * functions for debug-views
 ***********************************
*/

/*
 * prints out actual debug level
 */

static int debug_prolog_pages_fn(debug_info_t *id, struct debug_view *view,
				 char *out_buf)
{
	return sprintf(out_buf, "%i\n", id->pages_per_area);
}

/*
 * reads new size (number of pages per debug area)
 */

static int debug_input_pages_fn(debug_info_t *id, struct debug_view *view,
				struct file *file, const char __user *user_buf,
				size_t user_len, loff_t *offset)
{
	int rc, new_pages;
	char *str;

	if (user_len > 0x10000)
		user_len = 0x10000;
	if (*offset != 0) {
		rc = -EPIPE;
		goto out;
	}
	str = debug_get_user_string(user_buf, user_len);
	if (IS_ERR(str)) {
		rc = PTR_ERR(str);
		goto out;
	}
	new_pages = debug_get_uint(str);
	if (new_pages < 0) {
		rc = -EINVAL;
		goto free_str;
	}
	rc = debug_set_size(id, id->nr_areas, new_pages);
	if (rc != 0) {
		rc = -EINVAL;
		goto free_str;
	}
	rc = user_len;
free_str:
	kfree(str);
out:
	*offset += user_len;
	return rc;		/* number of input characters */
}

/*
 * prints out actual debug level
 */
static int debug_prolog_level_fn(debug_info_t *id, struct debug_view *view,
				 char *out_buf)
{
	int rc = 0;

	if (id->level == DEBUG_OFF_LEVEL)
		rc = sprintf(out_buf, "-\n");
	else
		rc = sprintf(out_buf, "%i\n", id->level);
	return rc;
}

/*
 * reads new debug level
 */
static int debug_input_level_fn(debug_info_t *id, struct debug_view *view,
				struct file *file, const char __user *user_buf,
				size_t user_len, loff_t *offset)
{
	int rc, new_level;
	char *str;

	if (user_len > 0x10000)
		user_len = 0x10000;
	if (*offset != 0) {
		rc = -EPIPE;
		goto out;
	}
	str = debug_get_user_string(user_buf, user_len);
	if (IS_ERR(str)) {
		rc = PTR_ERR(str);
		goto out;
	}
	if (str[0] == '-') {
		debug_set_level(id, DEBUG_OFF_LEVEL);
		rc = user_len;
		goto free_str;
	} else {
		new_level = debug_get_uint(str);
	}
	if (new_level < 0) {
		pr_warn("%s is not a valid level for a debug feature\n", str);
		rc = -EINVAL;
	} else {
		debug_set_level(id, new_level);
		rc = user_len;
	}
free_str:
	kfree(str);
out:
	*offset += user_len;
	return rc;		/* number of input characters */
}

/*
 * flushes debug areas
 */
static void debug_flush(debug_info_t *id, int area)
{
	unsigned long flags;
	int i, j;

	if (!id || !id->areas)
		return;
	spin_lock_irqsave(&id->lock, flags);
	if (area == DEBUG_FLUSH_ALL) {
		id->active_area = 0;
		memset(id->active_entries, 0, id->nr_areas * sizeof(int));
		for (i = 0; i < id->nr_areas; i++) {
			id->active_pages[i] = 0;
			for (j = 0; j < id->pages_per_area; j++)
				memset(id->areas[i][j], 0, PAGE_SIZE);
		}
	} else if (area >= 0 && area < id->nr_areas) {
		id->active_entries[area] = 0;
		id->active_pages[area] = 0;
		for (i = 0; i < id->pages_per_area; i++)
			memset(id->areas[area][i], 0, PAGE_SIZE);
	}
	spin_unlock_irqrestore(&id->lock, flags);
}

/*
 * view function: flushes debug areas
 */
static int debug_input_flush_fn(debug_info_t *id, struct debug_view *view,
				struct file *file, const char __user *user_buf,
				size_t user_len, loff_t *offset)
{
	char input_buf[1];
	int rc = user_len;

	if (user_len > 0x10000)
		user_len = 0x10000;
	if (*offset != 0) {
		rc = -EPIPE;
		goto out;
	}
	if (copy_from_user(input_buf, user_buf, 1)) {
		rc = -EFAULT;
		goto out;
	}
	if (input_buf[0] == '-') {
		debug_flush(id, DEBUG_FLUSH_ALL);
		goto out;
	}
	if (isdigit(input_buf[0])) {
		int area = ((int) input_buf[0] - (int) '0');

		debug_flush(id, area);
		goto out;
	}

	pr_info("Flushing debug data failed because %c is not a valid "
		 "area\n", input_buf[0]);

out:
	*offset += user_len;
	return rc;		/* number of input characters */
}

/*
 * prints debug data in hex/ascii format
 */
static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view,
				     char *out_buf, const char *in_buf)
{
	int i, rc = 0;

	for (i = 0; i < id->buf_size; i++)
		rc += sprintf(out_buf + rc, "%02x ", ((unsigned char *) in_buf)[i]);
	rc += sprintf(out_buf + rc, "| ");
	for (i = 0; i < id->buf_size; i++) {
		unsigned char c = in_buf[i];

		if (isascii(c) && isprint(c))
			rc += sprintf(out_buf + rc, "%c", c);
		else
			rc += sprintf(out_buf + rc, ".");
	}
	rc += sprintf(out_buf + rc, "\n");
	return rc;
}

/*
 * prints header for debug entry
 */
int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view,
			 int area, debug_entry_t *entry, char *out_buf)
{
	unsigned long sec, usec;
	unsigned long caller;
	unsigned int level;
	char *except_str;
	int rc = 0;

	level = entry->level;
	sec = entry->clock;
	usec = do_div(sec, USEC_PER_SEC);

	if (entry->exception)
		except_str = "*";
	else
		except_str = "-";
	caller = (unsigned long) entry->caller;
	rc += sprintf(out_buf, "%02i %011ld:%06lu %1u %1s %04u %px  ",
		      area, sec, usec, level, except_str,
		      entry->cpu, (void *)caller);
	return rc;
}
EXPORT_SYMBOL(debug_dflt_header_fn);

/*
 * prints debug data sprintf-formated:
 * debug_sprinf_event/exception calls must be used together with this view
 */

#define DEBUG_SPRINTF_MAX_ARGS 10

static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view,
				   char *out_buf, const char *inbuf)
{
	debug_sprintf_entry_t *curr_event = (debug_sprintf_entry_t *)inbuf;
	int num_longs, num_used_args = 0, i, rc = 0;
	int index[DEBUG_SPRINTF_MAX_ARGS];

	/* count of longs fit into one entry */
	num_longs = id->buf_size / sizeof(long);

	if (num_longs < 1)
		goto out; /* bufsize of entry too small */
	if (num_longs == 1) {
		/* no args, we use only the string */
		strcpy(out_buf, curr_event->string);
		rc = strlen(curr_event->string);
		goto out;
	}

	/* number of arguments used for sprintf (without the format string) */
	num_used_args = min(DEBUG_SPRINTF_MAX_ARGS, (num_longs - 1));

	memset(index, 0, DEBUG_SPRINTF_MAX_ARGS * sizeof(int));

	for (i = 0; i < num_used_args; i++)
		index[i] = i;

	rc = sprintf(out_buf, curr_event->string, curr_event->args[index[0]],
		     curr_event->args[index[1]], curr_event->args[index[2]],
		     curr_event->args[index[3]], curr_event->args[index[4]],
		     curr_event->args[index[5]], curr_event->args[index[6]],
		     curr_event->args[index[7]], curr_event->args[index[8]],
		     curr_event->args[index[9]]);
out:
	return rc;
}

/*
 * debug_init:
 * - is called exactly once to initialize the debug feature
 */
static int __init debug_init(void)
{
	s390dbf_sysctl_header = register_sysctl("s390dbf", s390dbf_table);
	mutex_lock(&debug_mutex);
	debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT, NULL);
	initialized = 1;
	mutex_unlock(&debug_mutex);
	return 0;
}
postcore_initcall(debug_init);
