1
2
3
4
5
6
7
8
9
10
11
12#define KMSG_COMPONENT "hvc_iucv"
13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14
15#include <linux/types.h>
16#include <linux/slab.h>
17#include <asm/ebcdic.h>
18#include <linux/ctype.h>
19#include <linux/delay.h>
20#include <linux/device.h>
21#include <linux/init.h>
22#include <linux/mempool.h>
23#include <linux/moduleparam.h>
24#include <linux/tty.h>
25#include <linux/wait.h>
26#include <net/iucv/iucv.h>
27
28#include "hvc_console.h"
29
30
31
32#define HVC_IUCV_MAGIC 0xc9e4c3e5
33#define MAX_HVC_IUCV_LINES HVC_ALLOC_TTY_ADAPTERS
34#define MEMPOOL_MIN_NR (PAGE_SIZE / sizeof(struct iucv_tty_buffer)/4)
35
36
37#define MSG_VERSION 0x02
38#define MSG_TYPE_ERROR 0x01
39#define MSG_TYPE_TERMENV 0x02
40#define MSG_TYPE_TERMIOS 0x04
41#define MSG_TYPE_WINSIZE 0x08
42#define MSG_TYPE_DATA 0x10
43
44struct iucv_tty_msg {
45 u8 version;
46 u8 type;
47#define MSG_MAX_DATALEN ((u16)(~0))
48 u16 datalen;
49 u8 data[];
50} __attribute__((packed));
51#define MSG_SIZE(s) ((s) + offsetof(struct iucv_tty_msg, data))
52
53enum iucv_state_t {
54 IUCV_DISCONN = 0,
55 IUCV_CONNECTED = 1,
56 IUCV_SEVERED = 2,
57};
58
59enum tty_state_t {
60 TTY_CLOSED = 0,
61 TTY_OPENED = 1,
62};
63
64struct hvc_iucv_private {
65 struct hvc_struct *hvc;
66 u8 srv_name[8];
67 unsigned char is_console;
68 enum iucv_state_t iucv_state;
69 enum tty_state_t tty_state;
70 struct iucv_path *path;
71 spinlock_t lock;
72#define SNDBUF_SIZE (PAGE_SIZE)
73 void *sndbuf;
74 size_t sndbuf_len;
75#define QUEUE_SNDBUF_DELAY (HZ / 25)
76 struct delayed_work sndbuf_work;
77 wait_queue_head_t sndbuf_waitq;
78 struct list_head tty_outqueue;
79 struct list_head tty_inqueue;
80 struct device *dev;
81 u8 info_path[16];
82};
83
84struct iucv_tty_buffer {
85 struct list_head list;
86 struct iucv_message msg;
87 size_t offset;
88 struct iucv_tty_msg *mbuf;
89};
90
91
92static int hvc_iucv_path_pending(struct iucv_path *, u8 *, u8 *);
93static void hvc_iucv_path_severed(struct iucv_path *, u8 *);
94static void hvc_iucv_msg_pending(struct iucv_path *, struct iucv_message *);
95static void hvc_iucv_msg_complete(struct iucv_path *, struct iucv_message *);
96
97
98
99static unsigned long hvc_iucv_devices = 1;
100
101
102static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
103#define IUCV_HVC_CON_IDX (0)
104
105#define MAX_VMID_FILTER (500)
106#define FILTER_WILDCARD_CHAR '*'
107static size_t hvc_iucv_filter_size;
108static void *hvc_iucv_filter;
109static const char *hvc_iucv_filter_string;
110static DEFINE_RWLOCK(hvc_iucv_filter_lock);
111
112
113static struct kmem_cache *hvc_iucv_buffer_cache;
114static mempool_t *hvc_iucv_mempool;
115
116
117static struct iucv_handler hvc_iucv_handler = {
118 .path_pending = hvc_iucv_path_pending,
119 .path_severed = hvc_iucv_path_severed,
120 .message_complete = hvc_iucv_msg_complete,
121 .message_pending = hvc_iucv_msg_pending,
122};
123
124
125
126
127
128
129
130
131
132static struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
133{
134 if ((num < HVC_IUCV_MAGIC) || (num - HVC_IUCV_MAGIC > hvc_iucv_devices))
135 return NULL;
136 return hvc_iucv_table[num - HVC_IUCV_MAGIC];
137}
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
153{
154 struct iucv_tty_buffer *bufp;
155
156 bufp = mempool_alloc(hvc_iucv_mempool, flags);
157 if (!bufp)
158 return NULL;
159 memset(bufp, 0, sizeof(*bufp));
160
161 if (size > 0) {
162 bufp->msg.length = MSG_SIZE(size);
163 bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA);
164 if (!bufp->mbuf) {
165 mempool_free(bufp, hvc_iucv_mempool);
166 return NULL;
167 }
168 bufp->mbuf->version = MSG_VERSION;
169 bufp->mbuf->type = MSG_TYPE_DATA;
170 bufp->mbuf->datalen = (u16) size;
171 }
172 return bufp;
173}
174
175
176
177
178
179static void destroy_tty_buffer(struct iucv_tty_buffer *bufp)
180{
181 kfree(bufp->mbuf);
182 mempool_free(bufp, hvc_iucv_mempool);
183}
184
185
186
187
188
189static void destroy_tty_buffer_list(struct list_head *list)
190{
191 struct iucv_tty_buffer *ent, *next;
192
193 list_for_each_entry_safe(ent, next, list, list) {
194 list_del(&ent->list);
195 destroy_tty_buffer(ent);
196 }
197}
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219static int hvc_iucv_write(struct hvc_iucv_private *priv,
220 char *buf, int count, int *has_more_data)
221{
222 struct iucv_tty_buffer *rb;
223 int written;
224 int rc;
225
226
227 if (priv->iucv_state == IUCV_DISCONN)
228 return 0;
229
230
231
232 if (priv->iucv_state == IUCV_SEVERED)
233 return -EPIPE;
234
235
236 if (list_empty(&priv->tty_inqueue))
237 return 0;
238
239
240 rb = list_first_entry(&priv->tty_inqueue, struct iucv_tty_buffer, list);
241
242 written = 0;
243 if (!rb->mbuf) {
244
245
246 rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA);
247 if (!rb->mbuf)
248 return -ENOMEM;
249
250 rc = __iucv_message_receive(priv->path, &rb->msg, 0,
251 rb->mbuf, rb->msg.length, NULL);
252 switch (rc) {
253 case 0:
254 break;
255 case 2:
256 case 9:
257 break;
258 default:
259 written = -EIO;
260 }
261
262
263 if (rc || (rb->mbuf->version != MSG_VERSION) ||
264 (rb->msg.length != MSG_SIZE(rb->mbuf->datalen)))
265 goto out_remove_buffer;
266 }
267
268 switch (rb->mbuf->type) {
269 case MSG_TYPE_DATA:
270 written = min_t(int, rb->mbuf->datalen - rb->offset, count);
271 memcpy(buf, rb->mbuf->data + rb->offset, written);
272 if (written < (rb->mbuf->datalen - rb->offset)) {
273 rb->offset += written;
274 *has_more_data = 1;
275 goto out_written;
276 }
277 break;
278
279 case MSG_TYPE_WINSIZE:
280 if (rb->mbuf->datalen != sizeof(struct winsize))
281 break;
282
283
284 __hvc_resize(priv->hvc, *((struct winsize *) rb->mbuf->data));
285 break;
286
287 case MSG_TYPE_ERROR:
288 case MSG_TYPE_TERMENV:
289 case MSG_TYPE_TERMIOS:
290 break;
291 }
292
293out_remove_buffer:
294 list_del(&rb->list);
295 destroy_tty_buffer(rb);
296 *has_more_data = !list_empty(&priv->tty_inqueue);
297
298out_written:
299 return written;
300}
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316static int hvc_iucv_get_chars(uint32_t vtermno, char *buf, int count)
317{
318 struct hvc_iucv_private *priv = hvc_iucv_get_private(vtermno);
319 int written;
320 int has_more_data;
321
322 if (count <= 0)
323 return 0;
324
325 if (!priv)
326 return -ENODEV;
327
328 spin_lock(&priv->lock);
329 has_more_data = 0;
330 written = hvc_iucv_write(priv, buf, count, &has_more_data);
331 spin_unlock(&priv->lock);
332
333
334 if (has_more_data)
335 hvc_kick();
336
337 return written;
338}
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356static int hvc_iucv_queue(struct hvc_iucv_private *priv, const char *buf,
357 int count)
358{
359 size_t len;
360
361 if (priv->iucv_state == IUCV_DISCONN)
362 return count;
363
364 if (priv->iucv_state == IUCV_SEVERED)
365 return -EPIPE;
366
367 len = min_t(size_t, count, SNDBUF_SIZE - priv->sndbuf_len);
368 if (!len)
369 return 0;
370
371 memcpy(priv->sndbuf + priv->sndbuf_len, buf, len);
372 priv->sndbuf_len += len;
373
374 if (priv->iucv_state == IUCV_CONNECTED)
375 schedule_delayed_work(&priv->sndbuf_work, QUEUE_SNDBUF_DELAY);
376
377 return len;
378}
379
380
381
382
383
384
385
386
387
388
389static int hvc_iucv_send(struct hvc_iucv_private *priv)
390{
391 struct iucv_tty_buffer *sb;
392 int rc, len;
393
394 if (priv->iucv_state == IUCV_SEVERED)
395 return -EPIPE;
396
397 if (priv->iucv_state == IUCV_DISCONN)
398 return -EIO;
399
400 if (!priv->sndbuf_len)
401 return 0;
402
403
404
405 sb = alloc_tty_buffer(priv->sndbuf_len, GFP_ATOMIC);
406 if (!sb)
407 return -ENOMEM;
408
409 memcpy(sb->mbuf->data, priv->sndbuf, priv->sndbuf_len);
410 sb->mbuf->datalen = (u16) priv->sndbuf_len;
411 sb->msg.length = MSG_SIZE(sb->mbuf->datalen);
412
413 list_add_tail(&sb->list, &priv->tty_outqueue);
414
415 rc = __iucv_message_send(priv->path, &sb->msg, 0, 0,
416 (void *) sb->mbuf, sb->msg.length);
417 if (rc) {
418
419
420 list_del(&sb->list);
421 destroy_tty_buffer(sb);
422 }
423 len = priv->sndbuf_len;
424 priv->sndbuf_len = 0;
425
426 return len;
427}
428
429
430
431
432
433
434
435
436static void hvc_iucv_sndbuf_work(struct work_struct *work)
437{
438 struct hvc_iucv_private *priv;
439
440 priv = container_of(work, struct hvc_iucv_private, sndbuf_work.work);
441 if (!priv)
442 return;
443
444 spin_lock_bh(&priv->lock);
445 hvc_iucv_send(priv);
446 spin_unlock_bh(&priv->lock);
447}
448
449
450
451
452
453
454
455
456
457
458
459
460
461static int hvc_iucv_put_chars(uint32_t vtermno, const char *buf, int count)
462{
463 struct hvc_iucv_private *priv = hvc_iucv_get_private(vtermno);
464 int queued;
465
466 if (count <= 0)
467 return 0;
468
469 if (!priv)
470 return -ENODEV;
471
472 spin_lock(&priv->lock);
473 queued = hvc_iucv_queue(priv, buf, count);
474 spin_unlock(&priv->lock);
475
476 return queued;
477}
478
479
480
481
482
483
484
485
486
487
488
489
490static int hvc_iucv_notifier_add(struct hvc_struct *hp, int id)
491{
492 struct hvc_iucv_private *priv;
493
494 priv = hvc_iucv_get_private(id);
495 if (!priv)
496 return 0;
497
498 spin_lock_bh(&priv->lock);
499 priv->tty_state = TTY_OPENED;
500 spin_unlock_bh(&priv->lock);
501
502 return 0;
503}
504
505
506
507
508
509static void hvc_iucv_cleanup(struct hvc_iucv_private *priv)
510{
511 destroy_tty_buffer_list(&priv->tty_outqueue);
512 destroy_tty_buffer_list(&priv->tty_inqueue);
513
514 priv->tty_state = TTY_CLOSED;
515 priv->iucv_state = IUCV_DISCONN;
516
517 priv->sndbuf_len = 0;
518}
519
520
521
522
523
524static inline int tty_outqueue_empty(struct hvc_iucv_private *priv)
525{
526 int rc;
527
528 spin_lock_bh(&priv->lock);
529 rc = list_empty(&priv->tty_outqueue);
530 spin_unlock_bh(&priv->lock);
531
532 return rc;
533}
534
535
536
537
538
539
540
541
542static void flush_sndbuf_sync(struct hvc_iucv_private *priv)
543{
544 int sync_wait;
545
546 cancel_delayed_work_sync(&priv->sndbuf_work);
547
548 spin_lock_bh(&priv->lock);
549 hvc_iucv_send(priv);
550 sync_wait = !list_empty(&priv->tty_outqueue);
551 spin_unlock_bh(&priv->lock);
552
553 if (sync_wait)
554 wait_event_timeout(priv->sndbuf_waitq,
555 tty_outqueue_empty(priv), HZ/10);
556}
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590static void hvc_iucv_hangup(struct hvc_iucv_private *priv)
591{
592 struct iucv_path *path;
593
594 path = NULL;
595 spin_lock(&priv->lock);
596 if (priv->iucv_state == IUCV_CONNECTED) {
597 path = priv->path;
598 priv->path = NULL;
599 priv->iucv_state = IUCV_SEVERED;
600 if (priv->tty_state == TTY_CLOSED)
601 hvc_iucv_cleanup(priv);
602 else
603
604 if (priv->is_console) {
605 hvc_iucv_cleanup(priv);
606 priv->tty_state = TTY_OPENED;
607 } else
608 hvc_kick();
609 }
610 spin_unlock(&priv->lock);
611
612
613 if (path) {
614 iucv_path_sever(path, NULL);
615 iucv_path_free(path);
616 }
617}
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636static void hvc_iucv_notifier_hangup(struct hvc_struct *hp, int id)
637{
638 struct hvc_iucv_private *priv;
639
640 priv = hvc_iucv_get_private(id);
641 if (!priv)
642 return;
643
644 flush_sndbuf_sync(priv);
645
646 spin_lock_bh(&priv->lock);
647
648
649
650
651
652
653
654 priv->tty_state = TTY_CLOSED;
655
656 if (priv->iucv_state == IUCV_SEVERED)
657 hvc_iucv_cleanup(priv);
658 spin_unlock_bh(&priv->lock);
659}
660
661
662
663
664
665
666
667
668
669
670static void hvc_iucv_dtr_rts(struct hvc_struct *hp, int raise)
671{
672 struct hvc_iucv_private *priv;
673 struct iucv_path *path;
674
675
676
677
678 if (raise)
679 return;
680
681 priv = hvc_iucv_get_private(hp->vtermno);
682 if (!priv)
683 return;
684
685
686
687
688 flush_sndbuf_sync(priv);
689
690 spin_lock_bh(&priv->lock);
691 path = priv->path;
692 priv->path = NULL;
693 priv->iucv_state = IUCV_DISCONN;
694 spin_unlock_bh(&priv->lock);
695
696
697
698 if (path) {
699 iucv_path_sever(path, NULL);
700 iucv_path_free(path);
701 }
702}
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
718{
719 struct hvc_iucv_private *priv;
720
721 priv = hvc_iucv_get_private(id);
722 if (!priv)
723 return;
724
725 flush_sndbuf_sync(priv);
726
727 spin_lock_bh(&priv->lock);
728 destroy_tty_buffer_list(&priv->tty_outqueue);
729 destroy_tty_buffer_list(&priv->tty_inqueue);
730 priv->tty_state = TTY_CLOSED;
731 priv->sndbuf_len = 0;
732 spin_unlock_bh(&priv->lock);
733}
734
735
736
737
738
739
740
741
742static int hvc_iucv_filter_connreq(u8 ipvmid[8])
743{
744 const char *wildcard, *filter_entry;
745 size_t i, len;
746
747
748 if (!hvc_iucv_filter_size)
749 return 0;
750
751 for (i = 0; i < hvc_iucv_filter_size; i++) {
752 filter_entry = hvc_iucv_filter + (8 * i);
753
754
755
756
757
758
759 wildcard = strnchr(filter_entry, 8, FILTER_WILDCARD_CHAR);
760 len = (wildcard) ? wildcard - filter_entry : 8;
761 if (0 == memcmp(ipvmid, filter_entry, len))
762 return 0;
763 }
764 return 1;
765}
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786static int hvc_iucv_path_pending(struct iucv_path *path, u8 *ipvmid,
787 u8 *ipuser)
788{
789 struct hvc_iucv_private *priv, *tmp;
790 u8 wildcard[9] = "lnxhvc ";
791 int i, rc, find_unused;
792 u8 nuser_data[16];
793 u8 vm_user_id[9];
794
795 ASCEBC(wildcard, sizeof(wildcard));
796 find_unused = !memcmp(wildcard, ipuser, 8);
797
798
799
800
801
802
803 priv = NULL;
804 for (i = 0; i < hvc_iucv_devices; i++) {
805 tmp = hvc_iucv_table[i];
806 if (!tmp)
807 continue;
808
809 if (find_unused) {
810 spin_lock(&tmp->lock);
811 if (tmp->iucv_state == IUCV_DISCONN)
812 priv = tmp;
813 spin_unlock(&tmp->lock);
814
815 } else if (!memcmp(tmp->srv_name, ipuser, 8))
816 priv = tmp;
817 if (priv)
818 break;
819 }
820 if (!priv)
821 return -ENODEV;
822
823
824 read_lock(&hvc_iucv_filter_lock);
825 rc = hvc_iucv_filter_connreq(ipvmid);
826 read_unlock(&hvc_iucv_filter_lock);
827 if (rc) {
828 iucv_path_sever(path, ipuser);
829 iucv_path_free(path);
830 memcpy(vm_user_id, ipvmid, 8);
831 vm_user_id[8] = 0;
832 pr_info("A connection request from z/VM user ID %s "
833 "was refused\n", vm_user_id);
834 return 0;
835 }
836
837 spin_lock(&priv->lock);
838
839
840
841
842 if (priv->iucv_state != IUCV_DISCONN) {
843 iucv_path_sever(path, ipuser);
844 iucv_path_free(path);
845 goto out_path_handled;
846 }
847
848
849 memcpy(nuser_data, ipuser + 8, 8);
850 memcpy(nuser_data + 8, ipuser, 8);
851 path->msglim = 0xffff;
852 path->flags &= ~IUCV_IPRMDATA;
853 rc = iucv_path_accept(path, &hvc_iucv_handler, nuser_data, priv);
854 if (rc) {
855 iucv_path_sever(path, ipuser);
856 iucv_path_free(path);
857 goto out_path_handled;
858 }
859 priv->path = path;
860 priv->iucv_state = IUCV_CONNECTED;
861
862
863 memcpy(priv->info_path, ipvmid, 8);
864 memcpy(priv->info_path + 8, ipuser + 8, 8);
865
866
867 schedule_delayed_work(&priv->sndbuf_work, 5);
868
869out_path_handled:
870 spin_unlock(&priv->lock);
871 return 0;
872}
873
874
875
876
877
878
879
880
881
882
883
884
885static void hvc_iucv_path_severed(struct iucv_path *path, u8 *ipuser)
886{
887 struct hvc_iucv_private *priv = path->private;
888
889 hvc_iucv_hangup(priv);
890}
891
892
893
894
895
896
897
898
899
900
901
902
903static void hvc_iucv_msg_pending(struct iucv_path *path,
904 struct iucv_message *msg)
905{
906 struct hvc_iucv_private *priv = path->private;
907 struct iucv_tty_buffer *rb;
908
909
910 if (msg->length > MSG_SIZE(MSG_MAX_DATALEN)) {
911 iucv_message_reject(path, msg);
912 return;
913 }
914
915 spin_lock(&priv->lock);
916
917
918 if (priv->tty_state == TTY_CLOSED) {
919 iucv_message_reject(path, msg);
920 goto unlock_return;
921 }
922
923
924 rb = alloc_tty_buffer(0, GFP_ATOMIC);
925 if (!rb) {
926 iucv_message_reject(path, msg);
927 goto unlock_return;
928 }
929 rb->msg = *msg;
930
931 list_add_tail(&rb->list, &priv->tty_inqueue);
932
933 hvc_kick();
934
935unlock_return:
936 spin_unlock(&priv->lock);
937}
938
939
940
941
942
943
944
945
946
947
948
949
950
951static void hvc_iucv_msg_complete(struct iucv_path *path,
952 struct iucv_message *msg)
953{
954 struct hvc_iucv_private *priv = path->private;
955 struct iucv_tty_buffer *ent, *next;
956 LIST_HEAD(list_remove);
957
958 spin_lock(&priv->lock);
959 list_for_each_entry_safe(ent, next, &priv->tty_outqueue, list)
960 if (ent->msg.id == msg->id) {
961 list_move(&ent->list, &list_remove);
962 break;
963 }
964 wake_up(&priv->sndbuf_waitq);
965 spin_unlock(&priv->lock);
966 destroy_tty_buffer_list(&list_remove);
967}
968
969
970
971
972
973
974
975
976static int hvc_iucv_pm_freeze(struct device *dev)
977{
978 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
979
980 local_bh_disable();
981 hvc_iucv_hangup(priv);
982 local_bh_enable();
983
984 return 0;
985}
986
987
988
989
990
991
992
993
994static int hvc_iucv_pm_restore_thaw(struct device *dev)
995{
996 hvc_kick();
997 return 0;
998}
999
1000static ssize_t hvc_iucv_dev_termid_show(struct device *dev,
1001 struct device_attribute *attr,
1002 char *buf)
1003{
1004 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
1005 size_t len;
1006
1007 len = sizeof(priv->srv_name);
1008 memcpy(buf, priv->srv_name, len);
1009 EBCASC(buf, len);
1010 buf[len++] = '\n';
1011 return len;
1012}
1013
1014static ssize_t hvc_iucv_dev_state_show(struct device *dev,
1015 struct device_attribute *attr,
1016 char *buf)
1017{
1018 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
1019 return sprintf(buf, "%u:%u\n", priv->iucv_state, priv->tty_state);
1020}
1021
1022static ssize_t hvc_iucv_dev_peer_show(struct device *dev,
1023 struct device_attribute *attr,
1024 char *buf)
1025{
1026 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
1027 char vmid[9], ipuser[9];
1028
1029 memset(vmid, 0, sizeof(vmid));
1030 memset(ipuser, 0, sizeof(ipuser));
1031
1032 spin_lock_bh(&priv->lock);
1033 if (priv->iucv_state == IUCV_CONNECTED) {
1034 memcpy(vmid, priv->info_path, 8);
1035 memcpy(ipuser, priv->info_path + 8, 8);
1036 }
1037 spin_unlock_bh(&priv->lock);
1038 EBCASC(ipuser, 8);
1039
1040 return sprintf(buf, "%s:%s\n", vmid, ipuser);
1041}
1042
1043
1044
1045static const struct hv_ops hvc_iucv_ops = {
1046 .get_chars = hvc_iucv_get_chars,
1047 .put_chars = hvc_iucv_put_chars,
1048 .notifier_add = hvc_iucv_notifier_add,
1049 .notifier_del = hvc_iucv_notifier_del,
1050 .notifier_hangup = hvc_iucv_notifier_hangup,
1051 .dtr_rts = hvc_iucv_dtr_rts,
1052};
1053
1054
1055static const struct dev_pm_ops hvc_iucv_pm_ops = {
1056 .freeze = hvc_iucv_pm_freeze,
1057 .thaw = hvc_iucv_pm_restore_thaw,
1058 .restore = hvc_iucv_pm_restore_thaw,
1059};
1060
1061
1062static struct device_driver hvc_iucv_driver = {
1063 .name = KMSG_COMPONENT,
1064 .bus = &iucv_bus,
1065 .pm = &hvc_iucv_pm_ops,
1066};
1067
1068
1069static DEVICE_ATTR(termid, 0640, hvc_iucv_dev_termid_show, NULL);
1070static DEVICE_ATTR(state, 0640, hvc_iucv_dev_state_show, NULL);
1071static DEVICE_ATTR(peer, 0640, hvc_iucv_dev_peer_show, NULL);
1072static struct attribute *hvc_iucv_dev_attrs[] = {
1073 &dev_attr_termid.attr,
1074 &dev_attr_state.attr,
1075 &dev_attr_peer.attr,
1076 NULL,
1077};
1078static struct attribute_group hvc_iucv_dev_attr_group = {
1079 .attrs = hvc_iucv_dev_attrs,
1080};
1081static const struct attribute_group *hvc_iucv_dev_attr_groups[] = {
1082 &hvc_iucv_dev_attr_group,
1083 NULL,
1084};
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096static int __init hvc_iucv_alloc(int id, unsigned int is_console)
1097{
1098 struct hvc_iucv_private *priv;
1099 char name[9];
1100 int rc;
1101
1102 priv = kzalloc(sizeof(struct hvc_iucv_private), GFP_KERNEL);
1103 if (!priv)
1104 return -ENOMEM;
1105
1106 spin_lock_init(&priv->lock);
1107 INIT_LIST_HEAD(&priv->tty_outqueue);
1108 INIT_LIST_HEAD(&priv->tty_inqueue);
1109 INIT_DELAYED_WORK(&priv->sndbuf_work, hvc_iucv_sndbuf_work);
1110 init_waitqueue_head(&priv->sndbuf_waitq);
1111
1112 priv->sndbuf = (void *) get_zeroed_page(GFP_KERNEL);
1113 if (!priv->sndbuf) {
1114 kfree(priv);
1115 return -ENOMEM;
1116 }
1117
1118
1119 priv->is_console = is_console;
1120
1121
1122 priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id,
1123 HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256);
1124 if (IS_ERR(priv->hvc)) {
1125 rc = PTR_ERR(priv->hvc);
1126 goto out_error_hvc;
1127 }
1128
1129
1130 priv->hvc->irq_requested = 1;
1131
1132
1133 snprintf(name, 9, "lnxhvc%-2d", id);
1134 memcpy(priv->srv_name, name, 8);
1135 ASCEBC(priv->srv_name, 8);
1136
1137
1138 priv->dev = kzalloc(sizeof(*priv->dev), GFP_KERNEL);
1139 if (!priv->dev) {
1140 rc = -ENOMEM;
1141 goto out_error_dev;
1142 }
1143 dev_set_name(priv->dev, "hvc_iucv%d", id);
1144 dev_set_drvdata(priv->dev, priv);
1145 priv->dev->bus = &iucv_bus;
1146 priv->dev->parent = iucv_root;
1147 priv->dev->driver = &hvc_iucv_driver;
1148 priv->dev->groups = hvc_iucv_dev_attr_groups;
1149 priv->dev->release = (void (*)(struct device *)) kfree;
1150 rc = device_register(priv->dev);
1151 if (rc) {
1152 put_device(priv->dev);
1153 goto out_error_dev;
1154 }
1155
1156 hvc_iucv_table[id] = priv;
1157 return 0;
1158
1159out_error_dev:
1160 hvc_remove(priv->hvc);
1161out_error_hvc:
1162 free_page((unsigned long) priv->sndbuf);
1163 kfree(priv);
1164
1165 return rc;
1166}
1167
1168
1169
1170
1171static void __init hvc_iucv_destroy(struct hvc_iucv_private *priv)
1172{
1173 hvc_remove(priv->hvc);
1174 device_unregister(priv->dev);
1175 free_page((unsigned long) priv->sndbuf);
1176 kfree(priv);
1177}
1178
1179
1180
1181
1182
1183
1184static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
1185{
1186 const char *nextdelim, *residual;
1187 size_t len;
1188
1189 nextdelim = strchr(filter, ',');
1190 if (nextdelim) {
1191 len = nextdelim - filter;
1192 residual = nextdelim + 1;
1193 } else {
1194 len = strlen(filter);
1195 residual = filter + len;
1196 }
1197
1198 if (len == 0)
1199 return ERR_PTR(-EINVAL);
1200
1201
1202 if (filter[len - 1] == '\n')
1203 len--;
1204
1205
1206 if (len == 1 && *filter == FILTER_WILDCARD_CHAR)
1207 return ERR_PTR(-EINVAL);
1208
1209 if (len > 8)
1210 return ERR_PTR(-EINVAL);
1211
1212
1213 memset(dest, ' ', 8);
1214 while (len--)
1215 dest[len] = toupper(filter[len]);
1216 return residual;
1217}
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229static int hvc_iucv_setup_filter(const char *val)
1230{
1231 const char *residual;
1232 int err;
1233 size_t size, count;
1234 void *array, *old_filter;
1235
1236 count = strlen(val);
1237 if (count == 0 || (count == 1 && val[0] == '\n')) {
1238 size = 0;
1239 array = NULL;
1240 goto out_replace_filter;
1241 }
1242
1243
1244 size = 1;
1245 residual = val;
1246 while ((residual = strchr(residual, ',')) != NULL) {
1247 residual++;
1248 size++;
1249 }
1250
1251
1252 if (size > MAX_VMID_FILTER)
1253 return -ENOSPC;
1254
1255 array = kcalloc(size, 8, GFP_KERNEL);
1256 if (!array)
1257 return -ENOMEM;
1258
1259 count = size;
1260 residual = val;
1261 while (*residual && count) {
1262 residual = hvc_iucv_parse_filter(residual,
1263 array + ((size - count) * 8));
1264 if (IS_ERR(residual)) {
1265 err = PTR_ERR(residual);
1266 kfree(array);
1267 goto out_err;
1268 }
1269 count--;
1270 }
1271
1272out_replace_filter:
1273 write_lock_bh(&hvc_iucv_filter_lock);
1274 old_filter = hvc_iucv_filter;
1275 hvc_iucv_filter_size = size;
1276 hvc_iucv_filter = array;
1277 write_unlock_bh(&hvc_iucv_filter_lock);
1278 kfree(old_filter);
1279
1280 err = 0;
1281out_err:
1282 return err;
1283}
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295static int param_set_vmidfilter(const char *val, const struct kernel_param *kp)
1296{
1297 int rc;
1298
1299 if (!MACHINE_IS_VM || !hvc_iucv_devices)
1300 return -ENODEV;
1301
1302 if (!val)
1303 return -EINVAL;
1304
1305 rc = 0;
1306 if (slab_is_available())
1307 rc = hvc_iucv_setup_filter(val);
1308 else
1309 hvc_iucv_filter_string = val;
1310 return rc;
1311}
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322static int param_get_vmidfilter(char *buffer, const struct kernel_param *kp)
1323{
1324 int rc;
1325 size_t index, len;
1326 void *start, *end;
1327
1328 if (!MACHINE_IS_VM || !hvc_iucv_devices)
1329 return -ENODEV;
1330
1331 rc = 0;
1332 read_lock_bh(&hvc_iucv_filter_lock);
1333 for (index = 0; index < hvc_iucv_filter_size; index++) {
1334 start = hvc_iucv_filter + (8 * index);
1335 end = memchr(start, ' ', 8);
1336 len = (end) ? end - start : 8;
1337 memcpy(buffer + rc, start, len);
1338 rc += len;
1339 buffer[rc++] = ',';
1340 }
1341 read_unlock_bh(&hvc_iucv_filter_lock);
1342 if (rc)
1343 buffer[--rc] = '\0';
1344 return rc;
1345}
1346
1347#define param_check_vmidfilter(name, p) __param_check(name, p, void)
1348
1349static const struct kernel_param_ops param_ops_vmidfilter = {
1350 .set = param_set_vmidfilter,
1351 .get = param_get_vmidfilter,
1352};
1353
1354
1355
1356
1357static int __init hvc_iucv_init(void)
1358{
1359 int rc;
1360 unsigned int i;
1361
1362 if (!hvc_iucv_devices)
1363 return -ENODEV;
1364
1365 if (!MACHINE_IS_VM) {
1366 pr_notice("The z/VM IUCV HVC device driver cannot "
1367 "be used without z/VM\n");
1368 rc = -ENODEV;
1369 goto out_error;
1370 }
1371
1372 if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) {
1373 pr_err("%lu is not a valid value for the hvc_iucv= "
1374 "kernel parameter\n", hvc_iucv_devices);
1375 rc = -EINVAL;
1376 goto out_error;
1377 }
1378
1379
1380 rc = driver_register(&hvc_iucv_driver);
1381 if (rc)
1382 goto out_error;
1383
1384
1385 if (hvc_iucv_filter_string) {
1386 rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
1387 switch (rc) {
1388 case 0:
1389 break;
1390 case -ENOMEM:
1391 pr_err("Allocating memory failed with "
1392 "reason code=%d\n", 3);
1393 goto out_error;
1394 case -EINVAL:
1395 pr_err("hvc_iucv_allow= does not specify a valid "
1396 "z/VM user ID list\n");
1397 goto out_error;
1398 case -ENOSPC:
1399 pr_err("hvc_iucv_allow= specifies too many "
1400 "z/VM user IDs\n");
1401 goto out_error;
1402 default:
1403 goto out_error;
1404 }
1405 }
1406
1407 hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
1408 sizeof(struct iucv_tty_buffer),
1409 0, 0, NULL);
1410 if (!hvc_iucv_buffer_cache) {
1411 pr_err("Allocating memory failed with reason code=%d\n", 1);
1412 rc = -ENOMEM;
1413 goto out_error;
1414 }
1415
1416 hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
1417 hvc_iucv_buffer_cache);
1418 if (!hvc_iucv_mempool) {
1419 pr_err("Allocating memory failed with reason code=%d\n", 2);
1420 kmem_cache_destroy(hvc_iucv_buffer_cache);
1421 rc = -ENOMEM;
1422 goto out_error;
1423 }
1424
1425
1426
1427 rc = hvc_instantiate(HVC_IUCV_MAGIC, IUCV_HVC_CON_IDX, &hvc_iucv_ops);
1428 if (rc) {
1429 pr_err("Registering HVC terminal device as "
1430 "Linux console failed\n");
1431 goto out_error_memory;
1432 }
1433
1434
1435 for (i = 0; i < hvc_iucv_devices; i++) {
1436 rc = hvc_iucv_alloc(i, (i == IUCV_HVC_CON_IDX) ? 1 : 0);
1437 if (rc) {
1438 pr_err("Creating a new HVC terminal device "
1439 "failed with error code=%d\n", rc);
1440 goto out_error_hvc;
1441 }
1442 }
1443
1444
1445 rc = iucv_register(&hvc_iucv_handler, 0);
1446 if (rc) {
1447 pr_err("Registering IUCV handlers failed with error code=%d\n",
1448 rc);
1449 goto out_error_hvc;
1450 }
1451
1452 return 0;
1453
1454out_error_hvc:
1455 for (i = 0; i < hvc_iucv_devices; i++)
1456 if (hvc_iucv_table[i])
1457 hvc_iucv_destroy(hvc_iucv_table[i]);
1458out_error_memory:
1459 mempool_destroy(hvc_iucv_mempool);
1460 kmem_cache_destroy(hvc_iucv_buffer_cache);
1461out_error:
1462 kfree(hvc_iucv_filter);
1463 hvc_iucv_devices = 0;
1464 return rc;
1465}
1466
1467
1468
1469
1470
1471static int __init hvc_iucv_config(char *val)
1472{
1473 return kstrtoul(val, 10, &hvc_iucv_devices);
1474}
1475
1476
1477device_initcall(hvc_iucv_init);
1478__setup("hvc_iucv=", hvc_iucv_config);
1479core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);
1480