linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch 0/5][V2] module: merge module_32.c and module_64.c
@ 2009-06-04  1:46 Amerigo Wang
  2009-06-04  1:46 ` [Patch 1/5] x86 module: merge the same functions in " Amerigo Wang
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Amerigo Wang @ 2009-06-04  1:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: jdike, rusty, hch, Amerigo Wang, akpm, mingo


This patch set aims to merge module_32.c and module_64.c into
module.c. And plus some other related fixes.

Please apply in order.

I have tested this patch set on x86_64, and uml over x86_64,
and compile tested on i386. It looks fine.

V2:
Trimming exception tables correctly.
Unify module_alloc() for x86.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Ingo Molnar <mingo@elte.hu>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Patch 1/5] x86 module: merge the same functions in module_32.c and module_64.c
  2009-06-04  1:46 [Patch 0/5][V2] module: merge module_32.c and module_64.c Amerigo Wang
@ 2009-06-04  1:46 ` Amerigo Wang
  2009-06-04  1:46 ` [Patch 2/5] x86 module: merge the rest functions with macros Amerigo Wang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Amerigo Wang @ 2009-06-04  1:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: jdike, rusty, hch, Amerigo Wang, mingo, akpm


Merge the same functions both in module_32.c and module_64.c into
module.c.

This is the first step to merge both of them finally.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu> 

---
Index: linux-2.6/arch/x86/kernel/module.c
===================================================================
--- /dev/null
+++ linux-2.6/arch/x86/kernel/module.c
@@ -0,0 +1,98 @@
+/*  Kernel module help for x86.
+    Copyright (C) 2001 Rusty Russell.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/mm.h>
+
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt...)
+#endif
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+	   table entries. */
+}
+
+/* We don't need anything special. */
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+			      Elf_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *mod)
+{
+	return 0;
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
+		*para = NULL;
+	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
+		if (!strcmp(".text", secstrings + s->sh_name))
+			text = s;
+		if (!strcmp(".altinstructions", secstrings + s->sh_name))
+			alt = s;
+		if (!strcmp(".smp_locks", secstrings + s->sh_name))
+			locks = s;
+		if (!strcmp(".parainstructions", secstrings + s->sh_name))
+			para = s;
+	}
+
+	if (alt) {
+		/* patch .altinstructions */
+		void *aseg = (void *)alt->sh_addr;
+		apply_alternatives(aseg, aseg + alt->sh_size);
+	}
+	if (locks && text) {
+		void *lseg = (void *)locks->sh_addr;
+		void *tseg = (void *)text->sh_addr;
+		alternatives_smp_module_add(me, me->name,
+					    lseg, lseg + locks->sh_size,
+					    tseg, tseg + text->sh_size);
+	}
+
+	if (para) {
+		void *pseg = (void *)para->sh_addr;
+		apply_paravirt(pseg, pseg + para->sh_size);
+	}
+
+	return module_bug_finalize(hdr, sechdrs, me);
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+	alternatives_smp_module_del(mod);
+	module_bug_cleanup(mod);
+}
Index: linux-2.6/arch/x86/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/x86/kernel/Makefile
+++ linux-2.6/arch/x86/kernel/Makefile
@@ -72,7 +72,7 @@ obj-$(CONFIG_KEXEC)		+= machine_kexec_$(
 obj-$(CONFIG_KEXEC)		+= relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_MODULES)		+= module_$(BITS).o
+obj-$(CONFIG_MODULES)		+= module.o module_$(BITS).o
 obj-$(CONFIG_EFI) 		+= efi.o efi_$(BITS).o efi_stub_$(BITS).o
 obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault_32.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
Index: linux-2.6/arch/x86/kernel/module_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module_32.c
+++ linux-2.6/arch/x86/kernel/module_32.c
@@ -37,23 +37,6 @@ void *module_alloc(unsigned long size)
 }
 
 
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-	vfree(module_region);
-	/* FIXME: If module_region == mod->init_region, trim exception
-	   table entries. */
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-			      Elf_Shdr *sechdrs,
-			      char *secstrings,
-			      struct module *mod)
-{
-	return 0;
-}
-
 int apply_relocate(Elf32_Shdr *sechdrs,
 		   const char *strtab,
 		   unsigned int symindex,
@@ -105,48 +88,3 @@ int apply_relocate_add(Elf32_Shdr *sechd
 	return -ENOEXEC;
 }
 
-int module_finalize(const Elf_Ehdr *hdr,
-		    const Elf_Shdr *sechdrs,
-		    struct module *me)
-{
-	const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
-		*para = NULL;
-	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-
-	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
-		if (!strcmp(".text", secstrings + s->sh_name))
-			text = s;
-		if (!strcmp(".altinstructions", secstrings + s->sh_name))
-			alt = s;
-		if (!strcmp(".smp_locks", secstrings + s->sh_name))
-			locks = s;
-		if (!strcmp(".parainstructions", secstrings + s->sh_name))
-			para = s;
-	}
-
-	if (alt) {
-		/* patch .altinstructions */
-		void *aseg = (void *)alt->sh_addr;
-		apply_alternatives(aseg, aseg + alt->sh_size);
-	}
-	if (locks && text) {
-		void *lseg = (void *)locks->sh_addr;
-		void *tseg = (void *)text->sh_addr;
-		alternatives_smp_module_add(me, me->name,
-					    lseg, lseg + locks->sh_size,
-					    tseg, tseg + text->sh_size);
-	}
-
-	if (para) {
-		void *pseg = (void *)para->sh_addr;
-		apply_paravirt(pseg, pseg + para->sh_size);
-	}
-
-	return module_bug_finalize(hdr, sechdrs, me);
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-	alternatives_smp_module_del(mod);
-	module_bug_cleanup(mod);
-}
Index: linux-2.6/arch/x86/kernel/module_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module_64.c
+++ linux-2.6/arch/x86/kernel/module_64.c
@@ -33,13 +33,6 @@
 #define DEBUGP(fmt...)
 
 #ifndef CONFIG_UML
-void module_free(struct module *mod, void *module_region)
-{
-	vfree(module_region);
-	/* FIXME: If module_region == mod->init_region, trim exception
-	   table entries. */
-}
-
 void *module_alloc(unsigned long size)
 {
 	struct vm_struct *area;
@@ -58,15 +51,6 @@ void *module_alloc(unsigned long size)
 }
 #endif
 
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-			      Elf_Shdr *sechdrs,
-			      char *secstrings,
-			      struct module *mod)
-{
-	return 0;
-}
-
 int apply_relocate_add(Elf64_Shdr *sechdrs,
 		   const char *strtab,
 		   unsigned int symindex,
@@ -147,48 +131,3 @@ int apply_relocate(Elf_Shdr *sechdrs,
 	return -ENOSYS;
 }
 
-int module_finalize(const Elf_Ehdr *hdr,
-		    const Elf_Shdr *sechdrs,
-		    struct module *me)
-{
-	const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
-		*para = NULL;
-	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-
-	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
-		if (!strcmp(".text", secstrings + s->sh_name))
-			text = s;
-		if (!strcmp(".altinstructions", secstrings + s->sh_name))
-			alt = s;
-		if (!strcmp(".smp_locks", secstrings + s->sh_name))
-			locks = s;
-		if (!strcmp(".parainstructions", secstrings + s->sh_name))
-			para = s;
-	}
-
-	if (alt) {
-		/* patch .altinstructions */
-		void *aseg = (void *)alt->sh_addr;
-		apply_alternatives(aseg, aseg + alt->sh_size);
-	}
-	if (locks && text) {
-		void *lseg = (void *)locks->sh_addr;
-		void *tseg = (void *)text->sh_addr;
-		alternatives_smp_module_add(me, me->name,
-					    lseg, lseg + locks->sh_size,
-					    tseg, tseg + text->sh_size);
-	}
-
-	if (para) {
-		void *pseg = (void *)para->sh_addr;
-		apply_paravirt(pseg, pseg + para->sh_size);
-	}
-
-	return module_bug_finalize(hdr, sechdrs, me);
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-	alternatives_smp_module_del(mod);
-	module_bug_cleanup(mod);
-}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Patch 2/5] x86 module: merge the rest functions with macros
  2009-06-04  1:46 [Patch 0/5][V2] module: merge module_32.c and module_64.c Amerigo Wang
  2009-06-04  1:46 ` [Patch 1/5] x86 module: merge the same functions in " Amerigo Wang
@ 2009-06-04  1:46 ` Amerigo Wang
  2009-06-04  1:46 ` [Patch 3/5] uml module: fix uml build process due to this merge Amerigo Wang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Amerigo Wang @ 2009-06-04  1:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: jdike, rusty, hch, Amerigo Wang, mingo, akpm


Merge the rest functions together, with proper preprocessing directives.
Finally remove module_{32|64}.c.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>

---
Index: linux-2.6/arch/x86/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/x86/kernel/Makefile
+++ linux-2.6/arch/x86/kernel/Makefile
@@ -72,7 +72,7 @@ obj-$(CONFIG_KEXEC)		+= machine_kexec_$(
 obj-$(CONFIG_KEXEC)		+= relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_MODULES)		+= module.o module_$(BITS).o
+obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_EFI) 		+= efi.o efi_$(BITS).o efi_stub_$(BITS).o
 obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault_32.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
Index: linux-2.6/arch/x86/kernel/module.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module.c
+++ linux-2.6/arch/x86/kernel/module.c
@@ -34,6 +34,32 @@
 #define DEBUGP(fmt...)
 #endif
 
+#if defined(CONFIG_UML) || defined(CONFIG_X86_32)
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return vmalloc_exec(size);
+}
+#else /*X86_64*/
+void *module_alloc(unsigned long size)
+{
+	struct vm_struct *area;
+
+	if (!size)
+		return NULL;
+	size = PAGE_ALIGN(size);
+	if (size > MODULES_LEN)
+		return NULL;
+
+	area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
+	if (!area)
+		return NULL;
+
+	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
+}
+#endif
+
 /* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
 {
@@ -51,6 +77,140 @@ int module_frob_arch_sections(Elf_Ehdr *
 	return 0;
 }
 
+#ifdef CONFIG_X86_32
+int apply_relocate(Elf32_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	unsigned int i;
+	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	uint32_t *location;
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(rel[i].r_info);
+
+		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_386_32:
+			/* We add the value into the location given */
+			*location += sym->st_value;
+			break;
+		case R_386_PC32:
+			/* Add the value, subtract its postition */
+			*location += sym->st_value - (uint32_t)location;
+			break;
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+			       me->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+	       me->name);
+	return -ENOEXEC;
+}
+#else /*X86_64*/
+int apply_relocate_add(Elf64_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	unsigned int i;
+	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf64_Sym *sym;
+	void *loc;
+	u64 val;
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
+			+ ELF64_R_SYM(rel[i].r_info);
+
+		DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
+			(int)ELF64_R_TYPE(rel[i].r_info),
+			sym->st_value, rel[i].r_addend, (u64)loc);
+
+		val = sym->st_value + rel[i].r_addend;
+
+		switch (ELF64_R_TYPE(rel[i].r_info)) {
+		case R_X86_64_NONE:
+			break;
+		case R_X86_64_64:
+			*(u64 *)loc = val;
+			break;
+		case R_X86_64_32:
+			*(u32 *)loc = val;
+			if (val != *(u32 *)loc)
+				goto overflow;
+			break;
+		case R_X86_64_32S:
+			*(s32 *)loc = val;
+			if ((s64)val != *(s32 *)loc)
+				goto overflow;
+			break;
+		case R_X86_64_PC32:
+			val -= (u64)loc;
+			*(u32 *)loc = val;
+#if 0
+			if ((s64)val != *(s32 *)loc)
+				goto overflow;
+#endif
+			break;
+		default:
+			printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n",
+			       me->name, ELF64_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+
+overflow:
+	printk(KERN_ERR "overflow in relocation type %d val %Lx\n",
+	       (int)ELF64_R_TYPE(rel[i].r_info), val);
+	printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n",
+	       me->name);
+	return -ENOEXEC;
+}
+
+int apply_relocate(Elf_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	printk(KERN_ERR "non add relocation not supported\n");
+	return -ENOSYS;
+}
+
+#endif
+
 int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
Index: linux-2.6/arch/x86/kernel/module_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module_32.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*  Kernel module help for i386.
-    Copyright (C) 2001 Rusty Russell.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/bug.h>
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt...)
-#endif
-
-void *module_alloc(unsigned long size)
-{
-	if (size == 0)
-		return NULL;
-	return vmalloc_exec(size);
-}
-
-
-int apply_relocate(Elf32_Shdr *sechdrs,
-		   const char *strtab,
-		   unsigned int symindex,
-		   unsigned int relsec,
-		   struct module *me)
-{
-	unsigned int i;
-	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
-	Elf32_Sym *sym;
-	uint32_t *location;
-
-	DEBUGP("Applying relocate section %u to %u\n", relsec,
-	       sechdrs[relsec].sh_info);
-	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
-		/* This is where to make the change */
-		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
-			+ rel[i].r_offset;
-		/* This is the symbol it is referring to.  Note that all
-		   undefined symbols have been resolved.  */
-		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
-			+ ELF32_R_SYM(rel[i].r_info);
-
-		switch (ELF32_R_TYPE(rel[i].r_info)) {
-		case R_386_32:
-			/* We add the value into the location given */
-			*location += sym->st_value;
-			break;
-		case R_386_PC32:
-			/* Add the value, subtract its postition */
-			*location += sym->st_value - (uint32_t)location;
-			break;
-		default:
-			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
-			       me->name, ELF32_R_TYPE(rel[i].r_info));
-			return -ENOEXEC;
-		}
-	}
-	return 0;
-}
-
-int apply_relocate_add(Elf32_Shdr *sechdrs,
-		       const char *strtab,
-		       unsigned int symindex,
-		       unsigned int relsec,
-		       struct module *me)
-{
-	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
-	       me->name);
-	return -ENOEXEC;
-}
-
Index: linux-2.6/arch/x86/kernel/module_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module_64.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*  Kernel module help for x86-64
-    Copyright (C) 2001 Rusty Russell.
-    Copyright (C) 2002,2003 Andi Kleen, SuSE Labs.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/bug.h>
-
-#include <asm/system.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#define DEBUGP(fmt...)
-
-#ifndef CONFIG_UML
-void *module_alloc(unsigned long size)
-{
-	struct vm_struct *area;
-
-	if (!size)
-		return NULL;
-	size = PAGE_ALIGN(size);
-	if (size > MODULES_LEN)
-		return NULL;
-
-	area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
-	if (!area)
-		return NULL;
-
-	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
-}
-#endif
-
-int apply_relocate_add(Elf64_Shdr *sechdrs,
-		   const char *strtab,
-		   unsigned int symindex,
-		   unsigned int relsec,
-		   struct module *me)
-{
-	unsigned int i;
-	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
-	Elf64_Sym *sym;
-	void *loc;
-	u64 val;
-
-	DEBUGP("Applying relocate section %u to %u\n", relsec,
-	       sechdrs[relsec].sh_info);
-	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
-		/* This is where to make the change */
-		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
-			+ rel[i].r_offset;
-
-		/* This is the symbol it is referring to.  Note that all
-		   undefined symbols have been resolved.  */
-		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
-			+ ELF64_R_SYM(rel[i].r_info);
-
-		DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
-			(int)ELF64_R_TYPE(rel[i].r_info),
-			sym->st_value, rel[i].r_addend, (u64)loc);
-
-		val = sym->st_value + rel[i].r_addend;
-
-		switch (ELF64_R_TYPE(rel[i].r_info)) {
-		case R_X86_64_NONE:
-			break;
-		case R_X86_64_64:
-			*(u64 *)loc = val;
-			break;
-		case R_X86_64_32:
-			*(u32 *)loc = val;
-			if (val != *(u32 *)loc)
-				goto overflow;
-			break;
-		case R_X86_64_32S:
-			*(s32 *)loc = val;
-			if ((s64)val != *(s32 *)loc)
-				goto overflow;
-			break;
-		case R_X86_64_PC32:
-			val -= (u64)loc;
-			*(u32 *)loc = val;
-#if 0
-			if ((s64)val != *(s32 *)loc)
-				goto overflow;
-#endif
-			break;
-		default:
-			printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n",
-			       me->name, ELF64_R_TYPE(rel[i].r_info));
-			return -ENOEXEC;
-		}
-	}
-	return 0;
-
-overflow:
-	printk(KERN_ERR "overflow in relocation type %d val %Lx\n",
-	       (int)ELF64_R_TYPE(rel[i].r_info), val);
-	printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n",
-	       me->name);
-	return -ENOEXEC;
-}
-
-int apply_relocate(Elf_Shdr *sechdrs,
-		   const char *strtab,
-		   unsigned int symindex,
-		   unsigned int relsec,
-		   struct module *me)
-{
-	printk(KERN_ERR "non add relocation not supported\n");
-	return -ENOSYS;
-}
-

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Patch 3/5] uml module: fix uml build process due to this merge
  2009-06-04  1:46 [Patch 0/5][V2] module: merge module_32.c and module_64.c Amerigo Wang
  2009-06-04  1:46 ` [Patch 1/5] x86 module: merge the same functions in " Amerigo Wang
  2009-06-04  1:46 ` [Patch 2/5] x86 module: merge the rest functions with macros Amerigo Wang
@ 2009-06-04  1:46 ` Amerigo Wang
  2009-06-04  1:46 ` [Patch 4/5] module: trim exception table in module_free() Amerigo Wang
  2009-06-04  1:46 ` [Patch 5/5] module: merge module_alloc() finally Amerigo Wang
  4 siblings, 0 replies; 14+ messages in thread
From: Amerigo Wang @ 2009-06-04  1:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: jdike, rusty, hch, Amerigo Wang, mingo, akpm


Due to the previous merge, uml needs to be fixed.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Jeff Dike <jdike@addtoit.com>

---
Index: linux-2.6/arch/um/sys-i386/Makefile
===================================================================
--- linux-2.6.orig/arch/um/sys-i386/Makefile
+++ linux-2.6/arch/um/sys-i386/Makefile
@@ -8,7 +8,7 @@ obj-y = bug.o bugs.o checksum.o delay.o 
 
 subarch-obj-y = lib/semaphore_32.o lib/string_32.o
 subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
-subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o
+subarch-obj-$(CONFIG_MODULES) += kernel/module.o
 
 USER_OBJS := bugs.o ptrace_user.o fault.o
 
Index: linux-2.6/arch/um/sys-x86_64/Makefile
===================================================================
--- linux-2.6.orig/arch/um/sys-x86_64/Makefile
+++ linux-2.6/arch/um/sys-x86_64/Makefile
@@ -8,10 +8,8 @@ obj-y = bug.o bugs.o delay.o fault.o ldt
 	setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \
 	sysrq.o ksyms.o tls.o
 
-obj-$(CONFIG_MODULES) += um_module.o
-
 subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
-subarch-obj-$(CONFIG_MODULES) += kernel/module_64.o
+subarch-obj-$(CONFIG_MODULES) += kernel/module.o
 
 ldt-y = ../sys-i386/ldt.o
 
Index: linux-2.6/arch/um/sys-x86_64/um_module.c
===================================================================
--- linux-2.6.orig/arch/um/sys-x86_64/um_module.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <linux/vmalloc.h>
-#include <linux/moduleloader.h>
-
-/* Copied from i386 arch/i386/kernel/module.c */
-void *module_alloc(unsigned long size)
-{
-	if (size == 0)
-		return NULL;
-	return vmalloc_exec(size);
-}
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-	vfree(module_region);
-	/*
-	 * FIXME: If module_region == mod->init_region, trim exception
-	 * table entries.
-	 */
-}
-

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Patch 4/5] module: trim exception table in module_free()
  2009-06-04  1:46 [Patch 0/5][V2] module: merge module_32.c and module_64.c Amerigo Wang
                   ` (2 preceding siblings ...)
  2009-06-04  1:46 ` [Patch 3/5] uml module: fix uml build process due to this merge Amerigo Wang
@ 2009-06-04  1:46 ` Amerigo Wang
  2009-06-04  8:30   ` Rusty Russell
  2009-06-04  1:46 ` [Patch 5/5] module: merge module_alloc() finally Amerigo Wang
  4 siblings, 1 reply; 14+ messages in thread
From: Amerigo Wang @ 2009-06-04  1:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: jdike, rusty, hch, Amerigo Wang, mingo, akpm


Just as the comment said, trim the exception table entries when
module_free() mod->module_init.

Currently, this is only done for x86. Other platforms should
also fix it like this (except sparc32).

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>

---
Index: linux-2.6/arch/x86/kernel/module.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module.c
+++ linux-2.6/arch/x86/kernel/module.c
@@ -27,6 +27,7 @@
 #include <asm/system.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/uaccess.h>
 
 #if 0
 #define DEBUGP printk
@@ -60,12 +61,24 @@ void *module_alloc(unsigned long size)
 }
 #endif
 
+static void trim_init_extable(struct module *m)
+{
+	/*trim the beginning*/
+	while (m->num_exentries && within_module_init(m->extable[0].insn, m)) {
+		m->extable++;
+		m->num_exentries--;
+	}
+	/*trim the end*/
+	while (m->num_exentries &&
+		within_module_init(m->extable[m->num_exentries-1].insn, m))
+		m->num_exentries--;
+}
+
 /* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
 {
 	vfree(module_region);
-	/* FIXME: If module_region == mod->init_region, trim exception
-	   table entries. */
+	trim_init_extable(mod);
 }
 
 /* We don't need anything special. */

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Patch 5/5] module: merge module_alloc() finally
  2009-06-04  1:46 [Patch 0/5][V2] module: merge module_32.c and module_64.c Amerigo Wang
                   ` (3 preceding siblings ...)
  2009-06-04  1:46 ` [Patch 4/5] module: trim exception table in module_free() Amerigo Wang
@ 2009-06-04  1:46 ` Amerigo Wang
  4 siblings, 0 replies; 14+ messages in thread
From: Amerigo Wang @ 2009-06-04  1:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: jdike, rusty, hch, Amerigo Wang, mingo, akpm


As Christoph Hellwig suggested, module_alloc() actually can be
unified for i386 and x86_64 (of course, also UML).

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: 'Ingo Molnar' <mingo@elte.hu>

---
Index: linux-2.6/arch/x86/include/asm/pgtable_32_types.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/pgtable_32_types.h
+++ linux-2.6/arch/x86/include/asm/pgtable_32_types.h
@@ -46,6 +46,10 @@ extern bool __vmalloc_start_set; /* set 
 # define VMALLOC_END	(FIXADDR_START - 2 * PAGE_SIZE)
 #endif
 
+#define MODULES_VADDR	VMALLOC_START
+#define MODULES_END	VMALLOC_END
+#define MODULES_LEN	(MODULES_VADDR - MODULES_END)
+
 #define MAXMEM	(VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
 
 #endif /* _ASM_X86_PGTABLE_32_DEFS_H */
Index: linux-2.6/arch/um/include/asm/pgtable.h
===================================================================
--- linux-2.6.orig/arch/um/include/asm/pgtable.h
+++ linux-2.6/arch/um/include/asm/pgtable.h
@@ -53,16 +53,21 @@ extern unsigned long end_iomem;
 #else
 # define VMALLOC_END	(FIXADDR_START-2*PAGE_SIZE)
 #endif
+#define MODULES_VADDR	VMALLOC_START
+#define MODULES_END	VMALLOC_END
+#define MODULES_LEN	(MODULES_VADDR - MODULES_END)
 
 #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
 #define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
 #define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
-
+#define __PAGE_KERNEL_EXEC                                              \
+        (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
 #define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+#define PAGE_KERNEL_EXEC	__pgprot(__PAGE_KERNEL_EXEC)
 
 /*
  * The i386 can't do page protection for execute, and considers that the same
Index: linux-2.6/arch/x86/kernel/module.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module.c
+++ linux-2.6/arch/x86/kernel/module.c
@@ -35,14 +35,6 @@
 #define DEBUGP(fmt...)
 #endif
 
-#if defined(CONFIG_UML) || defined(CONFIG_X86_32)
-void *module_alloc(unsigned long size)
-{
-	if (size == 0)
-		return NULL;
-	return vmalloc_exec(size);
-}
-#else /*X86_64*/
 void *module_alloc(unsigned long size)
 {
 	struct vm_struct *area;
@@ -57,9 +49,9 @@ void *module_alloc(unsigned long size)
 	if (!area)
 		return NULL;
 
-	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
+	return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM,
+					PAGE_KERNEL_EXEC);
 }
-#endif
 
 static void trim_init_extable(struct module *m)
 {

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Patch 4/5] module: trim exception table in module_free()
  2009-06-04  1:46 ` [Patch 4/5] module: trim exception table in module_free() Amerigo Wang
@ 2009-06-04  8:30   ` Rusty Russell
  2009-06-04  8:57     ` Amerigo Wang
  2009-06-07 12:15     ` Ingo Molnar
  0 siblings, 2 replies; 14+ messages in thread
From: Rusty Russell @ 2009-06-04  8:30 UTC (permalink / raw)
  To: Amerigo Wang; +Cc: linux-kernel, jdike, hch, mingo, akpm

On Thu, 4 Jun 2009 11:16:37 am Amerigo Wang wrote:
> Just as the comment said, trim the exception table entries when
> module_free() mod->module_init.
>
> Currently, this is only done for x86. Other platforms should
> also fix it like this (except sparc32).

I've taken this one to make it more generic.  I'll leave the x86 maintainers 
to apply the rest.

Thanks,
Rusty.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Patch 4/5] module: trim exception table in module_free()
  2009-06-04  8:30   ` Rusty Russell
@ 2009-06-04  8:57     ` Amerigo Wang
  2009-06-05 15:08       ` Rusty Russell
  2009-06-07 12:15     ` Ingo Molnar
  1 sibling, 1 reply; 14+ messages in thread
From: Amerigo Wang @ 2009-06-04  8:57 UTC (permalink / raw)
  To: Rusty Russell; +Cc: linux-kernel, jdike, hch, mingo, akpm

Rusty Russell wrote:
> On Thu, 4 Jun 2009 11:16:37 am Amerigo Wang wrote:
>   
>> Just as the comment said, trim the exception table entries when
>> module_free() mod->module_init.
>>
>> Currently, this is only done for x86. Other platforms should
>> also fix it like this (except sparc32).
>>     
>
> I've taken this one to make it more generic.  I'll leave the x86 maintainers 
> to apply the rest.
>   

Thank you. But this one depends on the previous, I don't think you can 
apply this without
the previous ones.

It's better to let Ingo take all of these, of coures, if he thinks they 
are fine. :)



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Patch 4/5] module: trim exception table in module_free()
  2009-06-04  8:57     ` Amerigo Wang
@ 2009-06-05 15:08       ` Rusty Russell
  2009-06-08  1:28         ` Amerigo Wang
  2009-06-10  8:09         ` David Miller
  0 siblings, 2 replies; 14+ messages in thread
From: Rusty Russell @ 2009-06-05 15:08 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-kernel, jdike, hch, mingo, akpm, David Miller, sparclinux,
	linux-alpha, linux-ia64

On Thu, 4 Jun 2009 06:27:06 pm Amerigo Wang wrote:
> Rusty Russell wrote:
> > I've taken this one to make it more generic.  I'll leave the x86
> > maintainers to apply the rest.
>
> Thank you. But this one depends on the previous, I don't think you can
> apply this without the previous ones.

Here's what I ended up with: I need to rig up a test and make sure it goes to
all the maintainers and linux-next.

Subject: module: trim exception table on init free.

It's theoretically possible that there are exception table entries
which point into the (freed) init text of modules.  These could cause
future problems if other modules get loaded into that memory and cause
an exception as we'd see the wrong fixup.

Amerigo fixed this long-standing FIXME in the x86 version, but this
patch is more general.

This implements trim_init_extable(); most archs are simple since they
use the standard lib/extable.c sort code.  Alpha and IA64 use relative
addresses in their fixups, so thier trimming is a slight variation.

Sparc32 is unique; it doesn't seem to define ARCH_HAS_SORT_EXTABLE,
yet it defines its own sort_extable() which overrides the one in lib.
It doesn't sort, so we have to mark deleted entries instead of
actually trimming them.

Inspired-by: Amerigo Wang <amwang@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 arch/alpha/mm/extable.c             |   19 +++++++++++++++++++
 arch/ia64/mm/extable.c              |   24 ++++++++++++++++++++++++
 arch/sparc/include/asm/uaccess_32.h |    3 +++
 arch/sparc/mm/extable.c             |   27 +++++++++++++++++++++++++++
 include/linux/module.h              |    1 +
 kernel/module.c                     |    1 +
 lib/extable.c                       |   17 +++++++++++++++++
 7 files changed, 92 insertions(+)

diff --git a/arch/alpha/mm/extable.c b/arch/alpha/mm/extable.c
--- a/arch/alpha/mm/extable.c
+++ b/arch/alpha/mm/extable.c
@@ -48,6 +48,25 @@ void sort_extable(struct exception_table
 	     cmp_ex, swap_ex);
 }
 
+/*
+ * Any entry referring to the module init will be at the beginning or
+ * the end.
+ */
+void trim_init_extable(struct module *m)
+{
+	/*trim the beginning*/
+	while (m->num_exentries &&
+	       within_module_init(ex_to_addr(&m->extable[0]), m)) {
+		m->extable++;
+		m->num_exentries--;
+	}
+	/*trim the end*/
+	while (m->num_exentries &&
+	       within_module_init(ex_to_addr(&m->extable[m->num_exentries-1]),
+				  m))
+		m->num_exentries--;
+}
+
 const struct exception_table_entry *
 search_extable(const struct exception_table_entry *first,
 	       const struct exception_table_entry *last,
diff --git a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c
--- a/arch/ia64/mm/extable.c
+++ b/arch/ia64/mm/extable.c
@@ -53,6 +53,30 @@ void sort_extable (struct exception_tabl
 	     cmp_ex, swap_ex);
 }
 
+static inline unsigned long ex_to_addr(const struct exception_table_entry *x)
+{
+	return (unsigned long)&x->insn + x->insn;
+}
+
+/*
+ * Any entry referring to the module init will be at the beginning or
+ * the end.
+ */
+void trim_init_extable(struct module *m)
+{
+	/*trim the beginning*/
+	while (m->num_exentries &&
+	       within_module_init(ex_to_addr(&m->extable[0]), m)) {
+		m->extable++;
+		m->num_exentries--;
+	}
+	/*trim the end*/
+	while (m->num_exentries &&
+	       within_module_init(ex_to_addr(&m->extable[m->num_exentries-1]),
+				  m))
+		m->num_exentries--;
+}
+
 const struct exception_table_entry *
 search_extable (const struct exception_table_entry *first,
 		const struct exception_table_entry *last,
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -17,6 +17,9 @@
 
 #ifndef __ASSEMBLY__
 
+#define ARCH_HAS_SORT_EXTABLE
+#define ARCH_HAS_SEARCH_EXTABLE
+
 /* Sparc is not segmented, however we need to be able to fool access_ok()
  * when doing system calls from kernel mode legitimately.
  *
diff --git a/arch/sparc/mm/extable.c b/arch/sparc/mm/extable.c
--- a/arch/sparc/mm/extable.c
+++ b/arch/sparc/mm/extable.c
@@ -28,6 +28,10 @@ search_extable(const struct exception_ta
 	 *	word 3: last insn address + 4 bytes
 	 *	word 4: fixup code address
 	 *
+	 * Deleted entries are encoded as:
+	 *	word 1: unused
+	 *	word 2: -1
+	 *
 	 * See asm/uaccess.h for more details.
 	 */
 
@@ -39,6 +43,10 @@ search_extable(const struct exception_ta
 			continue;
 		}
 
+		/* A deleted entry; see trim_init_extable */
+		if (walk->fixup == -1)
+			continue;
+
 		if (walk->insn == value)
 			return walk;
 	}
@@ -57,6 +65,25 @@ search_extable(const struct exception_ta
         return NULL;
 }
 
+/* We could memmove them around; easier to mark the trimmed ones. */
+void trim_init_extable(struct module *m)
+{
+	unsigned int i;
+	bool range;
+
+	for (i = 0; i < m->num_exentries; i += range ? 2 : 1) {
+		range = m->extable[i].fixup == 0;
+
+		if (within_module_init(m->extable[i].insn)) {
+			m->extable[i].fixup = -1;
+			if (range)
+				m->extable[i+1].fixup = -1;
+		}
+		if (range)
+			i++;
+	}
+}
+
 /* Special extable search, which handles ranges.  Returns fixup */
 unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
 {
diff --git a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -77,6 +77,7 @@ search_extable(const struct exception_ta
 void sort_extable(struct exception_table_entry *start,
 		  struct exception_table_entry *finish);
 void sort_main_extable(void);
+void trim_init_extable(struct module *m);
 
 #ifdef MODULE
 #define MODULE_GENERIC_TABLE(gtype,name)			\
diff --git a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2394,6 +2394,7 @@ SYSCALL_DEFINE3(init_module, void __user
 	mutex_lock(&module_mutex);
 	/* Drop initial reference. */
 	module_put(mod);
+	trim_init_extable(mod);
 	module_free(mod, mod->module_init);
 	mod->module_init = NULL;
 	mod->init_size = 0;
diff --git a/lib/extable.c b/lib/extable.c
--- a/lib/extable.c
+++ b/lib/extable.c
@@ -39,6 +39,23 @@ void sort_extable(struct exception_table
 	sort(start, finish - start, sizeof(struct exception_table_entry),
 	     cmp_ex, NULL);
 }
+
+/*
+ * If the exception table is sorted, any referring to the module init
+ * will be at the beginning or the end.
+ */
+void trim_init_extable(struct module *m)
+{
+	/*trim the beginning*/
+	while (m->num_exentries && within_module_init(m->extable[0].insn, m)) {
+		m->extable++;
+		m->num_exentries--;
+	}
+	/*trim the end*/
+	while (m->num_exentries &&
+		within_module_init(m->extable[m->num_exentries-1].insn, m))
+		m->num_exentries--;
+}
 #endif
 
 #ifndef ARCH_HAS_SEARCH_EXTABLE


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Patch 4/5] module: trim exception table in module_free()
  2009-06-04  8:30   ` Rusty Russell
  2009-06-04  8:57     ` Amerigo Wang
@ 2009-06-07 12:15     ` Ingo Molnar
  2009-06-08  1:36       ` Amerigo Wang
  1 sibling, 1 reply; 14+ messages in thread
From: Ingo Molnar @ 2009-06-07 12:15 UTC (permalink / raw)
  To: Rusty Russell; +Cc: Amerigo Wang, linux-kernel, jdike, hch, akpm


* Rusty Russell <rusty@rustcorp.com.au> wrote:

> On Thu, 4 Jun 2009 11:16:37 am Amerigo Wang wrote:
> > Just as the comment said, trim the exception table entries when
> > module_free() mod->module_init.
> >
> > Currently, this is only done for x86. Other platforms should 
> > also fix it like this (except sparc32).
> 
> I've taken this one to make it more generic.  I'll leave the x86 
> maintainers to apply the rest.

I think it makes most sense to handle them together. We have no 
interacting changes pending in the x86 tree, feel free to pick them 
up.

	Ingo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Patch 4/5] module: trim exception table in module_free()
  2009-06-05 15:08       ` Rusty Russell
@ 2009-06-08  1:28         ` Amerigo Wang
  2009-06-10  8:09         ` David Miller
  1 sibling, 0 replies; 14+ messages in thread
From: Amerigo Wang @ 2009-06-08  1:28 UTC (permalink / raw)
  To: Rusty Russell
  Cc: linux-kernel, jdike, hch, mingo, akpm, David Miller, sparclinux,
	linux-alpha, linux-ia64

Rusty Russell wrote:
> On Thu, 4 Jun 2009 06:27:06 pm Amerigo Wang wrote:
>   
>> Rusty Russell wrote:
>>     
>>> I've taken this one to make it more generic.  I'll leave the x86
>>> maintainers to apply the rest.
>>>       
>> Thank you. But this one depends on the previous, I don't think you can
>> apply this without the previous ones.
>>     
>
> Here's what I ended up with: I need to rig up a test and make sure it goes to
> all the maintainers and linux-next.
>
> Subject: module: trim exception table on init free.
>
> It's theoretically possible that there are exception table entries
> which point into the (freed) init text of modules.  These could cause
> future problems if other modules get loaded into that memory and cause
> an exception as we'd see the wrong fixup.
>
> Amerigo fixed this long-standing FIXME in the x86 version, but this
> patch is more general.
>
> This implements trim_init_extable(); most archs are simple since they
> use the standard lib/extable.c sort code.  Alpha and IA64 use relative
> addresses in their fixups, so thier trimming is a slight variation.
>
> Sparc32 is unique; it doesn't seem to define ARCH_HAS_SORT_EXTABLE,
> yet it defines its own sort_extable() which overrides the one in lib.
> It doesn't sort, so we have to mark deleted entries instead of
> actually trimming them.
>
> Inspired-by: Amerigo Wang <amwang@redhat.com>
> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
>   

Very nice!
The generic part of this patch looks good for me, of course. :)

Thank you, Rusty!



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Patch 4/5] module: trim exception table in module_free()
  2009-06-07 12:15     ` Ingo Molnar
@ 2009-06-08  1:36       ` Amerigo Wang
  2009-06-09  7:51         ` Rusty Russell
  0 siblings, 1 reply; 14+ messages in thread
From: Amerigo Wang @ 2009-06-08  1:36 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Rusty Russell, linux-kernel, jdike, hch, akpm

Ingo Molnar wrote:
> * Rusty Russell <rusty@rustcorp.com.au> wrote:
>
>   
>> On Thu, 4 Jun 2009 11:16:37 am Amerigo Wang wrote:
>>     
>>> Just as the comment said, trim the exception table entries when
>>> module_free() mod->module_init.
>>>
>>> Currently, this is only done for x86. Other platforms should 
>>> also fix it like this (except sparc32).
>>>       
>> I've taken this one to make it more generic.  I'll leave the x86 
>> maintainers to apply the rest.
>>     
>
> I think it makes most sense to handle them together. We have no 
> interacting changes pending in the x86 tree, feel free to pick them 
> up.
>   

Thanks for clarifying.

So, Rusty, could you please take all of these except patch 4/5? Since you
have a much better one to replace that one. :)

Thank you.




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Patch 4/5] module: trim exception table in module_free()
  2009-06-08  1:36       ` Amerigo Wang
@ 2009-06-09  7:51         ` Rusty Russell
  0 siblings, 0 replies; 14+ messages in thread
From: Rusty Russell @ 2009-06-09  7:51 UTC (permalink / raw)
  To: Amerigo Wang; +Cc: Ingo Molnar, linux-kernel, jdike, hch, akpm

On Mon, 8 Jun 2009 11:06:14 am Amerigo Wang wrote:
> Ingo Molnar wrote:
> > I think it makes most sense to handle them together. We have no
> > interacting changes pending in the x86 tree, feel free to pick them
> > up.
>
> Thanks for clarifying.
>
> So, Rusty, could you please take all of these except patch 4/5? Since you
> have a much better one to replace that one. :)

Yep, I've put them in my tree for testing; if all goes well, they'll hit 
linux-next in a couple of days.

Thanks!
Rusty.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Patch 4/5] module: trim exception table in module_free()
  2009-06-05 15:08       ` Rusty Russell
  2009-06-08  1:28         ` Amerigo Wang
@ 2009-06-10  8:09         ` David Miller
  1 sibling, 0 replies; 14+ messages in thread
From: David Miller @ 2009-06-10  8:09 UTC (permalink / raw)
  To: rusty
  Cc: amwang, linux-kernel, jdike, hch, mingo, akpm, sparclinux,
	linux-alpha, linux-ia64

From: Rusty Russell <rusty@rustcorp.com.au>
Date: Sat, 6 Jun 2009 00:38:02 +0930

> Sparc32 is unique; it doesn't seem to define ARCH_HAS_SORT_EXTABLE,
> yet it defines its own sort_extable() which overrides the one in lib.
> It doesn't sort, so we have to mark deleted entries instead of
> actually trimming them.
> 
> Inspired-by: Amerigo Wang <amwang@redhat.com>
> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2009-06-10  8:09 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-04  1:46 [Patch 0/5][V2] module: merge module_32.c and module_64.c Amerigo Wang
2009-06-04  1:46 ` [Patch 1/5] x86 module: merge the same functions in " Amerigo Wang
2009-06-04  1:46 ` [Patch 2/5] x86 module: merge the rest functions with macros Amerigo Wang
2009-06-04  1:46 ` [Patch 3/5] uml module: fix uml build process due to this merge Amerigo Wang
2009-06-04  1:46 ` [Patch 4/5] module: trim exception table in module_free() Amerigo Wang
2009-06-04  8:30   ` Rusty Russell
2009-06-04  8:57     ` Amerigo Wang
2009-06-05 15:08       ` Rusty Russell
2009-06-08  1:28         ` Amerigo Wang
2009-06-10  8:09         ` David Miller
2009-06-07 12:15     ` Ingo Molnar
2009-06-08  1:36       ` Amerigo Wang
2009-06-09  7:51         ` Rusty Russell
2009-06-04  1:46 ` [Patch 5/5] module: merge module_alloc() finally Amerigo Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).