diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2005-05-01 11:58:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-01 11:58:58 -0400 |
commit | 15439d74f621ff8252b53136d259781148e6e768 (patch) | |
tree | 3c92de3587f0ec51055423a08c1d2a37b7eee877 | |
parent | 0b642ede47969d4180b0922d982777fe64379228 (diff) |
[PATCH] s390: cmm guest sender id
An arbitrary guest must not be allowed to trigger cmm actions. Only one
specific guest namely the one that serves as the resource monitor may send cmm
messages. Add a parameter that allows to specify the guest that may send
messages. z/VMs resource manager has the name 'VMRMSVM' which is the default.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/s390/mm/cmm.c | 9 | ||||
-rw-r--r-- | drivers/s390/net/smsgiucv.c | 19 | ||||
-rw-r--r-- | drivers/s390/net/smsgiucv.h | 4 |
3 files changed, 24 insertions, 8 deletions
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index d30cdb4248..f5a5bc09b8 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c | |||
@@ -20,6 +20,11 @@ | |||
20 | #include <asm/pgalloc.h> | 20 | #include <asm/pgalloc.h> |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | 22 | ||
23 | static char *sender = "VMRMSVM"; | ||
24 | module_param(sender, charp, 0); | ||
25 | MODULE_PARM_DESC(sender, | ||
26 | "Guest name that may send SMSG messages (default VMRMSVM)"); | ||
27 | |||
23 | #include "../../../drivers/s390/net/smsgiucv.h" | 28 | #include "../../../drivers/s390/net/smsgiucv.h" |
24 | 29 | ||
25 | #define CMM_NR_PAGES ((PAGE_SIZE / sizeof(unsigned long)) - 2) | 30 | #define CMM_NR_PAGES ((PAGE_SIZE / sizeof(unsigned long)) - 2) |
@@ -367,10 +372,12 @@ static struct ctl_table cmm_dir_table[] = { | |||
367 | #ifdef CONFIG_CMM_IUCV | 372 | #ifdef CONFIG_CMM_IUCV |
368 | #define SMSG_PREFIX "CMM" | 373 | #define SMSG_PREFIX "CMM" |
369 | static void | 374 | static void |
370 | cmm_smsg_target(char *msg) | 375 | cmm_smsg_target(char *from, char *msg) |
371 | { | 376 | { |
372 | long pages, seconds; | 377 | long pages, seconds; |
373 | 378 | ||
379 | if (strlen(sender) > 0 && strcmp(from, sender) != 0) | ||
380 | return; | ||
374 | if (!cmm_skip_blanks(msg + strlen(SMSG_PREFIX), &msg)) | 381 | if (!cmm_skip_blanks(msg + strlen(SMSG_PREFIX), &msg)) |
375 | return; | 382 | return; |
376 | if (strncmp(msg, "SHRINK", 6) == 0) { | 383 | if (strncmp(msg, "SHRINK", 6) == 0) { |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index a3d2858595..1e3f7f3c66 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -32,7 +32,7 @@ struct smsg_callback { | |||
32 | struct list_head list; | 32 | struct list_head list; |
33 | char *prefix; | 33 | char *prefix; |
34 | int len; | 34 | int len; |
35 | void (*callback)(char *str); | 35 | void (*callback)(char *from, char *str); |
36 | }; | 36 | }; |
37 | 37 | ||
38 | MODULE_AUTHOR | 38 | MODULE_AUTHOR |
@@ -55,8 +55,9 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) | |||
55 | { | 55 | { |
56 | struct smsg_callback *cb; | 56 | struct smsg_callback *cb; |
57 | unsigned char *msg; | 57 | unsigned char *msg; |
58 | unsigned char sender[9]; | ||
58 | unsigned short len; | 59 | unsigned short len; |
59 | int rc; | 60 | int rc, i; |
60 | 61 | ||
61 | len = eib->ln1msg2.ipbfln1f; | 62 | len = eib->ln1msg2.ipbfln1f; |
62 | msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); | 63 | msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); |
@@ -69,10 +70,18 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) | |||
69 | if (rc == 0) { | 70 | if (rc == 0) { |
70 | msg[len] = 0; | 71 | msg[len] = 0; |
71 | EBCASC(msg, len); | 72 | EBCASC(msg, len); |
73 | memcpy(sender, msg, 8); | ||
74 | sender[8] = 0; | ||
75 | /* Remove trailing whitespace from the sender name. */ | ||
76 | for (i = 7; i >= 0; i--) { | ||
77 | if (sender[i] != ' ' && sender[i] != '\t') | ||
78 | break; | ||
79 | sender[i] = 0; | ||
80 | } | ||
72 | spin_lock(&smsg_list_lock); | 81 | spin_lock(&smsg_list_lock); |
73 | list_for_each_entry(cb, &smsg_list, list) | 82 | list_for_each_entry(cb, &smsg_list, list) |
74 | if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { | 83 | if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { |
75 | cb->callback(msg + 8); | 84 | cb->callback(sender, msg + 8); |
76 | break; | 85 | break; |
77 | } | 86 | } |
78 | spin_unlock(&smsg_list_lock); | 87 | spin_unlock(&smsg_list_lock); |
@@ -91,7 +100,7 @@ static struct device_driver smsg_driver = { | |||
91 | }; | 100 | }; |
92 | 101 | ||
93 | int | 102 | int |
94 | smsg_register_callback(char *prefix, void (*callback)(char *str)) | 103 | smsg_register_callback(char *prefix, void (*callback)(char *from, char *str)) |
95 | { | 104 | { |
96 | struct smsg_callback *cb; | 105 | struct smsg_callback *cb; |
97 | 106 | ||
@@ -108,7 +117,7 @@ smsg_register_callback(char *prefix, void (*callback)(char *str)) | |||
108 | } | 117 | } |
109 | 118 | ||
110 | void | 119 | void |
111 | smsg_unregister_callback(char *prefix, void (*callback)(char *str)) | 120 | smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str)) |
112 | { | 121 | { |
113 | struct smsg_callback *cb, *tmp; | 122 | struct smsg_callback *cb, *tmp; |
114 | 123 | ||
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h index 04cd871529..67f5d4f837 100644 --- a/drivers/s390/net/smsgiucv.h +++ b/drivers/s390/net/smsgiucv.h | |||
@@ -5,6 +5,6 @@ | |||
5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | 5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) |
6 | */ | 6 | */ |
7 | 7 | ||
8 | int smsg_register_callback(char *, void (*)(char *)); | 8 | int smsg_register_callback(char *, void (*)(char *, char *)); |
9 | void smsg_unregister_callback(char *, void (*)(char *)); | 9 | void smsg_unregister_callback(char *, void (*)(char *, char *)); |
10 | 10 | ||