diff options
author | Tony Luck <tony.luck@intel.com> | 2012-05-23 14:14:22 -0700 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2012-05-23 14:22:44 -0700 |
commit | 875e26648cf9b6db9d8dc07b7959d7c61fb3f49c (patch) | |
tree | 8854063a634093b107e15f79d8c8000b5541c7bd /arch/x86 | |
parent | a129a7c84582629741e5fa6f40026efcd7a65bd4 (diff) | |
download | op-kernel-dev-875e26648cf9b6db9d8dc07b7959d7c61fb3f49c.zip op-kernel-dev-875e26648cf9b6db9d8dc07b7959d7c61fb3f49c.tar.gz |
x86/mce: Fix check for processor context when machine check was taken.
Linus pointed out that there was no value is checking whether m->ip
was zero - because zero is a legimate value. If we have a reliable
(or faked in the VM86 case) "m->cs" we can use it to tell whether we
were in user mode or kernelwhen the machine check hit.
Reported-by: Linus Torvalds <torvalds@linuxfoundation.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-severity.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c index 0c82091..1ccd453 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-severity.c +++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c @@ -165,15 +165,19 @@ static struct severity { }; /* - * If the EIPV bit is set, it means the saved IP is the - * instruction which caused the MCE. + * If mcgstatus indicated that ip/cs on the stack were + * no good, then "m->cs" will be zero and we will have + * to assume the worst case (IN_KERNEL) as we actually + * have no idea what we were executing when the machine + * check hit. + * If we do have a good "m->cs" (or a faked one in the + * case we were executing in VM86 mode) we can use it to + * distinguish an exception taken in user from from one + * taken in the kernel. */ static int error_context(struct mce *m) { - if (m->mcgstatus & MCG_STATUS_EIPV) - return (m->ip && (m->cs & 3) == 3) ? IN_USER : IN_KERNEL; - /* Unknown, assume kernel */ - return IN_KERNEL; + return ((m->cs & 3) == 3) ? IN_USER : IN_KERNEL; } int mce_severity(struct mce *m, int tolerant, char **msg) |