aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c47
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
2477err_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
2484err_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
2494err_out_mem:
2495 free_cpumask_var(mce_device_initialized);
2496
2497err_out:
2498 pr_err("Unable to init device /dev/mcelog (rc: %d)\n", err);
2466 2499
2467 return err; 2500 return err;
2468} 2501}