Skip to contentSkip to conversation

x86,mm: vdso fixes for an OOPS and /proc/PID/maps

PATCH In review Andy Lutomirski 4 participants 20 messages May 19, 2014 – May 21, 2014

Subsystems (8)
Memory management x86 VFS MM core +4 more subsystems
lore
Share & tools
lore
#0 lore raw

cover x86,mm: vdso fixes for an OOPS and /proc/PID/maps

[This applies to tip/x86/vdso. Patch 1/4 is a resend.]

This fixes an OOPS on systems without an HPET and incomplete information in /proc/PID/maps.

The latter is done by adding a new vm_ops callback to replace arch_vma_name, which is inflexible and awkward to use correctly.

With this series applied, calling mremap on the vdso results in sensible output in /proc/PID/maps and the vvar area shows up correctly. I don't want to guarantee that mremap on the vdso will do anything sensible right now, but that's unchanged from before. In fact, I suspect that mremapping the vdso on 32-bit tasks is rather broken right now due to sigreturn.

In current kernels, mremapping the vdso blows away the name:
badc0de0000-badc0de2000 r-xp 00000000 00:00 0

Now it doesn't:
badc0de0000-badc0de1000 r-xp 00000000 00:00 0 [vdso]

As a followup, it might pay to replace install_special_mapping with a new install_vdso_mapping function that hardcodes the "[vdso]" name, to separately fix all the other arch_vma_name users (maybe just ARM?) and then kill arch_vma_name completely.

NB: This touches core mm code. I'd appreciate some review by the mm folks.

Andy Lutomirski (4):
x86,vdso: Fix an OOPS accessing the hpet mapping w/o an hpet mm,fs: Add vm_ops->name as an alternative to arch_vma_name x86,mm: Improve _install_special_mapping and fix x86 vdso naming x86,mm: Replace arch_vma_name with vm_ops->name for vsyscalls

 arch/x86/include/asm/vdso.h  |  6 ++-
 arch/x86/mm/init_64.c        | 20 +++++-----
 arch/x86/vdso/vdso2c.h       |  5 ++-
 arch/x86/vdso/vdso32-setup.c |  7 ----
 arch/x86/vdso/vma.c          | 26 ++++++++-----
 fs/binfmt_elf.c              |  8 ++++
 fs/proc/task_mmu.c           |  6 +++
 include/linux/mm.h           | 10 ++++-
 include/linux/mm_types.h     |  6 +++
 mm/mmap.c                    | 89 +++++++++++++++++++++++++++++---------------
 10 files changed, 124 insertions(+), 59 deletions(-)
Signature · 7 lines
1.9.0

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#1 lore raw

PATCH 1/4 x86,vdso: Fix an OOPS accessing the hpet mapping w/o an hpet

The oops can be triggered in qemu using -no-hpet (but not nohpet) by reading a couple of pages past the end of the vdso text. This should send SIGBUS instead of OOPSing.

The bug was introduced by:

commit 7a59ed415f5b57469e22e41fc4188d5399e0b194

Author: Stefani Seibold <[email protected]>
Date:   Mon Mar 17 23:22:09 2014 +0100

x86, vdso: Add 32 bit VDSO time support for 32 bit kernel

which is new in 3.15.

This will be fixed separately in 3.15, but that patch will not apply to tip/x86/vdso. This is the equivalent fix for tip/x86/vdso and, presumably, 3.16.

---
 arch/x86/vdso/vma.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/vdso/vma.c +2 -1
index e915eae..8ad0081 100644
@@ -90,6 +90,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
 	struct vm_area_struct *vma;
 	unsigned long addr;
 	int ret = 0;
+	static struct page *no_pages[] = {NULL};
 
 	if (calculate_addr) {
 		addr = vdso_addr(current->mm->start_stack,
@@ -125,7 +126,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
 				       addr + image->size,
 				       image->sym_end_mapping - image->size,
 				       VM_READ,
-				       NULL);
+				       no_pages);
 
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
Signature · 7 lines
1.9.0

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#2 lore raw

[tip:x86/vdso] x86, vdso: Fix an OOPS accessing the HPET mapping w/o an HPET

x86, vdso: Fix an OOPS accessing the HPET mapping w/o an HPET
Commit-ID:  1e844fb43c96dcdba3b578918f5c485d88750891
Gitweb:     http://git.kernel.org/tip/1e844fb43c96dcdba3b578918f5c485d88750891
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Mon, 19 May 2014 15:58:31 -0700
Committer:  H. Peter Anvin <[email protected]>
CommitDate: Tue, 20 May 2014 11:36:21 -0700

x86, vdso: Fix an OOPS accessing the HPET mapping w/o an HPET

The oops can be triggered in qemu using -no-hpet (but not nohpet) by reading a couple of pages past the end of the vdso text. This should send SIGBUS instead of OOPSing.

The bug was introduced by:

commit 7a59ed415f5b57469e22e41fc4188d5399e0b194

Author: Stefani Seibold <[email protected]>
Date:   Mon Mar 17 23:22:09 2014 +0100

x86, vdso: Add 32 bit VDSO time support for 32 bit kernel

which is new in 3.15.

This will be fixed separately in 3.15, but that patch will not apply to tip/x86/vdso. This is the equivalent fix for tip/x86/vdso and, presumably, 3.16.

---
 arch/x86/vdso/vma.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/vdso/vma.c +2 -1
index e915eae..8ad0081 100644
@@ -90,6 +90,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
 	struct vm_area_struct *vma;
 	unsigned long addr;
 	int ret = 0;
+	static struct page *no_pages[] = {NULL};
 
 	if (calculate_addr) {
 		addr = vdso_addr(current->mm->start_stack,
@@ -125,7 +126,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
 				       addr + image->size,
 				       image->sym_end_mapping - image->size,
 				       VM_READ,
-				       NULL);
+				       no_pages);
 
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
#3 lore raw

PATCH 2/4 mm,fs: Add vm_ops->name as an alternative to arch_vma_name

In reply to Andy Lutomirski

arch_vma_name sucks. It's a silly hack, and it's annoying to implement correctly. In fact, AFAICS, even the straightforward x86 implementation is incorrect (I suspect that it breaks if the vdso mapping is split or gets remapped).

This adds a new vm_ops->name operation that can replace it. The followup patches will remove all uses of arch_vma_name on x86, fixing a couple of annoyances in the process.

---
 fs/binfmt_elf.c    | 8 ++++++++
 fs/proc/task_mmu.c | 6 ++++++
 include/linux/mm.h | 6 ++++++
 3 files changed, 20 insertions(+)
fs/binfmt_elf.c +8 -0
index aa3cb62..df9ea41 100644
@@ -1108,6 +1108,14 @@ static bool always_dump_vma(struct vm_area_struct *vma)
 	/* Any vsyscall mappings? */
 	if (vma == get_gate_vma(vma->vm_mm))
 		return true;
+
+	/*
+	 * Assume that all vmas with a .name op should always be dumped.
+	 * If this changes, a new vm_ops field can easily be added.
+	 */
+	if (vma->vm_ops && vma->vm_ops->name && vma->vm_ops->name(vma))
+		return true;
+
 	/*
 	 * arch_vma_name() returns non-NULL for special architecture mappings,
 	 * such as vDSO sections.
fs/proc/task_mmu.c +6 -0
index 442177b..9b2f5d6 100644
@@ -300,6 +300,12 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
 		goto done;
 	}
 
+	if (vma->vm_ops && vma->vm_ops->name) {
+		name = vma->vm_ops->name(vma);
+		if (name)
+			goto done;
+	}
+
 	name = arch_vma_name(vma);
 	if (!name) {
 		pid_t tid;
include/linux/mm.h +6 -0
index bf9811e..63f8d4e 100644
@@ -239,6 +239,12 @@ struct vm_operations_struct {
 	 */
 	int (*access)(struct vm_area_struct *vma, unsigned long addr,
 		      void *buf, int len, int write);
+
+	/* Called by the /proc/PID/maps code to ask the vma whether it
+	 * has a special name.  Returning non-NULL will also cause this
+	 * vma to be dumped unconditionally. */
+	const char *(*name)(struct vm_area_struct *vma);
+
 #ifdef CONFIG_NUMA
 	/*
 	 * set_policy() op must add a reference to any non-NULL @new mempolicy
Signature · 7 lines
1.9.0

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#4 lore raw

[tip:x86/vdso] mm, fs: Add vm_ops-> name as an alternative to arch_vma_name

mm, fs: Add vm_ops->name as an alternative to arch_vma_name
Commit-ID:  78d683e838a60ec4ba4591cca4364cba84a9e626
Gitweb:     http://git.kernel.org/tip/78d683e838a60ec4ba4591cca4364cba84a9e626
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Mon, 19 May 2014 15:58:32 -0700
Committer:  H. Peter Anvin <[email protected]>
CommitDate: Tue, 20 May 2014 11:36:31 -0700

mm, fs: Add vm_ops->name as an alternative to arch_vma_name

arch_vma_name sucks. It's a silly hack, and it's annoying to implement correctly. In fact, AFAICS, even the straightforward x86 implementation is incorrect (I suspect that it breaks if the vdso mapping is split or gets remapped).

This adds a new vm_ops->name operation that can replace it. The followup patches will remove all uses of arch_vma_name on x86, fixing a couple of annoyances in the process.

---
 fs/binfmt_elf.c    | 8 ++++++++
 fs/proc/task_mmu.c | 6 ++++++
 include/linux/mm.h | 6 ++++++
 3 files changed, 20 insertions(+)
fs/binfmt_elf.c +8 -0
index aa3cb62..df9ea41 100644
@@ -1108,6 +1108,14 @@ static bool always_dump_vma(struct vm_area_struct *vma)
 	/* Any vsyscall mappings? */
 	if (vma == get_gate_vma(vma->vm_mm))
 		return true;
+
+	/*
+	 * Assume that all vmas with a .name op should always be dumped.
+	 * If this changes, a new vm_ops field can easily be added.
+	 */
+	if (vma->vm_ops && vma->vm_ops->name && vma->vm_ops->name(vma))
+		return true;
+
 	/*
 	 * arch_vma_name() returns non-NULL for special architecture mappings,
 	 * such as vDSO sections.
fs/proc/task_mmu.c +6 -0
index 442177b..9b2f5d6 100644
@@ -300,6 +300,12 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
 		goto done;
 	}
 
+	if (vma->vm_ops && vma->vm_ops->name) {
+		name = vma->vm_ops->name(vma);
+		if (name)
+			goto done;
+	}
+
 	name = arch_vma_name(vma);
 	if (!name) {
 		pid_t tid;
include/linux/mm.h +6 -0
index bf9811e..63f8d4e 100644
@@ -239,6 +239,12 @@ struct vm_operations_struct {
 	 */
 	int (*access)(struct vm_area_struct *vma, unsigned long addr,
 		      void *buf, int len, int write);
+
+	/* Called by the /proc/PID/maps code to ask the vma whether it
+	 * has a special name.  Returning non-NULL will also cause this
+	 * vma to be dumped unconditionally. */
+	const char *(*name)(struct vm_area_struct *vma);
+
 #ifdef CONFIG_NUMA
 	/*
 	 * set_policy() op must add a reference to any non-NULL @new mempolicy
#5 lore raw

PATCH 3/4 x86,mm: Improve _install_special_mapping and fix x86 vdso naming

In reply to Andy Lutomirski

Using arch_vma_name to give special mappings a name is awkward. x86 currently implements it by comparing the start address of the vma to the expected address of the vdso. This requires tracking the start address of special mappings and is probably buggy if a special vma is split or moved.

Improve _install_special_mapping to just name the vma directly. Use it to give the x86 vvar area a name, which should make CRIU's life easier.

As a side effect, the vvar area will show up in core dumps. This could be considered weird and is fixable. Thoughts?

Cc Cyrill Gorcunov <[email protected]>
Cc Pavel Emelyanov <[email protected]>
---
 arch/x86/include/asm/vdso.h  |  6 ++-
 arch/x86/mm/init_64.c        |  3 --
 arch/x86/vdso/vdso2c.h       |  5 ++-
 arch/x86/vdso/vdso32-setup.c |  7 ----
 arch/x86/vdso/vma.c          | 25 ++++++++-----
 include/linux/mm.h           |  4 +-
 include/linux/mm_types.h     |  6 +++
 mm/mmap.c                    | 89 +++++++++++++++++++++++++++++---------------
 8 files changed, 94 insertions(+), 51 deletions(-)
arch/x86/include/asm/vdso.h +5 -1
index d0a2c90..30be253 100644
@@ -7,10 +7,14 @@
 
 #ifndef __ASSEMBLER__
 
+#include <linux/mm_types.h>
+
 struct vdso_image {
 	void *data;
 	unsigned long size;   /* Always a multiple of PAGE_SIZE */
-	struct page **pages;  /* Big enough for data/size page pointers */
+
+	/* text_mapping.pages is big enough for data/size page pointers */
+	struct vm_special_mapping text_mapping;
 
 	unsigned long alt, alt_len;
 
arch/x86/mm/init_64.c +0 -3
index 6f88184..9deb59b 100644
@@ -1223,9 +1223,6 @@ int in_gate_area_no_mm(unsigned long addr)
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-	if (vma->vm_mm && vma->vm_start ==
-	    (long __force)vma->vm_mm->context.vdso)
-		return "[vdso]";
 	if (vma == &gate_vma)
 		return "[vsyscall]";
 	return NULL;
arch/x86/vdso/vdso2c.h +4 -1
index ed2e894..3dcc61e 100644
@@ -136,7 +136,10 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
 	fprintf(outfile, "const struct vdso_image %s = {\n", name);
 	fprintf(outfile, "\t.data = raw_data,\n");
 	fprintf(outfile, "\t.size = %lu,\n", data_size);
-	fprintf(outfile, "\t.pages = pages,\n");
+	fprintf(outfile, "\t.text_mapping = {\n");
+	fprintf(outfile, "\t\t.name = \"[vdso]\",\n");
+	fprintf(outfile, "\t\t.pages = pages,\n");
+	fprintf(outfile, "\t},\n");
 	if (alt_sec) {
 		fprintf(outfile, "\t.alt = %lu,\n",
 			(unsigned long)alt_sec->sh_offset);
arch/x86/vdso/vdso32-setup.c +0 -7
index c3ed708..e4f7781 100644
@@ -119,13 +119,6 @@ __initcall(ia32_binfmt_init);
 
 #else  /* CONFIG_X86_32 */
 
-const char *arch_vma_name(struct vm_area_struct *vma)
-{
-	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
-		return "[vdso]";
-	return NULL;
-}
-
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 {
 	return NULL;
arch/x86/vdso/vma.c +16 -9
index 8ad0081..e1513c4 100644
@@ -30,7 +30,8 @@ void __init init_vdso_image(const struct vdso_image *image)
 
 	BUG_ON(image->size % PAGE_SIZE != 0);
 	for (i = 0; i < npages; i++)
-		image->pages[i] = virt_to_page(image->data + i*PAGE_SIZE);
+		image->text_mapping.pages[i] =
+			virt_to_page(image->data + i*PAGE_SIZE);
 
 	apply_alternatives((struct alt_instr *)(image->data + image->alt),
 			   (struct alt_instr *)(image->data + image->alt +
@@ -91,6 +92,10 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
 	unsigned long addr;
 	int ret = 0;
 	static struct page *no_pages[] = {NULL};
+	static struct vm_special_mapping vvar_mapping = {
+		.name = "[vvar]",
+		.pages = no_pages,
+	};
 
 	if (calculate_addr) {
 		addr = vdso_addr(current->mm->start_stack,
@@ -112,21 +117,23 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
 	/*
 	 * MAYWRITE to allow gdb to COW and set breakpoints
 	 */
-	ret = install_special_mapping(mm,
-				      addr,
-				      image->size,
-				      VM_READ|VM_EXEC|
-				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-				      image->pages);
+	vma = _install_special_mapping(mm,
+				       addr,
+				       image->size,
+				       VM_READ|VM_EXEC|
+				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+				       &image->text_mapping);
 
-	if (ret)
+	if (IS_ERR(vma)) {
+		ret = PTR_ERR(vma);
 		goto up_fail;
+	}
 
 	vma = _install_special_mapping(mm,
 				       addr + image->size,
 				       image->sym_end_mapping - image->size,
 				       VM_READ,
-				       no_pages);
+				       &vvar_mapping);
 
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
include/linux/mm.h +3 -1
index 63f8d4e..05aab09 100644
@@ -1782,7 +1782,9 @@ extern struct file *get_mm_exe_file(struct mm_struct *mm);
 extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
 extern struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
 				   unsigned long addr, unsigned long len,
-				   unsigned long flags, struct page **pages);
+				   unsigned long flags,
+				   const struct vm_special_mapping *spec);
+/* This is an obsolete alternative to _install_special_mapping. */
 extern int install_special_mapping(struct mm_struct *mm,
 				   unsigned long addr, unsigned long len,
 				   unsigned long flags, struct page **pages);
include/linux/mm_types.h +6 -0
index 8967e20..22c6f4e 100644
@@ -510,4 +510,10 @@ static inline void clear_tlb_flush_pending(struct mm_struct *mm)
 }
 #endif
 
+struct vm_special_mapping
+{
+	const char *name;
+	struct page **pages;
+};
+
 #endif /* _LINUX_MM_TYPES_H */
mm/mmap.c +60 -29

123 lines not on this page · raw message

Signature · 7 lines
1.9.0

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#6 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 10 lines · Andy Lutomirski

Using arch_vma_name to give special mappings a name is awkward. x86 currently implements it by comparing the start address of the vma to the expected address of the vdso. This requires tracking the start address of special mappings and is probably buggy if a special vma is split or moved.

Improve _install_special_mapping to just name the vma directly. Use it to give the x86 vvar area a name, which should make CRIU's life easier.

Quoted 6 lines

As a side effect, the vvar area will show up in core dumps. This could be considered weird and is fixable. Thoughts?

Cc Cyrill Gorcunov <[email protected]>
Cc Pavel Emelyanov <[email protected]>

Hi Andy, thanks a lot for this! I must confess I don't yet know how would we deal with compat tasks but this is 'must have' mark which allow us to detect vvar area!

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 14 lines · Cyrill Gorcunov
Quoted 13 lines · Andy Lutomirski

Using arch_vma_name to give special mappings a name is awkward. x86 currently implements it by comparing the start address of the vma to the expected address of the vdso. This requires tracking the start address of special mappings and is probably buggy if a special vma is split or moved.

Improve _install_special_mapping to just name the vma directly. Use it to give the x86 vvar area a name, which should make CRIU's life easier.

As a side effect, the vvar area will show up in core dumps. This could be considered weird and is fixable. Thoughts?

Quoted 7 lines
Quoted 3 lines
Cc Cyrill Gorcunov <[email protected]>
Cc Pavel Emelyanov <[email protected]>

Hi Andy, thanks a lot for this! I must confess I don't yet know how would we deal with compat tasks but this is 'must have' mark which allow us to detect vvar area!

Out of curiosity, how does CRIU currently handle checkpointing a restored task? In current kernels, the "[vdso]" name in maps goes away after mremapping the vdso.

I suspect that you'll need kernel changes for compat tasks, since I think that mremapping the vdso on any reasonably modern hardware in a 32-bit task will cause sigreturn to blow up. This could be fixed by making mremap magical, although adding a new prctl or arch_prctl to reliably move the vdso might be a better bet.

--Andy

Signature · 8 lines
Andy Lutomirski
AMA Capital Management, LLC

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#8 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 19 lines · Andy Lutomirski
Quoted 18 lines · Cyrill Gorcunov
Quoted 16 lines · Andy Lutomirski

Using arch_vma_name to give special mappings a name is awkward. x86 currently implements it by comparing the start address of the vma to the expected address of the vdso. This requires tracking the start address of special mappings and is probably buggy if a special vma is split or moved.

Improve _install_special_mapping to just name the vma directly. Use it to give the x86 vvar area a name, which should make CRIU's life easier.

As a side effect, the vvar area will show up in core dumps. This could be considered weird and is fixable. Thoughts?

Cc Cyrill Gorcunov <[email protected]>
Cc Pavel Emelyanov <[email protected]>
Quoted 7 lines
Quoted 3 lines

Hi Andy, thanks a lot for this! I must confess I don't yet know how would we deal with compat tasks but this is 'must have' mark which allow us to detect vvar area!

Out of curiosity, how does CRIU currently handle checkpointing a restored task? In current kernels, the "[vdso]" name in maps goes away after mremapping the vdso.

We use not only [vdso] mark to detect vdso area but also page frame
number of the living vdso. If mark is not present in procfs output we examinate executable areas and check if pfn == vdso_pfn, it's a slow path because there migh be a bunch of executable areas and touching every of it is not that fast thing, but we simply have no choise.

The situation get worse when task was dumped on one kernel and
then restored on another kernel where vdso content is different from one save in image -- is such case as I mentioned we need that named vdso proxy which redirect calls to vdso of the system where task is restoring. And when such "restored" task get checkpointed second time we don't dump new living vdso but save only old vdso proxy on disk (detecting it is a different story, in short we inject a unique mark into elf header).

Quoted 6 lines

I suspect that you'll need kernel changes for compat tasks, since I think that mremapping the vdso on any reasonably modern hardware in a 32-bit task will cause sigreturn to blow up. This could be fixed by making mremap magical, although adding a new prctl or arch_prctl to reliably move the vdso might be a better bet.

Well, as far as I understand compat code uses abs addressing for vvar data and if vvar data position doesn't change we're safe, but same time because vvar addresses are not abi I fear one day we indeed hit the problems and the only solution would be to use kernel's help. But again, Andy, I didn't think much about implementing compat mode in criu yet so i might be missing some details.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#9 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 28 lines · Cyrill Gorcunov
Quoted 19 lines · Andy Lutomirski
Quoted 18 lines · Cyrill Gorcunov
Quoted 16 lines · Andy Lutomirski

Using arch_vma_name to give special mappings a name is awkward. x86 currently implements it by comparing the start address of the vma to the expected address of the vdso. This requires tracking the start address of special mappings and is probably buggy if a special vma is split or moved.

Improve _install_special_mapping to just name the vma directly. Use it to give the x86 vvar area a name, which should make CRIU's life easier.

As a side effect, the vvar area will show up in core dumps. This could be considered weird and is fixable. Thoughts?

Cc Cyrill Gorcunov <[email protected]>
Cc Pavel Emelyanov <[email protected]>
Quoted 7 lines
Quoted 3 lines

Hi Andy, thanks a lot for this! I must confess I don't yet know how would we deal with compat tasks but this is 'must have' mark which allow us to detect vvar area!

Out of curiosity, how does CRIU currently handle checkpointing a restored task? In current kernels, the "[vdso]" name in maps goes away after mremapping the vdso.

Quoted 6 lines

We use not only [vdso] mark to detect vdso area but also page frame
number of the living vdso. If mark is not present in procfs output we examinate executable areas and check if pfn == vdso_pfn, it's a slow path because there migh be a bunch of executable areas and touching every of it is not that fast thing, but we simply have no choise.

This patch should fix this issue, at least. If there's still a way to get a native vdso that doesn't say "[vdso]", please let me know/

Quoted 9 lines

The situation get worse when task was dumped on one kernel and
then restored on another kernel where vdso content is different from one save in image -- is such case as I mentioned we need that named vdso proxy which redirect calls to vdso of the system where task is restoring. And when such "restored" task get checkpointed second time we don't dump new living vdso but save only old vdso proxy on disk (detecting it is a different story, in short we inject a unique mark into elf header).

Yuck. But I don't know whether the kernel can help much here.

Quoted 8 lines
Quoted 7 lines

I suspect that you'll need kernel changes for compat tasks, since I think that mremapping the vdso on any reasonably modern hardware in a 32-bit task will cause sigreturn to blow up. This could be fixed by making mremap magical, although adding a new prctl or arch_prctl to reliably move the vdso might be a better bet.

Quoted 7 lines

Well, as far as I understand compat code uses abs addressing for vvar data and if vvar data position doesn't change we're safe, but same time because vvar addresses are not abi I fear one day we indeed hit the problems and the only solution would be to use kernel's help. But again, Andy, I didn't think much about implementing compat mode in criu yet so i might be missing some details.

Prior to 3.15, the compat code didn't have vvar data at all. In 3.15 and up, the vvar data is accessed using PC-relative addressing, even in compat mode (using the usual call; mov trick to read EIP).

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#10 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 10 lines · Andy Lutomirski
Quoted 7 lines

We use not only [vdso] mark to detect vdso area but also page frame
number of the living vdso. If mark is not present in procfs output we examinate executable areas and check if pfn == vdso_pfn, it's a slow path because there migh be a bunch of executable areas and touching every of it is not that fast thing, but we simply have no choise.

This patch should fix this issue, at least. If there's still a way to get a native vdso that doesn't say "[vdso]", please let me know/

Yes, having a native procfs way to detect vdso is much preferred!

Quoted 10 lines
Quoted 8 lines

The situation get worse when task was dumped on one kernel and
then restored on another kernel where vdso content is different from one save in image -- is such case as I mentioned we need that named vdso proxy which redirect calls to vdso of the system where task is restoring. And when such "restored" task get checkpointed second time we don't dump new living vdso but save only old vdso proxy on disk (detecting it is a different story, in short we inject a unique mark into elf header).

Yuck. But I don't know whether the kernel can help much here.

Some prctl which would tell kernel to put vdso at specifed address. We can live without it for now so not a big deal (yet ;)

Quoted 14 lines
Quoted 6 lines
Quoted 5 lines

I suspect that you'll need kernel changes for compat tasks, since I think that mremapping the vdso on any reasonably modern hardware in a 32-bit task will cause sigreturn to blow up. This could be fixed by making mremap magical, although adding a new prctl or arch_prctl to reliably move the vdso might be a better bet.

Quoted 7 lines

Well, as far as I understand compat code uses abs addressing for vvar data and if vvar data position doesn't change we're safe, but same time because vvar addresses are not abi I fear one day we indeed hit the problems and the only solution would be to use kernel's help. But again, Andy, I didn't think much about implementing compat mode in criu yet so i might be missing some details.

Quoted 3 lines

Prior to 3.15, the compat code didn't have vvar data at all. In 3.15 and up, the vvar data is accessed using PC-relative addressing, even in compat mode (using the usual call; mov trick to read EIP).

i see. I'll ping you for help once I start implementing compat mode ;)

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#11 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 6 lines · Cyrill Gorcunov
Quoted 3 lines

This patch should fix this issue, at least. If there's still a way to get a native vdso that doesn't say "[vdso]", please let me know/

Yes, having a native procfs way to detect vdso is much preferred!

Is there any path by which we can end up with [vdso] without a leading slash in /proc/self/maps? Otherwise, why is that not "native"?

Quoted 9 lines
Quoted 9 lines
Quoted 8 lines

The situation get worse when task was dumped on one kernel and
then restored on another kernel where vdso content is different from one save in image -- is such case as I mentioned we need that named vdso proxy which redirect calls to vdso of the system where task is restoring. And when such "restored" task get checkpointed second time we don't dump new living vdso but save only old vdso proxy on disk (detecting it is a different story, in short we inject a unique mark into elf header).

Quoted 4 lines
Quoted 1 line

Yuck. But I don't know whether the kernel can help much here.

Some prctl which would tell kernel to put vdso at specifed address. We can live without it for now so not a big deal (yet ;)

mremap() will do this for you.

-hpa

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#12 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 10 lines · H. Peter Anvin
Quoted 6 lines · Cyrill Gorcunov
Quoted 3 lines

This patch should fix this issue, at least. If there's still a way to get a native vdso that doesn't say "[vdso]", please let me know/

Yes, having a native procfs way to detect vdso is much preferred!

Is there any path by which we can end up with [vdso] without a leading slash in /proc/self/maps? Otherwise, why is that not "native"?

Dunno. But before this patch the reverse was possible: we can end up with a vdso that doesn't say [vdso].

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines

The situation get worse when task was dumped on one kernel and
then restored on another kernel where vdso content is different from one save in image -- is such case as I mentioned we need that named vdso proxy which redirect calls to vdso of the system where task is restoring. And when such "restored" task get checkpointed second time we don't dump new living vdso but save only old vdso proxy on disk (detecting it is a different story, in short we inject a unique mark into elf header).

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Yuck. But I don't know whether the kernel can help much here.

Some prctl which would tell kernel to put vdso at specifed address. We can live without it for now so not a big deal (yet ;)

mremap() will do this for you.

Except that it's buggy: it doesn't change mm->context.vdso. For 64-bit tasks, the only consumer outside exec was arch_vma_name, and this patch removes even that. For 32-bit tasks, though, it's needed for signal delivery.

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#13 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 6 lines · Andy Lutomirski
Quoted 5 lines · H. Peter Anvin
Quoted 4 lines · Cyrill Gorcunov
Quoted 3 lines

This patch should fix this issue, at least. If there's still a way to get a native vdso that doesn't say "[vdso]", please let me know/

Quoted 9 lines
Quoted 5 lines
Quoted 2 lines

Yes, having a native procfs way to detect vdso is much preferred!

Is there any path by which we can end up with [vdso] without a leading slash in /proc/self/maps? Otherwise, why is that not "native"?

Dunno. But before this patch the reverse was possible: we can end up with a vdso that doesn't say [vdso].

That's a bug, which is being fixed. We can't go back in time and create new interfaces on old kernels.

Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
Quoted 11 lines
Quoted 9 lines

The situation get worse when task was dumped on one kernel and
then restored on another kernel where vdso content is different from one save in image -- is such case as I mentioned we need that named vdso proxy which redirect calls to vdso of the system where task is restoring. And when such "restored" task get checkpointed second time we don't dump new living vdso but save only old vdso proxy on disk (detecting it is a different story, in short we inject a unique mark into elf header).

Yuck. But I don't know whether the kernel can help much here.

Some prctl which would tell kernel to put vdso at specifed address. We can live without it for now so not a big deal (yet ;)

Quoted 7 lines
Quoted 1 line

mremap() will do this for you.

Except that it's buggy: it doesn't change mm->context.vdso. For 64-bit tasks, the only consumer outside exec was arch_vma_name, and this patch removes even that. For 32-bit tasks, though, it's needed for signal delivery.

Again, a bug, let's fix it rather than saying we need a new interface.

-hpa

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#14 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

Quoted 37 lines · H. Peter Anvin
Quoted 6 lines · Andy Lutomirski
Quoted 5 lines · H. Peter Anvin
Quoted 4 lines · Cyrill Gorcunov
Quoted 3 lines

This patch should fix this issue, at least. If there's still a way to get a native vdso that doesn't say "[vdso]", please let me know/

Quoted 9 lines
Quoted 5 lines
Quoted 2 lines

Yes, having a native procfs way to detect vdso is much preferred!

Is there any path by which we can end up with [vdso] without a leading slash in /proc/self/maps? Otherwise, why is that not "native"?

Dunno. But before this patch the reverse was possible: we can end up with a vdso that doesn't say [vdso].

That's a bug, which is being fixed. We can't go back in time and create new interfaces on old kernels.

Quoted 17 lines
Quoted 16 lines
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines

The situation get worse when task was dumped on one kernel and
then restored on another kernel where vdso content is different from one save in image -- is such case as I mentioned we need that named vdso proxy which redirect calls to vdso of the system where task is restoring. And when such "restored" task get checkpointed second time we don't dump new living vdso but save only old vdso proxy on disk (detecting it is a different story, in short we inject a unique mark into elf header).

Quoted 4 lines
Quoted 1 line

Yuck. But I don't know whether the kernel can help much here.

Some prctl which would tell kernel to put vdso at specifed address. We can live without it for now so not a big deal (yet ;)

mremap() will do this for you.

Quoted 7 lines
Quoted 5 lines

Except that it's buggy: it doesn't change mm->context.vdso. For 64-bit tasks, the only consumer outside exec was arch_vma_name, and this patch removes even that. For 32-bit tasks, though, it's needed for signal delivery.

Again, a bug, let's fix it rather than saying we need a new interface.

What happens if someone remaps just part of the vdso?

Presumably we'd just track the position of the first page of the vdso, but this might be hard to implement: I don't think there's any callback from the core mm code for ths.

--Andy

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#15 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

In reply to Andy Lutomirski
Quoted 6 lines · Andy Lutomirski
Quoted 5 lines · H. Peter Anvin
Quoted 4 lines · Cyrill Gorcunov
Quoted 3 lines

This patch should fix this issue, at least. If there's still a way to get a native vdso that doesn't say "[vdso]", please let me know/

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Yes, having a native procfs way to detect vdso is much preferred!

Is there any path by which we can end up with [vdso] without a leading slash in /proc/self/maps? Otherwise, why is that not "native"?

Dunno. But before this patch the reverse was possible: we can end up with a vdso that doesn't say [vdso].

I fear I don't understand the phrase "leading slash in /proc/self/maps". Peter could you rephrase please?

Quoted 14 lines
Quoted 14 lines
Quoted 13 lines
Quoted 10 lines
Quoted 8 lines

The situation get worse when task was dumped on one kernel and
then restored on another kernel where vdso content is different from one save in image -- is such case as I mentioned we need that named vdso proxy which redirect calls to vdso of the system where task is restoring. And when such "restored" task get checkpointed second time we don't dump new living vdso but save only old vdso proxy on disk (detecting it is a different story, in short we inject a unique mark into elf header).

Yuck. But I don't know whether the kernel can help much here.

Some prctl which would tell kernel to put vdso at specifed address. We can live without it for now so not a big deal (yet ;)

Quoted 6 lines
Quoted 1 line

mremap() will do this for you.

Except that it's buggy: it doesn't change mm->context.vdso. For 64-bit tasks, the only consumer outside exec was arch_vma_name, and this patch removes even that. For 32-bit tasks, though, it's needed for signal delivery.

yes, fwiw we can deal with it currently but i'm not sure yet about compat case simply because didn't look presicely.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#16 lore raw

Re: [PATCH 3/4] x86,mm: Improve _install_special_mapping and fix x86 vdso naming

In reply to Andy Lutomirski
Quoted 4 lines · Andy Lutomirski

As a side effect, the vvar area will show up in core dumps. This could be considered weird and is fixable. Thoughts?

On this issue... I don't know if this is likely to break anything. My suggestion is that we accept it as-is but be prepared to deal with it if it breaks something.

-hpa

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#17 lore raw

[tip:x86/vdso] x86, mm: Improve _install_special_mapping and fix x86 vdso naming

In reply to Andy Lutomirski
x86, mm: Improve _install_special_mapping and fix x86 vdso naming
Commit-ID:  a62c34bd2a8a3f159945becd57401e478818d51c
Gitweb:     http://git.kernel.org/tip/a62c34bd2a8a3f159945becd57401e478818d51c
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Mon, 19 May 2014 15:58:33 -0700
Committer:  H. Peter Anvin <[email protected]>
CommitDate: Tue, 20 May 2014 11:38:42 -0700

x86, mm: Improve _install_special_mapping and fix x86 vdso naming

Using arch_vma_name to give special mappings a name is awkward. x86 currently implements it by comparing the start address of the vma to the expected address of the vdso. This requires tracking the start address of special mappings and is probably buggy if a special vma is split or moved.

Improve _install_special_mapping to just name the vma directly. Use it to give the x86 vvar area a name, which should make CRIU's life easier.

As a side effect, the vvar area will show up in core dumps. This could be considered weird and is fixable.

[hpa: I say we accept this as-is but be prepared to deal with knocking
out the vvars from core dumps if this becomes a problem.]

---
 arch/x86/include/asm/vdso.h  |  6 ++-
 arch/x86/mm/init_64.c        |  3 --
 arch/x86/vdso/vdso2c.h       |  5 ++-
 arch/x86/vdso/vdso32-setup.c |  7 ----
 arch/x86/vdso/vma.c          | 25 ++++++++-----
 include/linux/mm.h           |  4 +-
 include/linux/mm_types.h     |  6 +++
 mm/mmap.c                    | 89 +++++++++++++++++++++++++++++---------------
 8 files changed, 94 insertions(+), 51 deletions(-)
arch/x86/include/asm/vdso.h +5 -1
index d0a2c90..30be253 100644
@@ -7,10 +7,14 @@
 
 #ifndef __ASSEMBLER__
 
+#include <linux/mm_types.h>
+
 struct vdso_image {
 	void *data;
 	unsigned long size;   /* Always a multiple of PAGE_SIZE */
-	struct page **pages;  /* Big enough for data/size page pointers */
+
+	/* text_mapping.pages is big enough for data/size page pointers */
+	struct vm_special_mapping text_mapping;
 
 	unsigned long alt, alt_len;
 
arch/x86/mm/init_64.c +0 -3
index 6f88184..9deb59b 100644
@@ -1223,9 +1223,6 @@ int in_gate_area_no_mm(unsigned long addr)
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-	if (vma->vm_mm && vma->vm_start ==
-	    (long __force)vma->vm_mm->context.vdso)
-		return "[vdso]";
 	if (vma == &gate_vma)
 		return "[vsyscall]";
 	return NULL;
arch/x86/vdso/vdso2c.h +4 -1
index ed2e894..3dcc61e 100644
@@ -136,7 +136,10 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
 	fprintf(outfile, "const struct vdso_image %s = {\n", name);
 	fprintf(outfile, "\t.data = raw_data,\n");
 	fprintf(outfile, "\t.size = %lu,\n", data_size);
-	fprintf(outfile, "\t.pages = pages,\n");
+	fprintf(outfile, "\t.text_mapping = {\n");
+	fprintf(outfile, "\t\t.name = \"[vdso]\",\n");
+	fprintf(outfile, "\t\t.pages = pages,\n");
+	fprintf(outfile, "\t},\n");
 	if (alt_sec) {
 		fprintf(outfile, "\t.alt = %lu,\n",
 			(unsigned long)alt_sec->sh_offset);
arch/x86/vdso/vdso32-setup.c +0 -7
index c3ed708..e4f7781 100644
@@ -119,13 +119,6 @@ __initcall(ia32_binfmt_init);
 
 #else  /* CONFIG_X86_32 */
 
-const char *arch_vma_name(struct vm_area_struct *vma)
-{
-	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
-		return "[vdso]";
-	return NULL;
-}
-
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 {
 	return NULL;
arch/x86/vdso/vma.c +16 -9
index 8ad0081..e1513c4 100644
@@ -30,7 +30,8 @@ void __init init_vdso_image(const struct vdso_image *image)
 
 	BUG_ON(image->size % PAGE_SIZE != 0);
 	for (i = 0; i < npages; i++)
-		image->pages[i] = virt_to_page(image->data + i*PAGE_SIZE);
+		image->text_mapping.pages[i] =
+			virt_to_page(image->data + i*PAGE_SIZE);
 
 	apply_alternatives((struct alt_instr *)(image->data + image->alt),
 			   (struct alt_instr *)(image->data + image->alt +
@@ -91,6 +92,10 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
 	unsigned long addr;
 	int ret = 0;
 	static struct page *no_pages[] = {NULL};
+	static struct vm_special_mapping vvar_mapping = {
+		.name = "[vvar]",
+		.pages = no_pages,
+	};
 
 	if (calculate_addr) {
 		addr = vdso_addr(current->mm->start_stack,
@@ -112,21 +117,23 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
 	/*
 	 * MAYWRITE to allow gdb to COW and set breakpoints
 	 */
-	ret = install_special_mapping(mm,
-				      addr,
-				      image->size,
-				      VM_READ|VM_EXEC|
-				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-				      image->pages);
+	vma = _install_special_mapping(mm,
+				       addr,
+				       image->size,
+				       VM_READ|VM_EXEC|
+				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+				       &image->text_mapping);
 
-	if (ret)
+	if (IS_ERR(vma)) {
+		ret = PTR_ERR(vma);
 		goto up_fail;
+	}
 
 	vma = _install_special_mapping(mm,
 				       addr + image->size,
 				       image->sym_end_mapping - image->size,
 				       VM_READ,
-				       no_pages);
+				       &vvar_mapping);
 
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
include/linux/mm.h +3 -1
index 63f8d4e..05aab09 100644
@@ -1782,7 +1782,9 @@ extern struct file *get_mm_exe_file(struct mm_struct *mm);
 extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
 extern struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
 				   unsigned long addr, unsigned long len,
-				   unsigned long flags, struct page **pages);
+				   unsigned long flags,
+				   const struct vm_special_mapping *spec);
+/* This is an obsolete alternative to _install_special_mapping. */
 extern int install_special_mapping(struct mm_struct *mm,
 				   unsigned long addr, unsigned long len,
 				   unsigned long flags, struct page **pages);
include/linux/mm_types.h +6 -0
index 8967e20..22c6f4e 100644
@@ -510,4 +510,10 @@ static inline void clear_tlb_flush_pending(struct mm_struct *mm)
 }
 #endif
 
+struct vm_special_mapping
+{
+	const char *name;
+	struct page **pages;
+};
+
 #endif /* _LINUX_MM_TYPES_H */
mm/mmap.c +60 -29

123 lines not on this page · raw message

#18 lore raw

PATCH 4/4 x86,mm: Replace arch_vma_name with vm_ops->name for vsyscalls

In reply to Andy Lutomirski

arch_vma_name is now completely gone from x86. Good riddance.

---
 arch/x86/mm/init_64.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
arch/x86/mm/init_64.c +9 -8
index 9deb59b..bdcde58 100644
@@ -1185,11 +1185,19 @@ int kern_addr_valid(unsigned long addr)
  * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
  * not need special handling anymore:
  */
+static const char *gate_vma_name(struct vm_area_struct *vma)
+{
+	return "[vsyscall]";
+}
+static struct vm_operations_struct gate_vma_ops = {
+	.name = gate_vma_name,
+};
 static struct vm_area_struct gate_vma = {
 	.vm_start	= VSYSCALL_ADDR,
 	.vm_end		= VSYSCALL_ADDR + PAGE_SIZE,
 	.vm_page_prot	= PAGE_READONLY_EXEC,
-	.vm_flags	= VM_READ | VM_EXEC
+	.vm_flags	= VM_READ | VM_EXEC,
+	.vm_ops		= &gate_vma_ops,
 };
 
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
@@ -1221,13 +1229,6 @@ int in_gate_area_no_mm(unsigned long addr)
 	return (addr & PAGE_MASK) == VSYSCALL_ADDR;
 }
 
-const char *arch_vma_name(struct vm_area_struct *vma)
-{
-	if (vma == &gate_vma)
-		return "[vsyscall]";
-	return NULL;
-}
-
 #ifdef CONFIG_X86_UV
 unsigned long memory_block_size_bytes(void)
 {
Signature · 7 lines
1.9.0

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#19 lore raw

[tip:x86/vdso] x86, mm: Replace arch_vma_name with vm_ops-> name for vsyscalls

x86, mm: Replace arch_vma_name with vm_ops->name for vsyscalls
Commit-ID:  ac49b9a9f26b6c42585f87857722085ef4b19c13
Gitweb:     http://git.kernel.org/tip/ac49b9a9f26b6c42585f87857722085ef4b19c13
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Mon, 19 May 2014 15:58:34 -0700
Committer:  H. Peter Anvin <[email protected]>
CommitDate: Tue, 20 May 2014 11:39:31 -0700

x86, mm: Replace arch_vma_name with vm_ops->name for vsyscalls

This removes the last vestiges of arch_vma_name from x86, replacing it with vm_ops->name. Good riddance.

---
 arch/x86/mm/init_64.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
arch/x86/mm/init_64.c +9 -8
index 9deb59b..bdcde58 100644
@@ -1185,11 +1185,19 @@ int kern_addr_valid(unsigned long addr)
  * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
  * not need special handling anymore:
  */
+static const char *gate_vma_name(struct vm_area_struct *vma)
+{
+	return "[vsyscall]";
+}
+static struct vm_operations_struct gate_vma_ops = {
+	.name = gate_vma_name,
+};
 static struct vm_area_struct gate_vma = {
 	.vm_start	= VSYSCALL_ADDR,
 	.vm_end		= VSYSCALL_ADDR + PAGE_SIZE,
 	.vm_page_prot	= PAGE_READONLY_EXEC,
-	.vm_flags	= VM_READ | VM_EXEC
+	.vm_flags	= VM_READ | VM_EXEC,
+	.vm_ops		= &gate_vma_ops,
 };
 
 struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
@@ -1221,13 +1229,6 @@ int in_gate_area_no_mm(unsigned long addr)
 	return (addr & PAGE_MASK) == VSYSCALL_ADDR;
 }
 
-const char *arch_vma_name(struct vm_area_struct *vma)
-{
-	if (vma == &gate_vma)
-		return "[vsyscall]";
-	return NULL;
-}
-
 #ifdef CONFIG_X86_UV
 unsigned long memory_block_size_bytes(void)
 {