0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define KMSG_COMPONENT "monreader"
0011 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0012
0013 #include <linux/module.h>
0014 #include <linux/moduleparam.h>
0015 #include <linux/init.h>
0016 #include <linux/errno.h>
0017 #include <linux/types.h>
0018 #include <linux/kernel.h>
0019 #include <linux/miscdevice.h>
0020 #include <linux/ctype.h>
0021 #include <linux/spinlock.h>
0022 #include <linux/interrupt.h>
0023 #include <linux/poll.h>
0024 #include <linux/slab.h>
0025 #include <net/iucv/iucv.h>
0026 #include <linux/uaccess.h>
0027 #include <asm/ebcdic.h>
0028 #include <asm/extmem.h>
0029
0030
0031 #define MON_COLLECT_SAMPLE 0x80
0032 #define MON_COLLECT_EVENT 0x40
0033 #define MON_SERVICE "*MONITOR"
0034 #define MON_IN_USE 0x01
0035 #define MON_MSGLIM 255
0036
0037 static char mon_dcss_name[9] = "MONDCSS\0";
0038
0039 struct mon_msg {
0040 u32 pos;
0041 u32 mca_offset;
0042 struct iucv_message msg;
0043 char msglim_reached;
0044 char replied_msglim;
0045 };
0046
0047 struct mon_private {
0048 struct iucv_path *path;
0049 struct mon_msg *msg_array[MON_MSGLIM];
0050 unsigned int write_index;
0051 unsigned int read_index;
0052 atomic_t msglim_count;
0053 atomic_t read_ready;
0054 atomic_t iucv_connected;
0055 atomic_t iucv_severed;
0056 };
0057
0058 static unsigned long mon_in_use = 0;
0059
0060 static unsigned long mon_dcss_start;
0061 static unsigned long mon_dcss_end;
0062
0063 static DECLARE_WAIT_QUEUE_HEAD(mon_read_wait_queue);
0064 static DECLARE_WAIT_QUEUE_HEAD(mon_conn_wait_queue);
0065
0066 static u8 user_data_connect[16] = {
0067
0068 0x01,
0069
0070 MON_COLLECT_SAMPLE | MON_COLLECT_EVENT,
0071
0072 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0073 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0074 };
0075
0076 static u8 user_data_sever[16] = {
0077 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0078 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0079 };
0080
0081
0082
0083
0084
0085
0086
0087
0088 static void dcss_mkname(char *ascii_name, char *ebcdic_name)
0089 {
0090 int i;
0091
0092 for (i = 0; i < 8; i++) {
0093 if (ascii_name[i] == '\0')
0094 break;
0095 ebcdic_name[i] = toupper(ascii_name[i]);
0096 }
0097 for (; i < 8; i++)
0098 ebcdic_name[i] = ' ';
0099 ASCEBC(ebcdic_name, 8);
0100 }
0101
0102 static inline unsigned long mon_mca_start(struct mon_msg *monmsg)
0103 {
0104 return *(u32 *) &monmsg->msg.rmmsg;
0105 }
0106
0107 static inline unsigned long mon_mca_end(struct mon_msg *monmsg)
0108 {
0109 return *(u32 *) &monmsg->msg.rmmsg[4];
0110 }
0111
0112 static inline u8 mon_mca_type(struct mon_msg *monmsg, u8 index)
0113 {
0114 return *((u8 *) mon_mca_start(monmsg) + monmsg->mca_offset + index);
0115 }
0116
0117 static inline u32 mon_mca_size(struct mon_msg *monmsg)
0118 {
0119 return mon_mca_end(monmsg) - mon_mca_start(monmsg) + 1;
0120 }
0121
0122 static inline u32 mon_rec_start(struct mon_msg *monmsg)
0123 {
0124 return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 4));
0125 }
0126
0127 static inline u32 mon_rec_end(struct mon_msg *monmsg)
0128 {
0129 return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 8));
0130 }
0131
0132 static int mon_check_mca(struct mon_msg *monmsg)
0133 {
0134 if ((mon_rec_end(monmsg) <= mon_rec_start(monmsg)) ||
0135 (mon_rec_start(monmsg) < mon_dcss_start) ||
0136 (mon_rec_end(monmsg) > mon_dcss_end) ||
0137 (mon_mca_type(monmsg, 0) == 0) ||
0138 (mon_mca_size(monmsg) % 12 != 0) ||
0139 (mon_mca_end(monmsg) <= mon_mca_start(monmsg)) ||
0140 (mon_mca_end(monmsg) > mon_dcss_end) ||
0141 (mon_mca_start(monmsg) < mon_dcss_start) ||
0142 ((mon_mca_type(monmsg, 1) == 0) && (mon_mca_type(monmsg, 2) == 0)))
0143 return -EINVAL;
0144 return 0;
0145 }
0146
0147 static int mon_send_reply(struct mon_msg *monmsg,
0148 struct mon_private *monpriv)
0149 {
0150 int rc;
0151
0152 rc = iucv_message_reply(monpriv->path, &monmsg->msg,
0153 IUCV_IPRMDATA, NULL, 0);
0154 atomic_dec(&monpriv->msglim_count);
0155 if (likely(!monmsg->msglim_reached)) {
0156 monmsg->pos = 0;
0157 monmsg->mca_offset = 0;
0158 monpriv->read_index = (monpriv->read_index + 1) %
0159 MON_MSGLIM;
0160 atomic_dec(&monpriv->read_ready);
0161 } else
0162 monmsg->replied_msglim = 1;
0163 if (rc) {
0164 pr_err("Reading monitor data failed with rc=%i\n", rc);
0165 return -EIO;
0166 }
0167 return 0;
0168 }
0169
0170 static void mon_free_mem(struct mon_private *monpriv)
0171 {
0172 int i;
0173
0174 for (i = 0; i < MON_MSGLIM; i++)
0175 kfree(monpriv->msg_array[i]);
0176 kfree(monpriv);
0177 }
0178
0179 static struct mon_private *mon_alloc_mem(void)
0180 {
0181 int i;
0182 struct mon_private *monpriv;
0183
0184 monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
0185 if (!monpriv)
0186 return NULL;
0187 for (i = 0; i < MON_MSGLIM; i++) {
0188 monpriv->msg_array[i] = kzalloc(sizeof(struct mon_msg),
0189 GFP_KERNEL);
0190 if (!monpriv->msg_array[i]) {
0191 mon_free_mem(monpriv);
0192 return NULL;
0193 }
0194 }
0195 return monpriv;
0196 }
0197
0198 static inline void mon_next_mca(struct mon_msg *monmsg)
0199 {
0200 if (likely((mon_mca_size(monmsg) - monmsg->mca_offset) == 12))
0201 return;
0202 monmsg->mca_offset += 12;
0203 monmsg->pos = 0;
0204 }
0205
0206 static struct mon_msg *mon_next_message(struct mon_private *monpriv)
0207 {
0208 struct mon_msg *monmsg;
0209
0210 if (!atomic_read(&monpriv->read_ready))
0211 return NULL;
0212 monmsg = monpriv->msg_array[monpriv->read_index];
0213 if (unlikely(monmsg->replied_msglim)) {
0214 monmsg->replied_msglim = 0;
0215 monmsg->msglim_reached = 0;
0216 monmsg->pos = 0;
0217 monmsg->mca_offset = 0;
0218 monpriv->read_index = (monpriv->read_index + 1) %
0219 MON_MSGLIM;
0220 atomic_dec(&monpriv->read_ready);
0221 return ERR_PTR(-EOVERFLOW);
0222 }
0223 return monmsg;
0224 }
0225
0226
0227
0228
0229
0230 static void mon_iucv_path_complete(struct iucv_path *path, u8 *ipuser)
0231 {
0232 struct mon_private *monpriv = path->private;
0233
0234 atomic_set(&monpriv->iucv_connected, 1);
0235 wake_up(&mon_conn_wait_queue);
0236 }
0237
0238 static void mon_iucv_path_severed(struct iucv_path *path, u8 *ipuser)
0239 {
0240 struct mon_private *monpriv = path->private;
0241
0242 pr_err("z/VM *MONITOR system service disconnected with rc=%i\n",
0243 ipuser[0]);
0244 iucv_path_sever(path, NULL);
0245 atomic_set(&monpriv->iucv_severed, 1);
0246 wake_up(&mon_conn_wait_queue);
0247 wake_up_interruptible(&mon_read_wait_queue);
0248 }
0249
0250 static void mon_iucv_message_pending(struct iucv_path *path,
0251 struct iucv_message *msg)
0252 {
0253 struct mon_private *monpriv = path->private;
0254
0255 memcpy(&monpriv->msg_array[monpriv->write_index]->msg,
0256 msg, sizeof(*msg));
0257 if (atomic_inc_return(&monpriv->msglim_count) == MON_MSGLIM) {
0258 pr_warn("The read queue for monitor data is full\n");
0259 monpriv->msg_array[monpriv->write_index]->msglim_reached = 1;
0260 }
0261 monpriv->write_index = (monpriv->write_index + 1) % MON_MSGLIM;
0262 atomic_inc(&monpriv->read_ready);
0263 wake_up_interruptible(&mon_read_wait_queue);
0264 }
0265
0266 static struct iucv_handler monreader_iucv_handler = {
0267 .path_complete = mon_iucv_path_complete,
0268 .path_severed = mon_iucv_path_severed,
0269 .message_pending = mon_iucv_message_pending,
0270 };
0271
0272
0273
0274
0275 static int mon_open(struct inode *inode, struct file *filp)
0276 {
0277 struct mon_private *monpriv;
0278 int rc;
0279
0280
0281
0282
0283 rc = -EBUSY;
0284 if (test_and_set_bit(MON_IN_USE, &mon_in_use))
0285 goto out;
0286
0287 rc = -ENOMEM;
0288 monpriv = mon_alloc_mem();
0289 if (!monpriv)
0290 goto out_use;
0291
0292
0293
0294
0295 monpriv->path = iucv_path_alloc(MON_MSGLIM, IUCV_IPRMDATA, GFP_KERNEL);
0296 if (!monpriv->path)
0297 goto out_priv;
0298 rc = iucv_path_connect(monpriv->path, &monreader_iucv_handler,
0299 MON_SERVICE, NULL, user_data_connect, monpriv);
0300 if (rc) {
0301 pr_err("Connecting to the z/VM *MONITOR system service "
0302 "failed with rc=%i\n", rc);
0303 rc = -EIO;
0304 goto out_path;
0305 }
0306
0307
0308
0309 wait_event(mon_conn_wait_queue,
0310 atomic_read(&monpriv->iucv_connected) ||
0311 atomic_read(&monpriv->iucv_severed));
0312 if (atomic_read(&monpriv->iucv_severed)) {
0313 atomic_set(&monpriv->iucv_severed, 0);
0314 atomic_set(&monpriv->iucv_connected, 0);
0315 rc = -EIO;
0316 goto out_path;
0317 }
0318 filp->private_data = monpriv;
0319 return nonseekable_open(inode, filp);
0320
0321 out_path:
0322 iucv_path_free(monpriv->path);
0323 out_priv:
0324 mon_free_mem(monpriv);
0325 out_use:
0326 clear_bit(MON_IN_USE, &mon_in_use);
0327 out:
0328 return rc;
0329 }
0330
0331 static int mon_close(struct inode *inode, struct file *filp)
0332 {
0333 int rc, i;
0334 struct mon_private *monpriv = filp->private_data;
0335
0336
0337
0338
0339 if (monpriv->path) {
0340 rc = iucv_path_sever(monpriv->path, user_data_sever);
0341 if (rc)
0342 pr_warn("Disconnecting the z/VM *MONITOR system service failed with rc=%i\n",
0343 rc);
0344 iucv_path_free(monpriv->path);
0345 }
0346
0347 atomic_set(&monpriv->iucv_severed, 0);
0348 atomic_set(&monpriv->iucv_connected, 0);
0349 atomic_set(&monpriv->read_ready, 0);
0350 atomic_set(&monpriv->msglim_count, 0);
0351 monpriv->write_index = 0;
0352 monpriv->read_index = 0;
0353
0354 for (i = 0; i < MON_MSGLIM; i++)
0355 kfree(monpriv->msg_array[i]);
0356 kfree(monpriv);
0357 clear_bit(MON_IN_USE, &mon_in_use);
0358 return 0;
0359 }
0360
0361 static ssize_t mon_read(struct file *filp, char __user *data,
0362 size_t count, loff_t *ppos)
0363 {
0364 struct mon_private *monpriv = filp->private_data;
0365 struct mon_msg *monmsg;
0366 int ret;
0367 u32 mce_start;
0368
0369 monmsg = mon_next_message(monpriv);
0370 if (IS_ERR(monmsg))
0371 return PTR_ERR(monmsg);
0372
0373 if (!monmsg) {
0374 if (filp->f_flags & O_NONBLOCK)
0375 return -EAGAIN;
0376 ret = wait_event_interruptible(mon_read_wait_queue,
0377 atomic_read(&monpriv->read_ready) ||
0378 atomic_read(&monpriv->iucv_severed));
0379 if (ret)
0380 return ret;
0381 if (unlikely(atomic_read(&monpriv->iucv_severed)))
0382 return -EIO;
0383 monmsg = monpriv->msg_array[monpriv->read_index];
0384 }
0385
0386 if (!monmsg->pos)
0387 monmsg->pos = mon_mca_start(monmsg) + monmsg->mca_offset;
0388 if (mon_check_mca(monmsg))
0389 goto reply;
0390
0391
0392 mce_start = mon_mca_start(monmsg) + monmsg->mca_offset;
0393 if ((monmsg->pos >= mce_start) && (monmsg->pos < mce_start + 12)) {
0394 count = min(count, (size_t) mce_start + 12 - monmsg->pos);
0395 ret = copy_to_user(data, (void *) (unsigned long) monmsg->pos,
0396 count);
0397 if (ret)
0398 return -EFAULT;
0399 monmsg->pos += count;
0400 if (monmsg->pos == mce_start + 12)
0401 monmsg->pos = mon_rec_start(monmsg);
0402 goto out_copy;
0403 }
0404
0405
0406 if (monmsg->pos <= mon_rec_end(monmsg)) {
0407 count = min(count, (size_t) mon_rec_end(monmsg) - monmsg->pos
0408 + 1);
0409 ret = copy_to_user(data, (void *) (unsigned long) monmsg->pos,
0410 count);
0411 if (ret)
0412 return -EFAULT;
0413 monmsg->pos += count;
0414 if (monmsg->pos > mon_rec_end(monmsg))
0415 mon_next_mca(monmsg);
0416 goto out_copy;
0417 }
0418 reply:
0419 ret = mon_send_reply(monmsg, monpriv);
0420 return ret;
0421
0422 out_copy:
0423 *ppos += count;
0424 return count;
0425 }
0426
0427 static __poll_t mon_poll(struct file *filp, struct poll_table_struct *p)
0428 {
0429 struct mon_private *monpriv = filp->private_data;
0430
0431 poll_wait(filp, &mon_read_wait_queue, p);
0432 if (unlikely(atomic_read(&monpriv->iucv_severed)))
0433 return EPOLLERR;
0434 if (atomic_read(&monpriv->read_ready))
0435 return EPOLLIN | EPOLLRDNORM;
0436 return 0;
0437 }
0438
0439 static const struct file_operations mon_fops = {
0440 .owner = THIS_MODULE,
0441 .open = &mon_open,
0442 .release = &mon_close,
0443 .read = &mon_read,
0444 .poll = &mon_poll,
0445 .llseek = noop_llseek,
0446 };
0447
0448 static struct miscdevice mon_dev = {
0449 .name = "monreader",
0450 .fops = &mon_fops,
0451 .minor = MISC_DYNAMIC_MINOR,
0452 };
0453
0454
0455
0456
0457 static int __init mon_init(void)
0458 {
0459 int rc;
0460
0461 if (!MACHINE_IS_VM) {
0462 pr_err("The z/VM *MONITOR record device driver cannot be "
0463 "loaded without z/VM\n");
0464 return -ENODEV;
0465 }
0466
0467
0468
0469
0470 rc = iucv_register(&monreader_iucv_handler, 1);
0471 if (rc) {
0472 pr_err("The z/VM *MONITOR record device driver failed to "
0473 "register with IUCV\n");
0474 return rc;
0475 }
0476
0477 rc = segment_type(mon_dcss_name);
0478 if (rc < 0) {
0479 segment_warning(rc, mon_dcss_name);
0480 goto out_iucv;
0481 }
0482 if (rc != SEG_TYPE_SC) {
0483 pr_err("The specified *MONITOR DCSS %s does not have the "
0484 "required type SC\n", mon_dcss_name);
0485 rc = -EINVAL;
0486 goto out_iucv;
0487 }
0488
0489 rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
0490 &mon_dcss_start, &mon_dcss_end);
0491 if (rc < 0) {
0492 segment_warning(rc, mon_dcss_name);
0493 rc = -EINVAL;
0494 goto out_iucv;
0495 }
0496 dcss_mkname(mon_dcss_name, &user_data_connect[8]);
0497
0498
0499
0500
0501
0502 rc = misc_register(&mon_dev);
0503 if (rc < 0 )
0504 goto out;
0505 return 0;
0506
0507 out:
0508 segment_unload(mon_dcss_name);
0509 out_iucv:
0510 iucv_unregister(&monreader_iucv_handler, 1);
0511 return rc;
0512 }
0513
0514 static void __exit mon_exit(void)
0515 {
0516 segment_unload(mon_dcss_name);
0517 misc_deregister(&mon_dev);
0518 iucv_unregister(&monreader_iucv_handler, 1);
0519 return;
0520 }
0521
0522
0523 module_init(mon_init);
0524 module_exit(mon_exit);
0525
0526 module_param_string(mondcss, mon_dcss_name, 9, 0444);
0527 MODULE_PARM_DESC(mondcss, "Name of DCSS segment to be used for *MONITOR "
0528 "service, max. 8 chars. Default is MONDCSS");
0529
0530 MODULE_AUTHOR("Gerald Schaefer <geraldsc@de.ibm.com>");
0531 MODULE_DESCRIPTION("Character device driver for reading z/VM "
0532 "monitor service records.");
0533 MODULE_LICENSE("GPL");