67ad39b944d78b2bbf209c7144723776a00e5764
[linux-flexiantxendom0-natty.git] / arch / x86 / kernel / cpu / mcheck / mce-xeon75xx.c
1 /*
2  * Xeon 7500 series specific machine check support code.
3  * Copyright 2009, 2010 Intel Corporation
4  * Author: Andi Kleen
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 2
9  * of the License.
10  *
11  * Implement Xeon 7500 series specific code to retrieve the physical address
12  * and DIMM information for corrected memory errors.
13  *
14  * Interface: mce->aux0/aux1 is mapped to a struct pfa_dimm with pad
15  * redefined to DIMM valid bits. Consumers check CPUID and bank and
16  * then interpret aux0/aux1
17  */
18
19 /* #define DEBUG 1 */   /* disable for production */
20 #define pr_fmt(x) "MCE: " x
21
22 #include <linux/moduleparam.h>
23 #include <linux/pci_ids.h>
24 #include <linux/hrtimer.h>
25 #include <linux/string.h>
26 #include <linux/module.h>
27 #include <linux/kernel.h>
28 #include <linux/ktime.h>
29 #include <linux/init.h>
30 #include <linux/pci.h>
31 #include <asm/processor.h>
32 #include <asm/e820.h>
33 #include <asm/mce.h>
34 #include <asm/io.h>
35
36 #include "mce-internal.h"
37
38 #define PFA_SIG "$PFA"
39 #define PFA_SIG_LEN 4
40
41 /* DIMM description */
42 struct aux_pfa_dimm {
43         u8  fbd_channel_id;
44         u8  ddr_channel_id;
45         u8  ddr_dimm_id;
46         u8  ddr_rank_id;
47         u8  ddr_dimm_bank_id;
48         u8  ddr_dimm_row_id;
49         u8  ddr_dimm_column_id;
50         u8  valid;
51 } __attribute__((packed));
52
53 struct pfa_dimm {
54         u8  fbd_channel_id;
55         u8  ddr_channel_id;
56         u8  ddr_dimm_id;
57         u8  ddr_rank_id;
58         u8  ddr_dimm_bank_id;
59         u32 ddr_dimm_row_id;
60         u32 ddr_dimm_column_id;
61 } __attribute__((packed));
62
63 /* Memory translation table in memory. */
64 struct pfa_table {
65         u8  sig[PFA_SIG_LEN];   /* Signature: '$PFA' */
66         u16 len;                /* total length */
67         u16 revision;           /* 0x11 */
68         u8  checksum;           /* 8bit sum to zero */
69         u8  db_value;           /* mailbox port command value */
70         u8  db_port;            /* mailbox port */
71         /* end of header; end of checksum */
72         u8  command;            /* input command */
73         u32 valid;              /* valid input/output bits */
74         u16 status;             /* output status */
75         u8  socket_id;          /* input socket id*/
76         u8  bank_id;            /* input MCE bank id */
77         u32 pad1;
78         u64 mbox_address;
79         u64 physical_addr;      /* physical address */
80         struct pfa_dimm dimm[2];
81         /*
82          * topology information follows: not used for now.
83          */
84 } __attribute__((packed));
85
86 /* DIMM valid bits in valid: DIMM0: 8..12; DIMM1 16..20 */
87 #define DIMM_VALID_BITS(val, num) (((val) >> (4 + (num) * 8)) & DIMM_VALID_ALL)
88 #define DIMM_SET_VALID(val, num)  ((val) << (4 + (num) * 8))
89
90 enum {
91         MCE_BANK_MBOX0          = 8,
92         MCE_BANK_MBOX1          = 9,
93
94         PFA_REVISION            = 0x11,         /* v1.1 */
95
96         /* Status bits for valid field */
97         PFA_VALID_MA            = (1 << 0),
98         PFA_VALID_SOCKETID      = (1 << 1),
99         PFA_VALID_BANKID        = (1 << 2),
100         PFA_VALID_PA            = (1 << 3),
101
102         /* DIMM valid bits in valid */
103         /* use with DIMM_VALID_BITS/DIMM_SET_VALID for pfa->valid */
104         DIMM_VALID_FBD_CHAN      = (1 << 0),
105         DIMM_VALID_DDR_CHAN      = (1 << 1),
106         DIMM_VALID_DDR_DIMM      = (1 << 2),
107         DIMM_VALID_DDR_RANK      = (1 << 3),
108         DIMM_VALID_DIMM_BANK     = (1 << 4),
109         DIMM_VALID_DIMM_ROW      = (1 << 5),
110         DIMM_VALID_DIMM_COLUMN   = (1 << 6),
111         DIMM_VALID_ALL           = 0x7f,
112
113         PFA_DIMM_VALID_MASK      = DIMM_SET_VALID(DIMM_VALID_ALL, 0)
114                                  | DIMM_SET_VALID(DIMM_VALID_ALL, 1),
115
116         /* Values for status field */
117         PFA_STATUS_SUCCESS      = 0,
118         PFA_STATUS_SOCKET_INVALID  = (1 << 1),
119         PFA_STATUS_MBOX_INVALID = (1 << 2),
120         PFA_STATUS_MA_INVALID   = (1 << 3),
121         PFA_STATUS_PA_INVALID   = (1 << 4),
122
123         /* Values for command field */
124         PFA_CMD_GET_MEM_CORR_ERR_PA = 0,
125         PFA_CMD_PA_TO_DIMM_ADDR     = 1,
126         PFA_CMD_DIMM_TO_PA          = 2,
127         PFA_CMD_GET_TOPOLOGY        = 3,
128
129         /* PCI device IDs and the base register */
130         ICH_PFA_CFG             = 0x8c, /* SCRATCH4 */
131         PCI_DEVICE_ID_BXB_ICH_LEGACY0 = 0x3422,
132 };
133
134 static struct pfa_table *pfa_table __read_mostly;
135 static int memerr_max_conv_rate __read_mostly = 100;
136 static int memerr_min_interval __read_mostly = 500;
137 static int pfa_lost;    /* for diagnosis */
138
139 enum {
140         RATE_LIMIT_PERIOD = USEC_PER_SEC, /* in us; period of rate limit */
141 };
142
143 module_param(memerr_max_conv_rate, int, 0644);
144 MODULE_PARM_DESC(memerr_max_conv_rate,
145         "Maximum number of memory error conversions each second; 0 to disable");
146 module_param(memerr_min_interval, int, 0644);
147 MODULE_PARM_DESC(memerr_min_interval,
148         "Minimum time delta between two memory conversions; in us; default 500");
149
150 static int notest;
151 static int nocsum;
152 module_param(notest, int, 0);
153 module_param(nocsum, int, 0);
154
155 static u64 encode_dimm(struct pfa_dimm *d, u8 valid)
156 {
157         union {
158                 struct aux_pfa_dimm d;
159                 u64 v;
160         } p;
161
162         BUILD_BUG_ON(sizeof(struct aux_pfa_dimm) != sizeof(u64));
163         p.d.fbd_channel_id = d->fbd_channel_id;
164         p.d.ddr_channel_id = d->ddr_channel_id;
165         p.d.ddr_dimm_id = d->ddr_dimm_id;
166         p.d.ddr_rank_id = d->ddr_rank_id;
167         p.d.ddr_dimm_bank_id = d->ddr_dimm_bank_id;
168         p.d.ddr_dimm_row_id = d->ddr_dimm_row_id;
169         if (p.d.ddr_dimm_row_id != d->ddr_dimm_row_id) /* truncated? */
170                 valid &= ~DIMM_VALID_DIMM_ROW;
171         p.d.ddr_dimm_column_id = d->ddr_dimm_column_id;
172         if (p.d.ddr_dimm_column_id != d->ddr_dimm_column_id)
173                 valid &= ~DIMM_VALID_DIMM_COLUMN;
174         p.d.valid = valid;
175         pr_debug("PFA fbd_ch %u ddr_ch %u dimm %u rank %u bank %u valid %x\n",
176                  d->fbd_channel_id,
177                  d->ddr_channel_id,
178                  d->ddr_dimm_id,
179                  d->ddr_rank_id,
180                  d->ddr_dimm_bank_id,
181                  valid);
182         return p.v;
183 }
184
185 static u8 csum(u8 *table, u16 len)
186 {
187         u8 sum = 0;
188         int i;
189         for (i = 0; i < len; i++)
190                 sum += *table++;
191         return sum;
192 }
193
194 /*
195  * Execute a command through the mailbox interface.
196  */
197 static int
198 pfa_command(unsigned bank, unsigned socketid, unsigned command, unsigned valid)
199 {
200         pfa_table->bank_id = bank;
201         pfa_table->socket_id = socketid;
202         pfa_table->valid = valid | PFA_VALID_SOCKETID;
203         pfa_table->command = command;
204
205         outb(pfa_table->db_value, pfa_table->db_port);
206
207         mb();   /* Reread fields after they got changed */
208
209         if (pfa_table->status != PFA_STATUS_SUCCESS) {
210                 pr_debug("Memory PFA command %d failed: socket:%d bank:%d status:%x\n",
211                         command, socketid, bank, pfa_table->status);
212                 return -pfa_table->status;
213         }
214         return 0;
215 }
216
217 /*
218  * Retrieve physical address and DIMMs.
219  */
220 static int translate_memory_error(struct mce *m)
221 {
222         struct pfa_table *pfa = pfa_table;
223         u64 status;
224         int ret;
225         u32 valid;
226         int cpu = smp_processor_id();
227
228         /* Make sure our structures match the specification */
229         BUILD_BUG_ON(offsetof(struct pfa_table, physical_addr) != 0x20);
230         BUILD_BUG_ON(offsetof(struct pfa_table, status) != 0x10);
231         BUILD_BUG_ON(offsetof(struct pfa_table, physical_addr) != 0x20);
232         BUILD_BUG_ON(offsetof(struct pfa_table, dimm[1].ddr_dimm_column_id) !=
233                         0x3e);
234
235         /* Ask for PA/DIMMs of last error */
236         if (pfa_command(m->bank, m->socketid,
237                         PFA_CMD_GET_MEM_CORR_ERR_PA, PFA_VALID_BANKID) < 0)
238                 return -1;
239
240         /*
241          * Recheck machine check bank. If the overflow bit was set
242          * there was a race. Don't use the information in this case.
243          */
244         rdmsrl(MSR_IA32_MCx_STATUS(m->bank), status);
245         if (status & MCI_STATUS_OVER) {
246                 pr_debug("%d: overflow race on bank %d\n", cpu, m->bank);
247                 return -1;
248         }
249
250         ret = -1;
251         valid = pfa->valid;
252         if (valid & PFA_VALID_PA) {
253                 m->status |= MCI_STATUS_ADDRV;
254                 m->addr = pfa_table->physical_addr;
255                 pr_debug("%d: got physical address %llx valid %x\n",
256                         cpu, m->addr, valid);
257                 ret = 0;
258         }
259
260         /* When DIMM information was supplied pass it out */
261         if (valid & PFA_DIMM_VALID_MASK) {
262                 m->aux0 = encode_dimm(&pfa->dimm[0], DIMM_VALID_BITS(valid, 0));
263                 m->aux1 = encode_dimm(&pfa->dimm[1], DIMM_VALID_BITS(valid, 1));
264                 ret = 0;
265         }
266
267         return ret;
268 }
269
270 /*
271  * Xeon 75xx specific mce poll method to retrieve the physical address
272  * and DIMM information.
273  */
274 static void xeon75xx_mce_poll(struct mce *m)
275 {
276         static DEFINE_SPINLOCK(convert_lock); /* Protect table and static */
277         static unsigned long cperm;
278         static ktime_t last, last_int;
279         unsigned long flags;
280         ktime_t now;
281         s64 delta;
282
283         /* Memory error? */
284         if (m->bank != MCE_BANK_MBOX0 && m->bank != MCE_BANK_MBOX1)
285                 return;
286         if (m->status & MCI_STATUS_OVER)
287                 return;
288         if (memerr_max_conv_rate == 0)
289                 return;
290
291         spin_lock_irqsave(&convert_lock, flags);
292         /*
293          * Rate limit conversions. The conversion takes some time,
294          * but it's not good to use all the CPU time during a error
295          * flood.
296          * Enforce maximum number per second and minimum interval.
297          * The ktime call should use TSC on this machine and be fast.
298          */
299         now = ktime_get();
300         delta = ktime_us_delta(now, last);
301         if (delta >= RATE_LIMIT_PERIOD) {
302                 cperm = 0;
303                 last = now;
304         }
305         if (ktime_us_delta(now, last_int) >= memerr_min_interval &&
306            ++cperm <= memerr_max_conv_rate) {
307                 if (translate_memory_error(m) < 0) {
308                         /* On error stop converting for the next second */
309                         cperm = memerr_max_conv_rate;
310                         pr_debug("PFA translation failed\n");
311                 }
312         } else
313                 pfa_lost++;
314         last_int = now;
315         spin_unlock_irqrestore(&convert_lock, flags);
316 }
317
318 static struct pci_device_id bxb_mce_pciids[] = {
319         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_BXB_ICH_LEGACY0) },
320         {}
321 };
322
323 static int __init xeon75xx_mce_init(void)
324 {
325         u32 addr = 0;
326         struct pci_dev *dev;
327
328         if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
329             boot_cpu_data.x86 != 6 ||
330             boot_cpu_data.x86_model != 0x2e)
331                 return -ENODEV;
332
333         /*
334          * Get table address from register in IOH.
335          * This just looks up the device, because we don't want to "own" it.
336          */
337         dev = NULL;
338         while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, dev))
339                         != NULL) {
340                 if (!pci_match_id(bxb_mce_pciids, dev))
341                         continue;
342                 pci_read_config_dword(dev, ICH_PFA_CFG, &addr);
343                 if (addr)
344                         break;
345         }
346         pci_dev_put(dev);
347         if (!addr)
348                 return -ENODEV;
349
350         if (!e820_all_mapped(addr, addr + PAGE_SIZE, E820_RESERVED)) {
351                 pr_info("PFA table at %x not e820 reserved\n", addr);
352                 return -ENODEV;
353         }
354
355         pfa_table = (__force struct pfa_table *)ioremap_cache(addr, PAGE_SIZE);
356         if (!pfa_table) {
357                 pr_err("Cannot map PFA table at %x\n", addr);
358                 return -EIO;
359         }
360
361         if (memcmp(&pfa_table->sig, PFA_SIG, PFA_SIG_LEN) ||
362             pfa_table->len < sizeof(struct pfa_table) ||
363             /* assume newer versions are compatible */
364             pfa_table->revision < PFA_REVISION) {
365                 pr_info("PFA table at %x invalid\n", addr);
366                 goto error_unmap;
367         }
368
369         if (!nocsum && csum((u8 *)pfa_table,
370                                 offsetof(struct pfa_table, command))) {
371                 pr_info("PFA table at %x length %u has invalid checksum\n",
372                         addr, pfa_table->len);
373                 goto error_unmap;
374         }
375
376         /* Not strictly needed today */
377         if (pfa_table->len > PAGE_SIZE) {
378                 unsigned len = roundup(pfa_table->len, PAGE_SIZE);
379                 iounmap(pfa_table);
380                 pfa_table = (__force void *)ioremap_cache(addr, len);
381                 if (!pfa_table) {
382                         pr_err("Cannot remap %u bytes PFA table at %x\n",
383                                 len, addr);
384                         return -EIO;
385                 }
386         }
387
388         if (!notest) {
389                 int status = pfa_command(0, 0, PFA_CMD_GET_TOPOLOGY, 0);
390                 if (status < 0) {
391                         pr_err("Test of PFA table failed: %x\n", -status);
392                         goto error_unmap;
393                 }
394         }
395
396         pr_info("Found Xeon75xx PFA memory error translation table at %x\n",
397                 addr);
398         mb();
399         cpu_specific_poll = xeon75xx_mce_poll;
400         return 0;
401
402 error_unmap:
403         iounmap(pfa_table);
404         return -ENODEV;
405 }
406
407 MODULE_DEVICE_TABLE(pci, bxb_mce_pciids);
408 MODULE_LICENSE("GPL v2");
409 MODULE_AUTHOR("Andi Kleen");
410 MODULE_DESCRIPTION("Intel Xeon 75xx specific DIMM error reporting");
411
412 #ifdef CONFIG_MODULE
413 static void __exit xeon75xx_mce_exit(void)
414 {
415         cpu_specific_poll = NULL;
416         wmb();
417         /* Wait for all machine checks to finish before really unloading */
418         synchronize_rcu();
419         iounmap(pfa_table);
420 }
421
422 module_init(xeon75xx_mce_init);
423 module_exit(xeon75xx_mce_exit);
424 #else
425 /* When built-in run as soon as the PCI subsystem is up */
426 fs_initcall(xeon75xx_mce_init);
427 #endif