Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c15a24b authored by Mathieu Souchaud's avatar Mathieu Souchaud Committed by Borislav Petkov
Browse files

x86/mce: Improve mcheck_init_device() error handling



Check return code of every function called by mcheck_init_device().

Signed-off-by: default avatarMathieu Souchaud <mattieu.souchaud@free.fr>
Link: http://lkml.kernel.org/r/1399151031-19905-1-git-send-email-mattieu.souchaud@free.fr


Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
parent c7208164
Loading
Loading
Loading
Loading
+40 −7
Original line number Diff line number Diff line
@@ -2437,32 +2437,65 @@ static __init int mcheck_init_device(void)
	int err;
	int i = 0;

	if (!mce_available(&boot_cpu_data))
		return -EIO;
	if (!mce_available(&boot_cpu_data)) {
		err = -EIO;
		goto err_out;
	}

	zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL);
	if (!zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL)) {
		err = -ENOMEM;
		goto err_out;
	}

	mce_init_banks();

	err = subsys_system_register(&mce_subsys, NULL);
	if (err)
		return err;
		goto err_out_mem;

	cpu_notifier_register_begin();
	for_each_online_cpu(i) {
		err = mce_device_create(i);
		if (err) {
			cpu_notifier_register_done();
			return err;
			goto err_device_create;
		}
	}

	register_syscore_ops(&mce_syscore_ops);
	__register_hotcpu_notifier(&mce_cpu_notifier);
	cpu_notifier_register_done();

	register_syscore_ops(&mce_syscore_ops);

	/* register character device /dev/mcelog */
	misc_register(&mce_chrdev_device);
	err = misc_register(&mce_chrdev_device);
	if (err)
		goto err_register;

	return 0;

err_register:
	unregister_syscore_ops(&mce_syscore_ops);

	cpu_notifier_register_begin();
	__unregister_hotcpu_notifier(&mce_cpu_notifier);
	cpu_notifier_register_done();

err_device_create:
	/*
	 * We didn't keep track of which devices were created above, but
	 * even if we had, the set of online cpus might have changed.
	 * Play safe and remove for every possible cpu, since
	 * mce_device_remove() will do the right thing.
	 */
	for_each_possible_cpu(i)
		mce_device_remove(i);

err_out_mem:
	free_cpumask_var(mce_device_initialized);

err_out:
	pr_err("Unable to init device /dev/mcelog (rc: %d)\n", err);

	return err;
}