]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Nov 2025 01:46:18 +0000 (10:46 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Nov 2025 01:46:18 +0000 (10:46 +0900)
added patches:
acpi-pptt-remove-acpi_find_cache_levels.patch
acpi-pptt-update-acpi_find_last_cache_level-to-acpi_get_cache_info.patch
arch_topology-build-cacheinfo-from-primary-cpu.patch
arm64-tegra-update-cache-properties.patch
cacheinfo-check-cache-unified-property-to-count-cache-leaves.patch
cacheinfo-fix-llc-is-not-exported-through-sysfs.patch
cacheinfo-initialize-variables-in-fetch_cache_info.patch
cacheinfo-return-error-code-in-init_of_cache_level.patch
cacheinfo-use-risc-v-s-init_cache_level-as-generic-of-implementation.patch
drivers-base-cacheinfo-update-cpu_map_populated-during-cpu-hotplug.patch

queue-6.1/acpi-pptt-remove-acpi_find_cache_levels.patch [new file with mode: 0644]
queue-6.1/acpi-pptt-update-acpi_find_last_cache_level-to-acpi_get_cache_info.patch [new file with mode: 0644]
queue-6.1/arch_topology-build-cacheinfo-from-primary-cpu.patch [new file with mode: 0644]
queue-6.1/arm64-tegra-update-cache-properties.patch [new file with mode: 0644]
queue-6.1/cacheinfo-check-cache-unified-property-to-count-cache-leaves.patch [new file with mode: 0644]
queue-6.1/cacheinfo-fix-llc-is-not-exported-through-sysfs.patch [new file with mode: 0644]
queue-6.1/cacheinfo-initialize-variables-in-fetch_cache_info.patch [new file with mode: 0644]
queue-6.1/cacheinfo-return-error-code-in-init_of_cache_level.patch [new file with mode: 0644]
queue-6.1/cacheinfo-use-risc-v-s-init_cache_level-as-generic-of-implementation.patch [new file with mode: 0644]
queue-6.1/drivers-base-cacheinfo-update-cpu_map_populated-during-cpu-hotplug.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/acpi-pptt-remove-acpi_find_cache_levels.patch b/queue-6.1/acpi-pptt-remove-acpi_find_cache_levels.patch
new file mode 100644 (file)
index 0000000..cd5f749
--- /dev/null
@@ -0,0 +1,77 @@
+From wen.yang@linux.dev Tue Oct 21 02:37:24 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:18 +0800
+Subject: ACPI: PPTT: Remove acpi_find_cache_levels()
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Pierre Gondois <pierre.gondois@arm.com>, Jeremy Linton <jeremy.linton@arm.com>, "Rafael J . Wysocki" <rafael.j.wysocki@intel.com>, Palmer Dabbelt <palmer@rivosinc.com>, Sudeep Holla <sudeep.holla@arm.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-5-wen.yang@linux.dev>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit fa4d566a605bc4cf32d69f16ef8cf9696635f75a ]
+
+acpi_find_cache_levels() is used at a single place and is short
+enough to be merged into the calling function. The removal allows
+an easier renaming of the calling function in the next patch.
+
+Also reorder the local variables in the 'reversed Christmas tree'
+order.
+
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: Jeremy Linton <jeremy.linton@arm.com>
+Acked-by: Rafael J. Wysocki  <rafael.j.wysocki@intel.com>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+Link: https://lore.kernel.org/r/20230104183033.755668-5-pierre.gondois@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/acpi/pptt.c |   21 ++++++---------------
+ 1 file changed, 6 insertions(+), 15 deletions(-)
+
+--- a/drivers/acpi/pptt.c
++++ b/drivers/acpi/pptt.c
+@@ -286,19 +286,6 @@ static struct acpi_pptt_processor *acpi_
+       return NULL;
+ }
+-static int acpi_find_cache_levels(struct acpi_table_header *table_hdr,
+-                                u32 acpi_cpu_id)
+-{
+-      int number_of_levels = 0;
+-      struct acpi_pptt_processor *cpu;
+-
+-      cpu = acpi_find_processor_node(table_hdr, acpi_cpu_id);
+-      if (cpu)
+-              number_of_levels = acpi_count_levels(table_hdr, cpu);
+-
+-      return number_of_levels;
+-}
+-
+ static u8 acpi_cache_type(enum cache_type type)
+ {
+       switch (type) {
+@@ -621,9 +608,10 @@ static int check_acpi_cpu_flag(unsigned
+  */
+ int acpi_find_last_cache_level(unsigned int cpu)
+ {
+-      u32 acpi_cpu_id;
++      struct acpi_pptt_processor *cpu_node;
+       struct acpi_table_header *table;
+       int number_of_levels = 0;
++      u32 acpi_cpu_id;
+       table = acpi_get_pptt();
+       if (!table)
+@@ -632,7 +620,10 @@ int acpi_find_last_cache_level(unsigned
+       pr_debug("Cache Setup find last level CPU=%d\n", cpu);
+       acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+-      number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id);
++      cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
++      if (cpu_node)
++              number_of_levels = acpi_count_levels(table, cpu_node);
++
+       pr_debug("Cache Setup find last level level=%d\n", number_of_levels);
+       return number_of_levels;
diff --git a/queue-6.1/acpi-pptt-update-acpi_find_last_cache_level-to-acpi_get_cache_info.patch b/queue-6.1/acpi-pptt-update-acpi_find_last_cache_level-to-acpi_get_cache_info.patch
new file mode 100644 (file)
index 0000000..f6e80af
--- /dev/null
@@ -0,0 +1,266 @@
+From wen.yang@linux.dev Tue Oct 21 02:37:31 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:19 +0800
+Subject: ACPI: PPTT: Update acpi_find_last_cache_level() to acpi_get_cache_info()
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Pierre Gondois <pierre.gondois@arm.com>, Jeremy Linton <jeremy.linton@arm.com>, "Rafael J . Wysocki" <rafael.j.wysocki@intel.com>, Palmer Dabbelt <palmer@rivosinc.com>, Sudeep Holla <sudeep.holla@arm.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-6-wen.yang@linux.dev>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit bd500361a937c03a3da57178287ce543c8f3681b ]
+
+acpi_find_last_cache_level() allows to find the last level of cache
+for a given CPU. The function is only called on arm64 ACPI based
+platforms to check for cache information that would be missing in
+the CLIDR_EL1 register.
+To allow populating (struct cpu_cacheinfo).num_leaves by only parsing
+a PPTT, update acpi_find_last_cache_level() to get the 'split_levels',
+i.e. the number of cache levels being split in data/instruction
+caches.
+
+It is assumed that there will not be data/instruction caches above a
+unified cache.
+If a split level consist of one data cache and no instruction cache
+(or opposite), then the missing cache will still be populated
+by default with minimal cache information, and maximal cpumask
+(all non-existing caches have the same fw_token).
+
+Suggested-by: Jeremy Linton <jeremy.linton@arm.com>
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: Jeremy Linton <jeremy.linton@arm.com>
+Acked-by: Rafael J. Wysocki  <rafael.j.wysocki@intel.com>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+Link: https://lore.kernel.org/r/20230104183033.755668-6-pierre.gondois@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/cacheinfo.c |   11 +++---
+ drivers/acpi/pptt.c           |   76 +++++++++++++++++++++++++++---------------
+ include/linux/cacheinfo.h     |    9 +++-
+ 3 files changed, 63 insertions(+), 33 deletions(-)
+
+--- a/arch/arm64/kernel/cacheinfo.c
++++ b/arch/arm64/kernel/cacheinfo.c
+@@ -46,7 +46,7 @@ static void ci_leaf_init(struct cacheinf
+ int init_cache_level(unsigned int cpu)
+ {
+       unsigned int ctype, level, leaves;
+-      int fw_level;
++      int fw_level, ret;
+       struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+       for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) {
+@@ -59,10 +59,13 @@ int init_cache_level(unsigned int cpu)
+               leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1;
+       }
+-      if (acpi_disabled)
++      if (acpi_disabled) {
+               fw_level = of_find_last_cache_level(cpu);
+-      else
+-              fw_level = acpi_find_last_cache_level(cpu);
++      } else {
++              ret = acpi_get_cache_info(cpu, &fw_level, NULL);
++              if (ret < 0)
++                      return ret;
++      }
+       if (fw_level < 0)
+               return fw_level;
+--- a/drivers/acpi/pptt.c
++++ b/drivers/acpi/pptt.c
+@@ -81,6 +81,7 @@ static inline bool acpi_pptt_match_type(
+  * acpi_pptt_walk_cache() - Attempt to find the requested acpi_pptt_cache
+  * @table_hdr: Pointer to the head of the PPTT table
+  * @local_level: passed res reflects this cache level
++ * @split_levels: Number of split cache levels (data/instruction).
+  * @res: cache resource in the PPTT we want to walk
+  * @found: returns a pointer to the requested level if found
+  * @level: the requested cache level
+@@ -100,6 +101,7 @@ static inline bool acpi_pptt_match_type(
+  */
+ static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
+                                        unsigned int local_level,
++                                       unsigned int *split_levels,
+                                        struct acpi_subtable_header *res,
+                                        struct acpi_pptt_cache **found,
+                                        unsigned int level, int type)
+@@ -113,8 +115,17 @@ static unsigned int acpi_pptt_walk_cache
+       while (cache) {
+               local_level++;
++              if (!(cache->flags & ACPI_PPTT_CACHE_TYPE_VALID)) {
++                      cache = fetch_pptt_cache(table_hdr, cache->next_level_of_cache);
++                      continue;
++              }
++
++              if (split_levels &&
++                  (acpi_pptt_match_type(cache->attributes, ACPI_PPTT_CACHE_TYPE_DATA) ||
++                   acpi_pptt_match_type(cache->attributes, ACPI_PPTT_CACHE_TYPE_INSTR)))
++                      *split_levels = local_level;
++
+               if (local_level == level &&
+-                  cache->flags & ACPI_PPTT_CACHE_TYPE_VALID &&
+                   acpi_pptt_match_type(cache->attributes, type)) {
+                       if (*found != NULL && cache != *found)
+                               pr_warn("Found duplicate cache level/type unable to determine uniqueness\n");
+@@ -135,8 +146,8 @@ static unsigned int acpi_pptt_walk_cache
+ static struct acpi_pptt_cache *
+ acpi_find_cache_level(struct acpi_table_header *table_hdr,
+                     struct acpi_pptt_processor *cpu_node,
+-                    unsigned int *starting_level, unsigned int level,
+-                    int type)
++                    unsigned int *starting_level, unsigned int *split_levels,
++                    unsigned int level, int type)
+ {
+       struct acpi_subtable_header *res;
+       unsigned int number_of_levels = *starting_level;
+@@ -149,7 +160,8 @@ acpi_find_cache_level(struct acpi_table_
+               resource++;
+               local_level = acpi_pptt_walk_cache(table_hdr, *starting_level,
+-                                                 res, &ret, level, type);
++                                                 split_levels, res, &ret,
++                                                 level, type);
+               /*
+                * we are looking for the max depth. Since its potentially
+                * possible for a given node to have resources with differing
+@@ -165,29 +177,29 @@ acpi_find_cache_level(struct acpi_table_
+ }
+ /**
+- * acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches
++ * acpi_count_levels() - Given a PPTT table, and a CPU node, count the cache
++ * levels and split cache levels (data/instruction).
+  * @table_hdr: Pointer to the head of the PPTT table
+  * @cpu_node: processor node we wish to count caches for
++ * @levels: Number of levels if success.
++ * @split_levels:     Number of split cache levels (data/instruction) if
++ *                    success. Can by NULL.
+  *
+  * Given a processor node containing a processing unit, walk into it and count
+  * how many levels exist solely for it, and then walk up each level until we hit
+  * the root node (ignore the package level because it may be possible to have
+- * caches that exist across packages). Count the number of cache levels that
+- * exist at each level on the way up.
+- *
+- * Return: Total number of levels found.
++ * caches that exist across packages). Count the number of cache levels and
++ * split cache levels (data/instruction) that exist at each level on the way
++ * up.
+  */
+-static int acpi_count_levels(struct acpi_table_header *table_hdr,
+-                           struct acpi_pptt_processor *cpu_node)
++static void acpi_count_levels(struct acpi_table_header *table_hdr,
++                            struct acpi_pptt_processor *cpu_node,
++                            unsigned int *levels, unsigned int *split_levels)
+ {
+-      int total_levels = 0;
+-
+       do {
+-              acpi_find_cache_level(table_hdr, cpu_node, &total_levels, 0, 0);
++              acpi_find_cache_level(table_hdr, cpu_node, levels, split_levels, 0, 0);
+               cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
+       } while (cpu_node);
+-
+-      return total_levels;
+ }
+ /**
+@@ -326,7 +338,7 @@ static struct acpi_pptt_cache *acpi_find
+       while (cpu_node && !found) {
+               found = acpi_find_cache_level(table_hdr, cpu_node,
+-                                            &total_levels, level, acpi_type);
++                                            &total_levels, NULL, level, acpi_type);
+               *node = cpu_node;
+               cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
+       }
+@@ -597,36 +609,48 @@ static int check_acpi_cpu_flag(unsigned
+ }
+ /**
+- * acpi_find_last_cache_level() - Determines the number of cache levels for a PE
++ * acpi_get_cache_info() - Determine the number of cache levels and
++ * split cache levels (data/instruction) and for a PE.
+  * @cpu: Kernel logical CPU number
++ * @levels: Number of levels if success.
++ * @split_levels:     Number of levels being split (i.e. data/instruction)
++ *                    if success. Can by NULL.
+  *
+  * Given a logical CPU number, returns the number of levels of cache represented
+  * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
+  * indicating we didn't find any cache levels.
+  *
+- * Return: Cache levels visible to this core.
++ * Return: -ENOENT if no PPTT table or no PPTT processor struct found.
++ *       0 on success.
+  */
+-int acpi_find_last_cache_level(unsigned int cpu)
++int acpi_get_cache_info(unsigned int cpu, unsigned int *levels,
++                      unsigned int *split_levels)
+ {
+       struct acpi_pptt_processor *cpu_node;
+       struct acpi_table_header *table;
+-      int number_of_levels = 0;
+       u32 acpi_cpu_id;
++      *levels = 0;
++      if (split_levels)
++              *split_levels = 0;
++
+       table = acpi_get_pptt();
+       if (!table)
+               return -ENOENT;
+-      pr_debug("Cache Setup find last level CPU=%d\n", cpu);
++      pr_debug("Cache Setup: find cache levels for CPU=%d\n", cpu);
+       acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+       cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
+-      if (cpu_node)
+-              number_of_levels = acpi_count_levels(table, cpu_node);
++      if (!cpu_node)
++              return -ENOENT;
++
++      acpi_count_levels(table, cpu_node, levels, split_levels);
+-      pr_debug("Cache Setup find last level level=%d\n", number_of_levels);
++      pr_debug("Cache Setup: last_level=%d split_levels=%d\n",
++               *levels, split_levels ? *split_levels : -1);
+-      return number_of_levels;
++      return 0;
+ }
+ /**
+--- a/include/linux/cacheinfo.h
++++ b/include/linux/cacheinfo.h
+@@ -88,19 +88,22 @@ bool last_level_cache_is_shared(unsigned
+ int detect_cache_attributes(unsigned int cpu);
+ #ifndef CONFIG_ACPI_PPTT
+ /*
+- * acpi_find_last_cache_level is only called on ACPI enabled
++ * acpi_get_cache_info() is only called on ACPI enabled
+  * platforms using the PPTT for topology. This means that if
+  * the platform supports other firmware configuration methods
+  * we need to stub out the call when ACPI is disabled.
+  * ACPI enabled platforms not using PPTT won't be making calls
+  * to this function so we need not worry about them.
+  */
+-static inline int acpi_find_last_cache_level(unsigned int cpu)
++static inline
++int acpi_get_cache_info(unsigned int cpu,
++                      unsigned int *levels, unsigned int *split_levels)
+ {
+       return 0;
+ }
+ #else
+-int acpi_find_last_cache_level(unsigned int cpu);
++int acpi_get_cache_info(unsigned int cpu,
++                      unsigned int *levels, unsigned int *split_levels);
+ #endif
+ const struct attribute_group *cache_get_priv_group(struct cacheinfo *this_leaf);
diff --git a/queue-6.1/arch_topology-build-cacheinfo-from-primary-cpu.patch b/queue-6.1/arch_topology-build-cacheinfo-from-primary-cpu.patch
new file mode 100644 (file)
index 0000000..eff2f9b
--- /dev/null
@@ -0,0 +1,244 @@
+From wen.yang@linux.dev Tue Oct 21 02:37:41 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:20 +0800
+Subject: arch_topology: Build cacheinfo from primary CPU
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Pierre Gondois <pierre.gondois@arm.com>, Sudeep Holla <sudeep.holla@arm.com>, Palmer Dabbelt <palmer@rivosinc.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-7-wen.yang@linux.dev>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit 5944ce092b97caed5d86d961e963b883b5c44ee2 ]
+
+commit 3fcbf1c77d08 ("arch_topology: Fix cache attributes detection
+in the CPU hotplug path")
+adds a call to detect_cache_attributes() to populate the cacheinfo
+before updating the siblings mask. detect_cache_attributes() allocates
+memory and can take the PPTT mutex (on ACPI platforms). On PREEMPT_RT
+kernels, on secondary CPUs, this triggers a:
+  'BUG: sleeping function called from invalid context' [1]
+as the code is executed with preemption and interrupts disabled.
+
+The primary CPU was previously storing the cache information using
+the now removed (struct cpu_topology).llc_id:
+commit 5b8dc787ce4a ("arch_topology: Drop LLC identifier stash from
+the CPU topology")
+
+allocate_cache_info() tries to build the cacheinfo from the primary
+CPU prior secondary CPUs boot, if the DT/ACPI description
+contains cache information.
+If allocate_cache_info() fails, then fallback to the current state
+for the cacheinfo allocation. [1] will be triggered in such case.
+
+When unplugging a CPU, the cacheinfo memory cannot be freed. If it
+was, then the memory would be allocated early by the re-plugged
+CPU and would trigger [1].
+
+Note that populate_cache_leaves() might be called multiple times
+due to populate_leaves being moved up. This is required since
+detect_cache_attributes() might be called with per_cpu_cacheinfo(cpu)
+being allocated but not populated.
+
+[1]:
+ | BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46
+ | in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 0, name: swapper/111
+ | preempt_count: 1, expected: 0
+ | RCU nest depth: 1, expected: 1
+ | 3 locks held by swapper/111/0:
+ |  #0:  (&pcp->lock){+.+.}-{3:3}, at: get_page_from_freelist+0x218/0x12c8
+ |  #1:  (rcu_read_lock){....}-{1:3}, at: rt_spin_trylock+0x48/0xf0
+ |  #2:  (&zone->lock){+.+.}-{3:3}, at: rmqueue_bulk+0x64/0xa80
+ | irq event stamp: 0
+ | hardirqs last  enabled at (0):  0x0
+ | hardirqs last disabled at (0):  copy_process+0x5dc/0x1ab8
+ | softirqs last  enabled at (0):  copy_process+0x5dc/0x1ab8
+ | softirqs last disabled at (0):  0x0
+ | Preemption disabled at:
+ |  migrate_enable+0x30/0x130
+ | CPU: 111 PID: 0 Comm: swapper/111 Tainted: G        W          6.0.0-rc4-rt6-[...]
+ | Call trace:
+ |  __kmalloc+0xbc/0x1e8
+ |  detect_cache_attributes+0x2d4/0x5f0
+ |  update_siblings_masks+0x30/0x368
+ |  store_cpu_topology+0x78/0xb8
+ |  secondary_start_kernel+0xd0/0x198
+ |  __secondary_switched+0xb0/0xb4
+
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+Link: https://lore.kernel.org/r/20230104183033.755668-7-pierre.gondois@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/kernel/cacheinfo.c |    5 --
+ drivers/base/arch_topology.c  |   12 +++++--
+ drivers/base/cacheinfo.c      |   71 +++++++++++++++++++++++++++++++-----------
+ include/linux/cacheinfo.h     |    1 
+ 4 files changed, 65 insertions(+), 24 deletions(-)
+
+--- a/arch/riscv/kernel/cacheinfo.c
++++ b/arch/riscv/kernel/cacheinfo.c
+@@ -113,11 +113,6 @@ static void fill_cacheinfo(struct cachei
+       }
+ }
+-int init_cache_level(unsigned int cpu)
+-{
+-      return init_of_cache_level(cpu);
+-}
+-
+ int populate_cache_leaves(unsigned int cpu)
+ {
+       struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+--- a/drivers/base/arch_topology.c
++++ b/drivers/base/arch_topology.c
+@@ -736,7 +736,7 @@ void update_siblings_masks(unsigned int
+       ret = detect_cache_attributes(cpuid);
+       if (ret && ret != -ENOENT)
+-              pr_info("Early cacheinfo failed, ret = %d\n", ret);
++              pr_info("Early cacheinfo allocation failed, ret = %d\n", ret);
+       /* update core and thread sibling masks */
+       for_each_online_cpu(cpu) {
+@@ -825,7 +825,7 @@ __weak int __init parse_acpi_topology(vo
+ #if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
+ void __init init_cpu_topology(void)
+ {
+-      int ret;
++      int cpu, ret;
+       reset_cpu_topology();
+       ret = parse_acpi_topology();
+@@ -840,6 +840,14 @@ void __init init_cpu_topology(void)
+               reset_cpu_topology();
+               return;
+       }
++
++      for_each_possible_cpu(cpu) {
++              ret = fetch_cache_info(cpu);
++              if (ret) {
++                      pr_err("Early cacheinfo failed, ret = %d\n", ret);
++                      break;
++              }
++      }
+ }
+ void store_cpu_topology(unsigned int cpuid)
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -412,10 +412,6 @@ static void free_cache_attributes(unsign
+               return;
+       cache_shared_cpu_map_remove(cpu);
+-
+-      kfree(per_cpu_cacheinfo(cpu));
+-      per_cpu_cacheinfo(cpu) = NULL;
+-      cache_leaves(cpu) = 0;
+ }
+ int __weak init_cache_level(unsigned int cpu)
+@@ -428,29 +424,71 @@ int __weak populate_cache_leaves(unsigne
+       return -ENOENT;
+ }
++static inline
++int allocate_cache_info(int cpu)
++{
++      per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu),
++                                       sizeof(struct cacheinfo), GFP_ATOMIC);
++      if (!per_cpu_cacheinfo(cpu)) {
++              cache_leaves(cpu) = 0;
++              return -ENOMEM;
++      }
++
++      return 0;
++}
++
++int fetch_cache_info(unsigned int cpu)
++{
++      struct cpu_cacheinfo *this_cpu_ci;
++      unsigned int levels, split_levels;
++      int ret;
++
++      if (acpi_disabled) {
++              ret = init_of_cache_level(cpu);
++              if (ret < 0)
++                      return ret;
++      } else {
++              ret = acpi_get_cache_info(cpu, &levels, &split_levels);
++              if (ret < 0)
++                      return ret;
++
++              this_cpu_ci = get_cpu_cacheinfo(cpu);
++              this_cpu_ci->num_levels = levels;
++              /*
++               * This assumes that:
++               * - there cannot be any split caches (data/instruction)
++               *   above a unified cache
++               * - data/instruction caches come by pair
++               */
++              this_cpu_ci->num_leaves = levels + split_levels;
++      }
++      if (!cache_leaves(cpu))
++              return -ENOENT;
++
++      return allocate_cache_info(cpu);
++}
++
+ int detect_cache_attributes(unsigned int cpu)
+ {
+       int ret;
+-      /* Since early detection of the cacheinfo is allowed via this
+-       * function and this also gets called as CPU hotplug callbacks via
+-       * cacheinfo_cpu_online, the initialisation can be skipped and only
+-       * CPU maps can be updated as the CPU online status would be update
+-       * if called via cacheinfo_cpu_online path.
++      /* Since early initialization/allocation of the cacheinfo is allowed
++       * via fetch_cache_info() and this also gets called as CPU hotplug
++       * callbacks via cacheinfo_cpu_online, the init/alloc can be skipped
++       * as it will happen only once (the cacheinfo memory is never freed).
++       * Just populate the cacheinfo.
+        */
+       if (per_cpu_cacheinfo(cpu))
+-              goto update_cpu_map;
++              goto populate_leaves;
+       if (init_cache_level(cpu) || !cache_leaves(cpu))
+               return -ENOENT;
+-      per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu),
+-                                       sizeof(struct cacheinfo), GFP_ATOMIC);
+-      if (per_cpu_cacheinfo(cpu) == NULL) {
+-              cache_leaves(cpu) = 0;
+-              return -ENOMEM;
+-      }
++      ret = allocate_cache_info(cpu);
++      if (ret)
++              return ret;
++populate_leaves:
+       /*
+        * populate_cache_leaves() may completely setup the cache leaves and
+        * shared_cpu_map or it may leave it partially setup.
+@@ -459,7 +497,6 @@ int detect_cache_attributes(unsigned int
+       if (ret)
+               goto free_ci;
+-update_cpu_map:
+       /*
+        * For systems using DT for cache hierarchy, fw_token
+        * and shared_cpu_map will be set up here only if they are
+--- a/include/linux/cacheinfo.h
++++ b/include/linux/cacheinfo.h
+@@ -85,6 +85,7 @@ int populate_cache_leaves(unsigned int c
+ int cache_setup_acpi(unsigned int cpu);
+ bool last_level_cache_is_valid(unsigned int cpu);
+ bool last_level_cache_is_shared(unsigned int cpu_x, unsigned int cpu_y);
++int fetch_cache_info(unsigned int cpu);
+ int detect_cache_attributes(unsigned int cpu);
+ #ifndef CONFIG_ACPI_PPTT
+ /*
diff --git a/queue-6.1/arm64-tegra-update-cache-properties.patch b/queue-6.1/arm64-tegra-update-cache-properties.patch
new file mode 100644 (file)
index 0000000..d367e34
--- /dev/null
@@ -0,0 +1,247 @@
+From stable+bounces-188223-greg=kroah.com@vger.kernel.org Tue Oct 21 02:39:11 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:24 +0800
+Subject: arm64: tegra: Update cache properties
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Pierre Gondois <pierre.gondois@arm.com>, Thierry Reding <treding@nvidia.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-11-wen.yang@linux.dev>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit 27f1568b1d5fe35014074f92717b250afbe67031 ]
+
+The DeviceTree Specification v0.3 specifies that the cache node
+'compatible' and 'cache-level' properties are 'required'. Cf.
+s3.8 Multi-level and Shared Cache Nodes
+The 'cache-unified' property should be present if one of the
+properties for unified cache is present ('cache-size', ...).
+
+Update the Device Trees accordingly.
+
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra194.dtsi |   15 ++++++++++++++
+ arch/arm64/boot/dts/nvidia/tegra210.dtsi |    1 
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi |   33 +++++++++++++++++++++++++++++++
+ 3 files changed, 49 insertions(+)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+@@ -3029,36 +3029,51 @@
+               };
+               l2c_0: l2-cache0 {
++                      compatible = "cache";
++                      cache-unified;
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c>;
+               };
+               l2c_1: l2-cache1 {
++                      compatible = "cache";
++                      cache-unified;
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c>;
+               };
+               l2c_2: l2-cache2 {
++                      compatible = "cache";
++                      cache-unified;
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c>;
+               };
+               l2c_3: l2-cache3 {
++                      compatible = "cache";
++                      cache-unified;
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c>;
+               };
+               l3c: l3-cache {
++                      compatible = "cache";
++                      cache-unified;
+                       cache-size = <4194304>;
+                       cache-line-size = <64>;
++                      cache-level = <3>;
+                       cache-sets = <4096>;
+               };
+       };
+--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+@@ -2005,6 +2005,7 @@
+               L2: l2-cache {
+                       compatible = "cache";
++                      cache-level = <2>;
+               };
+       };
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -2907,117 +2907,150 @@
+               };
+               l2c0_0: l2-cache00 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c0>;
+               };
+               l2c0_1: l2-cache01 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c0>;
+               };
+               l2c0_2: l2-cache02 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c0>;
+               };
+               l2c0_3: l2-cache03 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c0>;
+               };
+               l2c1_0: l2-cache10 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c1>;
+               };
+               l2c1_1: l2-cache11 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c1>;
+               };
+               l2c1_2: l2-cache12 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c1>;
+               };
+               l2c1_3: l2-cache13 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c1>;
+               };
+               l2c2_0: l2-cache20 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c2>;
+               };
+               l2c2_1: l2-cache21 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c2>;
+               };
+               l2c2_2: l2-cache22 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c2>;
+               };
+               l2c2_3: l2-cache23 {
++                      compatible = "cache";
+                       cache-size = <262144>;
+                       cache-line-size = <64>;
+                       cache-sets = <512>;
+                       cache-unified;
++                      cache-level = <2>;
+                       next-level-cache = <&l3c2>;
+               };
+               l3c0: l3-cache0 {
++                      compatible = "cache";
++                      cache-unified;
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
++                      cache-level = <3>;
+               };
+               l3c1: l3-cache1 {
++                      compatible = "cache";
++                      cache-unified;
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
++                      cache-level = <3>;
+               };
+               l3c2: l3-cache2 {
++                      compatible = "cache";
++                      cache-unified;
+                       cache-size = <2097152>;
+                       cache-line-size = <64>;
+                       cache-sets = <2048>;
++                      cache-level = <3>;
+               };
+       };
diff --git a/queue-6.1/cacheinfo-check-cache-unified-property-to-count-cache-leaves.patch b/queue-6.1/cacheinfo-check-cache-unified-property-to-count-cache-leaves.patch
new file mode 100644 (file)
index 0000000..6c5bc46
--- /dev/null
@@ -0,0 +1,97 @@
+From wen.yang@linux.dev Tue Oct 21 02:37:19 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:17 +0800
+Subject: cacheinfo: Check 'cache-unified' property to count cache leaves
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Pierre Gondois <pierre.gondois@arm.com>, Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>, Sudeep Holla <sudeep.holla@arm.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-4-wen.yang@linux.dev>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit de0df442ee49cb1f6ee58f3fec5dcb5e5eb70aab ]
+
+The DeviceTree Specification v0.3 specifies that the cache node
+'[d-|i-|]cache-size' property is required. The 'cache-unified'
+property is specifies whether the cache level is separate
+or unified.
+
+If the cache-size property is missing, no cache leaves is accounted.
+This can lead to a 'BUG: KASAN: slab-out-of-bounds' [1] bug.
+
+Check 'cache-unified' property and always account for at least
+one cache leaf when parsing the device tree.
+
+[1] https://lore.kernel.org/all/0f19cb3f-d6cf-4032-66d2-dedc9d09a0e3@linaro.org/
+
+Reported-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20230104183033.755668-4-pierre.gondois@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/cacheinfo.c |   37 ++++++++++++++++++++++++++-----------
+ 1 file changed, 26 insertions(+), 11 deletions(-)
+
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -224,12 +224,9 @@ static int cache_setup_of_node(unsigned
+       return 0;
+ }
+-int init_of_cache_level(unsigned int cpu)
++static int of_count_cache_leaves(struct device_node *np)
+ {
+-      struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+-      struct device_node *np = of_cpu_device_node_get(cpu);
+-      struct device_node *prev = NULL;
+-      unsigned int levels = 0, leaves = 0, level;
++      unsigned int leaves = 0;
+       if (of_property_read_bool(np, "cache-size"))
+               ++leaves;
+@@ -237,6 +234,28 @@ int init_of_cache_level(unsigned int cpu
+               ++leaves;
+       if (of_property_read_bool(np, "d-cache-size"))
+               ++leaves;
++
++      if (!leaves) {
++              /* The '[i-|d-|]cache-size' property is required, but
++               * if absent, fallback on the 'cache-unified' property.
++               */
++              if (of_property_read_bool(np, "cache-unified"))
++                      return 1;
++              else
++                      return 2;
++      }
++
++      return leaves;
++}
++
++int init_of_cache_level(unsigned int cpu)
++{
++      struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
++      struct device_node *np = of_cpu_device_node_get(cpu);
++      struct device_node *prev = NULL;
++      unsigned int levels = 0, leaves, level;
++
++      leaves = of_count_cache_leaves(np);
+       if (leaves > 0)
+               levels = 1;
+@@ -250,12 +269,8 @@ int init_of_cache_level(unsigned int cpu
+                       goto err_out;
+               if (level <= levels)
+                       goto err_out;
+-              if (of_property_read_bool(np, "cache-size"))
+-                      ++leaves;
+-              if (of_property_read_bool(np, "i-cache-size"))
+-                      ++leaves;
+-              if (of_property_read_bool(np, "d-cache-size"))
+-                      ++leaves;
++
++              leaves += of_count_cache_leaves(np);
+               levels = level;
+       }
diff --git a/queue-6.1/cacheinfo-fix-llc-is-not-exported-through-sysfs.patch b/queue-6.1/cacheinfo-fix-llc-is-not-exported-through-sysfs.patch
new file mode 100644 (file)
index 0000000..40ba413
--- /dev/null
@@ -0,0 +1,78 @@
+From wen.yang@linux.dev Tue Oct 21 02:37:49 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:22 +0800
+Subject: cacheinfo: Fix LLC is not exported through sysfs
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Yicong Yang <yangyicong@hisilicon.com>, Pierre Gondois <pierre.gondois@arm.com>, Sudeep Holla <sudeep.holla@arm.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-9-wen.yang@linux.dev>
+
+From: Yicong Yang <yangyicong@hisilicon.com>
+
+[ Upstream commit 5c2712387d4850e0b64121d5fd3e6c4e84ea3266 ]
+
+After entering 6.3-rc1 the LLC cacheinfo is not exported on our ACPI
+based arm64 server. This is because the LLC cacheinfo is partly reset
+when secondary CPUs boot up. On arm64 the primary cpu will allocate
+and setup cacheinfo:
+init_cpu_topology()
+  for_each_possible_cpu()
+    fetch_cache_info() // Allocate cacheinfo and init levels
+detect_cache_attributes()
+  cache_shared_cpu_map_setup()
+    if (!last_level_cache_is_valid()) // not valid, setup LLC
+      cache_setup_properties() // setup LLC
+
+On secondary CPU boot up:
+detect_cache_attributes()
+  populate_cache_leaves()
+    get_cache_type() // Get cache type from clidr_el1,
+                     // for LLC type=CACHE_TYPE_NOCACHE
+  cache_shared_cpu_map_setup()
+    if (!last_level_cache_is_valid()) // Valid and won't go to this branch,
+                                      // leave LLC's type=CACHE_TYPE_NOCACHE
+
+The last_level_cache_is_valid() use cacheinfo->{attributes, fw_token} to
+test it's valid or not, but populate_cache_leaves() will only reset
+LLC's type, so we won't try to re-setup LLC's type and leave it
+CACHE_TYPE_NOCACHE and won't export it through sysfs.
+
+This patch tries to fix this by not re-populating the cache leaves if
+the LLC is valid.
+
+Fixes: 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU")
+Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
+Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Link: https://lore.kernel.org/r/20230328114915.33340-1-yangyicong@huawei.com
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/cacheinfo.c |   16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -490,12 +490,18 @@ int detect_cache_attributes(unsigned int
+ populate_leaves:
+       /*
+-       * populate_cache_leaves() may completely setup the cache leaves and
+-       * shared_cpu_map or it may leave it partially setup.
++       * If LLC is valid the cache leaves were already populated so just go to
++       * update the cpu map.
+        */
+-      ret = populate_cache_leaves(cpu);
+-      if (ret)
+-              goto free_ci;
++      if (!last_level_cache_is_valid(cpu)) {
++              /*
++               * populate_cache_leaves() may completely setup the cache leaves and
++               * shared_cpu_map or it may leave it partially setup.
++               */
++              ret = populate_cache_leaves(cpu);
++              if (ret)
++                      goto free_ci;
++      }
+       /*
+        * For systems using DT for cache hierarchy, fw_token
diff --git a/queue-6.1/cacheinfo-initialize-variables-in-fetch_cache_info.patch b/queue-6.1/cacheinfo-initialize-variables-in-fetch_cache_info.patch
new file mode 100644 (file)
index 0000000..7f9098e
--- /dev/null
@@ -0,0 +1,40 @@
+From wen.yang@linux.dev Tue Oct 21 02:37:43 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:21 +0800
+Subject: cacheinfo: Initialize variables in fetch_cache_info()
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Pierre Gondois <pierre.gondois@arm.com>, kernel test robot <lkp@intel.com>, Dan Carpenter <error27@gmail.com>, Conor Dooley <conor.dooley@microchip.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-8-wen.yang@linux.dev>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit ecaef469920fd6d2c7687f19081946f47684a423 ]
+
+Set potentially uninitialized variables to 0. This is particularly
+relevant when CONFIG_ACPI_PPTT is not set.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/all/202301052307.JYt1GWaJ-lkp@intel.com/
+Reported-by: Dan Carpenter <error27@gmail.com>
+Link: https://lore.kernel.org/all/Y86iruJPuwNN7rZw@kili/
+Fixes: 5944ce092b97 ("arch_topology: Build cacheinfo from primary CPU")
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230124154053.355376-2-pierre.gondois@arm.com
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/cacheinfo.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -440,7 +440,7 @@ int allocate_cache_info(int cpu)
+ int fetch_cache_info(unsigned int cpu)
+ {
+       struct cpu_cacheinfo *this_cpu_ci;
+-      unsigned int levels, split_levels;
++      unsigned int levels = 0, split_levels = 0;
+       int ret;
+       if (acpi_disabled) {
diff --git a/queue-6.1/cacheinfo-return-error-code-in-init_of_cache_level.patch b/queue-6.1/cacheinfo-return-error-code-in-init_of_cache_level.patch
new file mode 100644 (file)
index 0000000..dd8074f
--- /dev/null
@@ -0,0 +1,57 @@
+From wen.yang@linux.dev Tue Oct 21 02:37:15 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:16 +0800
+Subject: cacheinfo: Return error code in init_of_cache_level()
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Pierre Gondois <pierre.gondois@arm.com>, Palmer Dabbelt <palmer@rivosinc.com>, Sudeep Holla <sudeep.holla@arm.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-3-wen.yang@linux.dev>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit 8844c3df001bc1d8397fddea341308da63855d53 ]
+
+Make init_of_cache_level() return an error code when the cache
+information parsing fails to help detecting missing information.
+
+init_of_cache_level() is only called for riscv. Returning an error
+code instead of 0 will prevent detect_cache_attributes() to allocate
+memory if an incomplete DT is parsed.
+
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+Link: https://lore.kernel.org/r/20230104183033.755668-3-pierre.gondois@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/cacheinfo.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -245,11 +245,11 @@ int init_of_cache_level(unsigned int cpu
+               of_node_put(prev);
+               prev = np;
+               if (!of_device_is_compatible(np, "cache"))
+-                      break;
++                      goto err_out;
+               if (of_property_read_u32(np, "cache-level", &level))
+-                      break;
++                      goto err_out;
+               if (level <= levels)
+-                      break;
++                      goto err_out;
+               if (of_property_read_bool(np, "cache-size"))
+                       ++leaves;
+               if (of_property_read_bool(np, "i-cache-size"))
+@@ -264,6 +264,10 @@ int init_of_cache_level(unsigned int cpu
+       this_cpu_ci->num_leaves = leaves;
+       return 0;
++
++err_out:
++      of_node_put(np);
++      return -EINVAL;
+ }
+ #else
diff --git a/queue-6.1/cacheinfo-use-risc-v-s-init_cache_level-as-generic-of-implementation.patch b/queue-6.1/cacheinfo-use-risc-v-s-init_cache_level-as-generic-of-implementation.patch
new file mode 100644 (file)
index 0000000..32ecfa6
--- /dev/null
@@ -0,0 +1,147 @@
+From stable+bounces-188214-greg=kroah.com@vger.kernel.org Tue Oct 21 02:37:19 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:15 +0800
+Subject: cacheinfo: Use RISC-V's init_cache_level() as generic OF implementation
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, Pierre Gondois <pierre.gondois@arm.com>, Conor Dooley <conor.dooley@microchip.com>, Palmer Dabbelt <palmer@rivosinc.com>, Sudeep Holla <sudeep.holla@arm.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-2-wen.yang@linux.dev>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit c3719bd9eeb2edf84bd263d662e36ca0ba262a23 ]
+
+RISC-V's implementation of init_of_cache_level() is following
+the Devicetree Specification v0.3 regarding caches, cf.:
+- s3.7.3 'Internal (L1) Cache Properties'
+- s3.8 'Multi-level and Shared Cache Nodes'
+
+Allow reusing the implementation by moving it.
+
+Also make 'levels', 'leaves' and 'level' unsigned int.
+
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+Link: https://lore.kernel.org/r/20230104183033.755668-2-pierre.gondois@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/kernel/cacheinfo.c |   39 -------------------------------------
+ drivers/base/cacheinfo.c      |   44 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/cacheinfo.h     |    1 
+ 3 files changed, 46 insertions(+), 38 deletions(-)
+
+--- a/arch/riscv/kernel/cacheinfo.c
++++ b/arch/riscv/kernel/cacheinfo.c
+@@ -115,44 +115,7 @@ static void fill_cacheinfo(struct cachei
+ int init_cache_level(unsigned int cpu)
+ {
+-      struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+-      struct device_node *np = of_cpu_device_node_get(cpu);
+-      struct device_node *prev = NULL;
+-      int levels = 0, leaves = 0, level;
+-
+-      if (of_property_read_bool(np, "cache-size"))
+-              ++leaves;
+-      if (of_property_read_bool(np, "i-cache-size"))
+-              ++leaves;
+-      if (of_property_read_bool(np, "d-cache-size"))
+-              ++leaves;
+-      if (leaves > 0)
+-              levels = 1;
+-
+-      prev = np;
+-      while ((np = of_find_next_cache_node(np))) {
+-              of_node_put(prev);
+-              prev = np;
+-              if (!of_device_is_compatible(np, "cache"))
+-                      break;
+-              if (of_property_read_u32(np, "cache-level", &level))
+-                      break;
+-              if (level <= levels)
+-                      break;
+-              if (of_property_read_bool(np, "cache-size"))
+-                      ++leaves;
+-              if (of_property_read_bool(np, "i-cache-size"))
+-                      ++leaves;
+-              if (of_property_read_bool(np, "d-cache-size"))
+-                      ++leaves;
+-              levels = level;
+-      }
+-
+-      of_node_put(np);
+-      this_cpu_ci->num_levels = levels;
+-      this_cpu_ci->num_leaves = leaves;
+-
+-      return 0;
++      return init_of_cache_level(cpu);
+ }
+ int populate_cache_leaves(unsigned int cpu)
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -223,8 +223,52 @@ static int cache_setup_of_node(unsigned
+       return 0;
+ }
++
++int init_of_cache_level(unsigned int cpu)
++{
++      struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
++      struct device_node *np = of_cpu_device_node_get(cpu);
++      struct device_node *prev = NULL;
++      unsigned int levels = 0, leaves = 0, level;
++
++      if (of_property_read_bool(np, "cache-size"))
++              ++leaves;
++      if (of_property_read_bool(np, "i-cache-size"))
++              ++leaves;
++      if (of_property_read_bool(np, "d-cache-size"))
++              ++leaves;
++      if (leaves > 0)
++              levels = 1;
++
++      prev = np;
++      while ((np = of_find_next_cache_node(np))) {
++              of_node_put(prev);
++              prev = np;
++              if (!of_device_is_compatible(np, "cache"))
++                      break;
++              if (of_property_read_u32(np, "cache-level", &level))
++                      break;
++              if (level <= levels)
++                      break;
++              if (of_property_read_bool(np, "cache-size"))
++                      ++leaves;
++              if (of_property_read_bool(np, "i-cache-size"))
++                      ++leaves;
++              if (of_property_read_bool(np, "d-cache-size"))
++                      ++leaves;
++              levels = level;
++      }
++
++      of_node_put(np);
++      this_cpu_ci->num_levels = levels;
++      this_cpu_ci->num_leaves = leaves;
++
++      return 0;
++}
++
+ #else
+ static inline int cache_setup_of_node(unsigned int cpu) { return 0; }
++int init_of_cache_level(unsigned int cpu) { return 0; }
+ #endif
+ int __weak cache_setup_acpi(unsigned int cpu)
+--- a/include/linux/cacheinfo.h
++++ b/include/linux/cacheinfo.h
+@@ -80,6 +80,7 @@ struct cpu_cacheinfo {
+ struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu);
+ int init_cache_level(unsigned int cpu);
++int init_of_cache_level(unsigned int cpu);
+ int populate_cache_leaves(unsigned int cpu);
+ int cache_setup_acpi(unsigned int cpu);
+ bool last_level_cache_is_valid(unsigned int cpu);
diff --git a/queue-6.1/drivers-base-cacheinfo-update-cpu_map_populated-during-cpu-hotplug.patch b/queue-6.1/drivers-base-cacheinfo-update-cpu_map_populated-during-cpu-hotplug.patch
new file mode 100644 (file)
index 0000000..6ec63c1
--- /dev/null
@@ -0,0 +1,116 @@
+From stable+bounces-188222-greg=kroah.com@vger.kernel.org Tue Oct 21 02:38:25 2025
+From: Wen Yang <wen.yang@linux.dev>
+Date: Tue, 21 Oct 2025 01:36:23 +0800
+Subject: drivers: base: cacheinfo: Update cpu_map_populated during CPU Hotplug
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jon Hunter <jonathanh@nvidia.com>
+Cc: stable@vger.kernel.org, linux-kernel@vger.kernel.org, K Prateek Nayak <kprateek.nayak@amd.com>, Yicong Yang <yangyicong@hisilicon.com>, Sudeep Holla <sudeep.holla@arm.com>, Wen Yang <wen.yang@linux.dev>
+Message-ID: <20251020173624.20228-10-wen.yang@linux.dev>
+
+From: K Prateek Nayak <kprateek.nayak@amd.com>
+
+[ Upstream commit c26fabe73330d983c7ce822c6b6ec0879b4da61f ]
+
+Until commit 5c2712387d48 ("cacheinfo: Fix LLC is not exported through
+sysfs"), cacheinfo called populate_cache_leaves() for CPU coming online
+which let the arch specific functions handle (at least on x86)
+populating the shared_cpu_map. However, with the changes in the
+aforementioned commit, populate_cache_leaves() is not called when a CPU
+comes online as a result of hotplug since last_level_cache_is_valid()
+returns true as the cacheinfo data is not discarded. The CPU coming
+online is not present in shared_cpu_map, however, it will not be added
+since the cpu_cacheinfo->cpu_map_populated flag is set (it is set in
+populate_cache_leaves() when cacheinfo is first populated for x86)
+
+This can lead to inconsistencies in the shared_cpu_map when an offlined
+CPU comes online again. Example below depicts the inconsistency in the
+shared_cpu_list in cacheinfo when CPU8 is offlined and onlined again on
+a 3rd Generation EPYC processor:
+
+  # for i in /sys/devices/system/cpu/cpu8/cache/index*/shared_cpu_list; do echo -n "$i: "; cat $i; done
+    /sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list: 8-15,136-143
+
+  # echo 0 > /sys/devices/system/cpu/cpu8/online
+  # echo 1 > /sys/devices/system/cpu/cpu8/online
+
+  # for i in /sys/devices/system/cpu/cpu8/cache/index*/shared_cpu_list; do echo -n "$i: "; cat $i; done
+    /sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list: 8
+    /sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list: 8
+    /sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list: 8
+    /sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list: 8
+
+  # cat /sys/devices/system/cpu/cpu136/cache/index0/shared_cpu_list
+    136
+
+  # cat /sys/devices/system/cpu/cpu136/cache/index3/shared_cpu_list
+    9-15,136-143
+
+Clear the flag when the CPU is removed from shared_cpu_map when
+cache_shared_cpu_map_remove() is called during CPU hotplug. This will
+allow cache_shared_cpu_map_setup() to add the CPU coming back online in
+the shared_cpu_map. Set the flag again when the shared_cpu_map is setup.
+Following are results of performing the same test as described above with
+the changes:
+
+  # for i in /sys/devices/system/cpu/cpu8/cache/index*/shared_cpu_list; do echo -n "$i: "; cat $i; done
+    /sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list: 8-15,136-143
+
+  # echo 0 > /sys/devices/system/cpu/cpu8/online
+  # echo 1 > /sys/devices/system/cpu/cpu8/online
+
+  # for i in /sys/devices/system/cpu/cpu8/cache/index*/shared_cpu_list; do echo -n "$i: "; cat $i; done
+    /sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list: 8,136
+    /sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list: 8-15,136-143
+
+  # cat /sys/devices/system/cpu/cpu136/cache/index0/shared_cpu_list
+    8,136
+
+  # cat /sys/devices/system/cpu/cpu136/cache/index3/shared_cpu_list
+    8-15,136-143
+
+Fixes: 5c2712387d48 ("cacheinfo: Fix LLC is not exported through sysfs")
+Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
+Reviewed-by: Yicong Yang <yangyicong@hisilicon.com>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Link: https://lore.kernel.org/r/20230508084115.1157-3-kprateek.nayak@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/cacheinfo.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -365,11 +365,14 @@ static int cache_shared_cpu_map_setup(un
+                       coherency_max_size = this_leaf->coherency_line_size;
+       }
++      /* shared_cpu_map is now populated for the cpu */
++      this_cpu_ci->cpu_map_populated = true;
+       return 0;
+ }
+ static void cache_shared_cpu_map_remove(unsigned int cpu)
+ {
++      struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+       struct cacheinfo *this_leaf, *sib_leaf;
+       unsigned int sibling, index, sib_index;
+@@ -404,6 +407,9 @@ static void cache_shared_cpu_map_remove(
+               if (of_have_populated_dt())
+                       of_node_put(this_leaf->fw_token);
+       }
++
++      /* cpu is no longer populated in the shared map */
++      this_cpu_ci->cpu_map_populated = false;
+ }
+ static void free_cache_attributes(unsigned int cpu)
index fb1e12d65be71dc7668f7eac04da4a2be0a5f941..675c0d094b176a788af188ee7863ce7b552cb3ab 100644 (file)
@@ -62,3 +62,13 @@ net-phy-dp83867-disable-eee-support-as-not-implemented.patch
 mptcp-change-first-as-a-parameter.patch
 mptcp-drop-bogus-optimization-in-__mptcp_check_push.patch
 can-gs_usb-increase-max-interface-to-u8_max.patch
+cacheinfo-use-risc-v-s-init_cache_level-as-generic-of-implementation.patch
+cacheinfo-return-error-code-in-init_of_cache_level.patch
+cacheinfo-check-cache-unified-property-to-count-cache-leaves.patch
+acpi-pptt-remove-acpi_find_cache_levels.patch
+acpi-pptt-update-acpi_find_last_cache_level-to-acpi_get_cache_info.patch
+arch_topology-build-cacheinfo-from-primary-cpu.patch
+cacheinfo-initialize-variables-in-fetch_cache_info.patch
+cacheinfo-fix-llc-is-not-exported-through-sysfs.patch
+drivers-base-cacheinfo-update-cpu_map_populated-during-cpu-hotplug.patch
+arm64-tegra-update-cache-properties.patch