]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/thermal/x86_pkg_temp_thermal.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-imx.git] / drivers / thermal / x86_pkg_temp_thermal.c
index 034604c021d67b2a157b8647c92f4825e724244c..f36950e4134f55deb02e3a6eb172e9481828ea18 100644 (file)
@@ -54,6 +54,8 @@ MODULE_PARM_DESC(notify_delay_ms,
 * is some wrong values returned by cpuid for number of thresholds.
 */
 #define MAX_NUMBER_OF_TRIPS    2
+/* Limit number of package temp zones */
+#define MAX_PKG_TEMP_ZONE_IDS  256
 
 struct phy_dev_entry {
        struct list_head list;
@@ -394,12 +396,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
        char buffer[30];
        int thres_count;
        u32 eax, ebx, ecx, edx;
+       u8 *temp;
 
        cpuid(6, &eax, &ebx, &ecx, &edx);
        thres_count = ebx & 0x07;
        if (!thres_count)
                return -ENODEV;
 
+       if (topology_physical_package_id(cpu) > MAX_PKG_TEMP_ZONE_IDS)
+               return -ENODEV;
+
        thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
 
        err = get_tj_max(cpu, &tj_max);
@@ -417,13 +423,14 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
        spin_lock(&pkg_work_lock);
        if (topology_physical_package_id(cpu) > max_phy_id)
                max_phy_id = topology_physical_package_id(cpu);
-       pkg_work_scheduled = krealloc(pkg_work_scheduled,
-                               (max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
-       if (!pkg_work_scheduled) {
+       temp = krealloc(pkg_work_scheduled,
+                       (max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
+       if (!temp) {
                spin_unlock(&pkg_work_lock);
                err = -ENOMEM;
                goto err_ret_free;
        }
+       pkg_work_scheduled = temp;
        pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
        spin_unlock(&pkg_work_lock);
 
@@ -592,7 +599,6 @@ static int __init pkg_temp_thermal_init(void)
        return 0;
 
 err_ret:
-       get_online_cpus();
        for_each_online_cpu(i)
                put_core_offline(i);
        put_online_cpus();