linux/arch/x86/kernel/cpu/mcheck/mce_amd.c
<<
>>
Prefs
   1/*
   2 *  (c) 2005-2012 Advanced Micro Devices, Inc.
   3 *  Your use of this code is subject to the terms and conditions of the
   4 *  GNU general public license version 2. See "COPYING" or
   5 *  http://www.gnu.org/licenses/gpl.html
   6 *
   7 *  Written by Jacob Shin - AMD, Inc.
   8 *
   9 *  Maintained by: Borislav Petkov <bp@alien8.de>
  10 *
  11 *  April 2006
  12 *     - added support for AMD Family 0x10 processors
  13 *  May 2012
  14 *     - major scrubbing
  15 *
  16 *  All MC4_MISCi registers are shared between multi-cores
  17 */
  18#include <linux/interrupt.h>
  19#include <linux/notifier.h>
  20#include <linux/kobject.h>
  21#include <linux/percpu.h>
  22#include <linux/errno.h>
  23#include <linux/sched.h>
  24#include <linux/sysfs.h>
  25#include <linux/slab.h>
  26#include <linux/init.h>
  27#include <linux/cpu.h>
  28#include <linux/smp.h>
  29
  30#include <asm/amd_nb.h>
  31#include <asm/apic.h>
  32#include <asm/idle.h>
  33#include <asm/mce.h>
  34#include <asm/msr.h>
  35
  36#define NR_BANKS          6
  37#define NR_BLOCKS         9
  38#define THRESHOLD_MAX     0xFFF
  39#define INT_TYPE_APIC     0x00020000
  40#define MASK_VALID_HI     0x80000000
  41#define MASK_CNTP_HI      0x40000000
  42#define MASK_LOCKED_HI    0x20000000
  43#define MASK_LVTOFF_HI    0x00F00000
  44#define MASK_COUNT_EN_HI  0x00080000
  45#define MASK_INT_TYPE_HI  0x00060000
  46#define MASK_OVERFLOW_HI  0x00010000
  47#define MASK_ERR_COUNT_HI 0x00000FFF
  48#define MASK_BLKPTR_LO    0xFF000000
  49#define MCG_XBLK_ADDR     0xC0000400
  50
  51static const char * const th_names[] = {
  52        "load_store",
  53        "insn_fetch",
  54        "combined_unit",
  55        "",
  56        "northbridge",
  57        "execution_unit",
  58};
  59
  60static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks);
  61
  62static unsigned char shared_bank[NR_BANKS] = {
  63        0, 0, 0, 0, 1
  64};
  65
  66static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
  67
  68static void amd_threshold_interrupt(void);
  69
  70/*
  71 * CPU Initialization
  72 */
  73
  74struct thresh_restart {
  75        struct threshold_block  *b;
  76        int                     reset;
  77        int                     set_lvt_off;
  78        int                     lvt_off;
  79        u16                     old_limit;
  80};
  81
  82static const char * const bank4_names(struct threshold_block *b)
  83{
  84        switch (b->address) {
  85        /* MSR4_MISC0 */
  86        case 0x00000413:
  87                return "dram";
  88
  89        case 0xc0000408:
  90                return "ht_links";
  91
  92        case 0xc0000409:
  93                return "l3_cache";
  94
  95        default:
  96                WARN(1, "Funny MSR: 0x%08x\n", b->address);
  97                return "";
  98        }
  99};
 100
 101
 102static bool lvt_interrupt_supported(unsigned int bank, u32 msr_high_bits)
 103{
 104        /*
 105         * bank 4 supports APIC LVT interrupts implicitly since forever.
 106         */
 107        if (bank == 4)
 108                return true;
 109
 110        /*
 111         * IntP: interrupt present; if this bit is set, the thresholding
 112         * bank can generate APIC LVT interrupts
 113         */
 114        return msr_high_bits & BIT(28);
 115}
 116
 117static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
 118{
 119        int msr = (hi & MASK_LVTOFF_HI) >> 20;
 120
 121        if (apic < 0) {
 122                pr_err(FW_BUG "cpu %d, failed to setup threshold interrupt "
 123                       "for bank %d, block %d (MSR%08X=0x%x%08x)\n", b->cpu,
 124                       b->bank, b->block, b->address, hi, lo);
 125                return 0;
 126        }
 127
 128        if (apic != msr) {
 129                pr_err(FW_BUG "cpu %d, invalid threshold interrupt offset %d "
 130                       "for bank %d, block %d (MSR%08X=0x%x%08x)\n",
 131                       b->cpu, apic, b->bank, b->block, b->address, hi, lo);
 132                return 0;
 133        }
 134
 135        return 1;
 136};
 137
 138/*
 139 * Called via smp_call_function_single(), must be called with correct
 140 * cpu affinity.
 141 */
 142static void threshold_restart_bank(void *_tr)
 143{
 144        struct thresh_restart *tr = _tr;
 145        u32 hi, lo;
 146
 147        rdmsr(tr->b->address, lo, hi);
 148
 149        if (tr->b->threshold_limit < (hi & THRESHOLD_MAX))
 150                tr->reset = 1;  /* limit cannot be lower than err count */
 151
 152        if (tr->reset) {                /* reset err count and overflow bit */
 153                hi =
 154                    (hi & ~(MASK_ERR_COUNT_HI | MASK_OVERFLOW_HI)) |
 155                    (THRESHOLD_MAX - tr->b->threshold_limit);
 156        } else if (tr->old_limit) {     /* change limit w/o reset */
 157                int new_count = (hi & THRESHOLD_MAX) +
 158                    (tr->old_limit - tr->b->threshold_limit);
 159
 160                hi = (hi & ~MASK_ERR_COUNT_HI) |
 161                    (new_count & THRESHOLD_MAX);
 162        }
 163
 164        /* clear IntType */
 165        hi &= ~MASK_INT_TYPE_HI;
 166
 167        if (!tr->b->interrupt_capable)
 168                goto done;
 169
 170        if (tr->set_lvt_off) {
 171                if (lvt_off_valid(tr->b, tr->lvt_off, lo, hi)) {
 172                        /* set new lvt offset */
 173                        hi &= ~MASK_LVTOFF_HI;
 174                        hi |= tr->lvt_off << 20;
 175                }
 176        }
 177
 178        if (tr->b->interrupt_enable)
 179                hi |= INT_TYPE_APIC;
 180
 181 done:
 182
 183        hi |= MASK_COUNT_EN_HI;
 184        wrmsr(tr->b->address, lo, hi);
 185}
 186
 187static void mce_threshold_block_init(struct threshold_block *b, int offset)
 188{
 189        struct thresh_restart tr = {
 190                .b                      = b,
 191                .set_lvt_off            = 1,
 192                .lvt_off                = offset,
 193        };
 194
 195        b->threshold_limit              = THRESHOLD_MAX;
 196        threshold_restart_bank(&tr);
 197};
 198
 199static int setup_APIC_mce(int reserved, int new)
 200{
 201        if (reserved < 0 && !setup_APIC_eilvt(new, THRESHOLD_APIC_VECTOR,
 202                                              APIC_EILVT_MSG_FIX, 0))
 203                return new;
 204
 205        return reserved;
 206}
 207
 208/* cpu init entry point, called from mce.c with preempt off */
 209void mce_amd_feature_init(struct cpuinfo_x86 *c)
 210{
 211        struct threshold_block b;
 212        unsigned int cpu = smp_processor_id();
 213        u32 low = 0, high = 0, address = 0;
 214        unsigned int bank, block;
 215        int offset = -1;
 216
 217        for (bank = 0; bank < NR_BANKS; ++bank) {
 218                for (block = 0; block < NR_BLOCKS; ++block) {
 219                        if (block == 0)
 220                                address = MSR_IA32_MC0_MISC + bank * 4;
 221                        else if (block == 1) {
 222                                address = (low & MASK_BLKPTR_LO) >> 21;
 223                                if (!address)
 224                                        break;
 225
 226                                address += MCG_XBLK_ADDR;
 227                        } else
 228                                ++address;
 229
 230                        if (rdmsr_safe(address, &low, &high))
 231                                break;
 232
 233                        if (!(high & MASK_VALID_HI))
 234                                continue;
 235
 236                        if (!(high & MASK_CNTP_HI)  ||
 237                             (high & MASK_LOCKED_HI))
 238                                continue;
 239
 240                        if (!block)
 241                                per_cpu(bank_map, cpu) |= (1 << bank);
 242
 243                        memset(&b, 0, sizeof(b));
 244                        b.cpu                   = cpu;
 245                        b.bank                  = bank;
 246                        b.block                 = block;
 247                        b.address               = address;
 248                        b.interrupt_capable     = lvt_interrupt_supported(bank, high);
 249
 250                        if (b.interrupt_capable) {
 251                                int new = (high & MASK_LVTOFF_HI) >> 20;
 252                                offset  = setup_APIC_mce(offset, new);
 253                        }
 254
 255                        mce_threshold_block_init(&b, offset);
 256                        mce_threshold_vector = amd_threshold_interrupt;
 257                }
 258        }
 259}
 260
 261/*
 262 * APIC Interrupt Handler
 263 */
 264
 265/*
 266 * threshold interrupt handler will service THRESHOLD_APIC_VECTOR.
 267 * the interrupt goes off when error_count reaches threshold_limit.
 268 * the handler will simply log mcelog w/ software defined bank number.
 269 */
 270static void amd_threshold_interrupt(void)
 271{
 272        u32 low = 0, high = 0, address = 0;
 273        unsigned int bank, block;
 274        struct mce m;
 275
 276        mce_setup(&m);
 277
 278        /* assume first bank caused it */
 279        for (bank = 0; bank < NR_BANKS; ++bank) {
 280                if (!(per_cpu(bank_map, m.cpu) & (1 << bank)))
 281                        continue;
 282                for (block = 0; block < NR_BLOCKS; ++block) {
 283                        if (block == 0) {
 284                                address = MSR_IA32_MC0_MISC + bank * 4;
 285                        } else if (block == 1) {
 286                                address = (low & MASK_BLKPTR_LO) >> 21;
 287                                if (!address)
 288                                        break;
 289                                address += MCG_XBLK_ADDR;
 290                        } else {
 291                                ++address;
 292                        }
 293
 294                        if (rdmsr_safe(address, &low, &high))
 295                                break;
 296
 297                        if (!(high & MASK_VALID_HI)) {
 298                                if (block)
 299                                        continue;
 300                                else
 301                                        break;
 302                        }
 303
 304                        if (!(high & MASK_CNTP_HI)  ||
 305                             (high & MASK_LOCKED_HI))
 306                                continue;
 307
 308                        /*
 309                         * Log the machine check that caused the threshold
 310                         * event.
 311                         */
 312                        machine_check_poll(MCP_TIMESTAMP,
 313                                        &__get_cpu_var(mce_poll_banks));
 314
 315                        if (high & MASK_OVERFLOW_HI) {
 316                                rdmsrl(address, m.misc);
 317                                rdmsrl(MSR_IA32_MC0_STATUS + bank * 4,
 318                                       m.status);
 319                                m.bank = K8_MCE_THRESHOLD_BASE
 320                                       + bank * NR_BLOCKS
 321                                       + block;
 322                                mce_log(&m);
 323                                return;
 324                        }
 325                }
 326        }
 327}
 328
 329/*
 330 * Sysfs Interface
 331 */
 332
 333struct threshold_attr {
 334        struct attribute attr;
 335        ssize_t (*show) (struct threshold_block *, char *);
 336        ssize_t (*store) (struct threshold_block *, const char *, size_t count);
 337};
 338
 339#define SHOW_FIELDS(name)                                               \
 340static ssize_t show_ ## name(struct threshold_block *b, char *buf)      \
 341{                                                                       \
 342        return sprintf(buf, "%lu\n", (unsigned long) b->name);          \
 343}
 344SHOW_FIELDS(interrupt_enable)
 345SHOW_FIELDS(threshold_limit)
 346
 347static ssize_t
 348store_interrupt_enable(struct threshold_block *b, const char *buf, size_t size)
 349{
 350        struct thresh_restart tr;
 351        unsigned long new;
 352
 353        if (!b->interrupt_capable)
 354                return -EINVAL;
 355
 356        if (strict_strtoul(buf, 0, &new) < 0)
 357                return -EINVAL;
 358
 359        b->interrupt_enable = !!new;
 360
 361        memset(&tr, 0, sizeof(tr));
 362        tr.b            = b;
 363
 364        smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
 365
 366        return size;
 367}
 368
 369static ssize_t
 370store_threshold_limit(struct threshold_block *b, const char *buf, size_t size)
 371{
 372        struct thresh_restart tr;
 373        unsigned long new;
 374
 375        if (strict_strtoul(buf, 0, &new) < 0)
 376                return -EINVAL;
 377
 378        if (new > THRESHOLD_MAX)
 379                new = THRESHOLD_MAX;
 380        if (new < 1)
 381                new = 1;
 382
 383        memset(&tr, 0, sizeof(tr));
 384        tr.old_limit = b->threshold_limit;
 385        b->threshold_limit = new;
 386        tr.b = b;
 387
 388        smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
 389
 390        return size;
 391}
 392
 393static ssize_t show_error_count(struct threshold_block *b, char *buf)
 394{
 395        u32 lo, hi;
 396
 397        rdmsr_on_cpu(b->cpu, b->address, &lo, &hi);
 398
 399        return sprintf(buf, "%u\n", ((hi & THRESHOLD_MAX) -
 400                                     (THRESHOLD_MAX - b->threshold_limit)));
 401}
 402
 403static struct threshold_attr error_count = {
 404        .attr = {.name = __stringify(error_count), .mode = 0444 },
 405        .show = show_error_count,
 406};
 407
 408#define RW_ATTR(val)                                                    \
 409static struct threshold_attr val = {                                    \
 410        .attr   = {.name = __stringify(val), .mode = 0644 },            \
 411        .show   = show_## val,                                          \
 412        .store  = store_## val,                                         \
 413};
 414
 415RW_ATTR(interrupt_enable);
 416RW_ATTR(threshold_limit);
 417
 418static struct attribute *default_attrs[] = {
 419        &threshold_limit.attr,
 420        &error_count.attr,
 421        NULL,   /* possibly interrupt_enable if supported, see below */
 422        NULL,
 423};
 424
 425#define to_block(k)     container_of(k, struct threshold_block, kobj)
 426#define to_attr(a)      container_of(a, struct threshold_attr, attr)
 427
 428static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
 429{
 430        struct threshold_block *b = to_block(kobj);
 431        struct threshold_attr *a = to_attr(attr);
 432        ssize_t ret;
 433
 434        ret = a->show ? a->show(b, buf) : -EIO;
 435
 436        return ret;
 437}
 438
 439static ssize_t store(struct kobject *kobj, struct attribute *attr,
 440                     const char *buf, size_t count)
 441{
 442        struct threshold_block *b = to_block(kobj);
 443        struct threshold_attr *a = to_attr(attr);
 444        ssize_t ret;
 445
 446        ret = a->store ? a->store(b, buf, count) : -EIO;
 447
 448        return ret;
 449}
 450
 451static const struct sysfs_ops threshold_ops = {
 452        .show                   = show,
 453        .store                  = store,
 454};
 455
 456static struct kobj_type threshold_ktype = {
 457        .sysfs_ops              = &threshold_ops,
 458        .default_attrs          = default_attrs,
 459};
 460
 461static __cpuinit int allocate_threshold_blocks(unsigned int cpu,
 462                                               unsigned int bank,
 463                                               unsigned int block,
 464                                               u32 address)
 465{
 466        struct threshold_block *b = NULL;
 467        u32 low, high;
 468        int err;
 469
 470        if ((bank >= NR_BANKS) || (block >= NR_BLOCKS))
 471                return 0;
 472
 473        if (rdmsr_safe_on_cpu(cpu, address, &low, &high))
 474                return 0;
 475
 476        if (!(high & MASK_VALID_HI)) {
 477                if (block)
 478                        goto recurse;
 479                else
 480                        return 0;
 481        }
 482
 483        if (!(high & MASK_CNTP_HI)  ||
 484             (high & MASK_LOCKED_HI))
 485                goto recurse;
 486
 487        b = kzalloc(sizeof(struct threshold_block), GFP_KERNEL);
 488        if (!b)
 489                return -ENOMEM;
 490
 491        b->block                = block;
 492        b->bank                 = bank;
 493        b->cpu                  = cpu;
 494        b->address              = address;
 495        b->interrupt_enable     = 0;
 496        b->interrupt_capable    = lvt_interrupt_supported(bank, high);
 497        b->threshold_limit      = THRESHOLD_MAX;
 498
 499        if (b->interrupt_capable)
 500                threshold_ktype.default_attrs[2] = &interrupt_enable.attr;
 501        else
 502                threshold_ktype.default_attrs[2] = NULL;
 503
 504        INIT_LIST_HEAD(&b->miscj);
 505
 506        if (per_cpu(threshold_banks, cpu)[bank]->blocks) {
 507                list_add(&b->miscj,
 508                         &per_cpu(threshold_banks, cpu)[bank]->blocks->miscj);
 509        } else {
 510                per_cpu(threshold_banks, cpu)[bank]->blocks = b;
 511        }
 512
 513        err = kobject_init_and_add(&b->kobj, &threshold_ktype,
 514                                   per_cpu(threshold_banks, cpu)[bank]->kobj,
 515                                   (bank == 4 ? bank4_names(b) : th_names[bank]));
 516        if (err)
 517                goto out_free;
 518recurse:
 519        if (!block) {
 520                address = (low & MASK_BLKPTR_LO) >> 21;
 521                if (!address)
 522                        return 0;
 523                address += MCG_XBLK_ADDR;
 524        } else {
 525                ++address;
 526        }
 527
 528        err = allocate_threshold_blocks(cpu, bank, ++block, address);
 529        if (err)
 530                goto out_free;
 531
 532        if (b)
 533                kobject_uevent(&b->kobj, KOBJ_ADD);
 534
 535        return err;
 536
 537out_free:
 538        if (b) {
 539                kobject_put(&b->kobj);
 540                list_del(&b->miscj);
 541                kfree(b);
 542        }
 543        return err;
 544}
 545
 546static __cpuinit int __threshold_add_blocks(struct threshold_bank *b)
 547{
 548        struct list_head *head = &b->blocks->miscj;
 549        struct threshold_block *pos = NULL;
 550        struct threshold_block *tmp = NULL;
 551        int err = 0;
 552
 553        err = kobject_add(&b->blocks->kobj, b->kobj, b->blocks->kobj.name);
 554        if (err)
 555                return err;
 556
 557        list_for_each_entry_safe(pos, tmp, head, miscj) {
 558
 559                err = kobject_add(&pos->kobj, b->kobj, pos->kobj.name);
 560                if (err) {
 561                        list_for_each_entry_safe_reverse(pos, tmp, head, miscj)
 562                                kobject_del(&pos->kobj);
 563
 564                        return err;
 565                }
 566        }
 567        return err;
 568}
 569
 570static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
 571{
 572        struct device *dev = per_cpu(mce_device, cpu);
 573        struct amd_northbridge *nb = NULL;
 574        struct threshold_bank *b = NULL;
 575        const char *name = th_names[bank];
 576        int err = 0;
 577
 578        if (shared_bank[bank]) {
 579                nb = node_to_amd_nb(amd_get_nb_id(cpu));
 580
 581                /* threshold descriptor already initialized on this node? */
 582                if (nb && nb->bank4) {
 583                        /* yes, use it */
 584                        b = nb->bank4;
 585                        err = kobject_add(b->kobj, &dev->kobj, name);
 586                        if (err)
 587                                goto out;
 588
 589                        per_cpu(threshold_banks, cpu)[bank] = b;
 590                        atomic_inc(&b->cpus);
 591
 592                        err = __threshold_add_blocks(b);
 593
 594                        goto out;
 595                }
 596        }
 597
 598        b = kzalloc(sizeof(struct threshold_bank), GFP_KERNEL);
 599        if (!b) {
 600                err = -ENOMEM;
 601                goto out;
 602        }
 603
 604        b->kobj = kobject_create_and_add(name, &dev->kobj);
 605        if (!b->kobj) {
 606                err = -EINVAL;
 607                goto out_free;
 608        }
 609
 610        per_cpu(threshold_banks, cpu)[bank] = b;
 611
 612        if (shared_bank[bank]) {
 613                atomic_set(&b->cpus, 1);
 614
 615                /* nb is already initialized, see above */
 616                if (nb) {
 617                        WARN_ON(nb->bank4);
 618                        nb->bank4 = b;
 619                }
 620        }
 621
 622        err = allocate_threshold_blocks(cpu, bank, 0,
 623                                        MSR_IA32_MC0_MISC + bank * 4);
 624        if (!err)
 625                goto out;
 626
 627 out_free:
 628        kfree(b);
 629
 630 out:
 631        return err;
 632}
 633
 634/* create dir/files for all valid threshold banks */
 635static __cpuinit int threshold_create_device(unsigned int cpu)
 636{
 637        unsigned int bank;
 638        int err = 0;
 639
 640        for (bank = 0; bank < NR_BANKS; ++bank) {
 641                if (!(per_cpu(bank_map, cpu) & (1 << bank)))
 642                        continue;
 643                err = threshold_create_bank(cpu, bank);
 644                if (err)
 645                        return err;
 646        }
 647
 648        return err;
 649}
 650
 651static void deallocate_threshold_block(unsigned int cpu,
 652                                                 unsigned int bank)
 653{
 654        struct threshold_block *pos = NULL;
 655        struct threshold_block *tmp = NULL;
 656        struct threshold_bank *head = per_cpu(threshold_banks, cpu)[bank];
 657
 658        if (!head)
 659                return;
 660
 661        list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
 662                kobject_put(&pos->kobj);
 663                list_del(&pos->miscj);
 664                kfree(pos);
 665        }
 666
 667        kfree(per_cpu(threshold_banks, cpu)[bank]->blocks);
 668        per_cpu(threshold_banks, cpu)[bank]->blocks = NULL;
 669}
 670
 671static void __threshold_remove_blocks(struct threshold_bank *b)
 672{
 673        struct threshold_block *pos = NULL;
 674        struct threshold_block *tmp = NULL;
 675
 676        kobject_del(b->kobj);
 677
 678        list_for_each_entry_safe(pos, tmp, &b->blocks->miscj, miscj)
 679                kobject_del(&pos->kobj);
 680}
 681
 682static void threshold_remove_bank(unsigned int cpu, int bank)
 683{
 684        struct amd_northbridge *nb;
 685        struct threshold_bank *b;
 686
 687        b = per_cpu(threshold_banks, cpu)[bank];
 688        if (!b)
 689                return;
 690
 691        if (!b->blocks)
 692                goto free_out;
 693
 694        if (shared_bank[bank]) {
 695                if (!atomic_dec_and_test(&b->cpus)) {
 696                        __threshold_remove_blocks(b);
 697                        per_cpu(threshold_banks, cpu)[bank] = NULL;
 698                        return;
 699                } else {
 700                        /*
 701                         * the last CPU on this node using the shared bank is
 702                         * going away, remove that bank now.
 703                         */
 704                        nb = node_to_amd_nb(amd_get_nb_id(cpu));
 705                        nb->bank4 = NULL;
 706                }
 707        }
 708
 709        deallocate_threshold_block(cpu, bank);
 710
 711free_out:
 712        kobject_del(b->kobj);
 713        kobject_put(b->kobj);
 714        kfree(b);
 715        per_cpu(threshold_banks, cpu)[bank] = NULL;
 716}
 717
 718static void threshold_remove_device(unsigned int cpu)
 719{
 720        unsigned int bank;
 721
 722        for (bank = 0; bank < NR_BANKS; ++bank) {
 723                if (!(per_cpu(bank_map, cpu) & (1 << bank)))
 724                        continue;
 725                threshold_remove_bank(cpu, bank);
 726        }
 727}
 728
 729/* get notified when a cpu comes on/off */
 730static void __cpuinit
 731amd_64_threshold_cpu_callback(unsigned long action, unsigned int cpu)
 732{
 733        switch (action) {
 734        case CPU_ONLINE:
 735        case CPU_ONLINE_FROZEN:
 736                threshold_create_device(cpu);
 737                break;
 738        case CPU_DEAD:
 739        case CPU_DEAD_FROZEN:
 740                threshold_remove_device(cpu);
 741                break;
 742        default:
 743                break;
 744        }
 745}
 746
 747static __init int threshold_init_device(void)
 748{
 749        unsigned lcpu = 0;
 750
 751        /* to hit CPUs online before the notifier is up */
 752        for_each_online_cpu(lcpu) {
 753                int err = threshold_create_device(lcpu);
 754
 755                if (err)
 756                        return err;
 757        }
 758        threshold_cpu_callback = amd_64_threshold_cpu_callback;
 759
 760        return 0;
 761}
 762/*
 763 * there are 3 funcs which need to be _initcalled in a logic sequence:
 764 * 1. xen_late_init_mcelog
 765 * 2. mcheck_init_device
 766 * 3. threshold_init_device
 767 *
 768 * xen_late_init_mcelog must register xen_mce_chrdev_device before
 769 * native mce_chrdev_device registration if running under xen platform;
 770 *
 771 * mcheck_init_device should be inited before threshold_init_device to
 772 * initialize mce_device, otherwise a NULL ptr dereference will cause panic.
 773 *
 774 * so we use following _initcalls
 775 * 1. device_initcall(xen_late_init_mcelog);
 776 * 2. device_initcall_sync(mcheck_init_device);
 777 * 3. late_initcall(threshold_init_device);
 778 *
 779 * when running under xen, the initcall order is 1,2,3;
 780 * on baremetal, we skip 1 and we do only 2 and 3.
 781 */
 782late_initcall(threshold_init_device);
 783