Commit b73d40c6 authored by Heiko Carstens's avatar Heiko Carstens Committed by Linus Torvalds

[PATCH] s390: instruction processing damage handling

In case of an instruction processing damage (IPD) machine check in kernel mode
the resulting action is always to stop the kernel.  This is not necessarily
the best solution since a retry of the failing instruction might succeed.  Add
logic to retry the instruction if no more than 30 instruction processing
damage checks occured in the last 5 minutes.
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 9b5dec1a
...@@ -362,12 +362,19 @@ s390_revalidate_registers(struct mci *mci) ...@@ -362,12 +362,19 @@ s390_revalidate_registers(struct mci *mci)
return kill_task; return kill_task;
} }
#define MAX_IPD_COUNT 29
#define MAX_IPD_TIME (5 * 60 * 100 * 1000) /* 5 minutes */
/* /*
* machine check handler. * machine check handler.
*/ */
void void
s390_do_machine_check(struct pt_regs *regs) s390_do_machine_check(struct pt_regs *regs)
{ {
static DEFINE_SPINLOCK(ipd_lock);
static unsigned long long last_ipd;
static int ipd_count;
unsigned long long tmp;
struct mci *mci; struct mci *mci;
struct mcck_struct *mcck; struct mcck_struct *mcck;
int umode; int umode;
...@@ -404,11 +411,27 @@ s390_do_machine_check(struct pt_regs *regs) ...@@ -404,11 +411,27 @@ s390_do_machine_check(struct pt_regs *regs)
s390_handle_damage("processing backup machine " s390_handle_damage("processing backup machine "
"check with damage."); "check with damage.");
} }
if (!umode)
s390_handle_damage("processing backup machine " /*
"check in kernel mode."); * Nullifying exigent condition, therefore we might
mcck->kill_task = 1; * retry this instruction.
mcck->mcck_code = *(unsigned long long *) mci; */
spin_lock(&ipd_lock);
tmp = get_clock();
if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME)
ipd_count++;
else
ipd_count = 1;
last_ipd = tmp;
if (ipd_count == MAX_IPD_COUNT)
s390_handle_damage("too many ipd retries.");
spin_unlock(&ipd_lock);
} }
else { else {
/* Processing damage -> stopping machine */ /* Processing damage -> stopping machine */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment