[PATCH] s390/mm,pageattr: avoid early calls into vmalloc code

From: Heiko Carstens
Date: Thu Mar 21 2024 - 04:41:20 EST


The vmalloc code got changed and doesn't have the global statically
initialized vmap_area_lock spinlock anymore. This leads to the following
lockdep splat when find_vm_area() is called before the vmalloc code is
initialized:

BUG: spinlock bad magic on CPU#0, swapper/0
lock: single+0x1868/0x1978, .magic: 00000000, .owner: swapper/0, .owner_cpu: 0

CPU: 0 PID: 0 Comm: swapper Not tainted 6.8.0-11767-g23956900041d #1
Hardware name: IBM 3931 A01 701 (KVM/Linux)
Call Trace:
[<00000000010d840a>] dump_stack_lvl+0xba/0x148
[<00000000001fdf5c>] do_raw_spin_unlock+0x7c/0xd0
[<000000000111d848>] _raw_spin_unlock+0x38/0x68
[<0000000000485830>] find_vmap_area+0xb0/0x108
[<0000000000485ada>] find_vm_area+0x22/0x40
[<0000000000132bbc>] __set_memory+0xbc/0x140
[<0000000001a7f048>] vmem_map_init+0x40/0x158
[<0000000001a7edc8>] paging_init+0x28/0x80
[<0000000001a7a6e2>] setup_arch+0x4b2/0x6d8
[<0000000001a74438>] start_kernel+0x98/0x4b0
[<0000000000100036>] startup_continue+0x36/0x40
INFO: lockdep is turned off.

Add a slab_is_available() check to change_page_attr_alias() in order to
avoid early calls into vmalloc code. slab_is_available() is not exactly
what is needed, but there is currently no other way to tell if the vmalloc
code is initialized or not, and there is no reason to expose
e.g. vmap_initialized from vmalloc to achieve the same.

The fixes tag does not mean that the referenced commit is broken, but that
there is a dependency to this commit if the vmalloc commit should be
backported.

Fixes: d093602919ad ("mm: vmalloc: remove global vmap_area_root rb-tree")
Signed-off-by: Heiko Carstens <hca@xxxxxxxxxxxxx>
---
arch/s390/mm/pageattr.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index 01bc8fad64d6..b6c6453d66e2 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -344,6 +344,9 @@ static int change_page_attr_alias(unsigned long addr, unsigned long end,
struct vm_struct *area;
int rc = 0;

+ /* Avoid early calls into not initialized vmalloc code. */
+ if (!slab_is_available())
+ return 0;
/*
* Changes to read-only permissions on kernel VA mappings are also
* applied to the kernel direct mapping. Execute permissions are
--
2.40.1