[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: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
889ee9556c
commit
8821d24cd2
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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());
|
||||||
|
Reference in New Issue
Block a user