x86, mce: fix a race condition in mce_read()
authorHuang Ying <ying.huang@intel.com>
Thu, 12 Feb 2009 12:39:34 +0000 (13:39 +0100)
committerH. Peter Anvin <hpa@linux.intel.com>
Tue, 17 Feb 2009 23:33:05 +0000 (15:33 -0800)
commitef41df4344ff952c79746d44a6126bd2cf7ed2bc
treea0756296c6f25e59a680bdc505233d611fd1f56e
parentd6b75584a3eaab8cb2ab3e8cf90c5e57c1928a85
x86, mce: fix a race condition in mce_read()

Impact: bugfix

Considering the situation as follow:

before: mcelog.next == 1, mcelog.entry[0].finished = 1

+--------------------------------------------------------------------------
R                   W1                  W2                  W3

read mcelog.next (1)
                    mcelog.next++ (2)
                    (working on entry 1,
                    finished == 0)

mcelog.next = 0
                                        mcelog.next++ (1)
                                        (working on entry 0)
                                                           mcelog.next++ (2)
                                                           (working on entry 1)
                        <----------------- race ---------------->
                    (done on entry 1,
                    finished = 1)
                                                           (done on entry 1,
                                                           finished = 1)

To fix the race condition, a cmpxchg loop is added to mce_read() to
ensure no new MCE record can be added between mcelog.next reading and
mcelog.next = 0.

Signed-off-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
arch/x86/kernel/cpu/mcheck/mce_64.c