brintos

brintos / linux-shallow public Read only

0
0
Text · 3.7 KiB · a2e771e Raw
172 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *   CIO inject interface4 *5 *    Copyright IBM Corp. 20216 *    Author(s): Vineeth Vijayan <vneethv@linux.ibm.com>7 */8 9#define KMSG_COMPONENT "cio"10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt11 12#include <linux/slab.h>13#include <linux/spinlock.h>14#include <linux/mm.h>15#include <linux/debugfs.h>16#include <asm/chpid.h>17 18#include "cio_inject.h"19#include "cio_debug.h"20 21static DEFINE_SPINLOCK(crw_inject_lock);22DEFINE_STATIC_KEY_FALSE(cio_inject_enabled);23static struct crw *crw_inject_data;24 25/**26 * crw_inject : Initiate the artificial CRW inject27 * @crw: The data which needs to be injected as new CRW.28 *29 * The CRW handler is called, which will use the provided artificial30 * data instead of the CRW from the underlying hardware.31 *32 * Return: 0 on success33 */34static int crw_inject(struct crw *crw)35{36	int rc = 0;37	struct crw *copy;38	unsigned long flags;39 40	copy = kmemdup(crw, sizeof(*crw), GFP_KERNEL);41	if (!copy)42		return -ENOMEM;43 44	spin_lock_irqsave(&crw_inject_lock, flags);45	if (crw_inject_data) {46		kfree(copy);47		rc = -EBUSY;48	} else {49		crw_inject_data = copy;50	}51	spin_unlock_irqrestore(&crw_inject_lock, flags);52 53	if (!rc)54		crw_handle_channel_report();55 56	return rc;57}58 59/**60 * stcrw_get_injected: Copy the artificial CRW data to CRW struct.61 * @crw: The target CRW pointer.62 *63 * Retrieve an injected CRW data. Return 0 on success, 1 if no64 * injected-CRW is available. The function reproduces the return65 * code of the actual STCRW function.66 */67int stcrw_get_injected(struct crw *crw)68{69	int rc = 1;70	unsigned long flags;71 72	spin_lock_irqsave(&crw_inject_lock, flags);73	if (crw_inject_data) {74		memcpy(crw, crw_inject_data, sizeof(*crw));75		kfree(crw_inject_data);76		crw_inject_data = NULL;77		rc = 0;78	}79	spin_unlock_irqrestore(&crw_inject_lock, flags);80 81	return rc;82}83 84/* The debugfs write handler for crw_inject nodes operation */85static ssize_t crw_inject_write(struct file *file, const char __user *buf,86				size_t lbuf, loff_t *ppos)87{88	u32 slct, oflw, chn, rsc, anc, erc, rsid;89	struct crw crw;90	char *buffer;91	int rc;92 93	if (!static_branch_likely(&cio_inject_enabled)) {94		pr_warn("CIO inject is not enabled - ignoring CRW inject\n");95		return -EINVAL;96	}97 98	buffer = memdup_user_nul(buf, lbuf);99	if (IS_ERR(buffer))100		return -ENOMEM;101 102	rc = sscanf(buffer, "%x %x %x %x %x %x %x", &slct, &oflw, &chn, &rsc, &anc,103		    &erc, &rsid);104 105	kvfree(buffer);106	if (rc != 7) {107		pr_warn("crw_inject: Invalid format (need <solicited> <overflow> <chaining> <rsc> <ancillary> <erc> <rsid>)\n");108		return -EINVAL;109	}110 111	memset(&crw, 0, sizeof(crw));112	crw.slct = slct;113	crw.oflw = oflw;114	crw.chn = chn;115	crw.rsc = rsc;116	crw.anc = anc;117	crw.erc = erc;118	crw.rsid = rsid;119 120	rc = crw_inject(&crw);121	if (rc)122		return rc;123 124	return lbuf;125}126 127/* Debugfs write handler for inject_enable node*/128static ssize_t enable_inject_write(struct file *file, const char __user *buf,129				   size_t lbuf, loff_t *ppos)130{131	unsigned long en = 0;132	int rc;133 134	rc = kstrtoul_from_user(buf, lbuf, 10, &en);135	if (rc)136		return rc;137 138	switch (en) {139	case 0:140		static_branch_disable(&cio_inject_enabled);141		break;142	case 1:143		static_branch_enable(&cio_inject_enabled);144		break;145	}146 147	return lbuf;148}149 150static const struct file_operations crw_fops = {151	.owner = THIS_MODULE,152	.write = crw_inject_write,153};154 155static const struct file_operations cio_en_fops = {156	.owner = THIS_MODULE,157	.write = enable_inject_write,158};159 160static int __init cio_inject_init(void)161{162	/* enable_inject node enables the static branching */163	debugfs_create_file("enable_inject", 0200, cio_debugfs_dir,164			    NULL, &cio_en_fops);165 166	debugfs_create_file("crw_inject", 0200, cio_debugfs_dir,167			    NULL, &crw_fops);168	return 0;169}170 171device_initcall(cio_inject_init);172