Commit 8284fb19 authored by Michael Ernst's avatar Michael Ernst Committed by Heiko Carstens

[S390] cio: fix parallel cm_enable processing.

It is now possible to trigger cm_enable processing several times in
parallel without causing a kernel panic.
Signed-off-by: default avatarMichael Ernst <mernst@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
parent fe6173d9
...@@ -766,7 +766,6 @@ chsc_secm(struct channel_subsystem *css, int enable) ...@@ -766,7 +766,6 @@ chsc_secm(struct channel_subsystem *css, int enable)
if (!secm_area) if (!secm_area)
return -ENOMEM; return -ENOMEM;
mutex_lock(&css->mutex);
if (enable && !css->cm_enabled) { if (enable && !css->cm_enabled) {
css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
...@@ -774,7 +773,6 @@ chsc_secm(struct channel_subsystem *css, int enable) ...@@ -774,7 +773,6 @@ chsc_secm(struct channel_subsystem *css, int enable)
free_page((unsigned long)css->cub_addr1); free_page((unsigned long)css->cub_addr1);
free_page((unsigned long)css->cub_addr2); free_page((unsigned long)css->cub_addr2);
free_page((unsigned long)secm_area); free_page((unsigned long)secm_area);
mutex_unlock(&css->mutex);
return -ENOMEM; return -ENOMEM;
} }
} }
...@@ -795,7 +793,6 @@ chsc_secm(struct channel_subsystem *css, int enable) ...@@ -795,7 +793,6 @@ chsc_secm(struct channel_subsystem *css, int enable)
free_page((unsigned long)css->cub_addr1); free_page((unsigned long)css->cub_addr1);
free_page((unsigned long)css->cub_addr2); free_page((unsigned long)css->cub_addr2);
} }
mutex_unlock(&css->mutex);
free_page((unsigned long)secm_area); free_page((unsigned long)secm_area);
return ret; return ret;
} }
......
...@@ -689,10 +689,14 @@ css_cm_enable_show(struct device *dev, struct device_attribute *attr, ...@@ -689,10 +689,14 @@ css_cm_enable_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct channel_subsystem *css = to_css(dev); struct channel_subsystem *css = to_css(dev);
int ret;
if (!css) if (!css)
return 0; return 0;
return sprintf(buf, "%x\n", css->cm_enabled); mutex_lock(&css->mutex);
ret = sprintf(buf, "%x\n", css->cm_enabled);
mutex_unlock(&css->mutex);
return ret;
} }
static ssize_t static ssize_t
...@@ -702,6 +706,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr, ...@@ -702,6 +706,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
struct channel_subsystem *css = to_css(dev); struct channel_subsystem *css = to_css(dev);
int ret; int ret;
mutex_lock(&css->mutex);
switch (buf[0]) { switch (buf[0]) {
case '0': case '0':
ret = css->cm_enabled ? chsc_secm(css, 0) : 0; ret = css->cm_enabled ? chsc_secm(css, 0) : 0;
...@@ -712,6 +717,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr, ...@@ -712,6 +717,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
mutex_unlock(&css->mutex);
return ret < 0 ? ret : count; return ret < 0 ? ret : count;
} }
...@@ -758,9 +764,11 @@ static int css_reboot_event(struct notifier_block *this, ...@@ -758,9 +764,11 @@ static int css_reboot_event(struct notifier_block *this,
struct channel_subsystem *css; struct channel_subsystem *css;
css = channel_subsystems[i]; css = channel_subsystems[i];
mutex_lock(&css->mutex);
if (css->cm_enabled) if (css->cm_enabled)
if (chsc_secm(css, 0)) if (chsc_secm(css, 0))
ret = NOTIFY_BAD; ret = NOTIFY_BAD;
mutex_unlock(&css->mutex);
} }
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment