[Devel,RHEL7,COMMIT] x86/mm: Support mremap()'ing vdso vma

Submitted by Konstantin Khorenko on May 31, 2017, 11:59 a.m.

Details

Message ID 201705311159.v4VBxq2C016557@finist_cl7.x64_64.work.ct
State New
Series "x86: C/R for ia32 tasks"
Headers show

Commit Message

Konstantin Khorenko May 31, 2017, 11:59 a.m.
The commit is pushed to "branch-rh7-3.10.0-514.16.1.vz7.32.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.16.1.vz7.32.5
------>
commit fa81ceee9f1e150abe1c3cc0e7e5abe178bdb51c
Author: Dmitry Safonov <dsafonov@virtuozzo.com>
Date:   Wed May 31 15:59:51 2017 +0400

    x86/mm: Support mremap()'ing vdso vma
    
    CRIU needs remapping vdso blob on restore. It moves vdso vma to the same
    position as it was on checkpoint with mremap() call.
    During mremap() the position of vma is changed with the result that
    current->mm->context.vdso pointer is no longer valid.
    By chance 64-bit signal processing code doesn't need context.vdso
    pointer for landing. But it's needed for ia32 signals.
    
    This is quite ugly backport of ms commit commit b059a453b1cf
    ("x86/vdso: Add mremap hook to vm_special_mapping").
    As vdso code was rewritten in ~3.16 kernel, it can't be backported
    as-is and here is the simplest result for the kernel which has
    no struct vm_special_mapping yet.
    
    Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
---
 arch/x86/include/asm/Kbuild          |  1 -
 arch/x86/include/asm/mm-arch-hooks.h | 20 ++++++++++++++++++++
 arch/x86/vdso/vdso32-setup.c         | 18 ++++++++++++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index 6ae17f5..7f66985 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -5,4 +5,3 @@  genhdr-y += unistd_64.h
 genhdr-y += unistd_x32.h
 
 generic-y += clkdev.h
-generic-y += mm-arch-hooks.h
diff --git a/arch/x86/include/asm/mm-arch-hooks.h b/arch/x86/include/asm/mm-arch-hooks.h
new file mode 100644
index 0000000..64fb20a
--- /dev/null
+++ b/arch/x86/include/asm/mm-arch-hooks.h
@@ -0,0 +1,20 @@ 
+/*
+ * Architecture specific mm hooks
+ *
+ * Copyright (C) 2015, IBM Corporation
+ * Author: Laurent Dufour <ldufour@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_POWERPC_MM_ARCH_HOOKS_H
+#define _ASM_POWERPC_MM_ARCH_HOOKS_H
+
+extern void arch_remap(struct mm_struct *mm,
+		unsigned long old_start, unsigned long old_end,
+		unsigned long new_start, unsigned long new_end);
+#define arch_remap arch_remap
+
+#endif /* _ASM_POWERPC_MM_ARCH_HOOKS_H */
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index 59ec0e2..776face 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -416,6 +416,24 @@  out:
 	return pages;
 }
 
+void arch_remap(struct mm_struct *mm,
+		unsigned long old_start, unsigned long old_end,
+		unsigned long new_start, unsigned long new_end)
+{
+	/*
+	 * mremap() doesn't allow moving multiple vmas so we can limit the
+	 * check to old_start == vdso_base.
+	 */
+	if (old_start == (unsigned long)mm->context.vdso) {
+		if (WARN_ON_ONCE(current->mm != mm))
+			return;
+
+		mm->context.vdso = (void *)new_start;
+		current_thread_info()->sysenter_return =
+			VDSO32_SYMBOL(new_start, SYSENTER_RETURN);
+	}
+}
+
 /* Call under mm->mmap_sem */
 static int __arch_setup_additional_pages(unsigned long addr, bool compat)
 {