aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/mce_64.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/arch/x86/kernel/mce_64.c b/arch/x86/kernel/mce_64.c
index 8ca8f8648969..66e6b797b2cb 100644
--- a/arch/x86/kernel/mce_64.c
+++ b/arch/x86/kernel/mce_64.c
@@ -802,16 +802,29 @@ static __cpuinit int mce_create_device(unsigned int cpu)
802 if (!mce_available(&cpu_data[cpu])) 802 if (!mce_available(&cpu_data[cpu]))
803 return -EIO; 803 return -EIO;
804 804
805 memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
805 per_cpu(device_mce,cpu).id = cpu; 806 per_cpu(device_mce,cpu).id = cpu;
806 per_cpu(device_mce,cpu).cls = &mce_sysclass; 807 per_cpu(device_mce,cpu).cls = &mce_sysclass;
807 808
808 err = sysdev_register(&per_cpu(device_mce,cpu)); 809 err = sysdev_register(&per_cpu(device_mce,cpu));
810 if (err)
811 return err;
812
813 for (i = 0; mce_attributes[i]; i++) {
814 err = sysdev_create_file(&per_cpu(device_mce,cpu),
815 mce_attributes[i]);
816 if (err)
817 goto error;
818 }
809 819
810 if (!err) { 820 return 0;
811 for (i = 0; mce_attributes[i]; i++) 821error:
812 sysdev_create_file(&per_cpu(device_mce,cpu), 822 while (i--) {
813 mce_attributes[i]); 823 sysdev_remove_file(&per_cpu(device_mce,cpu),
824 mce_attributes[i]);
814 } 825 }
826 sysdev_unregister(&per_cpu(device_mce,cpu));
827
815 return err; 828 return err;
816} 829}
817 830
@@ -823,7 +836,6 @@ static void mce_remove_device(unsigned int cpu)
823 sysdev_remove_file(&per_cpu(device_mce,cpu), 836 sysdev_remove_file(&per_cpu(device_mce,cpu),
824 mce_attributes[i]); 837 mce_attributes[i]);
825 sysdev_unregister(&per_cpu(device_mce,cpu)); 838 sysdev_unregister(&per_cpu(device_mce,cpu));
826 memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
827} 839}
828 840
829/* Get notified when a cpu comes on/off. Be hotplug friendly. */ 841/* Get notified when a cpu comes on/off. Be hotplug friendly. */
@@ -831,18 +843,21 @@ static int
831mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) 843mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
832{ 844{
833 unsigned int cpu = (unsigned long)hcpu; 845 unsigned int cpu = (unsigned long)hcpu;
846 int err = 0;
834 847
835 switch (action) { 848 switch (action) {
836 case CPU_ONLINE: 849 case CPU_UP_PREPARE:
837 case CPU_ONLINE_FROZEN: 850 case CPU_UP_PREPARE_FROZEN:
838 mce_create_device(cpu); 851 err = mce_create_device(cpu);
839 break; 852 break;
853 case CPU_UP_CANCELED:
854 case CPU_UP_CANCELED_FROZEN:
840 case CPU_DEAD: 855 case CPU_DEAD:
841 case CPU_DEAD_FROZEN: 856 case CPU_DEAD_FROZEN:
842 mce_remove_device(cpu); 857 mce_remove_device(cpu);
843 break; 858 break;
844 } 859 }
845 return NOTIFY_OK; 860 return err ? NOTIFY_BAD : NOTIFY_OK;
846} 861}
847 862
848static struct notifier_block mce_cpu_notifier = { 863static struct notifier_block mce_cpu_notifier = {
@@ -857,9 +872,13 @@ static __init int mce_init_device(void)
857 if (!mce_available(&boot_cpu_data)) 872 if (!mce_available(&boot_cpu_data))
858 return -EIO; 873 return -EIO;
859 err = sysdev_class_register(&mce_sysclass); 874 err = sysdev_class_register(&mce_sysclass);
875 if (err)
876 return err;
860 877
861 for_each_online_cpu(i) { 878 for_each_online_cpu(i) {
862 mce_create_device(i); 879 err = mce_create_device(i);
880 if (err)
881 return err;
863 } 882 }
864 883
865 register_hotcpu_notifier(&mce_cpu_notifier); 884 register_hotcpu_notifier(&mce_cpu_notifier);