Blame view

arch/x86/kernel/cpu/mcheck/mce.c 51.5 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  /*
   * Machine check handler.
e9eee03e9   Ingo Molnar   x86, mce: clean u...
3
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
   * K8 parts Copyright 2002,2003 Andi Kleen, SuSE Labs.
d88203d1a   Thomas Gleixner   x86: whitespace c...
5
6
   * Rest from unknown author(s).
   * 2004 Andi Kleen. Rewrote most of it.
b79109c3b   Andi Kleen   x86, mce: separat...
7
8
   * Copyright 2008 Intel Corporation
   * Author: Andi Kleen
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
   */
e9eee03e9   Ingo Molnar   x86, mce: clean u...
10
11
12
13
14
15
  #include <linux/thread_info.h>
  #include <linux/capability.h>
  #include <linux/miscdevice.h>
  #include <linux/ratelimit.h>
  #include <linux/kallsyms.h>
  #include <linux/rcupdate.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
16
  #include <linux/kobject.h>
14a02530e   Hidetoshi Seto   x86, mce: trivial...
17
  #include <linux/uaccess.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
18
19
20
  #include <linux/kdebug.h>
  #include <linux/kernel.h>
  #include <linux/percpu.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  #include <linux/string.h>
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
22
  #include <linux/device.h>
f3c6ea1b0   Rafael J. Wysocki   x86: Use syscore_...
23
  #include <linux/syscore_ops.h>
3c0797925   Andi Kleen   x86, mce: switch ...
24
  #include <linux/delay.h>
8c566ef5f   Andi Kleen   [PATCH] x86-64: A...
25
  #include <linux/ctype.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
26
  #include <linux/sched.h>
0d7482e3d   Andi Kleen   x86, mce: impleme...
27
  #include <linux/sysfs.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
28
  #include <linux/types.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
29
  #include <linux/slab.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
30
31
32
  #include <linux/init.h>
  #include <linux/kmod.h>
  #include <linux/poll.h>
3c0797925   Andi Kleen   x86, mce: switch ...
33
  #include <linux/nmi.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
34
  #include <linux/cpu.h>
14a02530e   Hidetoshi Seto   x86, mce: trivial...
35
  #include <linux/smp.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
36
  #include <linux/fs.h>
9b1beaf2b   Andi Kleen   x86, mce: support...
37
  #include <linux/mm.h>
5be9ed251   Huang Ying   x86, mce: Move de...
38
  #include <linux/debugfs.h>
b77e70bf3   Hidetoshi Seto   x86, mce: Replace...
39
  #include <linux/irq_work.h>
69c60c88e   Paul Gortmaker   x86: Fix files ex...
40
  #include <linux/export.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
41

d88203d1a   Thomas Gleixner   x86: whitespace c...
42
  #include <asm/processor.h>
e9eee03e9   Ingo Molnar   x86, mce: clean u...
43
44
  #include <asm/mce.h>
  #include <asm/msr.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45

bd19a5e6b   Andi Kleen   x86, mce: check e...
46
  #include "mce-internal.h"
711c2e481   Ingo Molnar   x86, mce: unify, ...
47

93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
48
  static DEFINE_MUTEX(mce_chrdev_read_mutex);
2aa2b50dd   Ingo Molnar   x86/mce: Fix buil...
49

f56e8a076   Paul E. McKenney   x86/mce: Fix RCU ...
50
  #define rcu_dereference_check_mce(p) \
ec8c27e04   Paul E. McKenney   mce: convert to r...
51
  	rcu_dereference_index_check((p), \
f56e8a076   Paul E. McKenney   x86/mce: Fix RCU ...
52
  			      rcu_read_lock_sched_held() || \
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
53
  			      lockdep_is_held(&mce_chrdev_read_mutex))
f56e8a076   Paul E. McKenney   x86/mce: Fix RCU ...
54

8968f9d3d   Hidetoshi Seto   perf_event, x86, ...
55
56
  #define CREATE_TRACE_POINTS
  #include <trace/events/mce.h>
4e5b3e690   Hidetoshi Seto   x86, mce: add __r...
57
  int mce_disabled __read_mostly;
04b2b1a4d   Andi Kleen   x86, mce: rename ...
58

e9eee03e9   Ingo Molnar   x86, mce: clean u...
59
  #define MISC_MCELOG_MINOR	227
0d7482e3d   Andi Kleen   x86, mce: impleme...
60

3c0797925   Andi Kleen   x86, mce: switch ...
61
  #define SPINUNIT 100	/* 100ns */
553f265fe   Andi Kleen   [PATCH] x86_64: D...
62
  atomic_t mce_entry;
01ca79f14   Andi Kleen   x86, mce: add mac...
63
  DEFINE_PER_CPU(unsigned, mce_exception_count);
bd78432c8   Tim Hockin   x86_64: mcelog to...
64
65
66
67
68
69
70
  /*
   * Tolerant levels:
   *   0: always panic on uncorrected errors, log corrected errors
   *   1: panic or SIGBUS on uncorrected errors, log corrected errors
   *   2: SIGBUS or log uncorrected errors (if possible), log corrected errors
   *   3: never panic or SIGBUS, log all errors (for testing only)
   */
4e5b3e690   Hidetoshi Seto   x86, mce: add __r...
71
72
  static int			tolerant		__read_mostly = 1;
  static int			banks			__read_mostly;
4e5b3e690   Hidetoshi Seto   x86, mce: add __r...
73
74
75
76
77
78
79
80
  static int			rip_msr			__read_mostly;
  static int			mce_bootlog		__read_mostly = -1;
  static int			monarch_timeout		__read_mostly = -1;
  static int			mce_panic_timeout	__read_mostly;
  static int			mce_dont_log_ce		__read_mostly;
  int				mce_cmci_disabled	__read_mostly;
  int				mce_ignore_ce		__read_mostly;
  int				mce_ser			__read_mostly;
a98f0dd34   Andi Kleen   [PATCH] x86-64: A...
81

cebe18203   Andi Kleen   x86: mce: Move pe...
82
  struct mce_bank                *mce_banks		__read_mostly;
1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
83
84
85
86
  /* User mode helper program triggered by machine check event */
  static unsigned long		mce_need_notify;
  static char			mce_helper[128];
  static char			*mce_helper_argv[2] = { mce_helper, NULL };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87

93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
88
  static DECLARE_WAIT_QUEUE_HEAD(mce_chrdev_wait);
3c0797925   Andi Kleen   x86, mce: switch ...
89
90
  static DEFINE_PER_CPU(struct mce, mces_seen);
  static int			cpu_missing;
ee031c31d   Andi Kleen   x86, mce, cmci: u...
91
92
93
94
  /* MCA banks polled by the period polling timer for corrected events */
  DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
  	[0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL
  };
9b1beaf2b   Andi Kleen   x86, mce: support...
95
  static DEFINE_PER_CPU(struct work_struct, mce_work);
3653ada5d   Borislav Petkov   x86, mce: Add wra...
96
97
98
99
100
  /*
   * CPU/chipset specific EDAC code can register a notifier call here to print
   * MCE errors in a human-readable form.
   */
  ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain);
b5f2fa4ea   Andi Kleen   x86, mce: factor ...
101
102
103
104
  /* Do initial initialization of a struct mce */
  void mce_setup(struct mce *m)
  {
  	memset(m, 0, sizeof(struct mce));
d620c67fb   Andi Kleen   x86, mce: support...
105
  	m->cpu = m->extcpu = smp_processor_id();
b5f2fa4ea   Andi Kleen   x86, mce: factor ...
106
  	rdtscll(m->tsc);
8ee08347c   Andi Kleen   x86, mce: extend ...
107
108
109
110
  	/* We hope get_seconds stays lockless */
  	m->time = get_seconds();
  	m->cpuvendor = boot_cpu_data.x86_vendor;
  	m->cpuid = cpuid_eax(1);
8ee08347c   Andi Kleen   x86, mce: extend ...
111
  	m->socketid = cpu_data(m->extcpu).phys_proc_id;
8ee08347c   Andi Kleen   x86, mce: extend ...
112
113
  	m->apicid = cpu_data(m->extcpu).initial_apicid;
  	rdmsrl(MSR_IA32_MCG_CAP, m->mcgcap);
b5f2fa4ea   Andi Kleen   x86, mce: factor ...
114
  }
ea149b36c   Andi Kleen   x86, mce: add bas...
115
116
  DEFINE_PER_CPU(struct mce, injectm);
  EXPORT_PER_CPU_SYMBOL_GPL(injectm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
120
121
  /*
   * Lockless MCE logging infrastructure.
   * This avoids deadlocks on printk locks without having to break locks. Also
   * separate MCEs from kernel messages to avoid bogus bug reports.
   */
231fd906c   Adrian Bunk   x86 mce_64.c: mak...
122
  static struct mce_log mcelog = {
f6fb0ac08   Andi Kleen   x86, mce: store r...
123
124
125
  	.signature	= MCE_LOG_SIGNATURE,
  	.len		= MCE_LOG_LEN,
  	.recordlen	= sizeof(struct mce),
d88203d1a   Thomas Gleixner   x86: whitespace c...
126
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
130
  
  void mce_log(struct mce *mce)
  {
  	unsigned next, entry;
f0cb54524   Borislav Petkov   x86, MCE: Use not...
131
  	int ret = 0;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
132

8968f9d3d   Hidetoshi Seto   perf_event, x86, ...
133
134
  	/* Emit the trace record: */
  	trace_mce_record(mce);
f0cb54524   Borislav Petkov   x86, MCE: Use not...
135
136
137
  	ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
  	if (ret == NOTIFY_STOP)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
  	mce->finished = 0;
7644143cd   Mike Waychison   [PATCH] x86_64: F...
139
  	wmb();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  	for (;;) {
f56e8a076   Paul E. McKenney   x86/mce: Fix RCU ...
141
  		entry = rcu_dereference_check_mce(mcelog.next);
673242c10   Andi Kleen   [PATCH] x86-64: M...
142
  		for (;;) {
696e409db   Mauro Carvalho Chehab   edac_mce: Add an ...
143
144
  
  			/*
e9eee03e9   Ingo Molnar   x86, mce: clean u...
145
146
147
148
  			 * When the buffer fills up discard new entries.
  			 * Assume that the earlier errors are the more
  			 * interesting ones:
  			 */
673242c10   Andi Kleen   [PATCH] x86-64: M...
149
  			if (entry >= MCE_LOG_LEN) {
14a02530e   Hidetoshi Seto   x86, mce: trivial...
150
151
  				set_bit(MCE_OVERFLOW,
  					(unsigned long *)&mcelog.flags);
673242c10   Andi Kleen   [PATCH] x86-64: M...
152
153
  				return;
  			}
e9eee03e9   Ingo Molnar   x86, mce: clean u...
154
  			/* Old left over entry. Skip: */
673242c10   Andi Kleen   [PATCH] x86-64: M...
155
156
157
158
  			if (mcelog.entry[entry].finished) {
  				entry++;
  				continue;
  			}
7644143cd   Mike Waychison   [PATCH] x86_64: F...
159
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
164
165
166
  		smp_rmb();
  		next = entry + 1;
  		if (cmpxchg(&mcelog.next, entry, next) == entry)
  			break;
  	}
  	memcpy(mcelog.entry + entry, mce, sizeof(struct mce));
7644143cd   Mike Waychison   [PATCH] x86_64: F...
167
  	wmb();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  	mcelog.entry[entry].finished = 1;
7644143cd   Mike Waychison   [PATCH] x86_64: F...
169
  	wmb();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170

a0189c70e   Andi Kleen   x86, mce: remove ...
171
  	mce->finished = 1;
1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
172
  	set_bit(0, &mce_need_notify);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  }
093719571   Borislav Petkov   x86, MCE: Drain m...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  static void drain_mcelog_buffer(void)
  {
  	unsigned int next, i, prev = 0;
  
  	next = rcu_dereference_check_mce(mcelog.next);
  
  	do {
  		struct mce *m;
  
  		/* drain what was logged during boot */
  		for (i = prev; i < next; i++) {
  			unsigned long start = jiffies;
  			unsigned retries = 1;
  
  			m = &mcelog.entry[i];
  
  			while (!m->finished) {
  				if (time_after_eq(jiffies, start + 2*retries))
  					retries++;
  
  				cpu_relax();
  
  				if (!m->finished && retries >= 4) {
  					pr_err("MCE: skipping error being logged currently!
  ");
  					break;
  				}
  			}
  			smp_rmb();
  			atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
  		}
  
  		memset(mcelog.entry + prev, 0, (next - prev) * sizeof(*m));
  		prev = next;
  		next = cmpxchg(&mcelog.next, prev, 0);
  	} while (next != prev);
  }
3653ada5d   Borislav Petkov   x86, mce: Add wra...
211
212
213
  void mce_register_decode_chain(struct notifier_block *nb)
  {
  	atomic_notifier_chain_register(&x86_mce_decoder_chain, nb);
093719571   Borislav Petkov   x86, MCE: Drain m...
214
  	drain_mcelog_buffer();
3653ada5d   Borislav Petkov   x86, mce: Add wra...
215
216
217
218
219
220
221
222
  }
  EXPORT_SYMBOL_GPL(mce_register_decode_chain);
  
  void mce_unregister_decode_chain(struct notifier_block *nb)
  {
  	atomic_notifier_chain_unregister(&x86_mce_decoder_chain, nb);
  }
  EXPORT_SYMBOL_GPL(mce_unregister_decode_chain);
77e26cca2   Hidetoshi Seto   x86, mce: Fix mce...
223
  static void print_mce(struct mce *m)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
  {
dffa4b2f6   Borislav Petkov   x86, mce: Drop th...
225
  	int ret = 0;
a2d7b0d48   Huang Ying   x86, mce: Use HW_...
226
227
  	pr_emerg(HW_ERR "CPU %d: Machine Check Exception: %Lx Bank %d: %016Lx
  ",
d620c67fb   Andi Kleen   x86, mce: support...
228
  	       m->extcpu, m->mcgstatus, m->bank, m->status);
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
229

65ea5b034   H. Peter Anvin   x86: rename the s...
230
  	if (m->ip) {
a2d7b0d48   Huang Ying   x86, mce: Use HW_...
231
  		pr_emerg(HW_ERR "RIP%s %02x:<%016Lx> ",
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
232
233
  			!(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
  				m->cs, m->ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  		if (m->cs == __KERNEL_CS)
65ea5b034   H. Peter Anvin   x86: rename the s...
235
  			print_symbol("{%s}", m->ip);
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
236
237
  		pr_cont("
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
  	}
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
239

a2d7b0d48   Huang Ying   x86, mce: Use HW_...
240
  	pr_emerg(HW_ERR "TSC %llx ", m->tsc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
  	if (m->addr)
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
242
  		pr_cont("ADDR %llx ", m->addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  	if (m->misc)
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
244
  		pr_cont("MISC %llx ", m->misc);
549d042df   Borislav Petkov   x86, mce: pass mc...
245

f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
246
247
  	pr_cont("
  ");
506ed6b53   Andi Kleen   x86, intel: Outpu...
248
249
250
251
  	/*
  	 * Note this output is parsed by external tools and old fields
  	 * should not be changed.
  	 */
881e23e56   Borislav Petkov   x86, microcode: C...
252
253
  	pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x microcode %x
  ",
506ed6b53   Andi Kleen   x86, intel: Outpu...
254
255
  		m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid,
  		cpu_data(m->extcpu).microcode);
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
256
257
258
  
  	/*
  	 * Print out human-readable details about the MCE error,
fb2531953   Borislav Petkov   mce, edac: Use an...
259
  	 * (if the CPU has an implementation for that)
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
260
  	 */
dffa4b2f6   Borislav Petkov   x86, mce: Drop th...
261
262
263
264
265
266
  	ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
  	if (ret == NOTIFY_STOP)
  		return;
  
  	pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog --ascii'
  ");
86503560e   Andi Kleen   x86, mce: print h...
267
  }
f94b61c2c   Andi Kleen   x86, mce: impleme...
268
269
270
  #define PANIC_TIMEOUT 5 /* 5 seconds */
  
  static atomic_t mce_paniced;
bf783f9f7   Huang Ying   x86, mce: Fake pa...
271
272
  static int fake_panic;
  static atomic_t mce_fake_paniced;
f94b61c2c   Andi Kleen   x86, mce: impleme...
273
274
275
276
  /* Panic in progress. Enable interrupts and wait for final IPI */
  static void wait_for_panic(void)
  {
  	long timeout = PANIC_TIMEOUT*USEC_PER_SEC;
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
277

f94b61c2c   Andi Kleen   x86, mce: impleme...
278
279
280
281
  	preempt_disable();
  	local_irq_enable();
  	while (timeout-- > 0)
  		udelay(1);
29b0f591d   Andi Kleen   x86, mce: default...
282
283
  	if (panic_timeout == 0)
  		panic_timeout = mce_panic_timeout;
f94b61c2c   Andi Kleen   x86, mce: impleme...
284
285
  	panic("Panicing machine check CPU died");
  }
bd19a5e6b   Andi Kleen   x86, mce: check e...
286
  static void mce_panic(char *msg, struct mce *final, char *exp)
d88203d1a   Thomas Gleixner   x86: whitespace c...
287
  {
482908b49   Huang Ying   ACPI, APEI, Use E...
288
  	int i, apei_err = 0;
e02e68d31   Tim Hockin   x86_64: support p...
289

bf783f9f7   Huang Ying   x86, mce: Fake pa...
290
291
292
293
294
295
296
  	if (!fake_panic) {
  		/*
  		 * Make sure only one CPU runs in machine check panic
  		 */
  		if (atomic_inc_return(&mce_paniced) > 1)
  			wait_for_panic();
  		barrier();
f94b61c2c   Andi Kleen   x86, mce: impleme...
297

bf783f9f7   Huang Ying   x86, mce: Fake pa...
298
299
300
301
302
303
304
  		bust_spinlocks(1);
  		console_verbose();
  	} else {
  		/* Don't log too much for fake panic */
  		if (atomic_inc_return(&mce_fake_paniced) > 1)
  			return;
  	}
a0189c70e   Andi Kleen   x86, mce: remove ...
305
  	/* First print corrected ones that are still unlogged */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
  	for (i = 0; i < MCE_LOG_LEN; i++) {
a0189c70e   Andi Kleen   x86, mce: remove ...
307
  		struct mce *m = &mcelog.entry[i];
77e26cca2   Hidetoshi Seto   x86, mce: Fix mce...
308
309
  		if (!(m->status & MCI_STATUS_VAL))
  			continue;
482908b49   Huang Ying   ACPI, APEI, Use E...
310
  		if (!(m->status & MCI_STATUS_UC)) {
77e26cca2   Hidetoshi Seto   x86, mce: Fix mce...
311
  			print_mce(m);
482908b49   Huang Ying   ACPI, APEI, Use E...
312
313
314
  			if (!apei_err)
  				apei_err = apei_write_mce(m);
  		}
a0189c70e   Andi Kleen   x86, mce: remove ...
315
316
317
318
319
  	}
  	/* Now print uncorrected but with the final one last */
  	for (i = 0; i < MCE_LOG_LEN; i++) {
  		struct mce *m = &mcelog.entry[i];
  		if (!(m->status & MCI_STATUS_VAL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  			continue;
77e26cca2   Hidetoshi Seto   x86, mce: Fix mce...
321
322
  		if (!(m->status & MCI_STATUS_UC))
  			continue;
482908b49   Huang Ying   ACPI, APEI, Use E...
323
  		if (!final || memcmp(m, final, sizeof(struct mce))) {
77e26cca2   Hidetoshi Seto   x86, mce: Fix mce...
324
  			print_mce(m);
482908b49   Huang Ying   ACPI, APEI, Use E...
325
326
327
  			if (!apei_err)
  				apei_err = apei_write_mce(m);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  	}
482908b49   Huang Ying   ACPI, APEI, Use E...
329
  	if (final) {
77e26cca2   Hidetoshi Seto   x86, mce: Fix mce...
330
  		print_mce(final);
482908b49   Huang Ying   ACPI, APEI, Use E...
331
332
333
  		if (!apei_err)
  			apei_err = apei_write_mce(final);
  	}
3c0797925   Andi Kleen   x86, mce: switch ...
334
  	if (cpu_missing)
a2d7b0d48   Huang Ying   x86, mce: Use HW_...
335
336
  		pr_emerg(HW_ERR "Some CPUs didn't answer in synchronization
  ");
bd19a5e6b   Andi Kleen   x86, mce: check e...
337
  	if (exp)
a2d7b0d48   Huang Ying   x86, mce: Use HW_...
338
339
  		pr_emerg(HW_ERR "Machine check: %s
  ", exp);
bf783f9f7   Huang Ying   x86, mce: Fake pa...
340
341
342
343
344
  	if (!fake_panic) {
  		if (panic_timeout == 0)
  			panic_timeout = mce_panic_timeout;
  		panic(msg);
  	} else
a2d7b0d48   Huang Ying   x86, mce: Use HW_...
345
346
  		pr_emerg(HW_ERR "Fake kernel panic: %s
  ", msg);
d88203d1a   Thomas Gleixner   x86: whitespace c...
347
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348

ea149b36c   Andi Kleen   x86, mce: add bas...
349
350
351
352
  /* Support code for software error injection */
  
  static int msr_to_offset(u32 msr)
  {
0a3aee0da   Tejun Heo   x86: Use this_cpu...
353
  	unsigned bank = __this_cpu_read(injectm.bank);
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
354

ea149b36c   Andi Kleen   x86, mce: add bas...
355
356
  	if (msr == rip_msr)
  		return offsetof(struct mce, ip);
a2d32bcbc   Andi Kleen   x86: mce: macros ...
357
  	if (msr == MSR_IA32_MCx_STATUS(bank))
ea149b36c   Andi Kleen   x86, mce: add bas...
358
  		return offsetof(struct mce, status);
a2d32bcbc   Andi Kleen   x86: mce: macros ...
359
  	if (msr == MSR_IA32_MCx_ADDR(bank))
ea149b36c   Andi Kleen   x86, mce: add bas...
360
  		return offsetof(struct mce, addr);
a2d32bcbc   Andi Kleen   x86: mce: macros ...
361
  	if (msr == MSR_IA32_MCx_MISC(bank))
ea149b36c   Andi Kleen   x86, mce: add bas...
362
363
364
365
366
  		return offsetof(struct mce, misc);
  	if (msr == MSR_IA32_MCG_STATUS)
  		return offsetof(struct mce, mcgstatus);
  	return -1;
  }
5f8c1a54c   Andi Kleen   x86, mce: add MSR...
367
368
369
370
  /* MSR access wrappers used for error injection */
  static u64 mce_rdmsrl(u32 msr)
  {
  	u64 v;
11868a2dc   Ingo Molnar   x86: mce: Use saf...
371

0a3aee0da   Tejun Heo   x86: Use this_cpu...
372
  	if (__this_cpu_read(injectm.finished)) {
ea149b36c   Andi Kleen   x86, mce: add bas...
373
  		int offset = msr_to_offset(msr);
11868a2dc   Ingo Molnar   x86: mce: Use saf...
374

ea149b36c   Andi Kleen   x86, mce: add bas...
375
376
377
378
  		if (offset < 0)
  			return 0;
  		return *(u64 *)((char *)&__get_cpu_var(injectm) + offset);
  	}
11868a2dc   Ingo Molnar   x86: mce: Use saf...
379
380
381
382
383
384
385
386
387
388
389
  
  	if (rdmsrl_safe(msr, &v)) {
  		WARN_ONCE(1, "mce: Unable to read msr %d!
  ", msr);
  		/*
  		 * Return zero in case the access faulted. This should
  		 * not happen normally but can happen if the CPU does
  		 * something weird, or if the code is buggy.
  		 */
  		v = 0;
  	}
5f8c1a54c   Andi Kleen   x86, mce: add MSR...
390
391
392
393
394
  	return v;
  }
  
  static void mce_wrmsrl(u32 msr, u64 v)
  {
0a3aee0da   Tejun Heo   x86: Use this_cpu...
395
  	if (__this_cpu_read(injectm.finished)) {
ea149b36c   Andi Kleen   x86, mce: add bas...
396
  		int offset = msr_to_offset(msr);
11868a2dc   Ingo Molnar   x86: mce: Use saf...
397

ea149b36c   Andi Kleen   x86, mce: add bas...
398
399
400
401
  		if (offset >= 0)
  			*(u64 *)((char *)&__get_cpu_var(injectm) + offset) = v;
  		return;
  	}
5f8c1a54c   Andi Kleen   x86, mce: add MSR...
402
403
  	wrmsrl(msr, v);
  }
9b1beaf2b   Andi Kleen   x86, mce: support...
404
  /*
b8325c5b1   Hidetoshi Seto   x86, mce: Introdu...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
   * Collect all global (w.r.t. this processor) status about this machine
   * check into our "mce" struct so that we can use it later to assess
   * the severity of the problem as we read per-bank specific details.
   */
  static inline void mce_gather_info(struct mce *m, struct pt_regs *regs)
  {
  	mce_setup(m);
  
  	m->mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS);
  	if (regs) {
  		/*
  		 * Get the address of the instruction at the time of
  		 * the machine check error.
  		 */
  		if (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) {
  			m->ip = regs->ip;
  			m->cs = regs->cs;
  		}
  		/* Use accurate RIP reporting if available. */
  		if (rip_msr)
  			m->ip = mce_rdmsrl(rip_msr);
  	}
  }
  
  /*
9b1beaf2b   Andi Kleen   x86, mce: support...
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
   * Simple lockless ring to communicate PFNs from the exception handler with the
   * process context work function. This is vastly simplified because there's
   * only a single reader and a single writer.
   */
  #define MCE_RING_SIZE 16	/* we use one entry less */
  
  struct mce_ring {
  	unsigned short start;
  	unsigned short end;
  	unsigned long ring[MCE_RING_SIZE];
  };
  static DEFINE_PER_CPU(struct mce_ring, mce_ring);
  
  /* Runs with CPU affinity in workqueue */
  static int mce_ring_empty(void)
  {
  	struct mce_ring *r = &__get_cpu_var(mce_ring);
  
  	return r->start == r->end;
  }
  
  static int mce_ring_get(unsigned long *pfn)
  {
  	struct mce_ring *r;
  	int ret = 0;
  
  	*pfn = 0;
  	get_cpu();
  	r = &__get_cpu_var(mce_ring);
  	if (r->start == r->end)
  		goto out;
  	*pfn = r->ring[r->start];
  	r->start = (r->start + 1) % MCE_RING_SIZE;
  	ret = 1;
  out:
  	put_cpu();
  	return ret;
  }
  
  /* Always runs in MCE context with preempt off */
  static int mce_ring_add(unsigned long pfn)
  {
  	struct mce_ring *r = &__get_cpu_var(mce_ring);
  	unsigned next;
  
  	next = (r->end + 1) % MCE_RING_SIZE;
  	if (next == r->start)
  		return -1;
  	r->ring[r->end] = pfn;
  	wmb();
  	r->end = next;
  	return 0;
  }
88ccbedd9   Andi Kleen   x86, mce, cmci: a...
483
  int mce_available(struct cpuinfo_x86 *c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  {
04b2b1a4d   Andi Kleen   x86, mce: rename ...
485
  	if (mce_disabled)
5b4408fda   Andi Kleen   x86, mce: don't s...
486
  		return 0;
3d1712c91   Akinobu Mita   [PATCH] x86_64: {...
487
  	return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
  }
9b1beaf2b   Andi Kleen   x86, mce: support...
489
490
491
492
493
494
495
496
  static void mce_schedule_work(void)
  {
  	if (!mce_ring_empty()) {
  		struct work_struct *work = &__get_cpu_var(mce_work);
  		if (!work_pending(work))
  			schedule_work(work);
  	}
  }
b77e70bf3   Hidetoshi Seto   x86, mce: Replace...
497
498
499
  DEFINE_PER_CPU(struct irq_work, mce_irq_work);
  
  static void mce_irq_work_cb(struct irq_work *entry)
ccc3c3192   Andi Kleen   x86, mce: impleme...
500
  {
9ff36ee96   Andi Kleen   x86, mce: rename ...
501
  	mce_notify_irq();
9b1beaf2b   Andi Kleen   x86, mce: support...
502
  	mce_schedule_work();
ccc3c3192   Andi Kleen   x86, mce: impleme...
503
  }
ccc3c3192   Andi Kleen   x86, mce: impleme...
504
505
506
507
  
  static void mce_report_event(struct pt_regs *regs)
  {
  	if (regs->flags & (X86_VM_MASK|X86_EFLAGS_IF)) {
9ff36ee96   Andi Kleen   x86, mce: rename ...
508
  		mce_notify_irq();
9b1beaf2b   Andi Kleen   x86, mce: support...
509
510
511
512
513
514
515
  		/*
  		 * Triggering the work queue here is just an insurance
  		 * policy in case the syscall exit notify handler
  		 * doesn't run soon enough or ends up running on the
  		 * wrong CPU (can happen when audit sleeps)
  		 */
  		mce_schedule_work();
ccc3c3192   Andi Kleen   x86, mce: impleme...
516
517
  		return;
  	}
b77e70bf3   Hidetoshi Seto   x86, mce: Replace...
518
  	irq_work_queue(&__get_cpu_var(mce_irq_work));
ccc3c3192   Andi Kleen   x86, mce: impleme...
519
  }
ca84f6969   Andi Kleen   x86, mce: add MCE...
520
  DEFINE_PER_CPU(unsigned, mce_poll_count);
d88203d1a   Thomas Gleixner   x86: whitespace c...
521
  /*
b79109c3b   Andi Kleen   x86, mce: separat...
522
523
524
525
   * Poll for corrected events or events that happened before reset.
   * Those are just logged through /dev/mcelog.
   *
   * This is executed in standard interrupt context.
ed7290d0e   Andi Kleen   x86, mce: impleme...
526
527
528
529
530
531
532
533
534
   *
   * Note: spec recommends to panic for fatal unsignalled
   * errors here. However this would be quite problematic --
   * we would need to reimplement the Monarch handling and
   * it would mess up the exclusion between exception handler
   * and poll hander -- * so we skip this for now.
   * These cases should not happen anyways, or only when the CPU
   * is already totally * confused. In this case it's likely it will
   * not fully execute the machine check handler either.
b79109c3b   Andi Kleen   x86, mce: separat...
535
   */
ee031c31d   Andi Kleen   x86, mce, cmci: u...
536
  void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
b79109c3b   Andi Kleen   x86, mce: separat...
537
538
539
  {
  	struct mce m;
  	int i;
402af0d7c   Jan Beulich   x86, asm: Introdu...
540
  	percpu_inc(mce_poll_count);
ca84f6969   Andi Kleen   x86, mce: add MCE...
541

b8325c5b1   Hidetoshi Seto   x86, mce: Introdu...
542
  	mce_gather_info(&m, NULL);
b79109c3b   Andi Kleen   x86, mce: separat...
543

b79109c3b   Andi Kleen   x86, mce: separat...
544
  	for (i = 0; i < banks; i++) {
cebe18203   Andi Kleen   x86: mce: Move pe...
545
  		if (!mce_banks[i].ctl || !test_bit(i, *b))
b79109c3b   Andi Kleen   x86, mce: separat...
546
547
548
549
550
551
552
553
  			continue;
  
  		m.misc = 0;
  		m.addr = 0;
  		m.bank = i;
  		m.tsc = 0;
  
  		barrier();
a2d32bcbc   Andi Kleen   x86: mce: macros ...
554
  		m.status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
b79109c3b   Andi Kleen   x86, mce: separat...
555
556
557
558
  		if (!(m.status & MCI_STATUS_VAL))
  			continue;
  
  		/*
ed7290d0e   Andi Kleen   x86, mce: impleme...
559
560
  		 * Uncorrected or signalled events are handled by the exception
  		 * handler when it is enabled, so don't process those here.
b79109c3b   Andi Kleen   x86, mce: separat...
561
562
563
  		 *
  		 * TBD do the same check for MCI_STATUS_EN here?
  		 */
ed7290d0e   Andi Kleen   x86, mce: impleme...
564
565
  		if (!(flags & MCP_UC) &&
  		    (m.status & (mce_ser ? MCI_STATUS_S : MCI_STATUS_UC)))
b79109c3b   Andi Kleen   x86, mce: separat...
566
567
568
  			continue;
  
  		if (m.status & MCI_STATUS_MISCV)
a2d32bcbc   Andi Kleen   x86: mce: macros ...
569
  			m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
b79109c3b   Andi Kleen   x86, mce: separat...
570
  		if (m.status & MCI_STATUS_ADDRV)
a2d32bcbc   Andi Kleen   x86: mce: macros ...
571
  			m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
b79109c3b   Andi Kleen   x86, mce: separat...
572
573
574
575
576
577
578
  
  		if (!(flags & MCP_TIMESTAMP))
  			m.tsc = 0;
  		/*
  		 * Don't get the IP here because it's unlikely to
  		 * have anything to do with the actual error location.
  		 */
f0cb54524   Borislav Petkov   x86, MCE: Use not...
579
  		if (!(flags & MCP_DONTLOG) && !mce_dont_log_ce)
5679af4c1   Andi Kleen   x86, mce: fix boo...
580
  			mce_log(&m);
b79109c3b   Andi Kleen   x86, mce: separat...
581
582
583
584
  
  		/*
  		 * Clear state for this bank.
  		 */
a2d32bcbc   Andi Kleen   x86: mce: macros ...
585
  		mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
b79109c3b   Andi Kleen   x86, mce: separat...
586
587
588
589
590
591
  	}
  
  	/*
  	 * Don't clear MCG_STATUS here because it's only defined for
  	 * exceptions.
  	 */
88921be30   Andi Kleen   x86, mce: synchro...
592
593
  
  	sync_core();
b79109c3b   Andi Kleen   x86, mce: separat...
594
  }
ea149b36c   Andi Kleen   x86, mce: add bas...
595
  EXPORT_SYMBOL_GPL(machine_check_poll);
b79109c3b   Andi Kleen   x86, mce: separat...
596
597
  
  /*
bd19a5e6b   Andi Kleen   x86, mce: check e...
598
599
600
601
602
603
604
605
   * Do a quick check if any of the events requires a panic.
   * This decides if we keep the events around or clear them.
   */
  static int mce_no_way_out(struct mce *m, char **msg)
  {
  	int i;
  
  	for (i = 0; i < banks; i++) {
a2d32bcbc   Andi Kleen   x86: mce: macros ...
606
  		m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
bd19a5e6b   Andi Kleen   x86, mce: check e...
607
608
609
610
611
612
613
  		if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY)
  			return 1;
  	}
  	return 0;
  }
  
  /*
3c0797925   Andi Kleen   x86, mce: switch ...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
   * Variable to establish order between CPUs while scanning.
   * Each CPU spins initially until executing is equal its number.
   */
  static atomic_t mce_executing;
  
  /*
   * Defines order of CPUs on entry. First CPU becomes Monarch.
   */
  static atomic_t mce_callin;
  
  /*
   * Check if a timeout waiting for other CPUs happened.
   */
  static int mce_timed_out(u64 *t)
  {
  	/*
  	 * The others already did panic for some reason.
  	 * Bail out like in a timeout.
  	 * rmb() to tell the compiler that system_state
  	 * might have been modified by someone else.
  	 */
  	rmb();
  	if (atomic_read(&mce_paniced))
  		wait_for_panic();
  	if (!monarch_timeout)
  		goto out;
  	if ((s64)*t < SPINUNIT) {
  		/* CHECKME: Make panic default for 1 too? */
  		if (tolerant < 1)
  			mce_panic("Timeout synchronizing machine check over CPUs",
  				  NULL, NULL);
  		cpu_missing = 1;
  		return 1;
  	}
  	*t -= SPINUNIT;
  out:
  	touch_nmi_watchdog();
  	return 0;
  }
  
  /*
   * The Monarch's reign.  The Monarch is the CPU who entered
   * the machine check handler first. It waits for the others to
   * raise the exception too and then grades them. When any
   * error is fatal panic. Only then let the others continue.
   *
   * The other CPUs entering the MCE handler will be controlled by the
   * Monarch. They are called Subjects.
   *
   * This way we prevent any potential data corruption in a unrecoverable case
   * and also makes sure always all CPU's errors are examined.
   *
680b6cfd3   Hidetoshi Seto   x86, mce: CE in l...
666
   * Also this detects the case of a machine check event coming from outer
3c0797925   Andi Kleen   x86, mce: switch ...
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
   * space (not detected by any CPUs) In this case some external agent wants
   * us to shut down, so panic too.
   *
   * The other CPUs might still decide to panic if the handler happens
   * in a unrecoverable place, but in this case the system is in a semi-stable
   * state and won't corrupt anything by itself. It's ok to let the others
   * continue for a bit first.
   *
   * All the spin loops have timeouts; when a timeout happens a CPU
   * typically elects itself to be Monarch.
   */
  static void mce_reign(void)
  {
  	int cpu;
  	struct mce *m = NULL;
  	int global_worst = 0;
  	char *msg = NULL;
  	char *nmsg = NULL;
  
  	/*
  	 * This CPU is the Monarch and the other CPUs have run
  	 * through their handlers.
  	 * Grade the severity of the errors of all the CPUs.
  	 */
  	for_each_possible_cpu(cpu) {
  		int severity = mce_severity(&per_cpu(mces_seen, cpu), tolerant,
  					    &nmsg);
  		if (severity > global_worst) {
  			msg = nmsg;
  			global_worst = severity;
  			m = &per_cpu(mces_seen, cpu);
  		}
  	}
  
  	/*
  	 * Cannot recover? Panic here then.
  	 * This dumps all the mces in the log buffer and stops the
  	 * other CPUs.
  	 */
  	if (m && global_worst >= MCE_PANIC_SEVERITY && tolerant < 3)
ac9603754   Andi Kleen   x86, mce: make no...
707
  		mce_panic("Fatal Machine check", m, msg);
3c0797925   Andi Kleen   x86, mce: switch ...
708
709
710
711
712
713
714
715
716
717
718
  
  	/*
  	 * For UC somewhere we let the CPU who detects it handle it.
  	 * Also must let continue the others, otherwise the handling
  	 * CPU could deadlock on a lock.
  	 */
  
  	/*
  	 * No machine check event found. Must be some external
  	 * source or one CPU is hung. Panic.
  	 */
680b6cfd3   Hidetoshi Seto   x86, mce: CE in l...
719
  	if (global_worst <= MCE_KEEP_SEVERITY && tolerant < 3)
3c0797925   Andi Kleen   x86, mce: switch ...
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
  		mce_panic("Machine check from unknown source", NULL, NULL);
  
  	/*
  	 * Now clear all the mces_seen so that they don't reappear on
  	 * the next mce.
  	 */
  	for_each_possible_cpu(cpu)
  		memset(&per_cpu(mces_seen, cpu), 0, sizeof(struct mce));
  }
  
  static atomic_t global_nwo;
  
  /*
   * Start of Monarch synchronization. This waits until all CPUs have
   * entered the exception handler and then determines if any of them
   * saw a fatal event that requires panic. Then it executes them
   * in the entry order.
   * TBD double check parallel CPU hotunplug
   */
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
739
  static int mce_start(int *no_way_out)
3c0797925   Andi Kleen   x86, mce: switch ...
740
  {
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
741
  	int order;
3c0797925   Andi Kleen   x86, mce: switch ...
742
743
  	int cpus = num_online_cpus();
  	u64 timeout = (u64)monarch_timeout * NSEC_PER_USEC;
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
744
745
  	if (!timeout)
  		return -1;
3c0797925   Andi Kleen   x86, mce: switch ...
746

7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
747
  	atomic_add(*no_way_out, &global_nwo);
184e1fdfe   Huang Ying   x86, mce: fix a r...
748
749
750
751
  	/*
  	 * global_nwo should be updated before mce_callin
  	 */
  	smp_wmb();
a95436e44   Borislav Petkov   x86, mce: use ato...
752
  	order = atomic_inc_return(&mce_callin);
3c0797925   Andi Kleen   x86, mce: switch ...
753
754
755
756
757
758
759
  
  	/*
  	 * Wait for everyone.
  	 */
  	while (atomic_read(&mce_callin) != cpus) {
  		if (mce_timed_out(&timeout)) {
  			atomic_set(&global_nwo, 0);
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
760
  			return -1;
3c0797925   Andi Kleen   x86, mce: switch ...
761
762
763
764
765
  		}
  		ndelay(SPINUNIT);
  	}
  
  	/*
184e1fdfe   Huang Ying   x86, mce: fix a r...
766
767
768
  	 * mce_callin should be read before global_nwo
  	 */
  	smp_rmb();
3c0797925   Andi Kleen   x86, mce: switch ...
769

7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
770
771
772
773
  	if (order == 1) {
  		/*
  		 * Monarch: Starts executing now, the others wait.
  		 */
3c0797925   Andi Kleen   x86, mce: switch ...
774
  		atomic_set(&mce_executing, 1);
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
775
776
777
778
779
780
781
782
783
784
785
786
787
788
  	} else {
  		/*
  		 * Subject: Now start the scanning loop one by one in
  		 * the original callin order.
  		 * This way when there are any shared banks it will be
  		 * only seen by one CPU before cleared, avoiding duplicates.
  		 */
  		while (atomic_read(&mce_executing) < order) {
  			if (mce_timed_out(&timeout)) {
  				atomic_set(&global_nwo, 0);
  				return -1;
  			}
  			ndelay(SPINUNIT);
  		}
3c0797925   Andi Kleen   x86, mce: switch ...
789
790
791
  	}
  
  	/*
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
792
  	 * Cache the global no_way_out state.
3c0797925   Andi Kleen   x86, mce: switch ...
793
  	 */
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
794
795
796
  	*no_way_out = atomic_read(&global_nwo);
  
  	return order;
3c0797925   Andi Kleen   x86, mce: switch ...
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
  }
  
  /*
   * Synchronize between CPUs after main scanning loop.
   * This invokes the bulk of the Monarch processing.
   */
  static int mce_end(int order)
  {
  	int ret = -1;
  	u64 timeout = (u64)monarch_timeout * NSEC_PER_USEC;
  
  	if (!timeout)
  		goto reset;
  	if (order < 0)
  		goto reset;
  
  	/*
  	 * Allow others to run.
  	 */
  	atomic_inc(&mce_executing);
  
  	if (order == 1) {
  		/* CHECKME: Can this race with a parallel hotplug? */
  		int cpus = num_online_cpus();
  
  		/*
  		 * Monarch: Wait for everyone to go through their scanning
  		 * loops.
  		 */
  		while (atomic_read(&mce_executing) <= cpus) {
  			if (mce_timed_out(&timeout))
  				goto reset;
  			ndelay(SPINUNIT);
  		}
  
  		mce_reign();
  		barrier();
  		ret = 0;
  	} else {
  		/*
  		 * Subject: Wait for Monarch to finish.
  		 */
  		while (atomic_read(&mce_executing) != 0) {
  			if (mce_timed_out(&timeout))
  				goto reset;
  			ndelay(SPINUNIT);
  		}
  
  		/*
  		 * Don't reset anything. That's done by the Monarch.
  		 */
  		return 0;
  	}
  
  	/*
  	 * Reset all global state.
  	 */
  reset:
  	atomic_set(&global_nwo, 0);
  	atomic_set(&mce_callin, 0);
  	barrier();
  
  	/*
  	 * Let others run again.
  	 */
  	atomic_set(&mce_executing, 0);
  	return ret;
  }
9b1beaf2b   Andi Kleen   x86, mce: support...
865
866
867
868
  /*
   * Check if the address reported by the CPU is in a format we can parse.
   * It would be possible to add code for most other cases, but all would
   * be somewhat complicated (e.g. segment offset would require an instruction
0d2eb44f6   Lucas De Marchi   x86: Fix common m...
869
   * parser). So only support physical addresses up to page granuality for now.
9b1beaf2b   Andi Kleen   x86, mce: support...
870
871
872
873
874
   */
  static int mce_usable_address(struct mce *m)
  {
  	if (!(m->status & MCI_STATUS_MISCV) || !(m->status & MCI_STATUS_ADDRV))
  		return 0;
2b90e77ea   Hidetoshi Seto   x86, mce: Replace...
875
  	if (MCI_MISC_ADDR_LSB(m->misc) > PAGE_SHIFT)
9b1beaf2b   Andi Kleen   x86, mce: support...
876
  		return 0;
2b90e77ea   Hidetoshi Seto   x86, mce: Replace...
877
  	if (MCI_MISC_ADDR_MODE(m->misc) != MCI_MISC_ADDR_PHYS)
9b1beaf2b   Andi Kleen   x86, mce: support...
878
879
880
  		return 0;
  	return 1;
  }
3c0797925   Andi Kleen   x86, mce: switch ...
881
882
883
884
885
886
  static void mce_clear_state(unsigned long *toclear)
  {
  	int i;
  
  	for (i = 0; i < banks; i++) {
  		if (test_bit(i, toclear))
a2d32bcbc   Andi Kleen   x86: mce: macros ...
887
  			mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
3c0797925   Andi Kleen   x86, mce: switch ...
888
889
890
891
  	}
  }
  
  /*
b79109c3b   Andi Kleen   x86, mce: separat...
892
893
894
895
896
897
   * The actual machine check handler. This only handles real
   * exceptions when something got corrupted coming in through int 18.
   *
   * This is executed in NMI context not subject to normal locking rules. This
   * implies that most kernel services cannot be safely used. Don't even
   * think about putting a printk in there!
3c0797925   Andi Kleen   x86, mce: switch ...
898
899
900
901
   *
   * On Intel systems this is entered on all CPUs in parallel through
   * MCE broadcast. However some CPUs might be broken beyond repair,
   * so be always careful when synchronizing with others.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
   */
e9eee03e9   Ingo Molnar   x86, mce: clean u...
903
  void do_machine_check(struct pt_regs *regs, long error_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
904
  {
3c0797925   Andi Kleen   x86, mce: switch ...
905
  	struct mce m, *final;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
906
  	int i;
3c0797925   Andi Kleen   x86, mce: switch ...
907
908
909
910
911
912
  	int worst = 0;
  	int severity;
  	/*
  	 * Establish sequential order between the CPUs entering the machine
  	 * check handler.
  	 */
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
913
  	int order;
bd78432c8   Tim Hockin   x86_64: mcelog to...
914
915
916
917
918
919
920
921
922
923
  	/*
  	 * If no_way_out gets set, there is no safe way to recover from this
  	 * MCE.  If tolerant is cranked up, we'll try anyway.
  	 */
  	int no_way_out = 0;
  	/*
  	 * If kill_it gets set, there might be a way to recover from this
  	 * error.
  	 */
  	int kill_it = 0;
b79109c3b   Andi Kleen   x86, mce: separat...
924
  	DECLARE_BITMAP(toclear, MAX_NR_BANKS);
bd19a5e6b   Andi Kleen   x86, mce: check e...
925
  	char *msg = "Unknown";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926

553f265fe   Andi Kleen   [PATCH] x86_64: D...
927
  	atomic_inc(&mce_entry);
402af0d7c   Jan Beulich   x86, asm: Introdu...
928
  	percpu_inc(mce_exception_count);
01ca79f14   Andi Kleen   x86, mce: add mac...
929

b79109c3b   Andi Kleen   x86, mce: separat...
930
  	if (!banks)
32561696c   Andi Kleen   x86, mce: rename ...
931
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
932

b8325c5b1   Hidetoshi Seto   x86, mce: Introdu...
933
  	mce_gather_info(&m, regs);
b5f2fa4ea   Andi Kleen   x86, mce: factor ...
934

3c0797925   Andi Kleen   x86, mce: switch ...
935
936
  	final = &__get_cpu_var(mces_seen);
  	*final = m;
680b6cfd3   Hidetoshi Seto   x86, mce: CE in l...
937
  	no_way_out = mce_no_way_out(&m, &msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
  	barrier();
3c0797925   Andi Kleen   x86, mce: switch ...
939
  	/*
ed7290d0e   Andi Kleen   x86, mce: impleme...
940
941
942
943
944
945
  	 * When no restart IP must always kill or panic.
  	 */
  	if (!(m.mcgstatus & MCG_STATUS_RIPV))
  		kill_it = 1;
  
  	/*
3c0797925   Andi Kleen   x86, mce: switch ...
946
947
948
949
  	 * Go through all the banks in exclusion of the other CPUs.
  	 * This way we don't report duplicated events on shared banks
  	 * because the first one to see it will clear it.
  	 */
7fb06fc96   Hidetoshi Seto   x86, mce: cleanup...
950
  	order = mce_start(&no_way_out);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
  	for (i = 0; i < banks; i++) {
b79109c3b   Andi Kleen   x86, mce: separat...
952
  		__clear_bit(i, toclear);
cebe18203   Andi Kleen   x86: mce: Move pe...
953
  		if (!mce_banks[i].ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
954
  			continue;
d88203d1a   Thomas Gleixner   x86: whitespace c...
955
956
  
  		m.misc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
957
958
  		m.addr = 0;
  		m.bank = i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
959

a2d32bcbc   Andi Kleen   x86: mce: macros ...
960
  		m.status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
961
962
  		if ((m.status & MCI_STATUS_VAL) == 0)
  			continue;
b79109c3b   Andi Kleen   x86, mce: separat...
963
  		/*
ed7290d0e   Andi Kleen   x86, mce: impleme...
964
965
  		 * Non uncorrected or non signaled errors are handled by
  		 * machine_check_poll. Leave them alone, unless this panics.
b79109c3b   Andi Kleen   x86, mce: separat...
966
  		 */
ed7290d0e   Andi Kleen   x86, mce: impleme...
967
968
  		if (!(m.status & (mce_ser ? MCI_STATUS_S : MCI_STATUS_UC)) &&
  			!no_way_out)
b79109c3b   Andi Kleen   x86, mce: separat...
969
970
971
972
973
974
  			continue;
  
  		/*
  		 * Set taint even when machine check was not enabled.
  		 */
  		add_taint(TAINT_MACHINE_CHECK);
ed7290d0e   Andi Kleen   x86, mce: impleme...
975
  		severity = mce_severity(&m, tolerant, NULL);
b79109c3b   Andi Kleen   x86, mce: separat...
976

ed7290d0e   Andi Kleen   x86, mce: impleme...
977
978
979
980
981
982
983
984
  		/*
  		 * When machine check was for corrected handler don't touch,
  		 * unless we're panicing.
  		 */
  		if (severity == MCE_KEEP_SEVERITY && !no_way_out)
  			continue;
  		__set_bit(i, toclear);
  		if (severity == MCE_NO_SEVERITY) {
b79109c3b   Andi Kleen   x86, mce: separat...
985
986
987
988
989
  			/*
  			 * Machine check event was not enabled. Clear, but
  			 * ignore.
  			 */
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
  		}
ed7290d0e   Andi Kleen   x86, mce: impleme...
991
992
993
994
995
  		/*
  		 * Kill on action required.
  		 */
  		if (severity == MCE_AR_SEVERITY)
  			kill_it = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
996
  		if (m.status & MCI_STATUS_MISCV)
a2d32bcbc   Andi Kleen   x86: mce: macros ...
997
  			m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
998
  		if (m.status & MCI_STATUS_ADDRV)
a2d32bcbc   Andi Kleen   x86: mce: macros ...
999
  			m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1000

9b1beaf2b   Andi Kleen   x86, mce: support...
1001
1002
1003
1004
1005
1006
1007
1008
1009
  		/*
  		 * Action optional error. Queue address for later processing.
  		 * When the ring overflows we just ignore the AO error.
  		 * RED-PEN add some logging mechanism when
  		 * usable_address or mce_add_ring fails.
  		 * RED-PEN don't ignore overflow for tolerant == 0
  		 */
  		if (severity == MCE_AO_SEVERITY && mce_usable_address(&m))
  			mce_ring_add(m.addr >> PAGE_SHIFT);
b79109c3b   Andi Kleen   x86, mce: separat...
1010
  		mce_log(&m);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011

3c0797925   Andi Kleen   x86, mce: switch ...
1012
1013
1014
  		if (severity > worst) {
  			*final = m;
  			worst = severity;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1015
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1016
  	}
3c0797925   Andi Kleen   x86, mce: switch ...
1017
1018
  	if (!no_way_out)
  		mce_clear_state(toclear);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1019
  	/*
3c0797925   Andi Kleen   x86, mce: switch ...
1020
1021
  	 * Do most of the synchronization with other CPUs.
  	 * When there's any problem use only local no_way_out state.
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1022
  	 */
3c0797925   Andi Kleen   x86, mce: switch ...
1023
1024
  	if (mce_end(order) < 0)
  		no_way_out = worst >= MCE_PANIC_SEVERITY;
bd78432c8   Tim Hockin   x86_64: mcelog to...
1025
1026
1027
  
  	/*
  	 * If we have decided that we just CAN'T continue, and the user
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1028
  	 * has not set tolerant to an insane level, give up and die.
3c0797925   Andi Kleen   x86, mce: switch ...
1029
1030
1031
  	 *
  	 * This is mainly used in the case when the system doesn't
  	 * support MCE broadcasting or it has been disabled.
bd78432c8   Tim Hockin   x86_64: mcelog to...
1032
1033
  	 */
  	if (no_way_out && tolerant < 3)
ac9603754   Andi Kleen   x86, mce: make no...
1034
  		mce_panic("Fatal machine check on current CPU", final, msg);
bd78432c8   Tim Hockin   x86_64: mcelog to...
1035
1036
1037
1038
1039
1040
1041
  
  	/*
  	 * If the error seems to be unrecoverable, something should be
  	 * done.  Try to kill as little as possible.  If we can kill just
  	 * one task, do that.  If the user has set the tolerance very
  	 * high, don't try to do anything at all.
  	 */
bd78432c8   Tim Hockin   x86_64: mcelog to...
1042

ed7290d0e   Andi Kleen   x86, mce: impleme...
1043
1044
  	if (kill_it && tolerant < 3)
  		force_sig(SIGBUS, current);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045

e02e68d31   Tim Hockin   x86_64: support p...
1046
1047
  	/* notify userspace ASAP */
  	set_thread_flag(TIF_MCE_NOTIFY);
3c0797925   Andi Kleen   x86, mce: switch ...
1048
1049
  	if (worst > 0)
  		mce_report_event(regs);
5f8c1a54c   Andi Kleen   x86, mce: add MSR...
1050
  	mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);
32561696c   Andi Kleen   x86, mce: rename ...
1051
  out:
553f265fe   Andi Kleen   [PATCH] x86_64: D...
1052
  	atomic_dec(&mce_entry);
88921be30   Andi Kleen   x86, mce: synchro...
1053
  	sync_core();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1054
  }
ea149b36c   Andi Kleen   x86, mce: add bas...
1055
  EXPORT_SYMBOL_GPL(do_machine_check);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1056

9b1beaf2b   Andi Kleen   x86, mce: support...
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
  /* dummy to break dependency. actual code is in mm/memory-failure.c */
  void __attribute__((weak)) memory_failure(unsigned long pfn, int vector)
  {
  	printk(KERN_ERR "Action optional memory failure at %lx ignored
  ", pfn);
  }
  
  /*
   * Called after mce notification in process context. This code
   * is allowed to sleep. Call the high level VM handler to process
   * any corrupted pages.
   * Assume that the work queue code only calls this one at a time
   * per CPU.
   * Note we don't disable preemption, so this code might run on the wrong
   * CPU. In this case the event is picked up by the scheduled work queue.
   * This is merely a fast path to expedite processing in some common
   * cases.
   */
  void mce_notify_process(void)
  {
  	unsigned long pfn;
  	mce_notify_irq();
  	while (mce_ring_get(&pfn))
  		memory_failure(pfn, MCE_VECTOR);
  }
  
  static void mce_process_work(struct work_struct *dummy)
  {
  	mce_notify_process();
  }
15d5f8398   Dmitriy Zavin   [PATCH] x86: Refa...
1087
1088
1089
  #ifdef CONFIG_X86_MCE_INTEL
  /***
   * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog
676b1855d   Simon Arlott   spelling fixes: a...
1090
   * @cpu: The CPU on which the event occurred.
15d5f8398   Dmitriy Zavin   [PATCH] x86: Refa...
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
   * @status: Event status information
   *
   * This function should be called by the thermal interrupt after the
   * event has been processed and the decision was made to log the event
   * further.
   *
   * The status parameter will be saved to the 'status' field of 'struct mce'
   * and historically has been the register value of the
   * MSR_IA32_THERMAL_STATUS (Intel) msr.
   */
b5f2fa4ea   Andi Kleen   x86, mce: factor ...
1101
  void mce_log_therm_throt_event(__u64 status)
15d5f8398   Dmitriy Zavin   [PATCH] x86: Refa...
1102
1103
  {
  	struct mce m;
b5f2fa4ea   Andi Kleen   x86, mce: factor ...
1104
  	mce_setup(&m);
15d5f8398   Dmitriy Zavin   [PATCH] x86: Refa...
1105
1106
  	m.bank = MCE_THERMAL_BANK;
  	m.status = status;
15d5f8398   Dmitriy Zavin   [PATCH] x86: Refa...
1107
1108
1109
  	mce_log(&m);
  }
  #endif /* CONFIG_X86_MCE_INTEL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1110
  /*
8a336b0a4   Tim Hockin   [PATCH] x86-64: D...
1111
1112
1113
   * Periodic polling timer for "silent" machine check errors.  If the
   * poller finds an MCE, poll 2x faster.  When the poller finds no more
   * errors, poll 2x slower (up to check_interval seconds).
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1114
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1115
  static int check_interval = 5 * 60; /* 5 minutes */
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1116

245b2e70e   Tejun Heo   percpu: clean up ...
1117
  static DEFINE_PER_CPU(int, mce_next_interval); /* in jiffies */
52d168e28   Andi Kleen   x86, mce: switch ...
1118
  static DEFINE_PER_CPU(struct timer_list, mce_timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1119

5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1120
  static void mce_start_timer(unsigned long data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1121
  {
52d168e28   Andi Kleen   x86, mce: switch ...
1122
  	struct timer_list *t = &per_cpu(mce_timer, data);
6298c512b   Andi Kleen   x86, mce: make po...
1123
  	int *n;
52d168e28   Andi Kleen   x86, mce: switch ...
1124
1125
  
  	WARN_ON(smp_processor_id() != data);
7b543a533   Tejun Heo   x86: Replace uses...
1126
  	if (mce_available(__this_cpu_ptr(&cpu_info))) {
ee031c31d   Andi Kleen   x86, mce, cmci: u...
1127
1128
  		machine_check_poll(MCP_TIMESTAMP,
  				&__get_cpu_var(mce_poll_banks));
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1129
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1130
1131
  
  	/*
e02e68d31   Tim Hockin   x86_64: support p...
1132
1133
  	 * Alert userspace if needed.  If we logged an MCE, reduce the
  	 * polling interval, otherwise increase the polling interval.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1134
  	 */
245b2e70e   Tejun Heo   percpu: clean up ...
1135
  	n = &__get_cpu_var(mce_next_interval);
9ff36ee96   Andi Kleen   x86, mce: rename ...
1136
  	if (mce_notify_irq())
6298c512b   Andi Kleen   x86, mce: make po...
1137
  		*n = max(*n/2, HZ/100);
14a02530e   Hidetoshi Seto   x86, mce: trivial...
1138
  	else
6298c512b   Andi Kleen   x86, mce: make po...
1139
  		*n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ));
e02e68d31   Tim Hockin   x86_64: support p...
1140

6298c512b   Andi Kleen   x86, mce: make po...
1141
  	t->expires = jiffies + *n;
5be6066a7   Hidetoshi Seto   x86, mce: percpu ...
1142
  	add_timer_on(t, smp_processor_id());
e02e68d31   Tim Hockin   x86_64: support p...
1143
  }
9aaef96f6   Hidetoshi Seto   x86, mce: Do not ...
1144
1145
1146
1147
1148
1149
1150
1151
  /* Must not be called in IRQ context where del_timer_sync() can deadlock */
  static void mce_timer_delete_all(void)
  {
  	int cpu;
  
  	for_each_online_cpu(cpu)
  		del_timer_sync(&per_cpu(mce_timer, cpu));
  }
9bd984058   Andi Kleen   x86, mce: always ...
1152
1153
  static void mce_do_trigger(struct work_struct *work)
  {
1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
1154
  	call_usermodehelper(mce_helper, mce_helper_argv, NULL, UMH_NO_WAIT);
9bd984058   Andi Kleen   x86, mce: always ...
1155
1156
1157
  }
  
  static DECLARE_WORK(mce_trigger_work, mce_do_trigger);
e02e68d31   Tim Hockin   x86_64: support p...
1158
  /*
9bd984058   Andi Kleen   x86, mce: always ...
1159
1160
1161
   * Notify the user(s) about new machine check events.
   * Can be called from interrupt context, but not from machine check/NMI
   * context.
e02e68d31   Tim Hockin   x86_64: support p...
1162
   */
9ff36ee96   Andi Kleen   x86, mce: rename ...
1163
  int mce_notify_irq(void)
e02e68d31   Tim Hockin   x86_64: support p...
1164
  {
8457c84d6   Andi Kleen   x86, mce: replace...
1165
1166
  	/* Not more than two messages every minute */
  	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
e02e68d31   Tim Hockin   x86_64: support p...
1167
  	clear_thread_flag(TIF_MCE_NOTIFY);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1168

1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
1169
  	if (test_and_clear_bit(0, &mce_need_notify)) {
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1170
1171
  		/* wake processes polling /dev/mcelog */
  		wake_up_interruptible(&mce_chrdev_wait);
9bd984058   Andi Kleen   x86, mce: always ...
1172
1173
1174
1175
1176
1177
  
  		/*
  		 * There is no risk of missing notifications because
  		 * work_pending is always cleared before the function is
  		 * executed.
  		 */
1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
1178
  		if (mce_helper[0] && !work_pending(&mce_trigger_work))
9bd984058   Andi Kleen   x86, mce: always ...
1179
  			schedule_work(&mce_trigger_work);
e02e68d31   Tim Hockin   x86_64: support p...
1180

8457c84d6   Andi Kleen   x86, mce: replace...
1181
  		if (__ratelimit(&ratelimit))
a2d7b0d48   Huang Ying   x86, mce: Use HW_...
1182
1183
  			pr_info(HW_ERR "Machine check events logged
  ");
e02e68d31   Tim Hockin   x86_64: support p...
1184
1185
  
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186
  	}
e02e68d31   Tim Hockin   x86_64: support p...
1187
1188
  	return 0;
  }
9ff36ee96   Andi Kleen   x86, mce: rename ...
1189
  EXPORT_SYMBOL_GPL(mce_notify_irq);
8a336b0a4   Tim Hockin   [PATCH] x86-64: D...
1190

cffd377e5   Hidetoshi Seto   x86, mce: Fix __i...
1191
  static int __cpuinit __mcheck_cpu_mce_banks_init(void)
cebe18203   Andi Kleen   x86: mce: Move pe...
1192
1193
1194
1195
1196
1197
1198
1199
  {
  	int i;
  
  	mce_banks = kzalloc(banks * sizeof(struct mce_bank), GFP_KERNEL);
  	if (!mce_banks)
  		return -ENOMEM;
  	for (i = 0; i < banks; i++) {
  		struct mce_bank *b = &mce_banks[i];
11868a2dc   Ingo Molnar   x86: mce: Use saf...
1200

cebe18203   Andi Kleen   x86: mce: Move pe...
1201
1202
1203
1204
1205
  		b->ctl = -1ULL;
  		b->init = 1;
  	}
  	return 0;
  }
d88203d1a   Thomas Gleixner   x86: whitespace c...
1206
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1207
1208
   * Initialize Machine Checks for a CPU.
   */
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1209
  static int __cpuinit __mcheck_cpu_cap_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1210
  {
0d7482e3d   Andi Kleen   x86, mce: impleme...
1211
  	unsigned b;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1212
  	u64 cap;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1213
1214
  
  	rdmsrl(MSR_IA32_MCG_CAP, cap);
01c6680a5   Thomas Gleixner   x86, mce: Cleanup...
1215
1216
  
  	b = cap & MCG_BANKCNT_MASK;
93ae5012a   Roland Dreier   x86: Don't print ...
1217
1218
1219
  	if (!banks)
  		printk(KERN_INFO "mce: CPU supports %d MCE banks
  ", b);
b659294b7   Ingo Molnar   x86, mce: print n...
1220

0d7482e3d   Andi Kleen   x86, mce: impleme...
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
  	if (b > MAX_NR_BANKS) {
  		printk(KERN_WARNING
  		       "MCE: Using only %u machine check banks out of %u
  ",
  			MAX_NR_BANKS, b);
  		b = MAX_NR_BANKS;
  	}
  
  	/* Don't support asymmetric configurations today */
  	WARN_ON(banks != 0 && b != banks);
  	banks = b;
cebe18203   Andi Kleen   x86: mce: Move pe...
1232
  	if (!mce_banks) {
cffd377e5   Hidetoshi Seto   x86, mce: Fix __i...
1233
  		int err = __mcheck_cpu_mce_banks_init();
11868a2dc   Ingo Molnar   x86: mce: Use saf...
1234

cebe18203   Andi Kleen   x86: mce: Move pe...
1235
1236
  		if (err)
  			return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1237
  	}
0d7482e3d   Andi Kleen   x86, mce: impleme...
1238

94ad84740   Andi Kleen   [PATCH] x86_64: U...
1239
  	/* Use accurate RIP reporting if available. */
01c6680a5   Thomas Gleixner   x86, mce: Cleanup...
1240
  	if ((cap & MCG_EXT_P) && MCG_EXT_CNT(cap) >= 9)
94ad84740   Andi Kleen   [PATCH] x86_64: U...
1241
  		rip_msr = MSR_IA32_MCG_EIP;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1242

ed7290d0e   Andi Kleen   x86, mce: impleme...
1243
1244
  	if (cap & MCG_SER_P)
  		mce_ser = 1;
0d7482e3d   Andi Kleen   x86, mce: impleme...
1245
1246
  	return 0;
  }
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1247
  static void __mcheck_cpu_init_generic(void)
0d7482e3d   Andi Kleen   x86, mce: impleme...
1248
  {
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1249
  	mce_banks_t all_banks;
0d7482e3d   Andi Kleen   x86, mce: impleme...
1250
1251
  	u64 cap;
  	int i;
b79109c3b   Andi Kleen   x86, mce: separat...
1252
1253
1254
  	/*
  	 * Log the machine checks left over from the previous reset.
  	 */
ee031c31d   Andi Kleen   x86, mce, cmci: u...
1255
  	bitmap_fill(all_banks, MAX_NR_BANKS);
5679af4c1   Andi Kleen   x86, mce: fix boo...
1256
  	machine_check_poll(MCP_UC|(!mce_bootlog ? MCP_DONTLOG : 0), &all_banks);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1257
1258
  
  	set_in_cr4(X86_CR4_MCE);
0d7482e3d   Andi Kleen   x86, mce: impleme...
1259
  	rdmsrl(MSR_IA32_MCG_CAP, cap);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1260
1261
1262
1263
  	if (cap & MCG_CTL_P)
  		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
  
  	for (i = 0; i < banks; i++) {
cebe18203   Andi Kleen   x86: mce: Move pe...
1264
  		struct mce_bank *b = &mce_banks[i];
11868a2dc   Ingo Molnar   x86: mce: Use saf...
1265

cebe18203   Andi Kleen   x86: mce: Move pe...
1266
  		if (!b->init)
06b7a7a5e   Andi Kleen   x86, mce: impleme...
1267
  			continue;
a2d32bcbc   Andi Kleen   x86: mce: macros ...
1268
1269
  		wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl);
  		wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
d88203d1a   Thomas Gleixner   x86: whitespace c...
1270
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1271
1272
1273
  }
  
  /* Add per CPU specific workarounds here */
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1274
  static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
d88203d1a   Thomas Gleixner   x86: whitespace c...
1275
  {
e412cd257   Ingo Molnar   x86, mce: Don't i...
1276
1277
1278
1279
1280
  	if (c->x86_vendor == X86_VENDOR_UNKNOWN) {
  		pr_info("MCE: unknown CPU type - not enabling MCE support.
  ");
  		return -EOPNOTSUPP;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1281
  	/* This should be disabled by the BIOS, but isn't always */
911f6a7ba   Jan Beulich   x86-64: extend MC...
1282
  	if (c->x86_vendor == X86_VENDOR_AMD) {
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1283
1284
1285
1286
1287
1288
  		if (c->x86 == 15 && banks > 4) {
  			/*
  			 * disable GART TBL walk error reporting, which
  			 * trips off incorrectly with the IOMMU & 3ware
  			 * & Cerberus:
  			 */
cebe18203   Andi Kleen   x86: mce: Move pe...
1289
  			clear_bit(10, (unsigned long *)&mce_banks[4].ctl);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1290
1291
1292
1293
1294
1295
  		}
  		if (c->x86 <= 17 && mce_bootlog < 0) {
  			/*
  			 * Lots of broken BIOS around that don't clear them
  			 * by default and leave crap in there. Don't log:
  			 */
911f6a7ba   Jan Beulich   x86-64: extend MC...
1296
  			mce_bootlog = 0;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1297
  		}
2e6f694fd   Andi Kleen   x86, mce: port K7...
1298
1299
1300
1301
  		/*
  		 * Various K7s with broken bank 0 around. Always disable
  		 * by default.
  		 */
203abd67b   Andi Kleen   x86: mce: Handle ...
1302
  		 if (c->x86 == 6 && banks > 0)
cebe18203   Andi Kleen   x86: mce: Move pe...
1303
  			mce_banks[0].ctl = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304
  	}
e583538f0   Andi Kleen   [PATCH] x86_64: L...
1305

06b7a7a5e   Andi Kleen   x86, mce: impleme...
1306
1307
1308
1309
1310
1311
1312
1313
1314
  	if (c->x86_vendor == X86_VENDOR_INTEL) {
  		/*
  		 * SDM documents that on family 6 bank 0 should not be written
  		 * because it aliases to another special BIOS controlled
  		 * register.
  		 * But it's not aliased anymore on model 0x1a+
  		 * Don't ignore bank 0 completely because there could be a
  		 * valid event later, merely don't write CTL0.
  		 */
cebe18203   Andi Kleen   x86: mce: Move pe...
1315
1316
  		if (c->x86 == 6 && c->x86_model < 0x1A && banks > 0)
  			mce_banks[0].init = 0;
3c0797925   Andi Kleen   x86, mce: switch ...
1317
1318
1319
1320
1321
1322
1323
1324
  
  		/*
  		 * All newer Intel systems support MCE broadcasting. Enable
  		 * synchronization with a one second timeout.
  		 */
  		if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) &&
  			monarch_timeout < 0)
  			monarch_timeout = USEC_PER_SEC;
c7f6fa441   Bartlomiej Zolnierkiewicz   x86, mce: don't l...
1325

e412cd257   Ingo Molnar   x86, mce: Don't i...
1326
1327
1328
1329
1330
  		/*
  		 * There are also broken BIOSes on some Pentium M and
  		 * earlier systems:
  		 */
  		if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0)
c7f6fa441   Bartlomiej Zolnierkiewicz   x86, mce: don't l...
1331
  			mce_bootlog = 0;
06b7a7a5e   Andi Kleen   x86, mce: impleme...
1332
  	}
3c0797925   Andi Kleen   x86, mce: switch ...
1333
1334
  	if (monarch_timeout < 0)
  		monarch_timeout = 0;
29b0f591d   Andi Kleen   x86, mce: default...
1335
1336
  	if (mce_bootlog != 0)
  		mce_panic_timeout = 30;
e412cd257   Ingo Molnar   x86, mce: Don't i...
1337
1338
  
  	return 0;
d88203d1a   Thomas Gleixner   x86: whitespace c...
1339
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1340

3a97fc341   Hidetoshi Seto   x86, mce: Check t...
1341
  static int __cpuinit __mcheck_cpu_ancient_init(struct cpuinfo_x86 *c)
4efc0670b   Andi Kleen   x86, mce: use 64b...
1342
1343
  {
  	if (c->x86 != 5)
3a97fc341   Hidetoshi Seto   x86, mce: Check t...
1344
  		return 0;
4efc0670b   Andi Kleen   x86, mce: use 64b...
1345
1346
  	switch (c->x86_vendor) {
  	case X86_VENDOR_INTEL:
c69783698   Hidetoshi Seto   x86, mce: make mc...
1347
  		intel_p5_mcheck_init(c);
3a97fc341   Hidetoshi Seto   x86, mce: Check t...
1348
  		return 1;
4efc0670b   Andi Kleen   x86, mce: use 64b...
1349
1350
1351
  		break;
  	case X86_VENDOR_CENTAUR:
  		winchip_mcheck_init(c);
3a97fc341   Hidetoshi Seto   x86, mce: Check t...
1352
  		return 1;
4efc0670b   Andi Kleen   x86, mce: use 64b...
1353
1354
  		break;
  	}
3a97fc341   Hidetoshi Seto   x86, mce: Check t...
1355
1356
  
  	return 0;
4efc0670b   Andi Kleen   x86, mce: use 64b...
1357
  }
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1358
  static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1359
1360
1361
1362
1363
  {
  	switch (c->x86_vendor) {
  	case X86_VENDOR_INTEL:
  		mce_intel_feature_init(c);
  		break;
89b831ef8   Jacob Shin   [PATCH] x86_64: S...
1364
1365
1366
  	case X86_VENDOR_AMD:
  		mce_amd_feature_init(c);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1367
1368
1369
1370
  	default:
  		break;
  	}
  }
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1371
  static void __mcheck_cpu_init_timer(void)
52d168e28   Andi Kleen   x86, mce: switch ...
1372
1373
  {
  	struct timer_list *t = &__get_cpu_var(mce_timer);
245b2e70e   Tejun Heo   percpu: clean up ...
1374
  	int *n = &__get_cpu_var(mce_next_interval);
52d168e28   Andi Kleen   x86, mce: switch ...
1375

bc09effab   Jan Beulich   x86/mce: Set up t...
1376
  	setup_timer(t, mce_start_timer, smp_processor_id());
62fdac591   Hidetoshi Seto   x86, mce: Add boo...
1377
1378
  	if (mce_ignore_ce)
  		return;
6298c512b   Andi Kleen   x86, mce: make po...
1379
1380
  	*n = check_interval * HZ;
  	if (!*n)
52d168e28   Andi Kleen   x86, mce: switch ...
1381
  		return;
6298c512b   Andi Kleen   x86, mce: make po...
1382
  	t->expires = round_jiffies(jiffies + *n);
5be6066a7   Hidetoshi Seto   x86, mce: percpu ...
1383
  	add_timer_on(t, smp_processor_id());
52d168e28   Andi Kleen   x86, mce: switch ...
1384
  }
9eda8cb3a   Andi Kleen   x86: mce: Move co...
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
  /* Handle unconfigured int18 (should never happen) */
  static void unexpected_machine_check(struct pt_regs *regs, long error_code)
  {
  	printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).
  ",
  	       smp_processor_id());
  }
  
  /* Call the installed machine check handler for this CPU setup. */
  void (*machine_check_vector)(struct pt_regs *, long error_code) =
  						unexpected_machine_check;
d88203d1a   Thomas Gleixner   x86: whitespace c...
1396
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1397
   * Called for each booted CPU to set up machine checks.
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1398
   * Must be called with preempt off:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1399
   */
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1400
  void __cpuinit mcheck_cpu_init(struct cpuinfo_x86 *c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1401
  {
4efc0670b   Andi Kleen   x86, mce: use 64b...
1402
1403
  	if (mce_disabled)
  		return;
3a97fc341   Hidetoshi Seto   x86, mce: Check t...
1404
1405
  	if (__mcheck_cpu_ancient_init(c))
  		return;
4efc0670b   Andi Kleen   x86, mce: use 64b...
1406

5b4408fda   Andi Kleen   x86, mce: don't s...
1407
  	if (!mce_available(c))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1408
  		return;
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1409
  	if (__mcheck_cpu_cap_init() < 0 || __mcheck_cpu_apply_quirks(c) < 0) {
04b2b1a4d   Andi Kleen   x86, mce: rename ...
1410
  		mce_disabled = 1;
0d7482e3d   Andi Kleen   x86, mce: impleme...
1411
1412
  		return;
  	}
0d7482e3d   Andi Kleen   x86, mce: impleme...
1413

5d7279268   Andi Kleen   x86, mce: use a c...
1414
  	machine_check_vector = do_machine_check;
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1415
1416
1417
  	__mcheck_cpu_init_generic();
  	__mcheck_cpu_init_vendor(c);
  	__mcheck_cpu_init_timer();
9b1beaf2b   Andi Kleen   x86, mce: support...
1418
  	INIT_WORK(&__get_cpu_var(mce_work), mce_process_work);
b77e70bf3   Hidetoshi Seto   x86, mce: Replace...
1419
  	init_irq_work(&__get_cpu_var(mce_irq_work), &mce_irq_work_cb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1420
1421
1422
  }
  
  /*
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1423
   * mce_chrdev: Character device /dev/mcelog to read and clear the MCE log.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1424
   */
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1425
1426
1427
  static DEFINE_SPINLOCK(mce_chrdev_state_lock);
  static int mce_chrdev_open_count;	/* #times opened */
  static int mce_chrdev_open_exclu;	/* already open exclusive? */
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1428

93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1429
  static int mce_chrdev_open(struct inode *inode, struct file *file)
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1430
  {
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1431
  	spin_lock(&mce_chrdev_state_lock);
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1432

93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1433
1434
1435
  	if (mce_chrdev_open_exclu ||
  	    (mce_chrdev_open_count && (file->f_flags & O_EXCL))) {
  		spin_unlock(&mce_chrdev_state_lock);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1436

f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1437
1438
1439
1440
  		return -EBUSY;
  	}
  
  	if (file->f_flags & O_EXCL)
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1441
1442
  		mce_chrdev_open_exclu = 1;
  	mce_chrdev_open_count++;
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1443

93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1444
  	spin_unlock(&mce_chrdev_state_lock);
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1445

bd78432c8   Tim Hockin   x86_64: mcelog to...
1446
  	return nonseekable_open(inode, file);
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1447
  }
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1448
  static int mce_chrdev_release(struct inode *inode, struct file *file)
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1449
  {
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1450
  	spin_lock(&mce_chrdev_state_lock);
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1451

93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1452
1453
  	mce_chrdev_open_count--;
  	mce_chrdev_open_exclu = 0;
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1454

93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1455
  	spin_unlock(&mce_chrdev_state_lock);
f528e7ba2   Tim Hockin   x86_64: O_EXCL on...
1456
1457
1458
  
  	return 0;
  }
d88203d1a   Thomas Gleixner   x86: whitespace c...
1459
1460
  static void collect_tscs(void *data)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1461
  	unsigned long *cpu_tsc = (unsigned long *)data;
d88203d1a   Thomas Gleixner   x86: whitespace c...
1462

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1463
  	rdtscll(cpu_tsc[smp_processor_id()]);
d88203d1a   Thomas Gleixner   x86: whitespace c...
1464
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1465

482908b49   Huang Ying   ACPI, APEI, Use E...
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
  static int mce_apei_read_done;
  
  /* Collect MCE record of previous boot in persistent storage via APEI ERST. */
  static int __mce_read_apei(char __user **ubuf, size_t usize)
  {
  	int rc;
  	u64 record_id;
  	struct mce m;
  
  	if (usize < sizeof(struct mce))
  		return -EINVAL;
  
  	rc = apei_read_mce(&m, &record_id);
  	/* Error or no more MCE record */
  	if (rc <= 0) {
  		mce_apei_read_done = 1;
  		return rc;
  	}
  	rc = -EFAULT;
  	if (copy_to_user(*ubuf, &m, sizeof(struct mce)))
  		return rc;
  	/*
  	 * In fact, we should have cleared the record after that has
  	 * been flushed to the disk or sent to network in
  	 * /sbin/mcelog, but we have no interface to support that now,
  	 * so just clear it to avoid duplication.
  	 */
  	rc = apei_clear_mce(record_id);
  	if (rc) {
  		mce_apei_read_done = 1;
  		return rc;
  	}
  	*ubuf += sizeof(struct mce);
  
  	return 0;
  }
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1502
1503
  static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf,
  				size_t usize, loff_t *off)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1504
  {
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1505
  	char __user *buf = ubuf;
f0de53bbc   Andi Kleen   [PATCH] x86_64: R...
1506
  	unsigned long *cpu_tsc;
ef41df434   Huang Ying   x86, mce: fix a r...
1507
  	unsigned prev, next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1508
  	int i, err;
6bca67f95   Mike Travis   NR_CPUS: Replace ...
1509
  	cpu_tsc = kmalloc(nr_cpu_ids * sizeof(long), GFP_KERNEL);
f0de53bbc   Andi Kleen   [PATCH] x86_64: R...
1510
1511
  	if (!cpu_tsc)
  		return -ENOMEM;
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1512
  	mutex_lock(&mce_chrdev_read_mutex);
482908b49   Huang Ying   ACPI, APEI, Use E...
1513
1514
1515
1516
1517
1518
  
  	if (!mce_apei_read_done) {
  		err = __mce_read_apei(&buf, usize);
  		if (err || buf != ubuf)
  			goto out;
  	}
f56e8a076   Paul E. McKenney   x86/mce: Fix RCU ...
1519
  	next = rcu_dereference_check_mce(mcelog.next);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1520
1521
  
  	/* Only supports full reads right now */
482908b49   Huang Ying   ACPI, APEI, Use E...
1522
1523
1524
  	err = -EINVAL;
  	if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce))
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1525
1526
  
  	err = 0;
ef41df434   Huang Ying   x86, mce: fix a r...
1527
1528
1529
1530
  	prev = 0;
  	do {
  		for (i = prev; i < next; i++) {
  			unsigned long start = jiffies;
559faa6be   Hidetoshi Seto   x86, mce: Cleanup...
1531
  			struct mce *m = &mcelog.entry[i];
ef41df434   Huang Ying   x86, mce: fix a r...
1532

559faa6be   Hidetoshi Seto   x86, mce: Cleanup...
1533
  			while (!m->finished) {
ef41df434   Huang Ying   x86, mce: fix a r...
1534
  				if (time_after_eq(jiffies, start + 2)) {
559faa6be   Hidetoshi Seto   x86, mce: Cleanup...
1535
  					memset(m, 0, sizeof(*m));
ef41df434   Huang Ying   x86, mce: fix a r...
1536
1537
1538
  					goto timeout;
  				}
  				cpu_relax();
673242c10   Andi Kleen   [PATCH] x86-64: M...
1539
  			}
ef41df434   Huang Ying   x86, mce: fix a r...
1540
  			smp_rmb();
559faa6be   Hidetoshi Seto   x86, mce: Cleanup...
1541
1542
  			err |= copy_to_user(buf, m, sizeof(*m));
  			buf += sizeof(*m);
ef41df434   Huang Ying   x86, mce: fix a r...
1543
1544
  timeout:
  			;
673242c10   Andi Kleen   [PATCH] x86-64: M...
1545
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1546

ef41df434   Huang Ying   x86, mce: fix a r...
1547
1548
1549
1550
1551
  		memset(mcelog.entry + prev, 0,
  		       (next - prev) * sizeof(struct mce));
  		prev = next;
  		next = cmpxchg(&mcelog.next, prev, 0);
  	} while (next != prev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1552

b2b186600   Paul E. McKenney   [PATCH] RCU: clea...
1553
  	synchronize_sched();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554

d88203d1a   Thomas Gleixner   x86: whitespace c...
1555
1556
1557
1558
  	/*
  	 * Collect entries that were still getting written before the
  	 * synchronize.
  	 */
15c8b6c1a   Jens Axboe   on_each_cpu(): ki...
1559
  	on_each_cpu(collect_tscs, cpu_tsc, 1);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1560

d88203d1a   Thomas Gleixner   x86: whitespace c...
1561
  	for (i = next; i < MCE_LOG_LEN; i++) {
559faa6be   Hidetoshi Seto   x86, mce: Cleanup...
1562
1563
1564
1565
  		struct mce *m = &mcelog.entry[i];
  
  		if (m->finished && m->tsc < cpu_tsc[m->cpu]) {
  			err |= copy_to_user(buf, m, sizeof(*m));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1566
  			smp_rmb();
559faa6be   Hidetoshi Seto   x86, mce: Cleanup...
1567
1568
  			buf += sizeof(*m);
  			memset(m, 0, sizeof(*m));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1569
  		}
d88203d1a   Thomas Gleixner   x86: whitespace c...
1570
  	}
482908b49   Huang Ying   ACPI, APEI, Use E...
1571
1572
1573
1574
1575
  
  	if (err)
  		err = -EFAULT;
  
  out:
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1576
  	mutex_unlock(&mce_chrdev_read_mutex);
f0de53bbc   Andi Kleen   [PATCH] x86_64: R...
1577
  	kfree(cpu_tsc);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1578

482908b49   Huang Ying   ACPI, APEI, Use E...
1579
  	return err ? err : buf - ubuf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1580
  }
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1581
  static unsigned int mce_chrdev_poll(struct file *file, poll_table *wait)
e02e68d31   Tim Hockin   x86_64: support p...
1582
  {
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1583
  	poll_wait(file, &mce_chrdev_wait, wait);
a4dd99250   Paul E. McKenney   rcu: create new r...
1584
  	if (rcu_access_index(mcelog.next))
e02e68d31   Tim Hockin   x86_64: support p...
1585
  		return POLLIN | POLLRDNORM;
482908b49   Huang Ying   ACPI, APEI, Use E...
1586
1587
  	if (!mce_apei_read_done && apei_check_mce())
  		return POLLIN | POLLRDNORM;
e02e68d31   Tim Hockin   x86_64: support p...
1588
1589
  	return 0;
  }
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1590
1591
  static long mce_chrdev_ioctl(struct file *f, unsigned int cmd,
  				unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1592
1593
  {
  	int __user *p = (int __user *)arg;
d88203d1a   Thomas Gleixner   x86: whitespace c...
1594

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1595
  	if (!capable(CAP_SYS_ADMIN))
d88203d1a   Thomas Gleixner   x86: whitespace c...
1596
  		return -EPERM;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1597

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1598
  	switch (cmd) {
d88203d1a   Thomas Gleixner   x86: whitespace c...
1599
  	case MCE_GET_RECORD_LEN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1600
1601
  		return put_user(sizeof(struct mce), p);
  	case MCE_GET_LOG_LEN:
d88203d1a   Thomas Gleixner   x86: whitespace c...
1602
  		return put_user(MCE_LOG_LEN, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1603
1604
  	case MCE_GETCLEAR_FLAGS: {
  		unsigned flags;
d88203d1a   Thomas Gleixner   x86: whitespace c...
1605
1606
  
  		do {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607
  			flags = mcelog.flags;
d88203d1a   Thomas Gleixner   x86: whitespace c...
1608
  		} while (cmpxchg(&mcelog.flags, flags, 0) != flags);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1609

d88203d1a   Thomas Gleixner   x86: whitespace c...
1610
  		return put_user(flags, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1611
1612
  	}
  	default:
d88203d1a   Thomas Gleixner   x86: whitespace c...
1613
1614
  		return -ENOTTY;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1615
  }
66f5ddf30   Tony Luck   x86/mce: Make mce...
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
  static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf,
  			    size_t usize, loff_t *off);
  
  void register_mce_write_callback(ssize_t (*fn)(struct file *filp,
  			     const char __user *ubuf,
  			     size_t usize, loff_t *off))
  {
  	mce_write = fn;
  }
  EXPORT_SYMBOL_GPL(register_mce_write_callback);
  
  ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
  			 size_t usize, loff_t *off)
  {
  	if (mce_write)
  		return mce_write(filp, ubuf, usize, off);
  	else
  		return -EINVAL;
  }
  
  static const struct file_operations mce_chrdev_ops = {
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1637
1638
1639
  	.open			= mce_chrdev_open,
  	.release		= mce_chrdev_release,
  	.read			= mce_chrdev_read,
66f5ddf30   Tony Luck   x86/mce: Make mce...
1640
  	.write			= mce_chrdev_write,
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1641
1642
1643
  	.poll			= mce_chrdev_poll,
  	.unlocked_ioctl		= mce_chrdev_ioctl,
  	.llseek			= no_llseek,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1644
  };
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
1645
  static struct miscdevice mce_chrdev_device = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1646
1647
1648
1649
  	MISC_MCELOG_MINOR,
  	"mcelog",
  	&mce_chrdev_ops,
  };
d88203d1a   Thomas Gleixner   x86: whitespace c...
1650
  /*
62fdac591   Hidetoshi Seto   x86, mce: Add boo...
1651
1652
1653
1654
   * mce=off Disables machine check
   * mce=no_cmci Disables CMCI
   * mce=dont_log_ce Clears corrected events silently, no log created for CEs.
   * mce=ignore_ce Disables polling and CMCI, corrected events are not cleared.
3c0797925   Andi Kleen   x86, mce: switch ...
1655
1656
1657
   * mce=TOLERANCELEVEL[,monarchtimeout] (number, see above)
   *	monarchtimeout is how long to wait for other CPUs on machine
   *	check, or 0 to not wait
13503fa91   Hidetoshi Seto   x86, mce: Cleanup...
1658
1659
1660
   * mce=bootlog Log MCEs from before booting. Disabled by default on AMD.
   * mce=nobootlog Don't log MCEs from before booting.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1661
1662
  static int __init mcheck_enable(char *str)
  {
e3346fc48   Bartlomiej Zolnierkiewicz   x86, mce: fix "mc...
1663
  	if (*str == 0) {
4efc0670b   Andi Kleen   x86, mce: use 64b...
1664
  		enable_p5_mce();
e3346fc48   Bartlomiej Zolnierkiewicz   x86, mce: fix "mc...
1665
1666
  		return 1;
  	}
4efc0670b   Andi Kleen   x86, mce: use 64b...
1667
1668
  	if (*str == '=')
  		str++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1669
  	if (!strcmp(str, "off"))
04b2b1a4d   Andi Kleen   x86, mce: rename ...
1670
  		mce_disabled = 1;
62fdac591   Hidetoshi Seto   x86, mce: Add boo...
1671
1672
1673
1674
1675
1676
  	else if (!strcmp(str, "no_cmci"))
  		mce_cmci_disabled = 1;
  	else if (!strcmp(str, "dont_log_ce"))
  		mce_dont_log_ce = 1;
  	else if (!strcmp(str, "ignore_ce"))
  		mce_ignore_ce = 1;
13503fa91   Hidetoshi Seto   x86, mce: Cleanup...
1677
1678
  	else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog"))
  		mce_bootlog = (str[0] == 'b');
3c0797925   Andi Kleen   x86, mce: switch ...
1679
  	else if (isdigit(str[0])) {
8c566ef5f   Andi Kleen   [PATCH] x86-64: A...
1680
  		get_option(&str, &tolerant);
3c0797925   Andi Kleen   x86, mce: switch ...
1681
1682
1683
1684
1685
  		if (*str == ',') {
  			++str;
  			get_option(&str, &monarch_timeout);
  		}
  	} else {
4efc0670b   Andi Kleen   x86, mce: use 64b...
1686
1687
  		printk(KERN_INFO "mce argument %s ignored. Please use /sys
  ",
13503fa91   Hidetoshi Seto   x86, mce: Cleanup...
1688
1689
1690
  		       str);
  		return 0;
  	}
9b41046cd   OGAWA Hirofumi   [PATCH] Don't pas...
1691
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1692
  }
4efc0670b   Andi Kleen   x86, mce: use 64b...
1693
  __setup("mce", mcheck_enable);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1694

a2202aa29   Yong Wang   x86: Under BIOS c...
1695
  int __init mcheck_init(void)
b33a63636   Borislav Petkov   x86, mce: Add a g...
1696
  {
a2202aa29   Yong Wang   x86: Under BIOS c...
1697
  	mcheck_intel_therm_init();
b33a63636   Borislav Petkov   x86, mce: Add a g...
1698
1699
  	return 0;
  }
b33a63636   Borislav Petkov   x86, mce: Add a g...
1700

d88203d1a   Thomas Gleixner   x86: whitespace c...
1701
  /*
c7cece89f   Hidetoshi Seto   x86, mce: Use mce...
1702
   * mce_syscore: PM support
d88203d1a   Thomas Gleixner   x86: whitespace c...
1703
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1704

973a2dd1d   Andi Kleen   x86, mce: disable...
1705
1706
1707
1708
  /*
   * Disable machine checks on suspend and shutdown. We can't really handle
   * them later.
   */
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1709
  static int mce_disable_error_reporting(void)
973a2dd1d   Andi Kleen   x86, mce: disable...
1710
1711
  {
  	int i;
06b7a7a5e   Andi Kleen   x86, mce: impleme...
1712
  	for (i = 0; i < banks; i++) {
cebe18203   Andi Kleen   x86: mce: Move pe...
1713
  		struct mce_bank *b = &mce_banks[i];
11868a2dc   Ingo Molnar   x86: mce: Use saf...
1714

cebe18203   Andi Kleen   x86: mce: Move pe...
1715
  		if (b->init)
a2d32bcbc   Andi Kleen   x86: mce: macros ...
1716
  			wrmsrl(MSR_IA32_MCx_CTL(i), 0);
06b7a7a5e   Andi Kleen   x86, mce: impleme...
1717
  	}
973a2dd1d   Andi Kleen   x86, mce: disable...
1718
1719
  	return 0;
  }
c7cece89f   Hidetoshi Seto   x86, mce: Use mce...
1720
  static int mce_syscore_suspend(void)
973a2dd1d   Andi Kleen   x86, mce: disable...
1721
  {
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1722
  	return mce_disable_error_reporting();
973a2dd1d   Andi Kleen   x86, mce: disable...
1723
  }
c7cece89f   Hidetoshi Seto   x86, mce: Use mce...
1724
  static void mce_syscore_shutdown(void)
973a2dd1d   Andi Kleen   x86, mce: disable...
1725
  {
f3c6ea1b0   Rafael J. Wysocki   x86: Use syscore_...
1726
  	mce_disable_error_reporting();
973a2dd1d   Andi Kleen   x86, mce: disable...
1727
  }
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1728
1729
1730
1731
1732
  /*
   * On resume clear all MCE state. Don't want to see leftovers from the BIOS.
   * Only one CPU is active at this time, the others get re-added later using
   * CPU hotplug:
   */
c7cece89f   Hidetoshi Seto   x86, mce: Use mce...
1733
  static void mce_syscore_resume(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1734
  {
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1735
  	__mcheck_cpu_init_generic();
7b543a533   Tejun Heo   x86: Replace uses...
1736
  	__mcheck_cpu_init_vendor(__this_cpu_ptr(&cpu_info));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1737
  }
f3c6ea1b0   Rafael J. Wysocki   x86: Use syscore_...
1738
  static struct syscore_ops mce_syscore_ops = {
c7cece89f   Hidetoshi Seto   x86, mce: Use mce...
1739
1740
1741
  	.suspend	= mce_syscore_suspend,
  	.shutdown	= mce_syscore_shutdown,
  	.resume		= mce_syscore_resume,
f3c6ea1b0   Rafael J. Wysocki   x86: Use syscore_...
1742
  };
c7cece89f   Hidetoshi Seto   x86, mce: Use mce...
1743
  /*
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1744
   * mce_device: Sysfs support
c7cece89f   Hidetoshi Seto   x86, mce: Use mce...
1745
   */
52d168e28   Andi Kleen   x86, mce: switch ...
1746
1747
  static void mce_cpu_restart(void *data)
  {
7b543a533   Tejun Heo   x86: Replace uses...
1748
  	if (!mce_available(__this_cpu_ptr(&cpu_info)))
33edbf02a   Hidetoshi Seto   x86, mce: don't i...
1749
  		return;
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1750
1751
  	__mcheck_cpu_init_generic();
  	__mcheck_cpu_init_timer();
52d168e28   Andi Kleen   x86, mce: switch ...
1752
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1753
  /* Reinit MCEs after user configuration changes */
d88203d1a   Thomas Gleixner   x86: whitespace c...
1754
1755
  static void mce_restart(void)
  {
9aaef96f6   Hidetoshi Seto   x86, mce: Do not ...
1756
  	mce_timer_delete_all();
52d168e28   Andi Kleen   x86, mce: switch ...
1757
  	on_each_cpu(mce_cpu_restart, NULL, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1758
  }
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1759
  /* Toggle features for corrected errors */
9aaef96f6   Hidetoshi Seto   x86, mce: Do not ...
1760
  static void mce_disable_cmci(void *data)
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1761
  {
7b543a533   Tejun Heo   x86: Replace uses...
1762
  	if (!mce_available(__this_cpu_ptr(&cpu_info)))
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1763
  		return;
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1764
1765
1766
1767
1768
  	cmci_clear();
  }
  
  static void mce_enable_ce(void *all)
  {
7b543a533   Tejun Heo   x86: Replace uses...
1769
  	if (!mce_available(__this_cpu_ptr(&cpu_info)))
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1770
1771
1772
1773
  		return;
  	cmci_reenable();
  	cmci_recheck();
  	if (all)
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
1774
  		__mcheck_cpu_init_timer();
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1775
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1776
  static struct bus_type mce_subsys = {
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1777
  	.name		= "machinecheck",
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1778
  	.dev_name	= "machinecheck",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1779
  };
e032d8077   Greg Kroah-Hartman   mce: fix warning ...
1780
  struct device *mce_device[CONFIG_NR_CPUS];
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1781
1782
1783
  
  __cpuinitdata
  void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1784

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1785
  static inline struct mce_bank *attr_to_bank(struct device_attribute *attr)
cebe18203   Andi Kleen   x86: mce: Move pe...
1786
1787
1788
  {
  	return container_of(attr, struct mce_bank, attr);
  }
0d7482e3d   Andi Kleen   x86, mce: impleme...
1789

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1790
  static ssize_t show_bank(struct device *s, struct device_attribute *attr,
0d7482e3d   Andi Kleen   x86, mce: impleme...
1791
1792
  			 char *buf)
  {
cebe18203   Andi Kleen   x86: mce: Move pe...
1793
1794
  	return sprintf(buf, "%llx
  ", attr_to_bank(attr)->ctl);
0d7482e3d   Andi Kleen   x86, mce: impleme...
1795
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1796
  static ssize_t set_bank(struct device *s, struct device_attribute *attr,
9319cec8c   Hidetoshi Seto   x86, mce: use str...
1797
  			const char *buf, size_t size)
0d7482e3d   Andi Kleen   x86, mce: impleme...
1798
  {
9319cec8c   Hidetoshi Seto   x86, mce: use str...
1799
  	u64 new;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1800

9319cec8c   Hidetoshi Seto   x86, mce: use str...
1801
  	if (strict_strtoull(buf, 0, &new) < 0)
0d7482e3d   Andi Kleen   x86, mce: impleme...
1802
  		return -EINVAL;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1803

cebe18203   Andi Kleen   x86: mce: Move pe...
1804
  	attr_to_bank(attr)->ctl = new;
0d7482e3d   Andi Kleen   x86, mce: impleme...
1805
  	mce_restart();
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1806

9319cec8c   Hidetoshi Seto   x86, mce: use str...
1807
  	return size;
0d7482e3d   Andi Kleen   x86, mce: impleme...
1808
  }
a98f0dd34   Andi Kleen   [PATCH] x86-64: A...
1809

e9eee03e9   Ingo Molnar   x86, mce: clean u...
1810
  static ssize_t
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1811
  show_trigger(struct device *s, struct device_attribute *attr, char *buf)
a98f0dd34   Andi Kleen   [PATCH] x86-64: A...
1812
  {
1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
1813
  	strcpy(buf, mce_helper);
a98f0dd34   Andi Kleen   [PATCH] x86-64: A...
1814
1815
  	strcat(buf, "
  ");
1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
1816
  	return strlen(mce_helper) + 1;
a98f0dd34   Andi Kleen   [PATCH] x86-64: A...
1817
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1818
  static ssize_t set_trigger(struct device *s, struct device_attribute *attr,
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1819
  				const char *buf, size_t siz)
a98f0dd34   Andi Kleen   [PATCH] x86-64: A...
1820
1821
  {
  	char *p;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1822

1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
1823
1824
  	strncpy(mce_helper, buf, sizeof(mce_helper));
  	mce_helper[sizeof(mce_helper)-1] = 0;
1020bcbcc   Hidetoshi Seto   x86, mce: rename ...
1825
1826
  	p = strchr(mce_helper, '
  ');
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1827

e9084ec98   Jan Beulich   x86, mce: Fix set...
1828
  	if (p)
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1829
  		*p = 0;
e9084ec98   Jan Beulich   x86, mce: Fix set...
1830
  	return strlen(mce_helper) + !!p;
a98f0dd34   Andi Kleen   [PATCH] x86-64: A...
1831
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1832
1833
  static ssize_t set_ignore_ce(struct device *s,
  			     struct device_attribute *attr,
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
  			     const char *buf, size_t size)
  {
  	u64 new;
  
  	if (strict_strtoull(buf, 0, &new) < 0)
  		return -EINVAL;
  
  	if (mce_ignore_ce ^ !!new) {
  		if (new) {
  			/* disable ce features */
9aaef96f6   Hidetoshi Seto   x86, mce: Do not ...
1844
1845
  			mce_timer_delete_all();
  			on_each_cpu(mce_disable_cmci, NULL, 1);
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1846
1847
1848
1849
1850
1851
1852
1853
1854
  			mce_ignore_ce = 1;
  		} else {
  			/* enable ce features */
  			mce_ignore_ce = 0;
  			on_each_cpu(mce_enable_ce, (void *)1, 1);
  		}
  	}
  	return size;
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1855
1856
  static ssize_t set_cmci_disabled(struct device *s,
  				 struct device_attribute *attr,
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
  				 const char *buf, size_t size)
  {
  	u64 new;
  
  	if (strict_strtoull(buf, 0, &new) < 0)
  		return -EINVAL;
  
  	if (mce_cmci_disabled ^ !!new) {
  		if (new) {
  			/* disable cmci */
9aaef96f6   Hidetoshi Seto   x86, mce: Do not ...
1867
  			on_each_cpu(mce_disable_cmci, NULL, 1);
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1868
1869
1870
1871
1872
1873
1874
1875
1876
  			mce_cmci_disabled = 1;
  		} else {
  			/* enable cmci */
  			mce_cmci_disabled = 0;
  			on_each_cpu(mce_enable_ce, NULL, 1);
  		}
  	}
  	return size;
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1877
1878
  static ssize_t store_int_with_restart(struct device *s,
  				      struct device_attribute *attr,
b56f642d2   Andi Kleen   x86, mce: use ext...
1879
1880
  				      const char *buf, size_t size)
  {
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1881
  	ssize_t ret = device_store_int(s, attr, buf, size);
b56f642d2   Andi Kleen   x86, mce: use ext...
1882
1883
1884
  	mce_restart();
  	return ret;
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1885
1886
1887
1888
  static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger);
  static DEVICE_INT_ATTR(tolerant, 0644, tolerant);
  static DEVICE_INT_ATTR(monarch_timeout, 0644, monarch_timeout);
  static DEVICE_INT_ATTR(dont_log_ce, 0644, mce_dont_log_ce);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1889

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1890
1891
  static struct dev_ext_attribute dev_attr_check_interval = {
  	__ATTR(check_interval, 0644, device_show_int, store_int_with_restart),
b56f642d2   Andi Kleen   x86, mce: use ext...
1892
1893
  	&check_interval
  };
e9eee03e9   Ingo Molnar   x86, mce: clean u...
1894

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1895
1896
  static struct dev_ext_attribute dev_attr_ignore_ce = {
  	__ATTR(ignore_ce, 0644, device_show_int, set_ignore_ce),
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1897
1898
  	&mce_ignore_ce
  };
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1899
1900
  static struct dev_ext_attribute dev_attr_cmci_disabled = {
  	__ATTR(cmci_disabled, 0644, device_show_int, set_cmci_disabled),
9af43b54a   Hidetoshi Seto   x86, mce: sysfs e...
1901
1902
  	&mce_cmci_disabled
  };
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1903
1904
1905
1906
1907
1908
1909
1910
  static struct device_attribute *mce_device_attrs[] = {
  	&dev_attr_tolerant.attr,
  	&dev_attr_check_interval.attr,
  	&dev_attr_trigger,
  	&dev_attr_monarch_timeout.attr,
  	&dev_attr_dont_log_ce.attr,
  	&dev_attr_ignore_ce.attr,
  	&dev_attr_cmci_disabled.attr,
a98f0dd34   Andi Kleen   [PATCH] x86-64: A...
1911
1912
  	NULL
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1913

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1914
  static cpumask_var_t mce_device_initialized;
bae19fe03   Andreas Herrmann   x86: don't call m...
1915

e032d8077   Greg Kroah-Hartman   mce: fix warning ...
1916
1917
1918
1919
  static void mce_device_release(struct device *dev)
  {
  	kfree(dev);
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1920
1921
  /* Per cpu device init. All of the cpus still share the same ctrl bank: */
  static __cpuinit int mce_device_create(unsigned int cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
  {
e032d8077   Greg Kroah-Hartman   mce: fix warning ...
1923
  	struct device *dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1924
  	int err;
b1f49f958   Hidetoshi Seto   x86, mce: fix err...
1925
  	int i, j;
92cb7612a   Mike Travis   x86: convert cpui...
1926

903675569   Andreas Herrmann   x86: fix cpu-hotp...
1927
  	if (!mce_available(&boot_cpu_data))
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
1928
  		return -EIO;
e032d8077   Greg Kroah-Hartman   mce: fix warning ...
1929
1930
1931
  	dev = kzalloc(sizeof *dev, GFP_KERNEL);
  	if (!dev)
  		return -ENOMEM;
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1932
1933
  	dev->id  = cpu;
  	dev->bus = &mce_subsys;
e032d8077   Greg Kroah-Hartman   mce: fix warning ...
1934
  	dev->release = &mce_device_release;
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
1935

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1936
  	err = device_register(dev);
d435d862b   Akinobu Mita   cpu hotplug: mce:...
1937
1938
  	if (err)
  		return err;
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1939
1940
  	for (i = 0; mce_device_attrs[i]; i++) {
  		err = device_create_file(dev, mce_device_attrs[i]);
d435d862b   Akinobu Mita   cpu hotplug: mce:...
1941
1942
1943
  		if (err)
  			goto error;
  	}
b1f49f958   Hidetoshi Seto   x86, mce: fix err...
1944
  	for (j = 0; j < banks; j++) {
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1945
  		err = device_create_file(dev, &mce_banks[j].attr);
0d7482e3d   Andi Kleen   x86, mce: impleme...
1946
1947
1948
  		if (err)
  			goto error2;
  	}
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1949
  	cpumask_set_cpu(cpu, mce_device_initialized);
e032d8077   Greg Kroah-Hartman   mce: fix warning ...
1950
  	mce_device[cpu] = dev;
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
1951

d435d862b   Akinobu Mita   cpu hotplug: mce:...
1952
  	return 0;
0d7482e3d   Andi Kleen   x86, mce: impleme...
1953
  error2:
b1f49f958   Hidetoshi Seto   x86, mce: fix err...
1954
  	while (--j >= 0)
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1955
  		device_remove_file(dev, &mce_banks[j].attr);
d435d862b   Akinobu Mita   cpu hotplug: mce:...
1956
  error:
cb491fca5   Ingo Molnar   x86, mce: Rename ...
1957
  	while (--i >= 0)
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1958
  		device_remove_file(dev, mce_device_attrs[i]);
cb491fca5   Ingo Molnar   x86, mce: Rename ...
1959

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1960
  	device_unregister(dev);
d435d862b   Akinobu Mita   cpu hotplug: mce:...
1961

91c6d4009   Andi Kleen   [PATCH] x86_64: C...
1962
1963
  	return err;
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1964
  static __cpuinit void mce_device_remove(unsigned int cpu)
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
1965
  {
e032d8077   Greg Kroah-Hartman   mce: fix warning ...
1966
  	struct device *dev = mce_device[cpu];
73ca5358a   Shaohua Li   [PATCH] x86_64: i...
1967
  	int i;
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1968
  	if (!cpumask_test_cpu(cpu, mce_device_initialized))
bae19fe03   Andreas Herrmann   x86: don't call m...
1969
  		return;
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1970
1971
  	for (i = 0; mce_device_attrs[i]; i++)
  		device_remove_file(dev, mce_device_attrs[i]);
cb491fca5   Ingo Molnar   x86, mce: Rename ...
1972

0d7482e3d   Andi Kleen   x86, mce: impleme...
1973
  	for (i = 0; i < banks; i++)
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1974
  		device_remove_file(dev, &mce_banks[i].attr);
cb491fca5   Ingo Molnar   x86, mce: Rename ...
1975

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
1976
1977
  	device_unregister(dev);
  	cpumask_clear_cpu(cpu, mce_device_initialized);
e032d8077   Greg Kroah-Hartman   mce: fix warning ...
1978
  	mce_device[cpu] = NULL;
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
1979
  }
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
1980

d6b75584a   Andi Kleen   x86, mce: disable...
1981
  /* Make sure there are no machine checks on offlined CPUs. */
767df1bdd   Hidetoshi Seto   x86, mce: Add __c...
1982
  static void __cpuinit mce_disable_cpu(void *h)
d6b75584a   Andi Kleen   x86, mce: disable...
1983
  {
88ccbedd9   Andi Kleen   x86, mce, cmci: a...
1984
  	unsigned long action = *(unsigned long *)h;
cb491fca5   Ingo Molnar   x86, mce: Rename ...
1985
  	int i;
d6b75584a   Andi Kleen   x86, mce: disable...
1986

7b543a533   Tejun Heo   x86: Replace uses...
1987
  	if (!mce_available(__this_cpu_ptr(&cpu_info)))
d6b75584a   Andi Kleen   x86, mce: disable...
1988
  		return;
767df1bdd   Hidetoshi Seto   x86, mce: Add __c...
1989

88ccbedd9   Andi Kleen   x86, mce, cmci: a...
1990
1991
  	if (!(action & CPU_TASKS_FROZEN))
  		cmci_clear();
06b7a7a5e   Andi Kleen   x86, mce: impleme...
1992
  	for (i = 0; i < banks; i++) {
cebe18203   Andi Kleen   x86: mce: Move pe...
1993
  		struct mce_bank *b = &mce_banks[i];
11868a2dc   Ingo Molnar   x86: mce: Use saf...
1994

cebe18203   Andi Kleen   x86: mce: Move pe...
1995
  		if (b->init)
a2d32bcbc   Andi Kleen   x86: mce: macros ...
1996
  			wrmsrl(MSR_IA32_MCx_CTL(i), 0);
06b7a7a5e   Andi Kleen   x86, mce: impleme...
1997
  	}
d6b75584a   Andi Kleen   x86, mce: disable...
1998
  }
767df1bdd   Hidetoshi Seto   x86, mce: Add __c...
1999
  static void __cpuinit mce_reenable_cpu(void *h)
d6b75584a   Andi Kleen   x86, mce: disable...
2000
  {
88ccbedd9   Andi Kleen   x86, mce, cmci: a...
2001
  	unsigned long action = *(unsigned long *)h;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
2002
  	int i;
d6b75584a   Andi Kleen   x86, mce: disable...
2003

7b543a533   Tejun Heo   x86: Replace uses...
2004
  	if (!mce_available(__this_cpu_ptr(&cpu_info)))
d6b75584a   Andi Kleen   x86, mce: disable...
2005
  		return;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
2006

88ccbedd9   Andi Kleen   x86, mce, cmci: a...
2007
2008
  	if (!(action & CPU_TASKS_FROZEN))
  		cmci_reenable();
06b7a7a5e   Andi Kleen   x86, mce: impleme...
2009
  	for (i = 0; i < banks; i++) {
cebe18203   Andi Kleen   x86: mce: Move pe...
2010
  		struct mce_bank *b = &mce_banks[i];
11868a2dc   Ingo Molnar   x86: mce: Use saf...
2011

cebe18203   Andi Kleen   x86: mce: Move pe...
2012
  		if (b->init)
a2d32bcbc   Andi Kleen   x86: mce: macros ...
2013
  			wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl);
06b7a7a5e   Andi Kleen   x86, mce: impleme...
2014
  	}
d6b75584a   Andi Kleen   x86, mce: disable...
2015
  }
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2016
  /* Get notified when a cpu comes on/off. Be hotplug friendly. */
e9eee03e9   Ingo Molnar   x86, mce: clean u...
2017
2018
  static int __cpuinit
  mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2019
2020
  {
  	unsigned int cpu = (unsigned long)hcpu;
52d168e28   Andi Kleen   x86, mce: switch ...
2021
  	struct timer_list *t = &per_cpu(mce_timer, cpu);
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2022
2023
  
  	switch (action) {
bae19fe03   Andreas Herrmann   x86: don't call m...
2024
2025
  	case CPU_ONLINE:
  	case CPU_ONLINE_FROZEN:
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
2026
  		mce_device_create(cpu);
8735728ef   Rafael J. Wysocki   x86 MCE: Fix CPU ...
2027
2028
  		if (threshold_cpu_callback)
  			threshold_cpu_callback(action, cpu);
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2029
  		break;
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2030
  	case CPU_DEAD:
8bb784428   Rafael J. Wysocki   Add suspend-relat...
2031
  	case CPU_DEAD_FROZEN:
8735728ef   Rafael J. Wysocki   x86 MCE: Fix CPU ...
2032
2033
  		if (threshold_cpu_callback)
  			threshold_cpu_callback(action, cpu);
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
2034
  		mce_device_remove(cpu);
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2035
  		break;
52d168e28   Andi Kleen   x86, mce: switch ...
2036
2037
2038
  	case CPU_DOWN_PREPARE:
  	case CPU_DOWN_PREPARE_FROZEN:
  		del_timer_sync(t);
88ccbedd9   Andi Kleen   x86, mce, cmci: a...
2039
  		smp_call_function_single(cpu, mce_disable_cpu, &action, 1);
52d168e28   Andi Kleen   x86, mce: switch ...
2040
2041
2042
  		break;
  	case CPU_DOWN_FAILED:
  	case CPU_DOWN_FAILED_FROZEN:
fe5ed91dd   Hidetoshi Seto   x86, mce: don't r...
2043
2044
  		if (!mce_ignore_ce && check_interval) {
  			t->expires = round_jiffies(jiffies +
245b2e70e   Tejun Heo   percpu: clean up ...
2045
  					   __get_cpu_var(mce_next_interval));
fe5ed91dd   Hidetoshi Seto   x86, mce: don't r...
2046
2047
  			add_timer_on(t, cpu);
  		}
88ccbedd9   Andi Kleen   x86, mce, cmci: a...
2048
2049
2050
2051
2052
  		smp_call_function_single(cpu, mce_reenable_cpu, &action, 1);
  		break;
  	case CPU_POST_DEAD:
  		/* intentionally ignoring frozen here */
  		cmci_rediscover(cpu);
52d168e28   Andi Kleen   x86, mce: switch ...
2053
  		break;
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2054
  	}
bae19fe03   Andreas Herrmann   x86: don't call m...
2055
  	return NOTIFY_OK;
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2056
  }
1e35669d0   Sam Ravnborg   x86: fix section ...
2057
  static struct notifier_block mce_cpu_notifier __cpuinitdata = {
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2058
2059
  	.notifier_call = mce_cpu_callback,
  };
cebe18203   Andi Kleen   x86: mce: Move pe...
2060
  static __init void mce_init_banks(void)
0d7482e3d   Andi Kleen   x86, mce: impleme...
2061
2062
  {
  	int i;
0d7482e3d   Andi Kleen   x86, mce: impleme...
2063
  	for (i = 0; i < banks; i++) {
cebe18203   Andi Kleen   x86: mce: Move pe...
2064
  		struct mce_bank *b = &mce_banks[i];
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
2065
  		struct device_attribute *a = &b->attr;
e9eee03e9   Ingo Molnar   x86, mce: clean u...
2066

a07e4156a   Eric W. Biederman   sysfs: Use sysfs_...
2067
  		sysfs_attr_init(&a->attr);
cebe18203   Andi Kleen   x86: mce: Move pe...
2068
2069
  		a->attr.name	= b->attrname;
  		snprintf(b->attrname, ATTR_LEN, "bank%d", i);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
2070
2071
2072
2073
  
  		a->attr.mode	= 0644;
  		a->show		= show_bank;
  		a->store	= set_bank;
0d7482e3d   Andi Kleen   x86, mce: impleme...
2074
  	}
0d7482e3d   Andi Kleen   x86, mce: impleme...
2075
  }
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
2076
  static __init int mcheck_init_device(void)
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2077
2078
2079
  {
  	int err;
  	int i = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2080
2081
  	if (!mce_available(&boot_cpu_data))
  		return -EIO;
0d7482e3d   Andi Kleen   x86, mce: impleme...
2082

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
2083
  	zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL);
996867d09   Rusty Russell   cpumask: convert ...
2084

cebe18203   Andi Kleen   x86: mce: Move pe...
2085
  	mce_init_banks();
0d7482e3d   Andi Kleen   x86, mce: impleme...
2086

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
2087
  	err = subsys_system_register(&mce_subsys, NULL);
d435d862b   Akinobu Mita   cpu hotplug: mce:...
2088
2089
  	if (err)
  		return err;
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2090
2091
  
  	for_each_online_cpu(i) {
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
2092
  		err = mce_device_create(i);
d435d862b   Akinobu Mita   cpu hotplug: mce:...
2093
2094
  		if (err)
  			return err;
91c6d4009   Andi Kleen   [PATCH] x86_64: C...
2095
  	}
f3c6ea1b0   Rafael J. Wysocki   x86: Use syscore_...
2096
  	register_syscore_ops(&mce_syscore_ops);
be6b5a350   Chandra Seetharaman   [PATCH] cpu hotpl...
2097
  	register_hotcpu_notifier(&mce_cpu_notifier);
93b62c3cf   Hidetoshi Seto   x86, mce: Use mce...
2098
2099
2100
  
  	/* register character device /dev/mcelog */
  	misc_register(&mce_chrdev_device);
e9eee03e9   Ingo Molnar   x86, mce: clean u...
2101

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2102
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2103
  }
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
2104
  device_initcall(mcheck_init_device);
a988d334a   Ingo Molnar   x86, mce: unify, ...
2105

d7c3c9a60   Andi Kleen   x86, mce: move mc...
2106
2107
2108
2109
2110
2111
2112
2113
2114
  /*
   * Old style boot options parsing. Only for compatibility.
   */
  static int __init mcheck_disable(char *str)
  {
  	mce_disabled = 1;
  	return 1;
  }
  __setup("nomce", mcheck_disable);
a988d334a   Ingo Molnar   x86, mce: unify, ...
2115

5be9ed251   Huang Ying   x86, mce: Move de...
2116
2117
  #ifdef CONFIG_DEBUG_FS
  struct dentry *mce_get_debugfs_dir(void)
a988d334a   Ingo Molnar   x86, mce: unify, ...
2118
  {
5be9ed251   Huang Ying   x86, mce: Move de...
2119
  	static struct dentry *dmce;
a988d334a   Ingo Molnar   x86, mce: unify, ...
2120

5be9ed251   Huang Ying   x86, mce: Move de...
2121
2122
  	if (!dmce)
  		dmce = debugfs_create_dir("mce", NULL);
a988d334a   Ingo Molnar   x86, mce: unify, ...
2123

5be9ed251   Huang Ying   x86, mce: Move de...
2124
2125
  	return dmce;
  }
a988d334a   Ingo Molnar   x86, mce: unify, ...
2126

bf783f9f7   Huang Ying   x86, mce: Fake pa...
2127
2128
2129
2130
2131
2132
2133
2134
  static void mce_reset(void)
  {
  	cpu_missing = 0;
  	atomic_set(&mce_fake_paniced, 0);
  	atomic_set(&mce_executing, 0);
  	atomic_set(&mce_callin, 0);
  	atomic_set(&global_nwo, 0);
  }
a988d334a   Ingo Molnar   x86, mce: unify, ...
2135

bf783f9f7   Huang Ying   x86, mce: Fake pa...
2136
2137
2138
2139
  static int fake_panic_get(void *data, u64 *val)
  {
  	*val = fake_panic;
  	return 0;
a988d334a   Ingo Molnar   x86, mce: unify, ...
2140
  }
bf783f9f7   Huang Ying   x86, mce: Fake pa...
2141
  static int fake_panic_set(void *data, u64 val)
a988d334a   Ingo Molnar   x86, mce: unify, ...
2142
  {
bf783f9f7   Huang Ying   x86, mce: Fake pa...
2143
2144
2145
  	mce_reset();
  	fake_panic = val;
  	return 0;
a988d334a   Ingo Molnar   x86, mce: unify, ...
2146
  }
a988d334a   Ingo Molnar   x86, mce: unify, ...
2147

bf783f9f7   Huang Ying   x86, mce: Fake pa...
2148
2149
2150
  DEFINE_SIMPLE_ATTRIBUTE(fake_panic_fops, fake_panic_get,
  			fake_panic_set, "%llu
  ");
d7c3c9a60   Andi Kleen   x86, mce: move mc...
2151

5e09954a9   Borislav Petkov   x86, mce: Fix up ...
2152
  static int __init mcheck_debugfs_init(void)
d7c3c9a60   Andi Kleen   x86, mce: move mc...
2153
  {
bf783f9f7   Huang Ying   x86, mce: Fake pa...
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
  	struct dentry *dmce, *ffake_panic;
  
  	dmce = mce_get_debugfs_dir();
  	if (!dmce)
  		return -ENOMEM;
  	ffake_panic = debugfs_create_file("fake_panic", 0444, dmce, NULL,
  					  &fake_panic_fops);
  	if (!ffake_panic)
  		return -ENOMEM;
  
  	return 0;
d7c3c9a60   Andi Kleen   x86, mce: move mc...
2165
  }
5e09954a9   Borislav Petkov   x86, mce: Fix up ...
2166
  late_initcall(mcheck_debugfs_init);
5be9ed251   Huang Ying   x86, mce: Move de...
2167
  #endif