Merge branch 'x86-topology-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2019 01:28:44 +0000 (18:28 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2019 01:28:44 +0000 (18:28 -0700)
Pull x86 topology updates from Ingo Molnar:
 "Implement multi-die topology support on Intel CPUs and expose the die
  topology to user-space tooling, by Len Brown, Kan Liang and Zhang Rui.

  These changes should have no effect on the kernel's existing
  understanding of topologies, i.e. there should be no behavioral impact
  on cache, NUMA, scheduler, perf and other topologies and overall
  system performance"

* 'x86-topology-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf/x86/intel/rapl: Cosmetic rename internal variables in response to multi-die/pkg support
  perf/x86/intel/uncore: Cosmetic renames in response to multi-die/pkg support
  hwmon/coretemp: Cosmetic: Rename internal variables to zones from packages
  thermal/x86_pkg_temp_thermal: Cosmetic: Rename internal variables to zones from packages
  perf/x86/intel/cstate: Support multi-die/package
  perf/x86/intel/rapl: Support multi-die/package
  perf/x86/intel/uncore: Support multi-die/package
  topology: Create core_cpus and die_cpus sysfs attributes
  topology: Create package_cpus sysfs attribute
  hwmon/coretemp: Support multi-die/package
  powercap/intel_rapl: Update RAPL domain name and debug messages
  thermal/x86_pkg_temp_thermal: Support multi-die/package
  powercap/intel_rapl: Support multi-die/package
  powercap/intel_rapl: Simplify rapl_find_package()
  x86/topology: Define topology_logical_die_id()
  x86/topology: Define topology_die_id()
  cpu/topology: Export die_id
  x86/topology: Create topology_max_die_per_package()
  x86/topology: Add CPUID.1F multi-die/package support

1  2 
arch/x86/events/intel/rapl.c
arch/x86/events/intel/uncore.c
arch/x86/include/asm/processor.h
arch/x86/include/asm/smp.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/smpboot.c
drivers/hwmon/coretemp.c
drivers/powercap/intel_rapl.c
drivers/thermal/intel/x86_pkg_temp_thermal.c

index 26c03f5adfb92f2ed5386efe552f7ca2c0548e6d,3992b0e65a5576fa395f4a58face3be68dbc524e..8c7ecde3ba70077d090397bc3993c650ab9281e1
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Support Intel RAPL energy consumption counters
   * Copyright (C) 2013 Google, Inc., Stephane Eranian
@@@ -149,7 -148,7 +149,7 @@@ struct rapl_pmu 
  
  struct rapl_pmus {
        struct pmu              pmu;
-       unsigned int            maxpkg;
+       unsigned int            maxdie;
        struct rapl_pmu         *pmus[];
  };
  
@@@ -162,13 -161,13 +162,13 @@@ static u64 rapl_timer_ms
  
  static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu)
  {
-       unsigned int pkgid = topology_logical_package_id(cpu);
+       unsigned int dieid = topology_logical_die_id(cpu);
  
        /*
         * The unsigned check also catches the '-1' return value for non
         * existent mappings in the topology map.
         */
-       return pkgid < rapl_pmus->maxpkg ? rapl_pmus->pmus[pkgid] : NULL;
+       return dieid < rapl_pmus->maxdie ? rapl_pmus->pmus[dieid] : NULL;
  }
  
  static inline u64 rapl_read_counter(struct perf_event *event)
@@@ -572,7 -571,7 +572,7 @@@ static int rapl_cpu_offline(unsigned in
  
        pmu->cpu = -1;
        /* Find a new cpu to collect rapl events */
-       target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
+       target = cpumask_any_but(topology_die_cpumask(cpu), cpu);
  
        /* Migrate rapl events to the new target */
        if (target < nr_cpu_ids) {
@@@ -599,14 -598,14 +599,14 @@@ static int rapl_cpu_online(unsigned in
                pmu->timer_interval = ms_to_ktime(rapl_timer_ms);
                rapl_hrtimer_init(pmu);
  
-               rapl_pmus->pmus[topology_logical_package_id(cpu)] = pmu;
+               rapl_pmus->pmus[topology_logical_die_id(cpu)] = pmu;
        }
  
        /*
         * Check if there is an online cpu in the package which collects rapl
         * events already.
         */
-       target = cpumask_any_and(&rapl_cpu_mask, topology_core_cpumask(cpu));
+       target = cpumask_any_and(&rapl_cpu_mask, topology_die_cpumask(cpu));
        if (target < nr_cpu_ids)
                return 0;
  
@@@ -669,22 -668,22 +669,22 @@@ static void cleanup_rapl_pmus(void
  {
        int i;
  
-       for (i = 0; i < rapl_pmus->maxpkg; i++)
+       for (i = 0; i < rapl_pmus->maxdie; i++)
                kfree(rapl_pmus->pmus[i]);
        kfree(rapl_pmus);
  }
  
  static int __init init_rapl_pmus(void)
  {
-       int maxpkg = topology_max_packages();
+       int maxdie = topology_max_packages() * topology_max_die_per_package();
        size_t size;
  
-       size = sizeof(*rapl_pmus) + maxpkg * sizeof(struct rapl_pmu *);
+       size = sizeof(*rapl_pmus) + maxdie * sizeof(struct rapl_pmu *);
        rapl_pmus = kzalloc(size, GFP_KERNEL);
        if (!rapl_pmus)
                return -ENOMEM;
  
-       rapl_pmus->maxpkg               = maxpkg;
+       rapl_pmus->maxdie               = maxdie;
        rapl_pmus->pmu.attr_groups      = rapl_attr_groups;
        rapl_pmus->pmu.task_ctx_nr      = perf_invalid_context;
        rapl_pmus->pmu.event_init       = rapl_pmu_event_init;
index 089bfcdf2f7fb93ebc850058269f8aef58e977b7,f943e4d0e66c802b27cd9d075eea851fc181cb70..6094c8db949d7593454f5fba61fc63d4aa2d37b4
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  #include <linux/module.h>
  
  #include <asm/cpu_device_id.h>
@@@ -15,7 -14,7 +15,7 @@@ struct pci_driver *uncore_pci_driver
  DEFINE_RAW_SPINLOCK(pci2phy_map_lock);
  struct list_head pci2phy_map_head = LIST_HEAD_INIT(pci2phy_map_head);
  struct pci_extra_dev *uncore_extra_pci_dev;
- static int max_packages;
+ static int max_dies;
  
  /* mask of cpus that collect uncore events */
  static cpumask_t uncore_cpu_mask;
@@@ -101,13 -100,13 +101,13 @@@ ssize_t uncore_event_show(struct kobjec
  
  struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
  {
-       unsigned int pkgid = topology_logical_package_id(cpu);
+       unsigned int dieid = topology_logical_die_id(cpu);
  
        /*
         * The unsigned check also catches the '-1' return value for non
         * existent mappings in the topology map.
         */
-       return pkgid < max_packages ? pmu->boxes[pkgid] : NULL;
+       return dieid < max_dies ? pmu->boxes[dieid] : NULL;
  }
  
  u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
@@@ -312,7 -311,7 +312,7 @@@ static struct intel_uncore_box *uncore_
        uncore_pmu_init_hrtimer(box);
        box->cpu = -1;
        box->pci_phys_id = -1;
-       box->pkgid = -1;
+       box->dieid = -1;
  
        /* set default hrtimer timeout */
        box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL;
@@@ -827,10 -826,10 +827,10 @@@ static void uncore_pmu_unregister(struc
  
  static void uncore_free_boxes(struct intel_uncore_pmu *pmu)
  {
-       int pkg;
+       int die;
  
-       for (pkg = 0; pkg < max_packages; pkg++)
-               kfree(pmu->boxes[pkg]);
+       for (die = 0; die < max_dies; die++)
+               kfree(pmu->boxes[die]);
        kfree(pmu->boxes);
  }
  
@@@ -867,7 -866,7 +867,7 @@@ static int __init uncore_type_init(stru
        if (!pmus)
                return -ENOMEM;
  
-       size = max_packages * sizeof(struct intel_uncore_box *);
+       size = max_dies * sizeof(struct intel_uncore_box *);
  
        for (i = 0; i < type->num_boxes; i++) {
                pmus[i].func_id = setid ? i : -1;
@@@ -937,20 -936,21 +937,21 @@@ static int uncore_pci_probe(struct pci_
        struct intel_uncore_type *type;
        struct intel_uncore_pmu *pmu = NULL;
        struct intel_uncore_box *box;
-       int phys_id, pkg, ret;
+       int phys_id, die, ret;
  
        phys_id = uncore_pcibus_to_physid(pdev->bus);
        if (phys_id < 0)
                return -ENODEV;
  
-       pkg = topology_phys_to_logical_pkg(phys_id);
-       if (pkg < 0)
+       die = (topology_max_die_per_package() > 1) ? phys_id :
+                                       topology_phys_to_logical_pkg(phys_id);
+       if (die < 0)
                return -EINVAL;
  
        if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
                int idx = UNCORE_PCI_DEV_IDX(id->driver_data);
  
-               uncore_extra_pci_dev[pkg].dev[idx] = pdev;
+               uncore_extra_pci_dev[die].dev[idx] = pdev;
                pci_set_drvdata(pdev, NULL);
                return 0;
        }
                pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
        }
  
-       if (WARN_ON_ONCE(pmu->boxes[pkg] != NULL))
+       if (WARN_ON_ONCE(pmu->boxes[die] != NULL))
                return -EINVAL;
  
        box = uncore_alloc_box(type, NUMA_NO_NODE);
  
        atomic_inc(&box->refcnt);
        box->pci_phys_id = phys_id;
-       box->pkgid = pkg;
+       box->dieid = die;
        box->pci_dev = pdev;
        box->pmu = pmu;
        uncore_box_init(box);
        pci_set_drvdata(pdev, box);
  
-       pmu->boxes[pkg] = box;
+       pmu->boxes[die] = box;
        if (atomic_inc_return(&pmu->activeboxes) > 1)
                return 0;
  
        ret = uncore_pmu_register(pmu);
        if (ret) {
                pci_set_drvdata(pdev, NULL);
-               pmu->boxes[pkg] = NULL;
+               pmu->boxes[die] = NULL;
                uncore_box_exit(box);
                kfree(box);
        }
@@@ -1028,16 -1028,17 +1029,17 @@@ static void uncore_pci_remove(struct pc
  {
        struct intel_uncore_box *box;
        struct intel_uncore_pmu *pmu;
-       int i, phys_id, pkg;
+       int i, phys_id, die;
  
        phys_id = uncore_pcibus_to_physid(pdev->bus);
  
        box = pci_get_drvdata(pdev);
        if (!box) {
-               pkg = topology_phys_to_logical_pkg(phys_id);
+               die = (topology_max_die_per_package() > 1) ? phys_id :
+                                       topology_phys_to_logical_pkg(phys_id);
                for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
-                       if (uncore_extra_pci_dev[pkg].dev[i] == pdev) {
-                               uncore_extra_pci_dev[pkg].dev[i] = NULL;
+                       if (uncore_extra_pci_dev[die].dev[i] == pdev) {
+                               uncore_extra_pci_dev[die].dev[i] = NULL;
                                break;
                        }
                }
                return;
  
        pci_set_drvdata(pdev, NULL);
-       pmu->boxes[box->pkgid] = NULL;
+       pmu->boxes[box->dieid] = NULL;
        if (atomic_dec_return(&pmu->activeboxes) == 0)
                uncore_pmu_unregister(pmu);
        uncore_box_exit(box);
@@@ -1062,7 -1063,7 +1064,7 @@@ static int __init uncore_pci_init(void
        size_t size;
        int ret;
  
-       size = max_packages * sizeof(struct pci_extra_dev);
+       size = max_dies * sizeof(struct pci_extra_dev);
        uncore_extra_pci_dev = kzalloc(size, GFP_KERNEL);
        if (!uncore_extra_pci_dev) {
                ret = -ENOMEM;
@@@ -1109,11 -1110,11 +1111,11 @@@ static void uncore_change_type_ctx(stru
  {
        struct intel_uncore_pmu *pmu = type->pmus;
        struct intel_uncore_box *box;
-       int i, pkg;
+       int i, die;
  
-       pkg = topology_logical_package_id(old_cpu < 0 ? new_cpu : old_cpu);
+       die = topology_logical_die_id(old_cpu < 0 ? new_cpu : old_cpu);
        for (i = 0; i < type->num_boxes; i++, pmu++) {
-               box = pmu->boxes[pkg];
+               box = pmu->boxes[die];
                if (!box)
                        continue;
  
@@@ -1146,13 -1147,13 +1148,13 @@@ static int uncore_event_cpu_offline(uns
        struct intel_uncore_type *type, **types = uncore_msr_uncores;
        struct intel_uncore_pmu *pmu;
        struct intel_uncore_box *box;
-       int i, pkg, target;
+       int i, die, target;
  
        /* Check if exiting cpu is used for collecting uncore events */
        if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask))
                goto unref;
        /* Find a new cpu to collect uncore events */
-       target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
+       target = cpumask_any_but(topology_die_cpumask(cpu), cpu);
  
        /* Migrate uncore events to the new target */
        if (target < nr_cpu_ids)
  
  unref:
        /* Clear the references */
-       pkg = topology_logical_package_id(cpu);
+       die = topology_logical_die_id(cpu);
        for (; *types; types++) {
                type = *types;
                pmu = type->pmus;
                for (i = 0; i < type->num_boxes; i++, pmu++) {
-                       box = pmu->boxes[pkg];
+                       box = pmu->boxes[die];
                        if (box && atomic_dec_return(&box->refcnt) == 0)
                                uncore_box_exit(box);
                }
  }
  
  static int allocate_boxes(struct intel_uncore_type **types,
-                        unsigned int pkg, unsigned int cpu)
+                        unsigned int die, unsigned int cpu)
  {
        struct intel_uncore_box *box, *tmp;
        struct intel_uncore_type *type;
                type = *types;
                pmu = type->pmus;
                for (i = 0; i < type->num_boxes; i++, pmu++) {
-                       if (pmu->boxes[pkg])
+                       if (pmu->boxes[die])
                                continue;
                        box = uncore_alloc_box(type, cpu_to_node(cpu));
                        if (!box)
                                goto cleanup;
                        box->pmu = pmu;
-                       box->pkgid = pkg;
+                       box->dieid = die;
                        list_add(&box->active_list, &allocated);
                }
        }
        /* Install them in the pmus */
        list_for_each_entry_safe(box, tmp, &allocated, active_list) {
                list_del_init(&box->active_list);
-               box->pmu->boxes[pkg] = box;
+               box->pmu->boxes[die] = box;
        }
        return 0;
  
@@@ -1222,10 -1223,10 +1224,10 @@@ static int uncore_event_cpu_online(unsi
        struct intel_uncore_type *type, **types = uncore_msr_uncores;
        struct intel_uncore_pmu *pmu;
        struct intel_uncore_box *box;
-       int i, ret, pkg, target;
+       int i, ret, die, target;
  
-       pkg = topology_logical_package_id(cpu);
-       ret = allocate_boxes(types, pkg, cpu);
+       die = topology_logical_die_id(cpu);
+       ret = allocate_boxes(types, die, cpu);
        if (ret)
                return ret;
  
                type = *types;
                pmu = type->pmus;
                for (i = 0; i < type->num_boxes; i++, pmu++) {
-                       box = pmu->boxes[pkg];
+                       box = pmu->boxes[die];
                        if (box && atomic_inc_return(&box->refcnt) == 1)
                                uncore_box_init(box);
                }
         * Check if there is an online cpu in the package
         * which collects uncore events already.
         */
-       target = cpumask_any_and(&uncore_cpu_mask, topology_core_cpumask(cpu));
+       target = cpumask_any_and(&uncore_cpu_mask, topology_die_cpumask(cpu));
        if (target < nr_cpu_ids)
                return 0;
  
@@@ -1400,7 -1401,6 +1402,7 @@@ static const struct x86_cpu_id intel_un
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE, skl_uncore_init),
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_uncore_init),
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, icl_uncore_init),
 +      X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_NNPI, icl_uncore_init),
        {},
  };
  
@@@ -1419,7 -1419,7 +1421,7 @@@ static int __init intel_uncore_init(voi
        if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
                return -ENODEV;
  
-       max_packages = topology_max_packages();
+       max_dies = topology_max_packages() * topology_max_die_per_package();
  
        uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
        if (uncore_init->pci_init) {
index e57d2ca2ed872265a7631bc126e7ead9cb5b5741,6aba36bde57f28084d042ef43eeb73f12a007c4b..3eab6ece52b44b25d156fa11027d69f8b0efbf88
@@@ -105,7 -105,7 +105,7 @@@ struct cpuinfo_x86 
        int                     x86_power;
        unsigned long           loops_per_jiffy;
        /* cpuid returned max cores value: */
-       u16                      x86_max_cores;
+       u16                     x86_max_cores;
        u16                     apicid;
        u16                     initial_apicid;
        u16                     x86_clflush_size;
        u16                     logical_proc_id;
        /* Core id: */
        u16                     cpu_core_id;
+       u16                     cpu_die_id;
+       u16                     logical_die_id;
        /* Index into per_cpu list: */
        u16                     cpu_index;
        u32                     microcode;
@@@ -144,8 -146,7 +146,8 @@@ enum cpuid_regs_idx 
  #define X86_VENDOR_TRANSMETA  7
  #define X86_VENDOR_NSC                8
  #define X86_VENDOR_HYGON      9
 -#define X86_VENDOR_NUM                10
 +#define X86_VENDOR_ZHAOXIN    10
 +#define X86_VENDOR_NUM                11
  
  #define X86_VENDOR_UNKNOWN    0xff
  
index 0d3fe060a44f3969d61a44e1f4d1454bff89957e,b673a226ad6cc7e8c3be5e71d872ea42b783bab5..e1356a3b8223b03ec7d245a6eb7b1b5479e8f1c6
@@@ -23,6 -23,7 +23,7 @@@ extern unsigned int num_processors
  
  DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
  DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
+ DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
  /* cpus sharing the last level cache: */
  DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
  DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id);
@@@ -162,8 -163,7 +163,8 @@@ __visible void smp_call_function_single
   * from the initial startup. We map APIC_BASE very early in page_setup(),
   * so this is correct in the x86 case.
   */
 -#define raw_smp_processor_id() (this_cpu_read(cpu_number))
 +#define raw_smp_processor_id()  this_cpu_read(cpu_number)
 +#define __smp_processor_id() __this_cpu_read(cpu_number)
  
  #ifdef CONFIG_X86_32
  extern int safe_smp_processor_id(void);
index 8febe90470f47ecb9e078e5cca21fbf897cb8512,8cdca1223b0f25e88193814fae315693b99fb5a3..309b6b9b49d4a92d74adae760d852a9293c9f826
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /* cpu_feature_enabled() cannot be used this early */
  #define USE_EARLY_PGTABLE_L5
  
@@@ -366,25 -365,6 +366,25 @@@ out
        cr4_clear_bits(X86_CR4_UMIP);
  }
  
 +DEFINE_STATIC_KEY_FALSE_RO(cr_pinning);
 +EXPORT_SYMBOL(cr_pinning);
 +unsigned long cr4_pinned_bits __ro_after_init;
 +EXPORT_SYMBOL(cr4_pinned_bits);
 +
 +/*
 + * Once CPU feature detection is finished (and boot params have been
 + * parsed), record any of the sensitive CR bits that are set, and
 + * enable CR pinning.
 + */
 +static void __init setup_cr_pinning(void)
 +{
 +      unsigned long mask;
 +
 +      mask = (X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP);
 +      cr4_pinned_bits = this_cpu_read(cpu_tlbstate.cr4) & mask;
 +      static_key_enable(&cr_pinning.key);
 +}
 +
  /*
   * Protection Keys are not available in 32-bit mode.
   */
@@@ -820,30 -800,6 +820,30 @@@ static void init_speculation_control(st
        }
  }
  
 +static void init_cqm(struct cpuinfo_x86 *c)
 +{
 +      if (!cpu_has(c, X86_FEATURE_CQM_LLC)) {
 +              c->x86_cache_max_rmid  = -1;
 +              c->x86_cache_occ_scale = -1;
 +              return;
 +      }
 +
 +      /* will be overridden if occupancy monitoring exists */
 +      c->x86_cache_max_rmid = cpuid_ebx(0xf);
 +
 +      if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC) ||
 +          cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL) ||
 +          cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)) {
 +              u32 eax, ebx, ecx, edx;
 +
 +              /* QoS sub-leaf, EAX=0Fh, ECX=1 */
 +              cpuid_count(0xf, 1, &eax, &ebx, &ecx, &edx);
 +
 +              c->x86_cache_max_rmid  = ecx;
 +              c->x86_cache_occ_scale = ebx;
 +      }
 +}
 +
  void get_cpu_cap(struct cpuinfo_x86 *c)
  {
        u32 eax, ebx, ecx, edx;
                c->x86_capability[CPUID_7_0_EBX] = ebx;
                c->x86_capability[CPUID_7_ECX] = ecx;
                c->x86_capability[CPUID_7_EDX] = edx;
 +
 +              /* Check valid sub-leaf index before accessing it */
 +              if (eax >= 1) {
 +                      cpuid_count(0x00000007, 1, &eax, &ebx, &ecx, &edx);
 +                      c->x86_capability[CPUID_7_1_EAX] = eax;
 +              }
        }
  
        /* Extended state features: level 0x0000000d */
                c->x86_capability[CPUID_D_1_EAX] = eax;
        }
  
 -      /* Additional Intel-defined flags: level 0x0000000F */
 -      if (c->cpuid_level >= 0x0000000F) {
 -
 -              /* QoS sub-leaf, EAX=0Fh, ECX=0 */
 -              cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx);
 -              c->x86_capability[CPUID_F_0_EDX] = edx;
 -
 -              if (cpu_has(c, X86_FEATURE_CQM_LLC)) {
 -                      /* will be overridden if occupancy monitoring exists */
 -                      c->x86_cache_max_rmid = ebx;
 -
 -                      /* QoS sub-leaf, EAX=0Fh, ECX=1 */
 -                      cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx);
 -                      c->x86_capability[CPUID_F_1_EDX] = edx;
 -
 -                      if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) ||
 -                            ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) ||
 -                             (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) {
 -                              c->x86_cache_max_rmid = ecx;
 -                              c->x86_cache_occ_scale = ebx;
 -                      }
 -              } else {
 -                      c->x86_cache_max_rmid = -1;
 -                      c->x86_cache_occ_scale = -1;
 -              }
 -      }
 -
        /* AMD-defined flags: level 0x80000001 */
        eax = cpuid_eax(0x80000000);
        c->extended_cpuid_level = eax;
  
        init_scattered_cpuid_features(c);
        init_speculation_control(c);
 +      init_cqm(c);
  
        /*
         * Clear/Set all flags overridden by options, after probe.
@@@ -1322,6 -1298,7 +1322,7 @@@ static void validate_apic_and_package_i
                       cpu, apicid, c->initial_apicid);
        }
        BUG_ON(topology_update_package_map(c->phys_proc_id, cpu));
+       BUG_ON(topology_update_die_map(c->cpu_die_id, cpu));
  #else
        c->logical_proc_id = 0;
  #endif
@@@ -1487,7 -1464,6 +1488,7 @@@ void __init identify_boot_cpu(void
        enable_sep_cpu();
  #endif
        cpu_detect_tlb(&boot_cpu_data);
 +      setup_cr_pinning();
  }
  
  void identify_secondary_cpu(struct cpuinfo_x86 *c)
index 1af7a2d89419b627137f8a778e82997dc7e162fd,1a19a5171949f4d6d644d3b9435a115571df0afb..f78801114ee1ce829837c5a1e3147cf119f6c1d0
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-or-later
   /*
   *    x86 SMP booting functions
   *
@@@ -13,6 -12,9 +13,6 @@@
   *    Pentium Pro and Pentium-II/Xeon MP machines.
   *    Original development of Linux SMP code supported by Caldera.
   *
 - *    This code is released under the GNU General Public License version 2 or
 - *    later.
 - *
   *    Fixes
   *            Felix Koop      :       NR_CPUS used properly
   *            Jose Renau      :       Handle single CPU case.
@@@ -89,6 -91,10 +89,10 @@@ EXPORT_PER_CPU_SYMBOL(cpu_sibling_map)
  DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
  EXPORT_PER_CPU_SYMBOL(cpu_core_map);
  
+ /* representing HT, core, and die siblings of each logical CPU */
+ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
+ EXPORT_PER_CPU_SYMBOL(cpu_die_map);
  DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
  
  /* Per CPU bogomips and other parameters */
@@@ -99,6 -105,7 +103,7 @@@ EXPORT_PER_CPU_SYMBOL(cpu_info)
  unsigned int __max_logical_packages __read_mostly;
  EXPORT_SYMBOL(__max_logical_packages);
  static unsigned int logical_packages __read_mostly;
+ static unsigned int logical_die __read_mostly;
  
  /* Maximum number of SMT threads on any online core */
  int __read_mostly __max_smt_threads = 1;
@@@ -205,19 -212,13 +210,19 @@@ static int enable_start_cpu0
   */
  static void notrace start_secondary(void *unused)
  {
 +      unsigned long cr4 = __read_cr4();
 +
        /*
         * Don't put *anything* except direct CPU state initialization
         * before cpu_init(), SMP booting is too fragile that we want to
         * limit the things done here to the most necessary things.
         */
        if (boot_cpu_has(X86_FEATURE_PCID))
 -              __write_cr4(__read_cr4() | X86_CR4_PCIDE);
 +              cr4 |= X86_CR4_PCIDE;
 +      if (static_branch_likely(&cr_pinning))
 +              cr4 |= cr4_pinned_bits;
 +
 +      __write_cr4(cr4);
  
  #ifdef CONFIG_X86_32
        /* switch away from the initial page table */
@@@ -306,6 -307,26 +311,26 @@@ int topology_phys_to_logical_pkg(unsign
        return -1;
  }
  EXPORT_SYMBOL(topology_phys_to_logical_pkg);
+ /**
+  * topology_phys_to_logical_die - Map a physical die id to logical
+  *
+  * Returns logical die id or -1 if not found
+  */
+ int topology_phys_to_logical_die(unsigned int die_id, unsigned int cur_cpu)
+ {
+       int cpu;
+       int proc_id = cpu_data(cur_cpu).phys_proc_id;
+       for_each_possible_cpu(cpu) {
+               struct cpuinfo_x86 *c = &cpu_data(cpu);
+               if (c->initialized && c->cpu_die_id == die_id &&
+                   c->phys_proc_id == proc_id)
+                       return c->logical_die_id;
+       }
+       return -1;
+ }
+ EXPORT_SYMBOL(topology_phys_to_logical_die);
  
  /**
   * topology_update_package_map - Update the physical to logical package map
@@@ -330,6 -351,29 +355,29 @@@ found
        cpu_data(cpu).logical_proc_id = new;
        return 0;
  }
+ /**
+  * topology_update_die_map - Update the physical to logical die map
+  * @die:      The die id as retrieved via CPUID
+  * @cpu:      The cpu for which this is updated
+  */
+ int topology_update_die_map(unsigned int die, unsigned int cpu)
+ {
+       int new;
+       /* Already available somewhere? */
+       new = topology_phys_to_logical_die(die, cpu);
+       if (new >= 0)
+               goto found;
+       new = logical_die++;
+       if (new != die) {
+               pr_info("CPU %u Converting physical %u to logical die %u\n",
+                       cpu, die, new);
+       }
+ found:
+       cpu_data(cpu).logical_die_id = new;
+       return 0;
+ }
  
  void __init smp_store_boot_cpu_info(void)
  {
        *c = boot_cpu_data;
        c->cpu_index = id;
        topology_update_package_map(c->phys_proc_id, id);
+       topology_update_die_map(c->cpu_die_id, id);
        c->initialized = true;
  }
  
@@@ -393,6 -438,7 +442,7 @@@ static bool match_smt(struct cpuinfo_x8
                int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
  
                if (c->phys_proc_id == o->phys_proc_id &&
+                   c->cpu_die_id == o->cpu_die_id &&
                    per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2)) {
                        if (c->cpu_core_id == o->cpu_core_id)
                                return topology_sane(c, o, "smt");
                }
  
        } else if (c->phys_proc_id == o->phys_proc_id &&
+                  c->cpu_die_id == o->cpu_die_id &&
                   c->cpu_core_id == o->cpu_core_id) {
                return topology_sane(c, o, "smt");
        }
@@@ -466,6 -513,15 +517,15 @@@ static bool match_pkg(struct cpuinfo_x8
        return false;
  }
  
+ static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
+ {
+       if ((c->phys_proc_id == o->phys_proc_id) &&
+               (c->cpu_die_id == o->cpu_die_id))
+               return true;
+       return false;
+ }
  #if defined(CONFIG_SCHED_SMT) || defined(CONFIG_SCHED_MC)
  static inline int x86_sched_itmt_flags(void)
  {
@@@ -528,6 -584,7 +588,7 @@@ void set_cpu_sibling_map(int cpu
                cpumask_set_cpu(cpu, topology_sibling_cpumask(cpu));
                cpumask_set_cpu(cpu, cpu_llc_shared_mask(cpu));
                cpumask_set_cpu(cpu, topology_core_cpumask(cpu));
+               cpumask_set_cpu(cpu, topology_die_cpumask(cpu));
                c->booted_cores = 1;
                return;
        }
                }
                if (match_pkg(c, o) && !topology_same_node(c, o))
                        x86_has_numa_in_package = true;
+               if ((i == cpu) || (has_mp && match_die(c, o)))
+                       link_mask(topology_die_cpumask, cpu, i);
        }
  
        threads = cpumask_weight(topology_sibling_cpumask(cpu));
@@@ -1180,6 -1240,7 +1244,7 @@@ static __init void disable_smp(void
                physid_set_mask_of_physid(0, &phys_cpu_present_map);
        cpumask_set_cpu(0, topology_sibling_cpumask(0));
        cpumask_set_cpu(0, topology_core_cpumask(0));
+       cpumask_set_cpu(0, topology_die_cpumask(0));
  }
  
  /*
@@@ -1275,6 -1336,7 +1340,7 @@@ void __init native_smp_prepare_cpus(uns
        for_each_possible_cpu(i) {
                zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
                zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
+               zalloc_cpumask_var(&per_cpu(cpu_die_map, i), GFP_KERNEL);
                zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL);
        }
  
@@@ -1495,6 -1557,8 +1561,8 @@@ static void remove_siblinginfo(int cpu
                        cpu_data(sibling).booted_cores--;
        }
  
+       for_each_cpu(sibling, topology_die_cpumask(cpu))
+               cpumask_clear_cpu(cpu, topology_die_cpumask(sibling));
        for_each_cpu(sibling, topology_sibling_cpumask(cpu))
                cpumask_clear_cpu(cpu, topology_sibling_cpumask(sibling));
        for_each_cpu(sibling, cpu_llc_shared_mask(cpu))
        cpumask_clear(cpu_llc_shared_mask(cpu));
        cpumask_clear(topology_sibling_cpumask(cpu));
        cpumask_clear(topology_core_cpumask(cpu));
+       cpumask_clear(topology_die_cpumask(cpu));
        c->cpu_core_id = 0;
        c->booted_cores = 0;
        cpumask_clear_cpu(cpu, cpu_sibling_setup_mask);
diff --combined drivers/hwmon/coretemp.c
index 4d0d6c86c12fef6227b07b9956b157d741e68a72,4ebed90d81aa87d800709b32aa05fc989550b8ff..fe6618e49dc436cafda1e5ad12f6a8cbd89ef7c6
@@@ -1,10 -1,23 +1,10 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * coretemp.c - Linux kernel module for hardware monitoring
   *
   * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
   *
   * Inspired from many hwmon drivers
 - *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License as published by
 - * the Free Software Foundation; version 2 of the License.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 - * 02110-1301 USA.
   */
  
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@@ -96,10 -109,10 +96,10 @@@ struct platform_data 
        struct device_attribute name_attr;
  };
  
- /* Keep track of how many package pointers we allocated in init() */
- static int max_packages __read_mostly;
- /* Array of package pointers. Serialized by cpu hotplug lock */
- static struct platform_device **pkg_devices;
+ /* Keep track of how many zone pointers we allocated in init() */
+ static int max_zones __read_mostly;
+ /* Array of zone pointers. Serialized by cpu hotplug lock */
+ static struct platform_device **zone_devices;
  
  static ssize_t show_label(struct device *dev,
                                struct device_attribute *devattr, char *buf)
@@@ -422,10 -435,10 +422,10 @@@ static int chk_ucode_version(unsigned i
  
  static struct platform_device *coretemp_get_pdev(unsigned int cpu)
  {
-       int pkgid = topology_logical_package_id(cpu);
+       int id = topology_logical_die_id(cpu);
  
-       if (pkgid >= 0 && pkgid < max_packages)
-               return pkg_devices[pkgid];
+       if (id >= 0 && id < max_zones)
+               return zone_devices[id];
        return NULL;
  }
  
@@@ -531,7 -544,7 +531,7 @@@ static int coretemp_probe(struct platfo
        struct device *dev = &pdev->dev;
        struct platform_data *pdata;
  
-       /* Initialize the per-package data structures */
+       /* Initialize the per-zone data structures */
        pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL);
        if (!pdata)
                return -ENOMEM;
@@@ -566,13 -579,13 +566,13 @@@ static struct platform_driver coretemp_
  
  static struct platform_device *coretemp_device_add(unsigned int cpu)
  {
-       int err, pkgid = topology_logical_package_id(cpu);
+       int err, zoneid = topology_logical_die_id(cpu);
        struct platform_device *pdev;
  
-       if (pkgid < 0)
+       if (zoneid < 0)
                return ERR_PTR(-ENOMEM);
  
-       pdev = platform_device_alloc(DRVNAME, pkgid);
+       pdev = platform_device_alloc(DRVNAME, zoneid);
        if (!pdev)
                return ERR_PTR(-ENOMEM);
  
                return ERR_PTR(err);
        }
  
-       pkg_devices[pkgid] = pdev;
+       zone_devices[zoneid] = pdev;
        return pdev;
  }
  
@@@ -690,7 -703,7 +690,7 @@@ static int coretemp_cpu_offline(unsigne
         * the rest.
         */
        if (cpumask_empty(&pd->cpumask)) {
-               pkg_devices[topology_logical_package_id(cpu)] = NULL;
+               zone_devices[topology_logical_die_id(cpu)] = NULL;
                platform_device_unregister(pdev);
                return 0;
        }
@@@ -728,10 -741,10 +728,10 @@@ static int __init coretemp_init(void
        if (!x86_match_cpu(coretemp_ids))
                return -ENODEV;
  
-       max_packages = topology_max_packages();
-       pkg_devices = kcalloc(max_packages, sizeof(struct platform_device *),
+       max_zones = topology_max_packages() * topology_max_die_per_package();
+       zone_devices = kcalloc(max_zones, sizeof(struct platform_device *),
                              GFP_KERNEL);
-       if (!pkg_devices)
+       if (!zone_devices)
                return -ENOMEM;
  
        err = platform_driver_register(&coretemp_driver);
  
  outdrv:
        platform_driver_unregister(&coretemp_driver);
-       kfree(pkg_devices);
+       kfree(zone_devices);
        return err;
  }
  module_init(coretemp_init)
@@@ -756,7 -769,7 +756,7 @@@ static void __exit coretemp_exit(void
  {
        cpuhp_remove_state(coretemp_hp_online);
        platform_driver_unregister(&coretemp_driver);
-       kfree(pkg_devices);
+       kfree(zone_devices);
  }
  module_exit(coretemp_exit)
  
index f888117b0efc5f4486be77a3b549db279bebe5eb,ad78c1d082603d372792abecfadaea66cc441aeb..8692f6b79f93248652307e62ea2ccb26d3023186
@@@ -1,7 -1,19 +1,7 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Intel Running Average Power Limit (RAPL) Driver
   * Copyright (c) 2013, Intel Corporation.
 - *
 - * This program is free software; you can redistribute it and/or modify it
 - * under the terms and conditions of the GNU General Public License,
 - * version 2, as published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope it will be useful, but WITHOUT
 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 - * more details.
 - *
 - * You should have received a copy of the GNU General Public License along with
 - * this program; if not, write to the Free Software Foundation, Inc.
 - *
   */
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
@@@ -166,12 -178,15 +166,15 @@@ struct rapl_domain 
  #define power_zone_to_rapl_domain(_zone) \
        container_of(_zone, struct rapl_domain, power_zone)
  
+ /* maximum rapl package domain name: package-%d-die-%d */
+ #define PACKAGE_DOMAIN_NAME_LENGTH 30
  
- /* Each physical package contains multiple domains, these are the common
+ /* Each rapl package contains multiple domains, these are the common
   * data across RAPL domains within a package.
   */
  struct rapl_package {
-       unsigned int id; /* physical package/socket id */
+       unsigned int id; /* logical die id, equals physical 1-die systems */
        unsigned int nr_domains;
        unsigned long domain_map; /* bit map of active domains */
        unsigned int power_unit;
        int lead_cpu; /* one active cpu per package for access */
        /* Track active cpus */
        struct cpumask cpumask;
+       char name[PACKAGE_DOMAIN_NAME_LENGTH];
  };
  
  struct rapl_defaults {
@@@ -252,8 -268,9 +256,9 @@@ static struct powercap_control_type *co
  static struct rapl_domain *platform_rapl_domain; /* Platform (PSys) domain */
  
  /* caller to ensure CPU hotplug lock is held */
- static struct rapl_package *find_package_by_id(int id)
+ static struct rapl_package *rapl_find_package_domain(int cpu)
  {
+       int id = topology_logical_die_id(cpu);
        struct rapl_package *rp;
  
        list_for_each_entry(rp, &rapl_packages, plist) {
@@@ -913,8 -930,8 +918,8 @@@ static int rapl_check_unit_core(struct 
        value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
        rp->time_unit = 1000000 / (1 << value);
  
-       pr_debug("Core CPU package %d energy=%dpJ, time=%dus, power=%duW\n",
-               rp->id, rp->energy_unit, rp->time_unit, rp->power_unit);
+       pr_debug("Core CPU %s energy=%dpJ, time=%dus, power=%duW\n",
+               rp->name, rp->energy_unit, rp->time_unit, rp->power_unit);
  
        return 0;
  }
@@@ -938,8 -955,8 +943,8 @@@ static int rapl_check_unit_atom(struct 
        value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
        rp->time_unit = 1000000 / (1 << value);
  
-       pr_debug("Atom package %d energy=%dpJ, time=%dus, power=%duW\n",
-               rp->id, rp->energy_unit, rp->time_unit, rp->power_unit);
+       pr_debug("Atom %s energy=%dpJ, time=%dus, power=%duW\n",
+               rp->name, rp->energy_unit, rp->time_unit, rp->power_unit);
  
        return 0;
  }
@@@ -1168,7 -1185,7 +1173,7 @@@ static void rapl_update_domain_data(str
        u64 val;
  
        for (dmn = 0; dmn < rp->nr_domains; dmn++) {
-               pr_debug("update package %d domain %s data\n", rp->id,
+               pr_debug("update %s domain %s data\n", rp->name,
                         rp->domains[dmn].name);
                /* exclude non-raw primitives */
                for (prim = 0; prim < NR_RAW_PRIMITIVES; prim++) {
@@@ -1193,7 -1210,6 +1198,6 @@@ static void rapl_unregister_powercap(vo
  static int rapl_package_register_powercap(struct rapl_package *rp)
  {
        struct rapl_domain *rd;
-       char dev_name[17]; /* max domain name = 7 + 1 + 8 for int + 1 for null*/
        struct powercap_zone *power_zone = NULL;
        int nr_pl, ret;
  
        for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
                if (rd->id == RAPL_DOMAIN_PACKAGE) {
                        nr_pl = find_nr_power_limit(rd);
-                       pr_debug("register socket %d package domain %s\n",
-                               rp->id, rd->name);
-                       memset(dev_name, 0, sizeof(dev_name));
-                       snprintf(dev_name, sizeof(dev_name), "%s-%d",
-                               rd->name, rp->id);
+                       pr_debug("register package domain %s\n", rp->name);
                        power_zone = powercap_register_zone(&rd->power_zone,
                                                        control_type,
-                                                       dev_name, NULL,
+                                                       rp->name, NULL,
                                                        &zone_ops[rd->id],
                                                        nr_pl,
                                                        &constraint_ops);
                        if (IS_ERR(power_zone)) {
-                               pr_debug("failed to register package, %d\n",
-                                       rp->id);
+                               pr_debug("failed to register power zone %s\n",
+                                       rp->name);
                                return PTR_ERR(power_zone);
                        }
                        /* track parent zone in per package/socket data */
                                                &constraint_ops);
  
                if (IS_ERR(power_zone)) {
-                       pr_debug("failed to register power_zone, %d:%s:%s\n",
-                               rp->id, rd->name, dev_name);
+                       pr_debug("failed to register power_zone, %s:%s\n",
+                               rp->name, rd->name);
                        ret = PTR_ERR(power_zone);
                        goto err_cleanup;
                }
@@@ -1257,7 -1269,7 +1257,7 @@@ err_cleanup
         * failed after the first domain setup.
         */
        while (--rd >= rp->domains) {
-               pr_debug("unregister package %d domain %s\n", rp->id, rd->name);
+               pr_debug("unregister %s domain %s\n", rp->name, rd->name);
                powercap_unregister_zone(control_type, &rd->power_zone);
        }
  
@@@ -1288,7 -1300,7 +1288,7 @@@ static int __init rapl_register_psys(vo
        rd->rpl[0].name = pl1_name;
        rd->rpl[1].prim_id = PL2_ENABLE;
        rd->rpl[1].name = pl2_name;
-       rd->rp = find_package_by_id(0);
+       rd->rp = rapl_find_package_domain(0);
  
        power_zone = powercap_register_zone(&rd->power_zone, control_type,
                                            "psys", NULL,
@@@ -1367,8 -1379,8 +1367,8 @@@ static void rapl_detect_powerlimit(stru
        /* check if the domain is locked by BIOS, ignore if MSR doesn't exist */
        if (!rapl_read_data_raw(rd, FW_LOCK, false, &val64)) {
                if (val64) {
-                       pr_info("RAPL package %d domain %s locked by BIOS\n",
-                               rd->rp->id, rd->name);
+                       pr_info("RAPL %s domain %s locked by BIOS\n",
+                               rd->rp->name, rd->name);
                        rd->state |= DOMAIN_STATE_BIOS_LOCKED;
                }
        }
@@@ -1397,10 -1409,10 +1397,10 @@@ static int rapl_detect_domains(struct r
        }
        rp->nr_domains = bitmap_weight(&rp->domain_map, RAPL_DOMAIN_MAX);
        if (!rp->nr_domains) {
-               pr_debug("no valid rapl domains found in package %d\n", rp->id);
+               pr_debug("no valid rapl domains found in %s\n", rp->name);
                return -ENODEV;
        }
-       pr_debug("found %d domains on package %d\n", rp->nr_domains, rp->id);
+       pr_debug("found %d domains on %s\n", rp->nr_domains, rp->name);
  
        rp->domains = kcalloc(rp->nr_domains + 1, sizeof(struct rapl_domain),
                        GFP_KERNEL);
@@@ -1433,8 -1445,8 +1433,8 @@@ static void rapl_remove_package(struct 
                        rd_package = rd;
                        continue;
                }
-               pr_debug("remove package, undo power limit on %d: %s\n",
-                        rp->id, rd->name);
+               pr_debug("remove package, undo power limit on %s: %s\n",
+                        rp->name, rd->name);
                powercap_unregister_zone(control_type, &rd->power_zone);
        }
        /* do parent zone last */
  }
  
  /* called from CPU hotplug notifier, hotplug lock held */
- static struct rapl_package *rapl_add_package(int cpu, int pkgid)
+ static struct rapl_package *rapl_add_package(int cpu)
  {
+       int id = topology_logical_die_id(cpu);
        struct rapl_package *rp;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
        int ret;
  
        rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL);
                return ERR_PTR(-ENOMEM);
  
        /* add the new package to the list */
-       rp->id = pkgid;
+       rp->id = id;
        rp->lead_cpu = cpu;
  
+       if (topology_max_die_per_package() > 1)
+               snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH,
+                       "package-%d-die-%d", c->phys_proc_id, c->cpu_die_id);
+       else
+               snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH, "package-%d",
+                       c->phys_proc_id);
        /* check if the package contains valid domains */
        if (rapl_detect_domains(rp, cpu) ||
                rapl_defaults->check_unit(rp, cpu)) {
@@@ -1485,12 -1506,11 +1494,11 @@@ err_free_package
   */
  static int rapl_cpu_online(unsigned int cpu)
  {
-       int pkgid = topology_physical_package_id(cpu);
        struct rapl_package *rp;
  
-       rp = find_package_by_id(pkgid);
+       rp = rapl_find_package_domain(cpu);
        if (!rp) {
-               rp = rapl_add_package(cpu, pkgid);
+               rp = rapl_add_package(cpu);
                if (IS_ERR(rp))
                        return PTR_ERR(rp);
        }
  
  static int rapl_cpu_down_prep(unsigned int cpu)
  {
-       int pkgid = topology_physical_package_id(cpu);
        struct rapl_package *rp;
        int lead_cpu;
  
-       rp = find_package_by_id(pkgid);
+       rp = rapl_find_package_domain(cpu);
        if (!rp)
                return 0;
  
index 319b7712616866781942a68bab8e791a35e1ee15,87e929ffb0cbdf9631163a3d232e8d3e1b6ce665..e85d54d1cdf3989fa07888466f8b0a9a4b98d375
@@@ -1,7 -1,19 +1,7 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * x86_pkg_temp_thermal driver
   * Copyright (c) 2013, Intel Corporation.
 - *
 - * This program is free software; you can redistribute it and/or modify it
 - * under the terms and conditions of the GNU General Public License,
 - * version 2, as published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope it will be useful, but WITHOUT
 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 - * more details.
 - *
 - * You should have received a copy of the GNU General Public License along with
 - * this program; if not, write to the Free Software Foundation, Inc.
 - *
   */
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
@@@ -43,7 -55,7 +43,7 @@@ MODULE_PARM_DESC(notify_delay_ms
  */
  #define MAX_NUMBER_OF_TRIPS   2
  
- struct pkg_device {
+ struct zone_device {
        int                             cpu;
        bool                            work_scheduled;
        u32                             tj_max;
@@@ -58,10 -70,10 +58,10 @@@ static struct thermal_zone_params pkg_t
        .no_hwmon       = true,
  };
  
- /* Keep track of how many package pointers we allocated in init() */
- static int max_packages __read_mostly;
- /* Array of package pointers */
- static struct pkg_device **packages;
+ /* Keep track of how many zone pointers we allocated in init() */
+ static int max_id __read_mostly;
+ /* Array of zone pointers */
+ static struct zone_device **zones;
  /* Serializes interrupt notification, work and hotplug */
  static DEFINE_SPINLOCK(pkg_temp_lock);
  /* Protects zone operation in the work function against hotplug removal */
@@@ -108,12 -120,12 +108,12 @@@ err_out
   *
   * - Other callsites: Must hold pkg_temp_lock
   */
- static struct pkg_device *pkg_temp_thermal_get_dev(unsigned int cpu)
+ static struct zone_device *pkg_temp_thermal_get_dev(unsigned int cpu)
  {
-       int pkgid = topology_logical_package_id(cpu);
+       int id = topology_logical_die_id(cpu);
  
-       if (pkgid >= 0 && pkgid < max_packages)
-               return packages[pkgid];
+       if (id >= 0 && id < max_id)
+               return zones[id];
        return NULL;
  }
  
@@@ -138,12 -150,13 +138,13 @@@ static int get_tj_max(int cpu, u32 *tj_
  
  static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
  {
-       struct pkg_device *pkgdev = tzd->devdata;
+       struct zone_device *zonedev = tzd->devdata;
        u32 eax, edx;
  
-       rdmsr_on_cpu(pkgdev->cpu, MSR_IA32_PACKAGE_THERM_STATUS, &eax, &edx);
+       rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_STATUS,
+                       &eax, &edx);
        if (eax & 0x80000000) {
-               *temp = pkgdev->tj_max - ((eax >> 16) & 0x7f) * 1000;
+               *temp = zonedev->tj_max - ((eax >> 16) & 0x7f) * 1000;
                pr_debug("sys_get_curr_temp %d\n", *temp);
                return 0;
        }
  static int sys_get_trip_temp(struct thermal_zone_device *tzd,
                             int trip, int *temp)
  {
-       struct pkg_device *pkgdev = tzd->devdata;
+       struct zone_device *zonedev = tzd->devdata;
        unsigned long thres_reg_value;
        u32 mask, shift, eax, edx;
        int ret;
                shift = THERM_SHIFT_THRESHOLD0;
        }
  
-       ret = rdmsr_on_cpu(pkgdev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
+       ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
                           &eax, &edx);
        if (ret < 0)
                return ret;
  
        thres_reg_value = (eax & mask) >> shift;
        if (thres_reg_value)
-               *temp = pkgdev->tj_max - thres_reg_value * 1000;
+               *temp = zonedev->tj_max - thres_reg_value * 1000;
        else
                *temp = 0;
        pr_debug("sys_get_trip_temp %d\n", *temp);
  static int
  sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
  {
-       struct pkg_device *pkgdev = tzd->devdata;
+       struct zone_device *zonedev = tzd->devdata;
        u32 l, h, mask, shift, intr;
        int ret;
  
-       if (trip >= MAX_NUMBER_OF_TRIPS || temp >= pkgdev->tj_max)
+       if (trip >= MAX_NUMBER_OF_TRIPS || temp >= zonedev->tj_max)
                return -EINVAL;
  
-       ret = rdmsr_on_cpu(pkgdev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
+       ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
                           &l, &h);
        if (ret < 0)
                return ret;
        if (!temp) {
                l &= ~intr;
        } else {
-               l |= (pkgdev->tj_max - temp)/1000 << shift;
+               l |= (zonedev->tj_max - temp)/1000 << shift;
                l |= intr;
        }
  
-       return wrmsr_on_cpu(pkgdev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
+       return wrmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
+                       l, h);
  }
  
  static int sys_get_trip_type(struct thermal_zone_device *thermal, int trip,
@@@ -275,26 -289,26 +277,26 @@@ static void pkg_temp_thermal_threshold_
  {
        struct thermal_zone_device *tzone = NULL;
        int cpu = smp_processor_id();
-       struct pkg_device *pkgdev;
+       struct zone_device *zonedev;
        u64 msr_val, wr_val;
  
        mutex_lock(&thermal_zone_mutex);
        spin_lock_irq(&pkg_temp_lock);
        ++pkg_work_cnt;
  
-       pkgdev = pkg_temp_thermal_get_dev(cpu);
-       if (!pkgdev) {
+       zonedev = pkg_temp_thermal_get_dev(cpu);
+       if (!zonedev) {
                spin_unlock_irq(&pkg_temp_lock);
                mutex_unlock(&thermal_zone_mutex);
                return;
        }
-       pkgdev->work_scheduled = false;
+       zonedev->work_scheduled = false;
  
        rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
        wr_val = msr_val & ~(THERM_LOG_THRESHOLD0 | THERM_LOG_THRESHOLD1);
        if (wr_val != msr_val) {
                wrmsrl(MSR_IA32_PACKAGE_THERM_STATUS, wr_val);
-               tzone = pkgdev->tzone;
+               tzone = zonedev->tzone;
        }
  
        enable_pkg_thres_interrupt();
@@@ -320,7 -334,7 +322,7 @@@ static void pkg_thermal_schedule_work(i
  static int pkg_thermal_notify(u64 msr_val)
  {
        int cpu = smp_processor_id();
-       struct pkg_device *pkgdev;
+       struct zone_device *zonedev;
        unsigned long flags;
  
        spin_lock_irqsave(&pkg_temp_lock, flags);
        disable_pkg_thres_interrupt();
  
        /* Work is per package, so scheduling it once is enough. */
-       pkgdev = pkg_temp_thermal_get_dev(cpu);
-       if (pkgdev && !pkgdev->work_scheduled) {
-               pkgdev->work_scheduled = true;
-               pkg_thermal_schedule_work(pkgdev->cpu, &pkgdev->work);
+       zonedev = pkg_temp_thermal_get_dev(cpu);
+       if (zonedev && !zonedev->work_scheduled) {
+               zonedev->work_scheduled = true;
+               pkg_thermal_schedule_work(zonedev->cpu, &zonedev->work);
        }
  
        spin_unlock_irqrestore(&pkg_temp_lock, flags);
  
  static int pkg_temp_thermal_device_add(unsigned int cpu)
  {
-       int pkgid = topology_logical_package_id(cpu);
+       int id = topology_logical_die_id(cpu);
        u32 tj_max, eax, ebx, ecx, edx;
-       struct pkg_device *pkgdev;
+       struct zone_device *zonedev;
        int thres_count, err;
  
-       if (pkgid >= max_packages)
+       if (id >= max_id)
                return -ENOMEM;
  
        cpuid(6, &eax, &ebx, &ecx, &edx);
        if (err)
                return err;
  
-       pkgdev = kzalloc(sizeof(*pkgdev), GFP_KERNEL);
-       if (!pkgdev)
+       zonedev = kzalloc(sizeof(*zonedev), GFP_KERNEL);
+       if (!zonedev)
                return -ENOMEM;
  
-       INIT_DELAYED_WORK(&pkgdev->work, pkg_temp_thermal_threshold_work_fn);
-       pkgdev->cpu = cpu;
-       pkgdev->tj_max = tj_max;
-       pkgdev->tzone = thermal_zone_device_register("x86_pkg_temp",
+       INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn);
+       zonedev->cpu = cpu;
+       zonedev->tj_max = tj_max;
+       zonedev->tzone = thermal_zone_device_register("x86_pkg_temp",
                        thres_count,
                        (thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01,
-                       pkgdev, &tzone_ops, &pkg_temp_tz_params, 0, 0);
-       if (IS_ERR(pkgdev->tzone)) {
-               err = PTR_ERR(pkgdev->tzone);
-               kfree(pkgdev);
+                       zonedev, &tzone_ops, &pkg_temp_tz_params, 0, 0);
+       if (IS_ERR(zonedev->tzone)) {
+               err = PTR_ERR(zonedev->tzone);
+               kfree(zonedev);
                return err;
        }
        /* Store MSR value for package thermal interrupt, to restore at exit */
-       rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, pkgdev->msr_pkg_therm_low,
-             pkgdev->msr_pkg_therm_high);
+       rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low,
+             zonedev->msr_pkg_therm_high);
  
-       cpumask_set_cpu(cpu, &pkgdev->cpumask);
+       cpumask_set_cpu(cpu, &zonedev->cpumask);
        spin_lock_irq(&pkg_temp_lock);
-       packages[pkgid] = pkgdev;
+       zones[id] = zonedev;
        spin_unlock_irq(&pkg_temp_lock);
        return 0;
  }
  
  static int pkg_thermal_cpu_offline(unsigned int cpu)
  {
-       struct pkg_device *pkgdev = pkg_temp_thermal_get_dev(cpu);
+       struct zone_device *zonedev = pkg_temp_thermal_get_dev(cpu);
        bool lastcpu, was_target;
        int target;
  
-       if (!pkgdev)
+       if (!zonedev)
                return 0;
  
-       target = cpumask_any_but(&pkgdev->cpumask, cpu);
-       cpumask_clear_cpu(cpu, &pkgdev->cpumask);
+       target = cpumask_any_but(&zonedev->cpumask, cpu);
+       cpumask_clear_cpu(cpu, &zonedev->cpumask);
        lastcpu = target >= nr_cpu_ids;
        /*
         * Remove the sysfs files, if this is the last cpu in the package
         * before doing further cleanups.
         */
        if (lastcpu) {
-               struct thermal_zone_device *tzone = pkgdev->tzone;
+               struct thermal_zone_device *tzone = zonedev->tzone;
  
                /*
                 * We must protect against a work function calling
                 * won't try to call.
                 */
                mutex_lock(&thermal_zone_mutex);
-               pkgdev->tzone = NULL;
+               zonedev->tzone = NULL;
                mutex_unlock(&thermal_zone_mutex);
  
                thermal_zone_device_unregister(tzone);
         * one. When we drop the lock, then the interrupt notify function
         * will see the new target.
         */
-       was_target = pkgdev->cpu == cpu;
-       pkgdev->cpu = target;
+       was_target = zonedev->cpu == cpu;
+       zonedev->cpu = target;
  
        /*
         * If this is the last CPU in the package remove the package
         * worker will see the package anymore.
         */
        if (lastcpu) {
-               packages[topology_logical_package_id(cpu)] = NULL;
+               zones[topology_logical_die_id(cpu)] = NULL;
                /* After this point nothing touches the MSR anymore. */
                wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
-                     pkgdev->msr_pkg_therm_low, pkgdev->msr_pkg_therm_high);
+                     zonedev->msr_pkg_therm_low, zonedev->msr_pkg_therm_high);
        }
  
        /*
         * Check whether there is work scheduled and whether the work is
         * targeted at the outgoing CPU.
         */
-       if (pkgdev->work_scheduled && was_target) {
+       if (zonedev->work_scheduled && was_target) {
                /*
                 * To cancel the work we need to drop the lock, otherwise
                 * we might deadlock if the work needs to be flushed.
                 */
                spin_unlock_irq(&pkg_temp_lock);
-               cancel_delayed_work_sync(&pkgdev->work);
+               cancel_delayed_work_sync(&zonedev->work);
                spin_lock_irq(&pkg_temp_lock);
                /*
                 * If this is not the last cpu in the package and the work
                 * need to reschedule the work, otherwise the interrupt
                 * stays disabled forever.
                 */
-               if (!lastcpu && pkgdev->work_scheduled)
-                       pkg_thermal_schedule_work(target, &pkgdev->work);
+               if (!lastcpu && zonedev->work_scheduled)
+                       pkg_thermal_schedule_work(target, &zonedev->work);
        }
  
        spin_unlock_irq(&pkg_temp_lock);
  
        /* Final cleanup if this is the last cpu */
        if (lastcpu)
-               kfree(pkgdev);
+               kfree(zonedev);
        return 0;
  }
  
  static int pkg_thermal_cpu_online(unsigned int cpu)
  {
-       struct pkg_device *pkgdev = pkg_temp_thermal_get_dev(cpu);
+       struct zone_device *zonedev = pkg_temp_thermal_get_dev(cpu);
        struct cpuinfo_x86 *c = &cpu_data(cpu);
  
        /* Paranoia check */
                return -ENODEV;
  
        /* If the package exists, nothing to do */
-       if (pkgdev) {
-               cpumask_set_cpu(cpu, &pkgdev->cpumask);
+       if (zonedev) {
+               cpumask_set_cpu(cpu, &zonedev->cpumask);
                return 0;
        }
        return pkg_temp_thermal_device_add(cpu);
@@@ -503,10 -517,10 +505,10 @@@ static int __init pkg_temp_thermal_init
        if (!x86_match_cpu(pkg_temp_thermal_ids))
                return -ENODEV;
  
-       max_packages = topology_max_packages();
-       packages = kcalloc(max_packages, sizeof(struct pkg_device *),
+       max_id = topology_max_packages() * topology_max_die_per_package();
+       zones = kcalloc(max_id, sizeof(struct zone_device *),
                           GFP_KERNEL);
-       if (!packages)
+       if (!zones)
                return -ENOMEM;
  
        ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "thermal/x86_pkg:online",
        return 0;
  
  err:
-       kfree(packages);
+       kfree(zones);
        return ret;
  }
  module_init(pkg_temp_thermal_init)
@@@ -537,7 -551,7 +539,7 @@@ static void __exit pkg_temp_thermal_exi
  
        cpuhp_remove_state(pkg_thermal_hp_state);
        debugfs_remove_recursive(debugfs);
-       kfree(packages);
+       kfree(zones);
  }
  module_exit(pkg_temp_thermal_exit)