0001
0002
0003
0004
0005
0006
0007
0008
0009 #define KMSG_COMPONENT "cio"
0010 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0011
0012 #include <linux/slab.h>
0013 #include <linux/spinlock.h>
0014 #include <linux/mm.h>
0015 #include <linux/debugfs.h>
0016 #include <asm/chpid.h>
0017
0018 #include "cio_inject.h"
0019 #include "cio_debug.h"
0020
0021 static DEFINE_SPINLOCK(crw_inject_lock);
0022 DEFINE_STATIC_KEY_FALSE(cio_inject_enabled);
0023 static struct crw *crw_inject_data;
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 static int crw_inject(struct crw *crw)
0035 {
0036 int rc = 0;
0037 struct crw *copy;
0038 unsigned long flags;
0039
0040 copy = kmemdup(crw, sizeof(*crw), GFP_KERNEL);
0041 if (!copy)
0042 return -ENOMEM;
0043
0044 spin_lock_irqsave(&crw_inject_lock, flags);
0045 if (crw_inject_data) {
0046 kfree(copy);
0047 rc = -EBUSY;
0048 } else {
0049 crw_inject_data = copy;
0050 }
0051 spin_unlock_irqrestore(&crw_inject_lock, flags);
0052
0053 if (!rc)
0054 crw_handle_channel_report();
0055
0056 return rc;
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 int stcrw_get_injected(struct crw *crw)
0068 {
0069 int rc = 1;
0070 unsigned long flags;
0071
0072 spin_lock_irqsave(&crw_inject_lock, flags);
0073 if (crw_inject_data) {
0074 memcpy(crw, crw_inject_data, sizeof(*crw));
0075 kfree(crw_inject_data);
0076 crw_inject_data = NULL;
0077 rc = 0;
0078 }
0079 spin_unlock_irqrestore(&crw_inject_lock, flags);
0080
0081 return rc;
0082 }
0083
0084
0085 static ssize_t crw_inject_write(struct file *file, const char __user *buf,
0086 size_t lbuf, loff_t *ppos)
0087 {
0088 u32 slct, oflw, chn, rsc, anc, erc, rsid;
0089 struct crw crw;
0090 char *buffer;
0091 int rc;
0092
0093 if (!static_branch_likely(&cio_inject_enabled)) {
0094 pr_warn("CIO inject is not enabled - ignoring CRW inject\n");
0095 return -EINVAL;
0096 }
0097
0098 buffer = vmemdup_user(buf, lbuf);
0099 if (IS_ERR(buffer))
0100 return -ENOMEM;
0101
0102 rc = sscanf(buffer, "%x %x %x %x %x %x %x", &slct, &oflw, &chn, &rsc, &anc,
0103 &erc, &rsid);
0104
0105 kvfree(buffer);
0106 if (rc != 7) {
0107 pr_warn("crw_inject: Invalid format (need <solicited> <overflow> <chaining> <rsc> <ancillary> <erc> <rsid>)\n");
0108 return -EINVAL;
0109 }
0110
0111 memset(&crw, 0, sizeof(crw));
0112 crw.slct = slct;
0113 crw.oflw = oflw;
0114 crw.chn = chn;
0115 crw.rsc = rsc;
0116 crw.anc = anc;
0117 crw.erc = erc;
0118 crw.rsid = rsid;
0119
0120 rc = crw_inject(&crw);
0121 if (rc)
0122 return rc;
0123
0124 return lbuf;
0125 }
0126
0127
0128 static ssize_t enable_inject_write(struct file *file, const char __user *buf,
0129 size_t lbuf, loff_t *ppos)
0130 {
0131 unsigned long en = 0;
0132 int rc;
0133
0134 rc = kstrtoul_from_user(buf, lbuf, 10, &en);
0135 if (rc)
0136 return rc;
0137
0138 switch (en) {
0139 case 0:
0140 static_branch_disable(&cio_inject_enabled);
0141 break;
0142 case 1:
0143 static_branch_enable(&cio_inject_enabled);
0144 break;
0145 }
0146
0147 return lbuf;
0148 }
0149
0150 static const struct file_operations crw_fops = {
0151 .owner = THIS_MODULE,
0152 .write = crw_inject_write,
0153 };
0154
0155 static const struct file_operations cio_en_fops = {
0156 .owner = THIS_MODULE,
0157 .write = enable_inject_write,
0158 };
0159
0160 static int __init cio_inject_init(void)
0161 {
0162
0163 debugfs_create_file("enable_inject", 0200, cio_debugfs_dir,
0164 NULL, &cio_en_fops);
0165
0166 debugfs_create_file("crw_inject", 0200, cio_debugfs_dir,
0167 NULL, &crw_fops);
0168 return 0;
0169 }
0170
0171 device_initcall(cio_inject_init);