2023-01-17 11:00:10

by Yong-Xuan Wang

[permalink] [raw]
Subject: [PATCH -next v4 0/1] drivers: base: cacheinfo: fix shared_cpu_map

Changelog:
--- v4 ---
break after we find the shared instance.

--- v3 ---
Remove unneeded semicolon

--- v2 ---
Rebase to the latest Linux codebase

Yong-Xuan Wang (1):
drivers: base: cacheinfo: fix shared_cpu_map

drivers/base/cacheinfo.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)


base-commit: 9ce08dd7ea24253aac5fd2519f9aea27dfb390c9
--
2.17.1


2023-01-17 11:35:18

by Yong-Xuan Wang

[permalink] [raw]
Subject: [PATCH -next v4 1/1] drivers: base: cacheinfo: fix shared_cpu_map

The cacheinfo sets up the shared_cpu_map by checking whether the caches
with the same index are shared between CPUs. However, this will trigger
slab-out-of-bounds access if the CPUs do not have the same cache hierarchy.
Another problem is the mismatched shared_cpu_map when the shared cache does
not have the same index between CPUs.

CPU0 I D L3
index 0 1 2 x
^ ^ ^ ^
index 0 1 2 3
CPU1 I D L2 L3

This patch checks each cache is shared with all caches on other CPUs.

Reviewed-by: Pierre Gondois <[email protected]>
Signed-off-by: Yong-Xuan Wang <[email protected]>
---
drivers/base/cacheinfo.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c
index 950b22cdb5f7..f05acf3c16c6 100644
--- a/drivers/base/cacheinfo.c
+++ b/drivers/base/cacheinfo.c
@@ -256,7 +256,7 @@ static int cache_shared_cpu_map_setup(unsigned int cpu)
{
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
struct cacheinfo *this_leaf, *sib_leaf;
- unsigned int index;
+ unsigned int index, sib_index;
int ret = 0;

if (this_cpu_ci->cpu_map_populated)
@@ -284,11 +284,13 @@ static int cache_shared_cpu_map_setup(unsigned int cpu)

if (i == cpu || !sib_cpu_ci->info_list)
continue;/* skip if itself or no cacheinfo */
-
- sib_leaf = per_cpu_cacheinfo_idx(i, index);
- if (cache_leaves_are_shared(this_leaf, sib_leaf)) {
- cpumask_set_cpu(cpu, &sib_leaf->shared_cpu_map);
- cpumask_set_cpu(i, &this_leaf->shared_cpu_map);
+ for (sib_index = 0; sib_index < cache_leaves(i); sib_index++) {
+ sib_leaf = per_cpu_cacheinfo_idx(i, sib_index);
+ if (cache_leaves_are_shared(this_leaf, sib_leaf)) {
+ cpumask_set_cpu(cpu, &sib_leaf->shared_cpu_map);
+ cpumask_set_cpu(i, &this_leaf->shared_cpu_map);
+ break;
+ }
}
}
/* record the maximum cache line size */
@@ -302,7 +304,7 @@ static int cache_shared_cpu_map_setup(unsigned int cpu)
static void cache_shared_cpu_map_remove(unsigned int cpu)
{
struct cacheinfo *this_leaf, *sib_leaf;
- unsigned int sibling, index;
+ unsigned int sibling, index, sib_index;

for (index = 0; index < cache_leaves(cpu); index++) {
this_leaf = per_cpu_cacheinfo_idx(cpu, index);
@@ -313,9 +315,14 @@ static void cache_shared_cpu_map_remove(unsigned int cpu)
if (sibling == cpu || !sib_cpu_ci->info_list)
continue;/* skip if itself or no cacheinfo */

- sib_leaf = per_cpu_cacheinfo_idx(sibling, index);
- cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map);
- cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map);
+ for (sib_index = 0; sib_index < cache_leaves(sibling); sib_index++) {
+ sib_leaf = per_cpu_cacheinfo_idx(sibling, sib_index);
+ if (cache_leaves_are_shared(this_leaf, sib_leaf)) {
+ cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map);
+ cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map);
+ break;
+ }
+ }
}
}
}
--
2.17.1

2023-01-18 13:36:11

by Sudeep Holla

[permalink] [raw]
Subject: Re: [PATCH -next v4 0/1] drivers: base: cacheinfo: fix shared_cpu_map

On Tue, 17 Jan 2023 10:51:32 +0000, Yong-Xuan Wang wrote:
> Changelog:
> --- v4 ---
> break after we find the shared instance.
>
> --- v3 ---
> Remove unneeded semicolon
>
> [...]

Applied to sudeep.holla/linux (for-next/cacheinfo), thanks!

[1/1] drivers: base: cacheinfo: fix shared_cpu_map
https://git.kernel.org/sudeep.holla/c/198102c9103f

--
Regards,
Sudeep