aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2012-05-23 17:14:22 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-01 03:13:00 -0400
commit1c4f53ca32463a742583976f40444ce4485f3cf9 (patch)
tree68dcbed29e197bf61c0265d1091778bddd32f7ec /arch/x86/kernel/cpu
parentc179c9851c1b009faf3ec15b2af5042431a5a2ca (diff)
x86/mce: Fix check for processor context when machine check was taken.
commit 875e26648cf9b6db9d8dc07b7959d7c61fb3f49c upstream. 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> Signed-off-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/x86/kernel/cpu')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-severity.c16
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 1e8d66c1336..362190bd9e1 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -101,15 +101,19 @@ static struct severity {
101}; 101};
102 102
103/* 103/*
104 * If the EIPV bit is set, it means the saved IP is the 104 * If mcgstatus indicated that ip/cs on the stack were
105 * instruction which caused the MCE. 105 * no good, then "m->cs" will be zero and we will have
106 * to assume the worst case (IN_KERNEL) as we actually
107 * have no idea what we were executing when the machine
108 * check hit.
109 * If we do have a good "m->cs" (or a faked one in the
110 * case we were executing in VM86 mode) we can use it to
111 * distinguish an exception taken in user from from one
112 * taken in the kernel.
106 */ 113 */
107static int error_context(struct mce *m) 114static int error_context(struct mce *m)
108{ 115{
109 if (m->mcgstatus & MCG_STATUS_EIPV) 116 return ((m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
110 return (m->ip && (m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
111 /* Unknown, assume kernel */
112 return IN_KERNEL;
113} 117}
114 118
115int mce_severity(struct mce *a, int tolerant, char **msg) 119int mce_severity(struct mce *a, int tolerant, char **msg)