Commit 1c8b8cf2 authored by Heiko Carstens's avatar Heiko Carstens Committed by Alexander Gordeev

s390/nmi: implement and use local_mcck_save() / local_mcck_restore()

Instead of using local_mcck_disable() / local_mcck_enable() implement and
use local_mcck_save() / local_mcck_restore() to disable machine checks, and
restoring the previous state.

The problem with using local_mcck_disable() / local_mcck_enable() is that
there is an assumption that machine checks are always enabled. While this
is currently the case the code still looks quite odd, readers need to
double check if the code is correct.

In order to increase readability save and then restore the old machine
check mask bit, instead of assuming that it must have been enabled.
Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 84e599e3
...@@ -332,14 +332,36 @@ static inline unsigned long __extract_psw(void) ...@@ -332,14 +332,36 @@ static inline unsigned long __extract_psw(void)
return (((unsigned long) reg1) << 32) | ((unsigned long) reg2); return (((unsigned long) reg1) << 32) | ((unsigned long) reg2);
} }
static inline void local_mcck_enable(void) static inline unsigned long __local_mcck_save(void)
{ {
__load_psw_mask(__extract_psw() | PSW_MASK_MCHECK); unsigned long mask = __extract_psw();
__load_psw_mask(mask & ~PSW_MASK_MCHECK);
return mask & PSW_MASK_MCHECK;
}
#define local_mcck_save(mflags) \
do { \
typecheck(unsigned long, mflags); \
mflags = __local_mcck_save(); \
} while (0)
static inline void local_mcck_restore(unsigned long mflags)
{
unsigned long mask = __extract_psw();
mask &= ~PSW_MASK_MCHECK;
__load_psw_mask(mask | mflags);
} }
static inline void local_mcck_disable(void) static inline void local_mcck_disable(void)
{ {
__load_psw_mask(__extract_psw() & ~PSW_MASK_MCHECK); __local_mcck_save();
}
static inline void local_mcck_enable(void)
{
__load_psw_mask(__extract_psw() | PSW_MASK_MCHECK);
} }
/* /*
......
...@@ -159,16 +159,17 @@ NOKPROBE_SYMBOL(s390_handle_damage); ...@@ -159,16 +159,17 @@ NOKPROBE_SYMBOL(s390_handle_damage);
void s390_handle_mcck(void) void s390_handle_mcck(void)
{ {
struct mcck_struct mcck; struct mcck_struct mcck;
unsigned long mflags;
/* /*
* Disable machine checks and get the current state of accumulated * Disable machine checks and get the current state of accumulated
* machine checks. Afterwards delete the old state and enable machine * machine checks. Afterwards delete the old state and enable machine
* checks again. * checks again.
*/ */
local_mcck_disable(); local_mcck_save(mflags);
mcck = *this_cpu_ptr(&cpu_mcck); mcck = *this_cpu_ptr(&cpu_mcck);
memset(this_cpu_ptr(&cpu_mcck), 0, sizeof(mcck)); memset(this_cpu_ptr(&cpu_mcck), 0, sizeof(mcck));
local_mcck_enable(); local_mcck_restore(mflags);
if (mcck.channel_report) if (mcck.channel_report)
crw_handle_channel_report(); crw_handle_channel_report();
......
...@@ -350,15 +350,15 @@ static noinline int unwindme_func3(struct unwindme *u) ...@@ -350,15 +350,15 @@ static noinline int unwindme_func3(struct unwindme *u)
/* This function must appear in the backtrace. */ /* This function must appear in the backtrace. */
static noinline int unwindme_func2(struct unwindme *u) static noinline int unwindme_func2(struct unwindme *u)
{ {
unsigned long flags; unsigned long flags, mflags;
int rc; int rc;
if (u->flags & UWM_SWITCH_STACK) { if (u->flags & UWM_SWITCH_STACK) {
local_irq_save(flags); local_irq_save(flags);
local_mcck_disable(); local_mcck_save(mflags);
rc = call_on_stack(1, S390_lowcore.nodat_stack, rc = call_on_stack(1, S390_lowcore.nodat_stack,
int, unwindme_func3, struct unwindme *, u); int, unwindme_func3, struct unwindme *, u);
local_mcck_enable(); local_mcck_restore(mflags);
local_irq_restore(flags); local_irq_restore(flags);
return rc; return rc;
} else { } else {
......
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