mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
[S390] Fix reboot hang on LPARs
Reboot hangs on LPARs without diag308 support. The reason for this is, that before the reboot is done, the channel subsystem is shut down. During the reset on each possible subchannel a "store subchannel" is done. This operation can end in a program check interruption, if the specified subchannel set is not implemented by the hardware. During the reset, currently we do not have a program check handler, which leads to the described kernel bug. We install now a new program check handler for the reboot code to fix this problem. Signed-off-by: Michael Holzheu <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
This commit is contained in:
parent
b3c14d0bfd
commit
a45e14148f
4 changed files with 75 additions and 3 deletions
|
|
@ -871,11 +871,32 @@ __clear_subchannel_easy(struct subchannel_id schid)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
static int pgm_check_occured;
|
||||
|
||||
static void cio_reset_pgm_check_handler(void)
|
||||
{
|
||||
pgm_check_occured = 1;
|
||||
}
|
||||
|
||||
static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
pgm_check_occured = 0;
|
||||
s390_reset_pgm_handler = cio_reset_pgm_check_handler;
|
||||
rc = stsch(schid, addr);
|
||||
s390_reset_pgm_handler = NULL;
|
||||
if (pgm_check_occured)
|
||||
return -EIO;
|
||||
else
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
|
||||
{
|
||||
struct schib schib;
|
||||
|
||||
if (stsch_err(schid, &schib))
|
||||
if (stsch_reset(schid, &schib))
|
||||
return -ENXIO;
|
||||
if (!schib.pmcw.ena)
|
||||
return 0;
|
||||
|
|
@ -972,7 +993,7 @@ static int __reipl_subchannel_match(struct subchannel_id schid, void *data)
|
|||
struct schib schib;
|
||||
struct sch_match_id *match_id = data;
|
||||
|
||||
if (stsch_err(schid, &schib))
|
||||
if (stsch_reset(schid, &schib))
|
||||
return -ENXIO;
|
||||
if (schib.pmcw.dnv &&
|
||||
(schib.pmcw.dev == match_id->devid.devno) &&
|
||||
|
|
|
|||
Loading…
Reference in a new issue