Commit 9e3d62d5 authored by Sven Schnelle's avatar Sven Schnelle Committed by Vasily Gorbik

s390/topology: clear thread/group maps for offline cpus

The current code doesn't clear the thread/group maps for offline
CPUs. This may cause kernel crashes like the one bewlow in common
code that assumes if a CPU has sibblings it is online.

Unable to handle kernel pointer dereference in virtual kernel address space

Call Trace:
 [<000000013a4b8c3c>] blk_mq_map_swqueue+0x10c/0x388
([<000000013a4b8bcc>] blk_mq_map_swqueue+0x9c/0x388)
 [<000000013a4b9300>] blk_mq_init_allocated_queue+0x448/0x478
 [<000000013a4b9416>] blk_mq_init_queue+0x4e/0x90
 [<000003ff8019d3e6>] loop_add+0x106/0x278 [loop]
 [<000003ff801b8148>] loop_init+0x148/0x1000 [loop]
 [<0000000139de4924>] do_one_initcall+0x3c/0x1e0
 [<0000000139ef449a>] do_init_module+0x6a/0x2a0
 [<0000000139ef61bc>] __do_sys_finit_module+0xa4/0xc0
 [<0000000139de9e6e>] do_syscall+0x7e/0xd0
 [<000000013a8e0aec>] __do_syscall+0xbc/0x110
 [<000000013a8ee2e8>] system_call+0x78/0xa0

Fixes: 52aeda7a ("s390/topology: remove offline CPUs from CPU topology masks")
Cc: <stable@kernel.org> # 5.7+
Reported-by: default avatarMarius Hillenbrand <mhillen@linux.ibm.com>
Signed-off-by: default avatarSven Schnelle <svens@linux.ibm.com>
Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 8c0795d2
...@@ -66,7 +66,10 @@ static void cpu_group_map(cpumask_t *dst, struct mask_info *info, unsigned int c ...@@ -66,7 +66,10 @@ static void cpu_group_map(cpumask_t *dst, struct mask_info *info, unsigned int c
{ {
static cpumask_t mask; static cpumask_t mask;
cpumask_copy(&mask, cpumask_of(cpu)); cpumask_clear(&mask);
if (!cpu_online(cpu))
goto out;
cpumask_set_cpu(cpu, &mask);
switch (topology_mode) { switch (topology_mode) {
case TOPOLOGY_MODE_HW: case TOPOLOGY_MODE_HW:
while (info) { while (info) {
...@@ -83,10 +86,10 @@ static void cpu_group_map(cpumask_t *dst, struct mask_info *info, unsigned int c ...@@ -83,10 +86,10 @@ static void cpu_group_map(cpumask_t *dst, struct mask_info *info, unsigned int c
default: default:
fallthrough; fallthrough;
case TOPOLOGY_MODE_SINGLE: case TOPOLOGY_MODE_SINGLE:
cpumask_copy(&mask, cpumask_of(cpu));
break; break;
} }
cpumask_and(&mask, &mask, cpu_online_mask); cpumask_and(&mask, &mask, cpu_online_mask);
out:
cpumask_copy(dst, &mask); cpumask_copy(dst, &mask);
} }
...@@ -95,7 +98,10 @@ static void cpu_thread_map(cpumask_t *dst, unsigned int cpu) ...@@ -95,7 +98,10 @@ static void cpu_thread_map(cpumask_t *dst, unsigned int cpu)
static cpumask_t mask; static cpumask_t mask;
int i; int i;
cpumask_copy(&mask, cpumask_of(cpu)); cpumask_clear(&mask);
if (!cpu_online(cpu))
goto out;
cpumask_set_cpu(cpu, &mask);
if (topology_mode != TOPOLOGY_MODE_HW) if (topology_mode != TOPOLOGY_MODE_HW)
goto out; goto out;
cpu -= cpu % (smp_cpu_mtid + 1); cpu -= cpu % (smp_cpu_mtid + 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment