hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/hwmon/coretemp.c
....@@ -1,23 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * coretemp.c - Linux kernel module for hardware monitoring
34 *
45 * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
56 *
67 * Inspired from many hwmon drivers
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; version 2 of the License.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
- * 02110-1301 USA.
218 */
229
2310 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -58,9 +45,6 @@
5845 #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */
5946 #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)
6047 #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
61
-
62
-#define TO_CORE_ID(cpu) (cpu_data(cpu).cpu_core_id)
63
-#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
6448
6549 #ifdef CONFIG_SMP
6650 #define for_each_sibling(i, cpu) \
....@@ -104,15 +88,17 @@
10488 struct platform_data {
10589 struct device *hwmon_dev;
10690 u16 pkg_id;
91
+ u16 cpu_map[NUM_REAL_CORES];
92
+ struct ida ida;
10793 struct cpumask cpumask;
10894 struct temp_data *core_data[MAX_CORE_DATA];
10995 struct device_attribute name_attr;
11096 };
11197
112
-/* Keep track of how many package pointers we allocated in init() */
113
-static int max_packages __read_mostly;
114
-/* Array of package pointers. Serialized by cpu hotplug lock */
115
-static struct platform_device **pkg_devices;
98
+/* Keep track of how many zone pointers we allocated in init() */
99
+static int max_zones __read_mostly;
100
+/* Array of zone pointers. Serialized by cpu hotplug lock */
101
+static struct platform_device **zone_devices;
116102
117103 static ssize_t show_label(struct device *dev,
118104 struct device_attribute *devattr, char *buf)
....@@ -256,10 +242,13 @@
256242 */
257243 if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL) {
258244 for (i = 0; i < ARRAY_SIZE(tjmax_pci_table); i++) {
259
- if (host_bridge->device == tjmax_pci_table[i].device)
245
+ if (host_bridge->device == tjmax_pci_table[i].device) {
246
+ pci_dev_put(host_bridge);
260247 return tjmax_pci_table[i].tjmax;
248
+ }
261249 }
262250 }
251
+ pci_dev_put(host_bridge);
263252
264253 for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) {
265254 if (strstr(c->x86_model_id, tjmax_table[i].id))
....@@ -407,7 +396,7 @@
407396 "temp%d_%s", attr_no, suffixes[i]);
408397 sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr);
409398 tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i];
410
- tdata->sd_attrs[i].dev_attr.attr.mode = S_IRUGO;
399
+ tdata->sd_attrs[i].dev_attr.attr.mode = 0444;
411400 tdata->sd_attrs[i].dev_attr.show = rd_ptr[i];
412401 tdata->sd_attrs[i].index = attr_no;
413402 tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr;
....@@ -435,10 +424,10 @@
435424
436425 static struct platform_device *coretemp_get_pdev(unsigned int cpu)
437426 {
438
- int pkgid = topology_logical_package_id(cpu);
427
+ int id = topology_logical_die_id(cpu);
439428
440
- if (pkgid >= 0 && pkgid < max_packages)
441
- return pkg_devices[pkgid];
429
+ if (id >= 0 && id < max_zones)
430
+ return zone_devices[id];
442431 return NULL;
443432 }
444433
....@@ -454,7 +443,7 @@
454443 MSR_IA32_THERM_STATUS;
455444 tdata->is_pkg_data = pkg_flag;
456445 tdata->cpu = cpu;
457
- tdata->cpu_core_id = TO_CORE_ID(cpu);
446
+ tdata->cpu_core_id = topology_core_id(cpu);
458447 tdata->attr_size = MAX_CORE_ATTRS;
459448 mutex_init(&tdata->update_lock);
460449 return tdata;
....@@ -467,7 +456,7 @@
467456 struct platform_data *pdata = platform_get_drvdata(pdev);
468457 struct cpuinfo_x86 *c = &cpu_data(cpu);
469458 u32 eax, edx;
470
- int err, attr_no;
459
+ int err, index, attr_no;
471460
472461 /*
473462 * Find attr number for sysfs:
....@@ -475,14 +464,26 @@
475464 * The attr number is always core id + 2
476465 * The Pkgtemp will always show up as temp1_*, if available
477466 */
478
- attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu);
467
+ if (pkg_flag) {
468
+ attr_no = PKG_SYSFS_ATTR_NO;
469
+ } else {
470
+ index = ida_alloc(&pdata->ida, GFP_KERNEL);
471
+ if (index < 0)
472
+ return index;
473
+ pdata->cpu_map[index] = topology_core_id(cpu);
474
+ attr_no = index + BASE_SYSFS_ATTR_NO;
475
+ }
479476
480
- if (attr_no > MAX_CORE_DATA - 1)
481
- return -ERANGE;
477
+ if (attr_no > MAX_CORE_DATA - 1) {
478
+ err = -ERANGE;
479
+ goto ida_free;
480
+ }
482481
483482 tdata = init_temp_data(cpu, pkg_flag);
484
- if (!tdata)
485
- return -ENOMEM;
483
+ if (!tdata) {
484
+ err = -ENOMEM;
485
+ goto ida_free;
486
+ }
486487
487488 /* Test if we can access the status register */
488489 err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx);
....@@ -518,6 +519,9 @@
518519 exit_free:
519520 pdata->core_data[attr_no] = NULL;
520521 kfree(tdata);
522
+ida_free:
523
+ if (!pkg_flag)
524
+ ida_free(&pdata->ida, index);
521525 return err;
522526 }
523527
....@@ -532,11 +536,18 @@
532536 {
533537 struct temp_data *tdata = pdata->core_data[indx];
534538
539
+ /* if we errored on add then this is already gone */
540
+ if (!tdata)
541
+ return;
542
+
535543 /* Remove the sysfs attributes */
536544 sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group);
537545
538546 kfree(pdata->core_data[indx]);
539547 pdata->core_data[indx] = NULL;
548
+
549
+ if (indx >= BASE_SYSFS_ATTR_NO)
550
+ ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO);
540551 }
541552
542553 static int coretemp_probe(struct platform_device *pdev)
....@@ -544,12 +555,13 @@
544555 struct device *dev = &pdev->dev;
545556 struct platform_data *pdata;
546557
547
- /* Initialize the per-package data structures */
558
+ /* Initialize the per-zone data structures */
548559 pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL);
549560 if (!pdata)
550561 return -ENOMEM;
551562
552563 pdata->pkg_id = pdev->id;
564
+ ida_init(&pdata->ida);
553565 platform_set_drvdata(pdev, pdata);
554566
555567 pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME,
....@@ -566,6 +578,7 @@
566578 if (pdata->core_data[i])
567579 coretemp_remove_core(pdata, i);
568580
581
+ ida_destroy(&pdata->ida);
569582 return 0;
570583 }
571584
....@@ -579,13 +592,13 @@
579592
580593 static struct platform_device *coretemp_device_add(unsigned int cpu)
581594 {
582
- int err, pkgid = topology_logical_package_id(cpu);
595
+ int err, zoneid = topology_logical_die_id(cpu);
583596 struct platform_device *pdev;
584597
585
- if (pkgid < 0)
598
+ if (zoneid < 0)
586599 return ERR_PTR(-ENOMEM);
587600
588
- pdev = platform_device_alloc(DRVNAME, pkgid);
601
+ pdev = platform_device_alloc(DRVNAME, zoneid);
589602 if (!pdev)
590603 return ERR_PTR(-ENOMEM);
591604
....@@ -595,7 +608,7 @@
595608 return ERR_PTR(err);
596609 }
597610
598
- pkg_devices[pkgid] = pdev;
611
+ zone_devices[zoneid] = pdev;
599612 return pdev;
600613 }
601614
....@@ -660,7 +673,7 @@
660673 struct platform_device *pdev = coretemp_get_pdev(cpu);
661674 struct platform_data *pd;
662675 struct temp_data *tdata;
663
- int indx, target;
676
+ int i, indx = -1, target;
664677
665678 /*
666679 * Don't execute this on suspend as the device remove locks
....@@ -673,12 +686,19 @@
673686 if (!pdev)
674687 return 0;
675688
676
- /* The core id is too big, just return */
677
- indx = TO_ATTR_NO(cpu);
678
- if (indx > MAX_CORE_DATA - 1)
689
+ pd = platform_get_drvdata(pdev);
690
+
691
+ for (i = 0; i < NUM_REAL_CORES; i++) {
692
+ if (pd->cpu_map[i] == topology_core_id(cpu)) {
693
+ indx = i + BASE_SYSFS_ATTR_NO;
694
+ break;
695
+ }
696
+ }
697
+
698
+ /* Too many cores and this core is not populated, just return */
699
+ if (indx < 0)
679700 return 0;
680701
681
- pd = platform_get_drvdata(pdev);
682702 tdata = pd->core_data[indx];
683703
684704 cpumask_clear_cpu(cpu, &pd->cpumask);
....@@ -703,7 +723,7 @@
703723 * the rest.
704724 */
705725 if (cpumask_empty(&pd->cpumask)) {
706
- pkg_devices[topology_logical_package_id(cpu)] = NULL;
726
+ zone_devices[topology_logical_die_id(cpu)] = NULL;
707727 platform_device_unregister(pdev);
708728 return 0;
709729 }
....@@ -722,7 +742,7 @@
722742 return 0;
723743 }
724744 static const struct x86_cpu_id __initconst coretemp_ids[] = {
725
- { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM },
745
+ X86_MATCH_VENDOR_FEATURE(INTEL, X86_FEATURE_DTHERM, NULL),
726746 {}
727747 };
728748 MODULE_DEVICE_TABLE(x86cpu, coretemp_ids);
....@@ -741,15 +761,15 @@
741761 if (!x86_match_cpu(coretemp_ids))
742762 return -ENODEV;
743763
744
- max_packages = topology_max_packages();
745
- pkg_devices = kcalloc(max_packages, sizeof(struct platform_device *),
764
+ max_zones = topology_max_packages() * topology_max_die_per_package();
765
+ zone_devices = kcalloc(max_zones, sizeof(struct platform_device *),
746766 GFP_KERNEL);
747
- if (!pkg_devices)
767
+ if (!zone_devices)
748768 return -ENOMEM;
749769
750770 err = platform_driver_register(&coretemp_driver);
751771 if (err)
752
- return err;
772
+ goto outzone;
753773
754774 err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online",
755775 coretemp_cpu_online, coretemp_cpu_offline);
....@@ -760,7 +780,8 @@
760780
761781 outdrv:
762782 platform_driver_unregister(&coretemp_driver);
763
- kfree(pkg_devices);
783
+outzone:
784
+ kfree(zone_devices);
764785 return err;
765786 }
766787 module_init(coretemp_init)
....@@ -769,7 +790,7 @@
769790 {
770791 cpuhp_remove_state(coretemp_hp_online);
771792 platform_driver_unregister(&coretemp_driver);
772
- kfree(pkg_devices);
793
+ kfree(zone_devices);
773794 }
774795 module_exit(coretemp_exit)
775796