#define TOTAL_ATTRS            (MAX_CORE_ATTRS + 1)
 #define MAX_CORE_DATA          (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
 
-#define TO_CORE_ID(cpu)                (cpu_data(cpu).cpu_core_id)
-#define TO_ATTR_NO(cpu)                (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
-
 #ifdef CONFIG_SMP
 #define for_each_sibling(i, cpu) \
        for_each_cpu(i, topology_sibling_cpumask(cpu))
 struct platform_data {
        struct device           *hwmon_dev;
        u16                     pkg_id;
+       u16                     cpu_map[NUM_REAL_CORES];
+       struct ida              ida;
        struct cpumask          cpumask;
        struct temp_data        *core_data[MAX_CORE_DATA];
        struct device_attribute name_attr;
                                                        MSR_IA32_THERM_STATUS;
        tdata->is_pkg_data = pkg_flag;
        tdata->cpu = cpu;
-       tdata->cpu_core_id = TO_CORE_ID(cpu);
+       tdata->cpu_core_id = topology_core_id(cpu);
        tdata->attr_size = MAX_CORE_ATTRS;
        mutex_init(&tdata->update_lock);
        return tdata;
        struct platform_data *pdata = platform_get_drvdata(pdev);
        struct cpuinfo_x86 *c = &cpu_data(cpu);
        u32 eax, edx;
-       int err, attr_no;
+       int err, index, attr_no;
 
        /*
         * Find attr number for sysfs:
         * The attr number is always core id + 2
         * The Pkgtemp will always show up as temp1_*, if available
         */
-       attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu);
+       if (pkg_flag) {
+               attr_no = PKG_SYSFS_ATTR_NO;
+       } else {
+               index = ida_alloc(&pdata->ida, GFP_KERNEL);
+               if (index < 0)
+                       return index;
+               pdata->cpu_map[index] = topology_core_id(cpu);
+               attr_no = index + BASE_SYSFS_ATTR_NO;
+       }
 
-       if (attr_no > MAX_CORE_DATA - 1)
-               return -ERANGE;
+       if (attr_no > MAX_CORE_DATA - 1) {
+               err = -ERANGE;
+               goto ida_free;
+       }
 
        tdata = init_temp_data(cpu, pkg_flag);
-       if (!tdata)
-               return -ENOMEM;
+       if (!tdata) {
+               err = -ENOMEM;
+               goto ida_free;
+       }
 
        /* Test if we can access the status register */
        err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx);
 exit_free:
        pdata->core_data[attr_no] = NULL;
        kfree(tdata);
+ida_free:
+       if (!pkg_flag)
+               ida_free(&pdata->ida, index);
        return err;
 }
 
 
        kfree(pdata->core_data[indx]);
        pdata->core_data[indx] = NULL;
+
+       if (indx >= BASE_SYSFS_ATTR_NO)
+               ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO);
 }
 
 static int coretemp_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        pdata->pkg_id = pdev->id;
+       ida_init(&pdata->ida);
        platform_set_drvdata(pdev, pdata);
 
        pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME,
                if (pdata->core_data[i])
                        coretemp_remove_core(pdata, i);
 
+       ida_destroy(&pdata->ida);
        return 0;
 }
 
        struct platform_device *pdev = coretemp_get_pdev(cpu);
        struct platform_data *pd;
        struct temp_data *tdata;
-       int indx, target;
+       int i, indx = -1, target;
 
        /*
         * Don't execute this on suspend as the device remove locks
        if (!pdev)
                return 0;
 
-       /* The core id is too big, just return */
-       indx = TO_ATTR_NO(cpu);
-       if (indx > MAX_CORE_DATA - 1)
+       pd = platform_get_drvdata(pdev);
+
+       for (i = 0; i < NUM_REAL_CORES; i++) {
+               if (pd->cpu_map[i] == topology_core_id(cpu)) {
+                       indx = i + BASE_SYSFS_ATTR_NO;
+                       break;
+               }
+       }
+
+       /* Too many cores and this core is not populated, just return */
+       if (indx < 0)
                return 0;
 
-       pd = platform_get_drvdata(pdev);
        tdata = pd->core_data[indx];
 
        cpumask_clear_cpu(cpu, &pd->cpumask);