diff options
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 68317c80de7f..0078761219a2 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -2437,32 +2437,65 @@ static __init int mcheck_init_device(void) | |||
2437 | int err; | 2437 | int err; |
2438 | int i = 0; | 2438 | int i = 0; |
2439 | 2439 | ||
2440 | if (!mce_available(&boot_cpu_data)) | 2440 | if (!mce_available(&boot_cpu_data)) { |
2441 | return -EIO; | 2441 | err = -EIO; |
2442 | goto err_out; | ||
2443 | } | ||
2442 | 2444 | ||
2443 | zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL); | 2445 | if (!zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL)) { |
2446 | err = -ENOMEM; | ||
2447 | goto err_out; | ||
2448 | } | ||
2444 | 2449 | ||
2445 | mce_init_banks(); | 2450 | mce_init_banks(); |
2446 | 2451 | ||
2447 | err = subsys_system_register(&mce_subsys, NULL); | 2452 | err = subsys_system_register(&mce_subsys, NULL); |
2448 | if (err) | 2453 | if (err) |
2449 | return err; | 2454 | goto err_out_mem; |
2450 | 2455 | ||
2451 | cpu_notifier_register_begin(); | 2456 | cpu_notifier_register_begin(); |
2452 | for_each_online_cpu(i) { | 2457 | for_each_online_cpu(i) { |
2453 | err = mce_device_create(i); | 2458 | err = mce_device_create(i); |
2454 | if (err) { | 2459 | if (err) { |
2455 | cpu_notifier_register_done(); | 2460 | cpu_notifier_register_done(); |
2456 | return err; | 2461 | goto err_device_create; |
2457 | } | 2462 | } |
2458 | } | 2463 | } |
2459 | 2464 | ||
2460 | register_syscore_ops(&mce_syscore_ops); | ||
2461 | __register_hotcpu_notifier(&mce_cpu_notifier); | 2465 | __register_hotcpu_notifier(&mce_cpu_notifier); |
2462 | cpu_notifier_register_done(); | 2466 | cpu_notifier_register_done(); |
2463 | 2467 | ||
2468 | register_syscore_ops(&mce_syscore_ops); | ||
2469 | |||
2464 | /* register character device /dev/mcelog */ | 2470 | /* register character device /dev/mcelog */ |
2465 | misc_register(&mce_chrdev_device); | 2471 | err = misc_register(&mce_chrdev_device); |
2472 | if (err) | ||
2473 | goto err_register; | ||
2474 | |||
2475 | return 0; | ||
2476 | |||
2477 | err_register: | ||
2478 | unregister_syscore_ops(&mce_syscore_ops); | ||
2479 | |||
2480 | cpu_notifier_register_begin(); | ||
2481 | __unregister_hotcpu_notifier(&mce_cpu_notifier); | ||
2482 | cpu_notifier_register_done(); | ||
2483 | |||
2484 | err_device_create: | ||
2485 | /* | ||
2486 | * We didn't keep track of which devices were created above, but | ||
2487 | * even if we had, the set of online cpus might have changed. | ||
2488 | * Play safe and remove for every possible cpu, since | ||
2489 | * mce_device_remove() will do the right thing. | ||
2490 | */ | ||
2491 | for_each_possible_cpu(i) | ||
2492 | mce_device_remove(i); | ||
2493 | |||
2494 | err_out_mem: | ||
2495 | free_cpumask_var(mce_device_initialized); | ||
2496 | |||
2497 | err_out: | ||
2498 | pr_err("Unable to init device /dev/mcelog (rc: %d)\n", err); | ||
2466 | 2499 | ||
2467 | return err; | 2500 | return err; |
2468 | } | 2501 | } |