[Devel] [PATCH RHEL8 COMMIT] vdso: fix VM_BUG_ON_PAGE(PageSlab(page)) on unmap
Konstantin Khorenko
khorenko at virtuozzo.com
Tue Dec 15 20:12:18 MSK 2020
The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.1
------>
commit eac26b43815a2f0ebc2128f9161097bed17bdc71
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date: Tue Dec 15 20:12:18 2020 +0300
vdso: fix VM_BUG_ON_PAGE(PageSlab(page)) on unmap
vdso_data is mapped to userspace which means that we can't
use kmalloc() to allocate it. Kmalloc() doesn't even guarantee
that we will get page aligned memory.
kernel BUG at include/linux/mm.h:693!
RIP: 0010:unmap_page_range+0x15f2/0x2630
Call Trace:
unmap_vmas+0x11e/0x1d0
exit_mmap+0x215/0x420
mmput+0x10a/0x400
do_exit+0x98f/0x2d00
do_group_exit+0xec/0x2b0
__x64_sys_exit_group+0x3a/0x50
do_syscall_64+0xa5/0x4d0
entry_SYSCALL_64_after_hwframe+0x6a/0xdf
Use alloc_pages_exact() to allocate it. We can't use
alloc_pages(), or __get_free_pages() here since vdso_fault()
need to perform get_page() on individual sub-pages and alloc_pages()
doesn't initalize sub-pages.
https://jira.sw.ru/browse/PSBM-123551
Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
kernel/ve/ve.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index b114e2918bb7..0c6630c6616a 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -568,7 +568,7 @@ static int copy_vdso(struct vdso_image **vdso_dst, const struct vdso_image *vdso
if (!vdso)
return -ENOMEM;
- vdso_data = kmalloc(vdso_src->size, GFP_KERNEL);
+ vdso_data = alloc_pages_exact(vdso_src->size, GFP_KERNEL);
if (!vdso_data) {
kfree(vdso);
return -ENOMEM;
@@ -585,11 +585,11 @@ static int copy_vdso(struct vdso_image **vdso_dst, const struct vdso_image *vdso
static void ve_free_vdso(struct ve_struct *ve)
{
if (ve->vdso_64 && ve->vdso_64 != &vdso_image_64) {
- kfree(ve->vdso_64->data);
+ free_pages_exact(ve->vdso_64->data, ve->vdso_64->size);
kfree(ve->vdso_64);
}
if (ve->vdso_32 && ve->vdso_32 != &vdso_image_32) {
- kfree(ve->vdso_32->data);
+ free_pages_exact(ve->vdso_32->data, ve->vdso_32->size);
kfree(ve->vdso_32);
}
}
More information about the Devel
mailing list