Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8821d24c authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

[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: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 889ee955
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch)
	 * since we don't have a way to clear the subchannel and
	 * cannot disable it with a request running.
	 */
	cc = stsch(sch->schid, &schib);
	cc = stsch_err(sch->schid, &schib);
	if (!cc && scsw_stctl(&schib.scsw))
		return -EAGAIN;
	return 0;
+9 −9
Original line number Diff line number Diff line
@@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel *sch)
	struct schib schib;
	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;

	for (retry = 0; retry < 5; retry++) {
@@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel *sch)
			return ccode;
		switch (ccode) {
		case 0: /* successful */
			if (stsch(sch->schid, &schib) ||
			if (stsch_err(sch->schid, &schib) ||
			    !css_sch_is_valid(&schib))
				return -ENODEV;
			if (cio_check_config(sch, &schib)) {
@@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *sch)
{
	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;

	memcpy(&sch->schib, &schib, sizeof(schib));
@@ -771,7 +771,7 @@ cio_get_console_sch_no(void)
	if (console_irq != -1) {
		/* VM provided us with the irq number of the console. */
		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.dnv)
			return -1;
@@ -863,10 +863,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
	cc = 0;
	for (retry=0;retry<3;retry++) {
		schib->pmcw.ena = 0;
		cc = msch(schid, schib);
		cc = msch_err(schid, schib);
		if (cc)
			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;
		if (!schib->pmcw.ena)
			return 0;
@@ -913,7 +913,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr)

	pgm_check_occured = 0;
	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;

	/* 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 */
			break;
		}
		stsch(schid, &schib);
		stsch_err(schid, &schib);
		__disable_subchannel_easy(schid, &schib);
	}
out:
@@ -1086,7 +1086,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
	schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
	if (!schid.one)
		return -ENODEV;
	if (stsch(schid, &schib))
	if (stsch_err(schid, &schib))
		return -ENODEV;
	if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
		return -ENODEV;
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_device *cdev)
	sch = to_subchannel(cdev->dev.parent);
	private = to_io_private(sch);
	orb = &private->orb;
	cc = stsch(sch->schid, &schib);
	cc = stsch_err(sch->schid, &schib);

	printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
	       "device information:\n", get_clock());