diff options
| author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2010-04-22 11:17:05 -0400 |
|---|---|---|
| committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-04-22 11:17:19 -0400 |
| commit | 8821d24cd261aede9b0436cd3252b17a60ccc33a (patch) | |
| tree | 66762388019bf846ea5205d9c9fd95ba364952a3 | |
| parent | 889ee9556c89a877b8343b6bbe6ac8dc5d57e433 (diff) | |
[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>
| -rw-r--r-- | drivers/s390/cio/chsc_sch.c | 2 | ||||
| -rw-r--r-- | drivers/s390/cio/cio.c | 18 | ||||
| -rw-r--r-- | drivers/s390/cio/device_fsm.c | 2 |
3 files changed, 11 insertions, 11 deletions
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 404f630c27ca..3b6f4adc5094 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c | |||
| @@ -124,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch) | |||
| 124 | * since we don't have a way to clear the subchannel and | 124 | * since we don't have a way to clear the subchannel and |
| 125 | * cannot disable it with a request running. | 125 | * cannot disable it with a request running. |
| 126 | */ | 126 | */ |
| 127 | cc = stsch(sch->schid, &schib); | 127 | cc = stsch_err(sch->schid, &schib); |
| 128 | if (!cc && scsw_stctl(&schib.scsw)) | 128 | if (!cc && scsw_stctl(&schib.scsw)) |
| 129 | return -EAGAIN; | 129 | return -EAGAIN; |
| 130 | return 0; | 130 | return 0; |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index f736cdcf08ad..5feea1a371e1 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
| @@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel *sch) | |||
| 361 | struct schib schib; | 361 | struct schib schib; |
| 362 | int ccode, retry, ret = 0; | 362 | int ccode, retry, ret = 0; |
| 363 | 363 | ||
| 364 | if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) | 364 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) |
| 365 | return -ENODEV; | 365 | return -ENODEV; |
| 366 | 366 | ||
| 367 | for (retry = 0; retry < 5; retry++) { | 367 | for (retry = 0; retry < 5; retry++) { |
| @@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel *sch) | |||
| 372 | return ccode; | 372 | return ccode; |
| 373 | switch (ccode) { | 373 | switch (ccode) { |
| 374 | case 0: /* successful */ | 374 | case 0: /* successful */ |
| 375 | if (stsch(sch->schid, &schib) || | 375 | if (stsch_err(sch->schid, &schib) || |
| 376 | !css_sch_is_valid(&schib)) | 376 | !css_sch_is_valid(&schib)) |
| 377 | return -ENODEV; | 377 | return -ENODEV; |
| 378 | if (cio_check_config(sch, &schib)) { | 378 | if (cio_check_config(sch, &schib)) { |
| @@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *sch) | |||
| 404 | { | 404 | { |
| 405 | struct schib schib; | 405 | struct schib schib; |
| 406 | 406 | ||
| 407 | if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) | 407 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) |
| 408 | return -ENODEV; | 408 | return -ENODEV; |
| 409 | 409 | ||
| 410 | memcpy(&sch->schib, &schib, sizeof(schib)); | 410 | memcpy(&sch->schib, &schib, sizeof(schib)); |
| @@ -771,7 +771,7 @@ cio_get_console_sch_no(void) | |||
| 771 | if (console_irq != -1) { | 771 | if (console_irq != -1) { |
| 772 | /* VM provided us with the irq number of the console. */ | 772 | /* VM provided us with the irq number of the console. */ |
| 773 | schid.sch_no = console_irq; | 773 | schid.sch_no = console_irq; |
| 774 | if (stsch(schid, &console_subchannel.schib) != 0 || | 774 | if (stsch_err(schid, &console_subchannel.schib) != 0 || |
| 775 | (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) || | 775 | (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) || |
| 776 | !console_subchannel.schib.pmcw.dnv) | 776 | !console_subchannel.schib.pmcw.dnv) |
| 777 | return -1; | 777 | return -1; |
| @@ -863,10 +863,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) | |||
| 863 | cc = 0; | 863 | cc = 0; |
| 864 | for (retry=0;retry<3;retry++) { | 864 | for (retry=0;retry<3;retry++) { |
| 865 | schib->pmcw.ena = 0; | 865 | schib->pmcw.ena = 0; |
| 866 | cc = msch(schid, schib); | 866 | cc = msch_err(schid, schib); |
| 867 | if (cc) | 867 | if (cc) |
| 868 | return (cc==3?-ENODEV:-EBUSY); | 868 | return (cc==3?-ENODEV:-EBUSY); |
| 869 | if (stsch(schid, schib) || !css_sch_is_valid(schib)) | 869 | if (stsch_err(schid, schib) || !css_sch_is_valid(schib)) |
| 870 | return -ENODEV; | 870 | return -ENODEV; |
| 871 | if (!schib->pmcw.ena) | 871 | if (!schib->pmcw.ena) |
| 872 | return 0; | 872 | return 0; |
| @@ -913,7 +913,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr) | |||
| 913 | 913 | ||
| 914 | pgm_check_occured = 0; | 914 | pgm_check_occured = 0; |
| 915 | s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; | 915 | s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; |
| 916 | rc = stsch(schid, addr); | 916 | rc = stsch_err(schid, addr); |
| 917 | s390_base_pgm_handler_fn = NULL; | 917 | s390_base_pgm_handler_fn = NULL; |
| 918 | 918 | ||
| 919 | /* The program check handler could have changed pgm_check_occured. */ | 919 | /* 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 | /* No default clear strategy */ | 950 | /* No default clear strategy */ |
| 951 | break; | 951 | break; |
| 952 | } | 952 | } |
| 953 | stsch(schid, &schib); | 953 | stsch_err(schid, &schib); |
| 954 | __disable_subchannel_easy(schid, &schib); | 954 | __disable_subchannel_easy(schid, &schib); |
| 955 | } | 955 | } |
| 956 | out: | 956 | out: |
| @@ -1086,7 +1086,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) | |||
| 1086 | schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id; | 1086 | schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id; |
| 1087 | if (!schid.one) | 1087 | if (!schid.one) |
| 1088 | return -ENODEV; | 1088 | return -ENODEV; |
| 1089 | if (stsch(schid, &schib)) | 1089 | if (stsch_err(schid, &schib)) |
| 1090 | return -ENODEV; | 1090 | return -ENODEV; |
| 1091 | if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) | 1091 | if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) |
| 1092 | return -ENODEV; | 1092 | return -ENODEV; |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index c56ab94612f9..c9b852647f01 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
| @@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_device *cdev) | |||
| 45 | sch = to_subchannel(cdev->dev.parent); | 45 | sch = to_subchannel(cdev->dev.parent); |
| 46 | private = to_io_private(sch); | 46 | private = to_io_private(sch); |
| 47 | orb = &private->orb; | 47 | orb = &private->orb; |
| 48 | cc = stsch(sch->schid, &schib); | 48 | cc = stsch_err(sch->schid, &schib); |
| 49 | 49 | ||
| 50 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " | 50 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " |
| 51 | "device information:\n", get_clock()); | 51 | "device information:\n", get_clock()); |
