提交 8821d24c 编写于 作者: S Sebastian Ott 提交者: Martin Schwidefsky

[S390] cio: use exception-save stsch

Using stsch on schids with ssid != 0 can lead to an operand
exception. Use stsch_err to handle potential exceptions
if we fail to reenable mss after hibernation.

Cc: <stable@kernel.org>
Signed-off-by: NSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: NMartin Schwidefsky <schwidefsky@de.ibm.com>
上级 889ee955
...@@ -124,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch) ...@@ -124,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch)
* since we don't have a way to clear the subchannel and * since we don't have a way to clear the subchannel and
* cannot disable it with a request running. * cannot disable it with a request running.
*/ */
cc = stsch(sch->schid, &schib); cc = stsch_err(sch->schid, &schib);
if (!cc && scsw_stctl(&schib.scsw)) if (!cc && scsw_stctl(&schib.scsw))
return -EAGAIN; return -EAGAIN;
return 0; return 0;
......
...@@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel *sch) ...@@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel *sch)
struct schib schib; struct schib schib;
int ccode, retry, ret = 0; int ccode, retry, ret = 0;
if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
return -ENODEV; return -ENODEV;
for (retry = 0; retry < 5; retry++) { for (retry = 0; retry < 5; retry++) {
...@@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel *sch) ...@@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel *sch)
return ccode; return ccode;
switch (ccode) { switch (ccode) {
case 0: /* successful */ case 0: /* successful */
if (stsch(sch->schid, &schib) || if (stsch_err(sch->schid, &schib) ||
!css_sch_is_valid(&schib)) !css_sch_is_valid(&schib))
return -ENODEV; return -ENODEV;
if (cio_check_config(sch, &schib)) { if (cio_check_config(sch, &schib)) {
...@@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *sch) ...@@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *sch)
{ {
struct schib schib; struct schib schib;
if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
return -ENODEV; return -ENODEV;
memcpy(&sch->schib, &schib, sizeof(schib)); memcpy(&sch->schib, &schib, sizeof(schib));
...@@ -771,7 +771,7 @@ cio_get_console_sch_no(void) ...@@ -771,7 +771,7 @@ cio_get_console_sch_no(void)
if (console_irq != -1) { if (console_irq != -1) {
/* VM provided us with the irq number of the console. */ /* VM provided us with the irq number of the console. */
schid.sch_no = console_irq; schid.sch_no = console_irq;
if (stsch(schid, &console_subchannel.schib) != 0 || if (stsch_err(schid, &console_subchannel.schib) != 0 ||
(console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) || (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) ||
!console_subchannel.schib.pmcw.dnv) !console_subchannel.schib.pmcw.dnv)
return -1; return -1;
...@@ -863,10 +863,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) ...@@ -863,10 +863,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
cc = 0; cc = 0;
for (retry=0;retry<3;retry++) { for (retry=0;retry<3;retry++) {
schib->pmcw.ena = 0; schib->pmcw.ena = 0;
cc = msch(schid, schib); cc = msch_err(schid, schib);
if (cc) if (cc)
return (cc==3?-ENODEV:-EBUSY); return (cc==3?-ENODEV:-EBUSY);
if (stsch(schid, schib) || !css_sch_is_valid(schib)) if (stsch_err(schid, schib) || !css_sch_is_valid(schib))
return -ENODEV; return -ENODEV;
if (!schib->pmcw.ena) if (!schib->pmcw.ena)
return 0; return 0;
...@@ -913,7 +913,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr) ...@@ -913,7 +913,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr)
pgm_check_occured = 0; pgm_check_occured = 0;
s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
rc = stsch(schid, addr); rc = stsch_err(schid, addr);
s390_base_pgm_handler_fn = NULL; s390_base_pgm_handler_fn = NULL;
/* The program check handler could have changed pgm_check_occured. */ /* The program check handler could have changed pgm_check_occured. */
...@@ -950,7 +950,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) ...@@ -950,7 +950,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
/* No default clear strategy */ /* No default clear strategy */
break; break;
} }
stsch(schid, &schib); stsch_err(schid, &schib);
__disable_subchannel_easy(schid, &schib); __disable_subchannel_easy(schid, &schib);
} }
out: out:
...@@ -1086,7 +1086,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) ...@@ -1086,7 +1086,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id; schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
if (!schid.one) if (!schid.one)
return -ENODEV; return -ENODEV;
if (stsch(schid, &schib)) if (stsch_err(schid, &schib))
return -ENODEV; return -ENODEV;
if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
return -ENODEV; return -ENODEV;
......
...@@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_device *cdev) ...@@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_device *cdev)
sch = to_subchannel(cdev->dev.parent); sch = to_subchannel(cdev->dev.parent);
private = to_io_private(sch); private = to_io_private(sch);
orb = &private->orb; orb = &private->orb;
cc = stsch(sch->schid, &schib); cc = stsch_err(sch->schid, &schib);
printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
"device information:\n", get_clock()); "device information:\n", get_clock());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册