From 15439d74f621ff8252b53136d259781148e6e768 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Sun, 1 May 2005 08:58:58 -0700 Subject: [PATCH] [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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/mm/cmm.c | 9 ++++++++- drivers/s390/net/smsgiucv.c | 19 ++++++++++++++----- 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 d30cdb4248a9..f5a5bc09b8fa 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -20,6 +20,11 @@ #include #include +static char *sender = "VMRMSVM"; +module_param(sender, charp, 0); +MODULE_PARM_DESC(sender, + "Guest name that may send SMSG messages (default VMRMSVM)"); + #include "../../../drivers/s390/net/smsgiucv.h" #define CMM_NR_PAGES ((PAGE_SIZE / sizeof(unsigned long)) - 2) @@ -367,10 +372,12 @@ static struct ctl_table cmm_dir_table[] = { #ifdef CONFIG_CMM_IUCV #define SMSG_PREFIX "CMM" static void -cmm_smsg_target(char *msg) +cmm_smsg_target(char *from, char *msg) { long pages, seconds; + if (strlen(sender) > 0 && strcmp(from, sender) != 0) + return; if (!cmm_skip_blanks(msg + strlen(SMSG_PREFIX), &msg)) return; if (strncmp(msg, "SHRINK", 6) == 0) { diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index a3d285859564..1e3f7f3c662f 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -32,7 +32,7 @@ struct smsg_callback { struct list_head list; char *prefix; int len; - void (*callback)(char *str); + void (*callback)(char *from, char *str); }; MODULE_AUTHOR @@ -55,8 +55,9 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) { struct smsg_callback *cb; unsigned char *msg; + unsigned char sender[9]; unsigned short len; - int rc; + int rc, i; len = eib->ln1msg2.ipbfln1f; msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); @@ -69,10 +70,18 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) if (rc == 0) { msg[len] = 0; EBCASC(msg, len); + memcpy(sender, msg, 8); + sender[8] = 0; + /* Remove trailing whitespace from the sender name. */ + for (i = 7; i >= 0; i--) { + if (sender[i] != ' ' && sender[i] != '\t') + break; + sender[i] = 0; + } spin_lock(&smsg_list_lock); list_for_each_entry(cb, &smsg_list, list) if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { - cb->callback(msg + 8); + cb->callback(sender, msg + 8); break; } spin_unlock(&smsg_list_lock); @@ -91,7 +100,7 @@ static struct device_driver smsg_driver = { }; int -smsg_register_callback(char *prefix, void (*callback)(char *str)) +smsg_register_callback(char *prefix, void (*callback)(char *from, char *str)) { struct smsg_callback *cb; @@ -108,7 +117,7 @@ smsg_register_callback(char *prefix, void (*callback)(char *str)) } void -smsg_unregister_callback(char *prefix, void (*callback)(char *str)) +smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str)) { struct smsg_callback *cb, *tmp; diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h index 04cd87152964..67f5d4f8378d 100644 --- a/drivers/s390/net/smsgiucv.h +++ b/drivers/s390/net/smsgiucv.h @@ -5,6 +5,6 @@ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) */ -int smsg_register_callback(char *, void (*)(char *)); -void smsg_unregister_callback(char *, void (*)(char *)); +int smsg_register_callback(char *, void (*)(char *, char *)); +void smsg_unregister_callback(char *, void (*)(char *, char *)); -- 2.20.1