aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/mm/extable.c21
-rw-r--r--arch/avr32/kernel/module.c2
-rw-r--r--arch/cris/kernel/module.c2
-rw-r--r--arch/frv/kernel/module.c2
-rw-r--r--arch/h8300/kernel/module.c2
-rw-r--r--arch/ia64/mm/extable.c26
-rw-r--r--arch/m32r/kernel/module.c2
-rw-r--r--arch/m68k/kernel/module.c2
-rw-r--r--arch/m68knommu/kernel/module.c2
-rw-r--r--arch/mips/kernel/module.c2
-rw-r--r--arch/mn10300/kernel/module.c2
-rw-r--r--arch/parisc/kernel/module.c2
-rw-r--r--arch/powerpc/kernel/module.c2
-rw-r--r--arch/s390/kernel/module.c2
-rw-r--r--arch/sh/kernel/module.c2
-rw-r--r--arch/sparc/include/asm/uaccess_32.h3
-rw-r--r--arch/sparc/kernel/module.c2
-rw-r--r--arch/sparc/mm/extable.c29
-rw-r--r--arch/um/include/asm/pgtable.h7
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-x86_64/Makefile4
-rw-r--r--arch/um/sys-x86_64/um_module.c21
-rw-r--r--arch/x86/include/asm/pgtable_32_types.h4
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/module.c (renamed from arch/x86/kernel/module_64.c)82
-rw-r--r--arch/x86/kernel/module_32.c152
-rw-r--r--arch/xtensa/kernel/module.c2
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/cyber2000fb.c9
-rw-r--r--drivers/video/uvesafb.c10
-rw-r--r--include/linux/compiler.h5
-rw-r--r--include/linux/module.h1
-rw-r--r--include/linux/moduleparam.h40
-rw-r--r--kernel/module.c1
-rw-r--r--kernel/params.c46
-rw-r--r--lib/extable.c21
36 files changed, 256 insertions, 262 deletions
diff --git a/arch/alpha/mm/extable.c b/arch/alpha/mm/extable.c
index 62dc379d301a..813c9b63c0e1 100644
--- a/arch/alpha/mm/extable.c
+++ b/arch/alpha/mm/extable.c
@@ -48,6 +48,27 @@ void sort_extable(struct exception_table_entry *start,
48 cmp_ex, swap_ex); 48 cmp_ex, swap_ex);
49} 49}
50 50
51#ifdef CONFIG_MODULES
52/*
53 * Any entry referring to the module init will be at the beginning or
54 * the end.
55 */
56void trim_init_extable(struct module *m)
57{
58 /*trim the beginning*/
59 while (m->num_exentries &&
60 within_module_init(ex_to_addr(&m->extable[0]), m)) {
61 m->extable++;
62 m->num_exentries--;
63 }
64 /*trim the end*/
65 while (m->num_exentries &&
66 within_module_init(ex_to_addr(&m->extable[m->num_exentries-1]),
67 m))
68 m->num_exentries--;
69}
70#endif /* CONFIG_MODULES */
71
51const struct exception_table_entry * 72const struct exception_table_entry *
52search_extable(const struct exception_table_entry *first, 73search_extable(const struct exception_table_entry *first,
53 const struct exception_table_entry *last, 74 const struct exception_table_entry *last,
diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c
index 1167fe9cf6c4..98f94d041d9c 100644
--- a/arch/avr32/kernel/module.c
+++ b/arch/avr32/kernel/module.c
@@ -32,8 +32,6 @@ void module_free(struct module *mod, void *module_region)
32 mod->arch.syminfo = NULL; 32 mod->arch.syminfo = NULL;
33 33
34 vfree(module_region); 34 vfree(module_region);
35 /* FIXME: if module_region == mod->init_region, trim exception
36 * table entries. */
37} 35}
38 36
39static inline int check_rela(Elf32_Rela *rela, struct module *module, 37static inline int check_rela(Elf32_Rela *rela, struct module *module,
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c
index a187833febc8..abc13e368b90 100644
--- a/arch/cris/kernel/module.c
+++ b/arch/cris/kernel/module.c
@@ -48,8 +48,6 @@ void *module_alloc(unsigned long size)
48void module_free(struct module *mod, void *module_region) 48void module_free(struct module *mod, void *module_region)
49{ 49{
50 FREE_MODULE(module_region); 50 FREE_MODULE(module_region);
51 /* FIXME: If module_region == mod->init_region, trim exception
52 table entries. */
53} 51}
54 52
55/* We don't need anything special. */ 53/* We don't need anything special. */
diff --git a/arch/frv/kernel/module.c b/arch/frv/kernel/module.c
index 850d168f69fc..711763c8a6f3 100644
--- a/arch/frv/kernel/module.c
+++ b/arch/frv/kernel/module.c
@@ -35,8 +35,6 @@ void *module_alloc(unsigned long size)
35void module_free(struct module *mod, void *module_region) 35void module_free(struct module *mod, void *module_region)
36{ 36{
37 vfree(module_region); 37 vfree(module_region);
38 /* FIXME: If module_region == mod->init_region, trim exception
39 table entries. */
40} 38}
41 39
42/* We don't need anything special. */ 40/* We don't need anything special. */
diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c
index cfc9127d2ced..0865e291c20d 100644
--- a/arch/h8300/kernel/module.c
+++ b/arch/h8300/kernel/module.c
@@ -23,8 +23,6 @@ void *module_alloc(unsigned long size)
23void module_free(struct module *mod, void *module_region) 23void module_free(struct module *mod, void *module_region)
24{ 24{
25 vfree(module_region); 25 vfree(module_region);
26 /* FIXME: If module_region == mod->init_region, trim exception
27 table entries. */
28} 26}
29 27
30/* We don't need anything special. */ 28/* We don't need anything special. */
diff --git a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c
index 71c50dd8f870..e95d5ad9285d 100644
--- a/arch/ia64/mm/extable.c
+++ b/arch/ia64/mm/extable.c
@@ -53,6 +53,32 @@ void sort_extable (struct exception_table_entry *start,
53 cmp_ex, swap_ex); 53 cmp_ex, swap_ex);
54} 54}
55 55
56static inline unsigned long ex_to_addr(const struct exception_table_entry *x)
57{
58 return (unsigned long)&x->insn + x->insn;
59}
60
61#ifdef CONFIG_MODULES
62/*
63 * Any entry referring to the module init will be at the beginning or
64 * the end.
65 */
66void trim_init_extable(struct module *m)
67{
68 /*trim the beginning*/
69 while (m->num_exentries &&
70 within_module_init(ex_to_addr(&m->extable[0]), m)) {
71 m->extable++;
72 m->num_exentries--;
73 }
74 /*trim the end*/
75 while (m->num_exentries &&
76 within_module_init(ex_to_addr(&m->extable[m->num_exentries-1]),
77 m))
78 m->num_exentries--;
79}
80#endif /* CONFIG_MODULES */
81
56const struct exception_table_entry * 82const struct exception_table_entry *
57search_extable (const struct exception_table_entry *first, 83search_extable (const struct exception_table_entry *first,
58 const struct exception_table_entry *last, 84 const struct exception_table_entry *last,
diff --git a/arch/m32r/kernel/module.c b/arch/m32r/kernel/module.c
index 8d4205794380..cb5f37d78d49 100644
--- a/arch/m32r/kernel/module.c
+++ b/arch/m32r/kernel/module.c
@@ -44,8 +44,6 @@ void *module_alloc(unsigned long size)
44void module_free(struct module *mod, void *module_region) 44void module_free(struct module *mod, void *module_region)
45{ 45{
46 vfree(module_region); 46 vfree(module_region);
47 /* FIXME: If module_region == mod->init_region, trim exception
48 table entries. */
49} 47}
50 48
51/* We don't need anything special. */ 49/* We don't need anything special. */
diff --git a/arch/m68k/kernel/module.c b/arch/m68k/kernel/module.c
index 774862bc6977..cd6bcb1c957e 100644
--- a/arch/m68k/kernel/module.c
+++ b/arch/m68k/kernel/module.c
@@ -31,8 +31,6 @@ void *module_alloc(unsigned long size)
31void module_free(struct module *mod, void *module_region) 31void module_free(struct module *mod, void *module_region)
32{ 32{
33 vfree(module_region); 33 vfree(module_region);
34 /* FIXME: If module_region == mod->init_region, trim exception
35 table entries. */
36} 34}
37 35
38/* We don't need anything special. */ 36/* We don't need anything special. */
diff --git a/arch/m68knommu/kernel/module.c b/arch/m68knommu/kernel/module.c
index 3b1a2ff61ddc..d11ffae7956a 100644
--- a/arch/m68knommu/kernel/module.c
+++ b/arch/m68knommu/kernel/module.c
@@ -23,8 +23,6 @@ void *module_alloc(unsigned long size)
23void module_free(struct module *mod, void *module_region) 23void module_free(struct module *mod, void *module_region)
24{ 24{
25 vfree(module_region); 25 vfree(module_region);
26 /* FIXME: If module_region == mod->init_region, trim exception
27 table entries. */
28} 26}
29 27
30/* We don't need anything special. */ 28/* We don't need anything special. */
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 1f60e27523d9..3e9100dcc12d 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -68,8 +68,6 @@ void *module_alloc(unsigned long size)
68void module_free(struct module *mod, void *module_region) 68void module_free(struct module *mod, void *module_region)
69{ 69{
70 vfree(module_region); 70 vfree(module_region);
71 /* FIXME: If module_region == mod->init_region, trim exception
72 table entries. */
73} 71}
74 72
75int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, 73int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c
index 6b287f2e8e84..4fa0e3648d8e 100644
--- a/arch/mn10300/kernel/module.c
+++ b/arch/mn10300/kernel/module.c
@@ -48,8 +48,6 @@ void *module_alloc(unsigned long size)
48void module_free(struct module *mod, void *module_region) 48void module_free(struct module *mod, void *module_region)
49{ 49{
50 vfree(module_region); 50 vfree(module_region);
51 /* FIXME: If module_region == mod->init_region, trim exception
52 * table entries. */
53} 51}
54 52
55/* 53/*
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index ecd1c5024447..ef5caf2e6ed0 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -267,8 +267,6 @@ void module_free(struct module *mod, void *module_region)
267 mod->arch.section = NULL; 267 mod->arch.section = NULL;
268 268
269 vfree(module_region); 269 vfree(module_region);
270 /* FIXME: If module_region == mod->init_region, trim exception
271 table entries. */
272} 270}
273 271
274/* Additional bytes needed in front of individual sections */ 272/* Additional bytes needed in front of individual sections */
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 43e7e3a7f130..477c663e0140 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -43,8 +43,6 @@ void *module_alloc(unsigned long size)
43void module_free(struct module *mod, void *module_region) 43void module_free(struct module *mod, void *module_region)
44{ 44{
45 vfree(module_region); 45 vfree(module_region);
46 /* FIXME: If module_region == mod->init_region, trim exception
47 table entries. */
48} 46}
49 47
50static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, 48static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index eed4a00cb676..ab2e3ed28abc 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -56,8 +56,6 @@ void *module_alloc(unsigned long size)
56void module_free(struct module *mod, void *module_region) 56void module_free(struct module *mod, void *module_region)
57{ 57{
58 vfree(module_region); 58 vfree(module_region);
59 /* FIXME: If module_region == mod->init_region, trim exception
60 table entries. */
61} 59}
62 60
63static void 61static void
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index c19b0f7d2cc1..c2efdcde266f 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -46,8 +46,6 @@ void *module_alloc(unsigned long size)
46void module_free(struct module *mod, void *module_region) 46void module_free(struct module *mod, void *module_region)
47{ 47{
48 vfree(module_region); 48 vfree(module_region);
49 /* FIXME: If module_region == mod->init_region, trim exception
50 table entries. */
51} 49}
52 50
53/* We don't need anything special. */ 51/* We don't need anything special. */
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 47d5619d43fa..8303ac481034 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -17,6 +17,9 @@
17 17
18#ifndef __ASSEMBLY__ 18#ifndef __ASSEMBLY__
19 19
20#define ARCH_HAS_SORT_EXTABLE
21#define ARCH_HAS_SEARCH_EXTABLE
22
20/* Sparc is not segmented, however we need to be able to fool access_ok() 23/* Sparc is not segmented, however we need to be able to fool access_ok()
21 * when doing system calls from kernel mode legitimately. 24 * when doing system calls from kernel mode legitimately.
22 * 25 *
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index 90273765e81f..0ee642f63234 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -75,8 +75,6 @@ void *module_alloc(unsigned long size)
75void module_free(struct module *mod, void *module_region) 75void module_free(struct module *mod, void *module_region)
76{ 76{
77 vfree(module_region); 77 vfree(module_region);
78 /* FIXME: If module_region == mod->init_region, trim exception
79 table entries. */
80} 78}
81 79
82/* Make generic code ignore STT_REGISTER dummy undefined symbols. */ 80/* Make generic code ignore STT_REGISTER dummy undefined symbols. */
diff --git a/arch/sparc/mm/extable.c b/arch/sparc/mm/extable.c
index 16cc28935e39..a61c349448e1 100644
--- a/arch/sparc/mm/extable.c
+++ b/arch/sparc/mm/extable.c
@@ -28,6 +28,10 @@ search_extable(const struct exception_table_entry *start,
28 * word 3: last insn address + 4 bytes 28 * word 3: last insn address + 4 bytes
29 * word 4: fixup code address 29 * word 4: fixup code address
30 * 30 *
31 * Deleted entries are encoded as:
32 * word 1: unused
33 * word 2: -1
34 *
31 * See asm/uaccess.h for more details. 35 * See asm/uaccess.h for more details.
32 */ 36 */
33 37
@@ -39,6 +43,10 @@ search_extable(const struct exception_table_entry *start,
39 continue; 43 continue;
40 } 44 }
41 45
46 /* A deleted entry; see trim_init_extable */
47 if (walk->fixup == -1)
48 continue;
49
42 if (walk->insn == value) 50 if (walk->insn == value)
43 return walk; 51 return walk;
44 } 52 }
@@ -57,6 +65,27 @@ search_extable(const struct exception_table_entry *start,
57 return NULL; 65 return NULL;
58} 66}
59 67
68#ifdef CONFIG_MODULES
69/* We could memmove them around; easier to mark the trimmed ones. */
70void trim_init_extable(struct module *m)
71{
72 unsigned int i;
73 bool range;
74
75 for (i = 0; i < m->num_exentries; i += range ? 2 : 1) {
76 range = m->extable[i].fixup == 0;
77
78 if (within_module_init(m->extable[i].insn, m)) {
79 m->extable[i].fixup = -1;
80 if (range)
81 m->extable[i+1].fixup = -1;
82 }
83 if (range)
84 i++;
85 }
86}
87#endif /* CONFIG_MODULES */
88
60/* Special extable search, which handles ranges. Returns fixup */ 89/* Special extable search, which handles ranges. Returns fixup */
61unsigned long search_extables_range(unsigned long addr, unsigned long *g2) 90unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
62{ 91{
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index 58da2480a7f4..9ce3f165111a 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -53,16 +53,21 @@ extern unsigned long end_iomem;
53#else 53#else
54# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) 54# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
55#endif 55#endif
56#define MODULES_VADDR VMALLOC_START
57#define MODULES_END VMALLOC_END
58#define MODULES_LEN (MODULES_VADDR - MODULES_END)
56 59
57#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) 60#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
58#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 61#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
59#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) 62#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
60 63#define __PAGE_KERNEL_EXEC \
64 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
61#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) 65#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
62#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) 66#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
63#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) 67#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
64#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) 68#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
65#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) 69#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
70#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC)
66 71
67/* 72/*
68 * The i386 can't do page protection for execute, and considers that the same 73 * The i386 can't do page protection for execute, and considers that the same
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 598b5c1903af..1b549bca4645 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -8,7 +8,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
8 8
9subarch-obj-y = lib/semaphore_32.o lib/string_32.o 9subarch-obj-y = lib/semaphore_32.o lib/string_32.o
10subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o 10subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
11subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o 11subarch-obj-$(CONFIG_MODULES) += kernel/module.o
12 12
13USER_OBJS := bugs.o ptrace_user.o fault.o 13USER_OBJS := bugs.o ptrace_user.o fault.o
14 14
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index c8b4cce9cfe1..2201e9c20e4a 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -8,10 +8,8 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
8 setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ 8 setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \
9 sysrq.o ksyms.o tls.o 9 sysrq.o ksyms.o tls.o
10 10
11obj-$(CONFIG_MODULES) += um_module.o
12
13subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o 11subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
14subarch-obj-$(CONFIG_MODULES) += kernel/module_64.o 12subarch-obj-$(CONFIG_MODULES) += kernel/module.o
15 13
16ldt-y = ../sys-i386/ldt.o 14ldt-y = ../sys-i386/ldt.o
17 15
diff --git a/arch/um/sys-x86_64/um_module.c b/arch/um/sys-x86_64/um_module.c
deleted file mode 100644
index 3dead392a415..000000000000
--- a/arch/um/sys-x86_64/um_module.c
+++ /dev/null
@@ -1,21 +0,0 @@
1#include <linux/vmalloc.h>
2#include <linux/moduleloader.h>
3
4/* Copied from i386 arch/i386/kernel/module.c */
5void *module_alloc(unsigned long size)
6{
7 if (size == 0)
8 return NULL;
9 return vmalloc_exec(size);
10}
11
12/* Free memory returned from module_alloc */
13void module_free(struct module *mod, void *module_region)
14{
15 vfree(module_region);
16 /*
17 * FIXME: If module_region == mod->init_region, trim exception
18 * table entries.
19 */
20}
21
diff --git a/arch/x86/include/asm/pgtable_32_types.h b/arch/x86/include/asm/pgtable_32_types.h
index 2733fad45f98..5e67c1532314 100644
--- a/arch/x86/include/asm/pgtable_32_types.h
+++ b/arch/x86/include/asm/pgtable_32_types.h
@@ -46,6 +46,10 @@ extern bool __vmalloc_start_set; /* set once high_memory is set */
46# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE) 46# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE)
47#endif 47#endif
48 48
49#define MODULES_VADDR VMALLOC_START
50#define MODULES_END VMALLOC_END
51#define MODULES_LEN (MODULES_VADDR - MODULES_END)
52
49#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE) 53#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
50 54
51#endif /* _ASM_X86_PGTABLE_32_DEFS_H */ 55#endif /* _ASM_X86_PGTABLE_32_DEFS_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 4f78bd682125..f3477bb84566 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -73,7 +73,7 @@ obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
73obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o 73obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
74obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o 74obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
75obj-$(CONFIG_KPROBES) += kprobes.o 75obj-$(CONFIG_KPROBES) += kprobes.o
76obj-$(CONFIG_MODULES) += module_$(BITS).o 76obj-$(CONFIG_MODULES) += module.o
77obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o 77obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
78obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o 78obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
79obj-$(CONFIG_KGDB) += kgdb.o 79obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/x86/kernel/module_64.c b/arch/x86/kernel/module.c
index c23880b90b5c..89f386f044e4 100644
--- a/arch/x86/kernel/module_64.c
+++ b/arch/x86/kernel/module.c
@@ -1,6 +1,5 @@
1/* Kernel module help for x86-64 1/* Kernel module help for x86.
2 Copyright (C) 2001 Rusty Russell. 2 Copyright (C) 2001 Rusty Russell.
3 Copyright (C) 2002,2003 Andi Kleen, SuSE Labs.
4 3
5 This program is free software; you can redistribute it and/or modify 4 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 5 it under the terms of the GNU General Public License as published by
@@ -22,23 +21,18 @@
22#include <linux/fs.h> 21#include <linux/fs.h>
23#include <linux/string.h> 22#include <linux/string.h>
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/mm.h>
26#include <linux/slab.h>
27#include <linux/bug.h> 24#include <linux/bug.h>
25#include <linux/mm.h>
28 26
29#include <asm/system.h> 27#include <asm/system.h>
30#include <asm/page.h> 28#include <asm/page.h>
31#include <asm/pgtable.h> 29#include <asm/pgtable.h>
32 30
31#if 0
32#define DEBUGP printk
33#else
33#define DEBUGP(fmt...) 34#define DEBUGP(fmt...)
34 35#endif
35#ifndef CONFIG_UML
36void module_free(struct module *mod, void *module_region)
37{
38 vfree(module_region);
39 /* FIXME: If module_region == mod->init_region, trim exception
40 table entries. */
41}
42 36
43void *module_alloc(unsigned long size) 37void *module_alloc(unsigned long size)
44{ 38{
@@ -54,9 +48,15 @@ void *module_alloc(unsigned long size)
54 if (!area) 48 if (!area)
55 return NULL; 49 return NULL;
56 50
57 return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); 51 return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM,
52 PAGE_KERNEL_EXEC);
53}
54
55/* Free memory returned from module_alloc */
56void module_free(struct module *mod, void *module_region)
57{
58 vfree(module_region);
58} 59}
59#endif
60 60
61/* We don't need anything special. */ 61/* We don't need anything special. */
62int module_frob_arch_sections(Elf_Ehdr *hdr, 62int module_frob_arch_sections(Elf_Ehdr *hdr,
@@ -67,6 +67,58 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
67 return 0; 67 return 0;
68} 68}
69 69
70#ifdef CONFIG_X86_32
71int apply_relocate(Elf32_Shdr *sechdrs,
72 const char *strtab,
73 unsigned int symindex,
74 unsigned int relsec,
75 struct module *me)
76{
77 unsigned int i;
78 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
79 Elf32_Sym *sym;
80 uint32_t *location;
81
82 DEBUGP("Applying relocate section %u to %u\n", relsec,
83 sechdrs[relsec].sh_info);
84 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
85 /* This is where to make the change */
86 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
87 + rel[i].r_offset;
88 /* This is the symbol it is referring to. Note that all
89 undefined symbols have been resolved. */
90 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
91 + ELF32_R_SYM(rel[i].r_info);
92
93 switch (ELF32_R_TYPE(rel[i].r_info)) {
94 case R_386_32:
95 /* We add the value into the location given */
96 *location += sym->st_value;
97 break;
98 case R_386_PC32:
99 /* Add the value, subtract its postition */
100 *location += sym->st_value - (uint32_t)location;
101 break;
102 default:
103 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
104 me->name, ELF32_R_TYPE(rel[i].r_info));
105 return -ENOEXEC;
106 }
107 }
108 return 0;
109}
110
111int apply_relocate_add(Elf32_Shdr *sechdrs,
112 const char *strtab,
113 unsigned int symindex,
114 unsigned int relsec,
115 struct module *me)
116{
117 printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
118 me->name);
119 return -ENOEXEC;
120}
121#else /*X86_64*/
70int apply_relocate_add(Elf64_Shdr *sechdrs, 122int apply_relocate_add(Elf64_Shdr *sechdrs,
71 const char *strtab, 123 const char *strtab,
72 unsigned int symindex, 124 unsigned int symindex,
@@ -147,6 +199,8 @@ int apply_relocate(Elf_Shdr *sechdrs,
147 return -ENOSYS; 199 return -ENOSYS;
148} 200}
149 201
202#endif
203
150int module_finalize(const Elf_Ehdr *hdr, 204int module_finalize(const Elf_Ehdr *hdr,
151 const Elf_Shdr *sechdrs, 205 const Elf_Shdr *sechdrs,
152 struct module *me) 206 struct module *me)
diff --git a/arch/x86/kernel/module_32.c b/arch/x86/kernel/module_32.c
deleted file mode 100644
index 0edd819050e7..000000000000
--- a/arch/x86/kernel/module_32.c
+++ /dev/null
@@ -1,152 +0,0 @@
1/* Kernel module help for i386.
2 Copyright (C) 2001 Rusty Russell.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18#include <linux/moduleloader.h>
19#include <linux/elf.h>
20#include <linux/vmalloc.h>
21#include <linux/fs.h>
22#include <linux/string.h>
23#include <linux/kernel.h>
24#include <linux/bug.h>
25
26#if 0
27#define DEBUGP printk
28#else
29#define DEBUGP(fmt...)
30#endif
31
32void *module_alloc(unsigned long size)
33{
34 if (size == 0)
35 return NULL;
36 return vmalloc_exec(size);
37}
38
39
40/* Free memory returned from module_alloc */
41void module_free(struct module *mod, void *module_region)
42{
43 vfree(module_region);
44 /* FIXME: If module_region == mod->init_region, trim exception
45 table entries. */
46}
47
48/* We don't need anything special. */
49int module_frob_arch_sections(Elf_Ehdr *hdr,
50 Elf_Shdr *sechdrs,
51 char *secstrings,
52 struct module *mod)
53{
54 return 0;
55}
56
57int apply_relocate(Elf32_Shdr *sechdrs,
58 const char *strtab,
59 unsigned int symindex,
60 unsigned int relsec,
61 struct module *me)
62{
63 unsigned int i;
64 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
65 Elf32_Sym *sym;
66 uint32_t *location;
67
68 DEBUGP("Applying relocate section %u to %u\n", relsec,
69 sechdrs[relsec].sh_info);
70 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
71 /* This is where to make the change */
72 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
73 + rel[i].r_offset;
74 /* This is the symbol it is referring to. Note that all
75 undefined symbols have been resolved. */
76 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
77 + ELF32_R_SYM(rel[i].r_info);
78
79 switch (ELF32_R_TYPE(rel[i].r_info)) {
80 case R_386_32:
81 /* We add the value into the location given */
82 *location += sym->st_value;
83 break;
84 case R_386_PC32:
85 /* Add the value, subtract its postition */
86 *location += sym->st_value - (uint32_t)location;
87 break;
88 default:
89 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
90 me->name, ELF32_R_TYPE(rel[i].r_info));
91 return -ENOEXEC;
92 }
93 }
94 return 0;
95}
96
97int apply_relocate_add(Elf32_Shdr *sechdrs,
98 const char *strtab,
99 unsigned int symindex,
100 unsigned int relsec,
101 struct module *me)
102{
103 printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
104 me->name);
105 return -ENOEXEC;
106}
107
108int module_finalize(const Elf_Ehdr *hdr,
109 const Elf_Shdr *sechdrs,
110 struct module *me)
111{
112 const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
113 *para = NULL;
114 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
115
116 for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
117 if (!strcmp(".text", secstrings + s->sh_name))
118 text = s;
119 if (!strcmp(".altinstructions", secstrings + s->sh_name))
120 alt = s;
121 if (!strcmp(".smp_locks", secstrings + s->sh_name))
122 locks = s;
123 if (!strcmp(".parainstructions", secstrings + s->sh_name))
124 para = s;
125 }
126
127 if (alt) {
128 /* patch .altinstructions */
129 void *aseg = (void *)alt->sh_addr;
130 apply_alternatives(aseg, aseg + alt->sh_size);
131 }
132 if (locks && text) {
133 void *lseg = (void *)locks->sh_addr;
134 void *tseg = (void *)text->sh_addr;
135 alternatives_smp_module_add(me, me->name,
136 lseg, lseg + locks->sh_size,
137 tseg, tseg + text->sh_size);
138 }
139
140 if (para) {
141 void *pseg = (void *)para->sh_addr;
142 apply_paravirt(pseg, pseg + para->sh_size);
143 }
144
145 return module_bug_finalize(hdr, sechdrs, me);
146}
147
148void module_arch_cleanup(struct module *mod)
149{
150 alternatives_smp_module_del(mod);
151 module_bug_cleanup(mod);
152}
diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c
index 3981a466c779..c1accea8cb56 100644
--- a/arch/xtensa/kernel/module.c
+++ b/arch/xtensa/kernel/module.c
@@ -34,8 +34,6 @@ void *module_alloc(unsigned long size)
34void module_free(struct module *mod, void *module_region) 34void module_free(struct module *mod, void *module_region)
35{ 35{
36 vfree(module_region); 36 vfree(module_region);
37 /* FIXME: If module_region == mod->init_region, trim exception
38 table entries. */
39} 37}
40 38
41int module_frob_arch_sections(Elf32_Ehdr *hdr, 39int module_frob_arch_sections(Elf32_Ehdr *hdr,
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 35e8eb02b9e9..e4e4d433b007 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -354,7 +354,7 @@ static int default_crt_on __devinitdata = 0;
354static int default_lcd_on __devinitdata = 1; 354static int default_lcd_on __devinitdata = 1;
355 355
356#ifdef CONFIG_MTRR 356#ifdef CONFIG_MTRR
357static int mtrr = 1; 357static bool mtrr = true;
358#endif 358#endif
359 359
360#ifdef CONFIG_PMAC_BACKLIGHT 360#ifdef CONFIG_PMAC_BACKLIGHT
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 83c5cefc266c..da7c01b39be2 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1736,10 +1736,8 @@ static int __init cyber2000fb_init(void)
1736 1736
1737#ifdef CONFIG_ARCH_SHARK 1737#ifdef CONFIG_ARCH_SHARK
1738 err = cyberpro_vl_probe(); 1738 err = cyberpro_vl_probe();
1739 if (!err) { 1739 if (!err)
1740 ret = 0; 1740 ret = 0;
1741 __module_get(THIS_MODULE);
1742 }
1743#endif 1741#endif
1744#ifdef CONFIG_PCI 1742#ifdef CONFIG_PCI
1745 err = pci_register_driver(&cyberpro_driver); 1743 err = pci_register_driver(&cyberpro_driver);
@@ -1749,14 +1747,15 @@ static int __init cyber2000fb_init(void)
1749 1747
1750 return ret ? err : 0; 1748 return ret ? err : 0;
1751} 1749}
1750module_init(cyber2000fb_init);
1752 1751
1752#ifndef CONFIG_ARCH_SHARK
1753static void __exit cyberpro_exit(void) 1753static void __exit cyberpro_exit(void)
1754{ 1754{
1755 pci_unregister_driver(&cyberpro_driver); 1755 pci_unregister_driver(&cyberpro_driver);
1756} 1756}
1757
1758module_init(cyber2000fb_init);
1759module_exit(cyberpro_exit); 1757module_exit(cyberpro_exit);
1758#endif
1760 1759
1761MODULE_AUTHOR("Russell King"); 1760MODULE_AUTHOR("Russell King");
1762MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver"); 1761MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 421770b5e6ab..ca5b4643a401 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -45,7 +45,7 @@ static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
45static int mtrr __devinitdata = 3; /* enable mtrr by default */ 45static int mtrr __devinitdata = 3; /* enable mtrr by default */
46static int blank = 1; /* enable blanking by default */ 46static int blank = 1; /* enable blanking by default */
47static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */ 47static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */
48static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */ 48static bool pmi_setpal __devinitdata = true; /* use PMI for palette changes */
49static int nocrtc __devinitdata; /* ignore CRTC settings */ 49static int nocrtc __devinitdata; /* ignore CRTC settings */
50static int noedid __devinitdata; /* don't try DDC transfers */ 50static int noedid __devinitdata; /* don't try DDC transfers */
51static int vram_remap __devinitdata; /* set amt. of memory to be used */ 51static int vram_remap __devinitdata; /* set amt. of memory to be used */
@@ -2002,11 +2002,7 @@ static void __devexit uvesafb_exit(void)
2002 2002
2003module_exit(uvesafb_exit); 2003module_exit(uvesafb_exit);
2004 2004
2005static int param_get_scroll(char *buffer, struct kernel_param *kp) 2005#define param_get_scroll NULL
2006{
2007 return 0;
2008}
2009
2010static int param_set_scroll(const char *val, struct kernel_param *kp) 2006static int param_set_scroll(const char *val, struct kernel_param *kp)
2011{ 2007{
2012 ypan = 0; 2008 ypan = 0;
@@ -2017,6 +2013,8 @@ static int param_set_scroll(const char *val, struct kernel_param *kp)
2017 ypan = 1; 2013 ypan = 1;
2018 else if (!strcmp(val, "ywrap")) 2014 else if (!strcmp(val, "ywrap"))
2019 ypan = 2; 2015 ypan = 2;
2016 else
2017 return -EINVAL;
2020 2018
2021 return 0; 2019 return 0;
2022} 2020}
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 37bcb50a4d7c..04fb5135b4e1 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -261,6 +261,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
261# define __section(S) __attribute__ ((__section__(#S))) 261# define __section(S) __attribute__ ((__section__(#S)))
262#endif 262#endif
263 263
264/* Are two types/vars the same type (ignoring qualifiers)? */
265#ifndef __same_type
266# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
267#endif
268
264/* 269/*
265 * Prevent the compiler from merging or refetching accesses. The compiler 270 * Prevent the compiler from merging or refetching accesses. The compiler
266 * is also forbidden from reordering successive instances of ACCESS_ONCE(), 271 * is also forbidden from reordering successive instances of ACCESS_ONCE(),
diff --git a/include/linux/module.h b/include/linux/module.h
index a8f2c0aa4c32..a7bc6e7b43a7 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -77,6 +77,7 @@ search_extable(const struct exception_table_entry *first,
77void sort_extable(struct exception_table_entry *start, 77void sort_extable(struct exception_table_entry *start,
78 struct exception_table_entry *finish); 78 struct exception_table_entry *finish);
79void sort_main_extable(void); 79void sort_main_extable(void);
80void trim_init_extable(struct module *m);
80 81
81#ifdef MODULE 82#ifdef MODULE
82#define MODULE_GENERIC_TABLE(gtype,name) \ 83#define MODULE_GENERIC_TABLE(gtype,name) \
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index a4f0b931846c..6547c3cdbc4c 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -36,9 +36,14 @@ typedef int (*param_set_fn)(const char *val, struct kernel_param *kp);
36/* Returns length written or -errno. Buffer is 4k (ie. be short!) */ 36/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
37typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp); 37typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp);
38 38
39/* Flag bits for kernel_param.flags */
40#define KPARAM_KMALLOCED 1
41#define KPARAM_ISBOOL 2
42
39struct kernel_param { 43struct kernel_param {
40 const char *name; 44 const char *name;
41 unsigned int perm; 45 u16 perm;
46 u16 flags;
42 param_set_fn set; 47 param_set_fn set;
43 param_get_fn get; 48 param_get_fn get;
44 union { 49 union {
@@ -79,7 +84,7 @@ struct kparam_array
79 parameters. perm sets the visibility in sysfs: 000 means it's 84 parameters. perm sets the visibility in sysfs: 000 means it's
80 not there, read bits mean it's readable, write bits mean it's 85 not there, read bits mean it's readable, write bits mean it's
81 writable. */ 86 writable. */
82#define __module_param_call(prefix, name, set, get, arg, perm) \ 87#define __module_param_call(prefix, name, set, get, arg, isbool, perm) \
83 /* Default value instead of permissions? */ \ 88 /* Default value instead of permissions? */ \
84 static int __param_perm_check_##name __attribute__((unused)) = \ 89 static int __param_perm_check_##name __attribute__((unused)) = \
85 BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ 90 BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \
@@ -88,10 +93,13 @@ struct kparam_array
88 static struct kernel_param __moduleparam_const __param_##name \ 93 static struct kernel_param __moduleparam_const __param_##name \
89 __used \ 94 __used \
90 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ 95 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
91 = { __param_str_##name, perm, set, get, { arg } } 96 = { __param_str_##name, perm, isbool ? KPARAM_ISBOOL : 0, \
97 set, get, { arg } }
92 98
93#define module_param_call(name, set, get, arg, perm) \ 99#define module_param_call(name, set, get, arg, perm) \
94 __module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm) 100 __module_param_call(MODULE_PARAM_PREFIX, \
101 name, set, get, arg, \
102 __same_type(*(arg), bool), perm)
95 103
96/* Helper functions: type is byte, short, ushort, int, uint, long, 104/* Helper functions: type is byte, short, ushort, int, uint, long,
97 ulong, charp, bool or invbool, or XXX if you define param_get_XXX, 105 ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
@@ -120,15 +128,16 @@ struct kparam_array
120#define core_param(name, var, type, perm) \ 128#define core_param(name, var, type, perm) \
121 param_check_##type(name, &(var)); \ 129 param_check_##type(name, &(var)); \
122 __module_param_call("", name, param_set_##type, param_get_##type, \ 130 __module_param_call("", name, param_set_##type, param_get_##type, \
123 &var, perm) 131 &var, __same_type(var, bool), perm)
124#endif /* !MODULE */ 132#endif /* !MODULE */
125 133
126/* Actually copy string: maxlen param is usually sizeof(string). */ 134/* Actually copy string: maxlen param is usually sizeof(string). */
127#define module_param_string(name, string, len, perm) \ 135#define module_param_string(name, string, len, perm) \
128 static const struct kparam_string __param_string_##name \ 136 static const struct kparam_string __param_string_##name \
129 = { len, string }; \ 137 = { len, string }; \
130 module_param_call(name, param_set_copystring, param_get_string, \ 138 __module_param_call(MODULE_PARAM_PREFIX, name, \
131 .str = &__param_string_##name, perm); \ 139 param_set_copystring, param_get_string, \
140 .str = &__param_string_##name, 0, perm); \
132 __MODULE_PARM_TYPE(name, "string") 141 __MODULE_PARM_TYPE(name, "string")
133 142
134/* Called on module insert or kernel boot */ 143/* Called on module insert or kernel boot */
@@ -186,21 +195,30 @@ extern int param_set_charp(const char *val, struct kernel_param *kp);
186extern int param_get_charp(char *buffer, struct kernel_param *kp); 195extern int param_get_charp(char *buffer, struct kernel_param *kp);
187#define param_check_charp(name, p) __param_check(name, p, char *) 196#define param_check_charp(name, p) __param_check(name, p, char *)
188 197
198/* For historical reasons "bool" parameters can be (unsigned) "int". */
189extern int param_set_bool(const char *val, struct kernel_param *kp); 199extern int param_set_bool(const char *val, struct kernel_param *kp);
190extern int param_get_bool(char *buffer, struct kernel_param *kp); 200extern int param_get_bool(char *buffer, struct kernel_param *kp);
191#define param_check_bool(name, p) __param_check(name, p, int) 201#define param_check_bool(name, p) \
202 static inline void __check_##name(void) \
203 { \
204 BUILD_BUG_ON(!__same_type(*(p), bool) && \
205 !__same_type(*(p), unsigned int) && \
206 !__same_type(*(p), int)); \
207 }
192 208
193extern int param_set_invbool(const char *val, struct kernel_param *kp); 209extern int param_set_invbool(const char *val, struct kernel_param *kp);
194extern int param_get_invbool(char *buffer, struct kernel_param *kp); 210extern int param_get_invbool(char *buffer, struct kernel_param *kp);
195#define param_check_invbool(name, p) __param_check(name, p, int) 211#define param_check_invbool(name, p) __param_check(name, p, bool)
196 212
197/* Comma-separated array: *nump is set to number they actually specified. */ 213/* Comma-separated array: *nump is set to number they actually specified. */
198#define module_param_array_named(name, array, type, nump, perm) \ 214#define module_param_array_named(name, array, type, nump, perm) \
199 static const struct kparam_array __param_arr_##name \ 215 static const struct kparam_array __param_arr_##name \
200 = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\ 216 = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\
201 sizeof(array[0]), array }; \ 217 sizeof(array[0]), array }; \
202 module_param_call(name, param_array_set, param_array_get, \ 218 __module_param_call(MODULE_PARAM_PREFIX, name, \
203 .arr = &__param_arr_##name, perm); \ 219 param_array_set, param_array_get, \
220 .arr = &__param_arr_##name, \
221 __same_type(array[0], bool), perm); \
204 __MODULE_PARM_TYPE(name, "array of " #type) 222 __MODULE_PARM_TYPE(name, "array of " #type)
205 223
206#define module_param_array(name, type, nump, perm) \ 224#define module_param_array(name, type, nump, perm) \
diff --git a/kernel/module.c b/kernel/module.c
index 35f7de00bf0d..e4ab36ce7672 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2455,6 +2455,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
2455 mutex_lock(&module_mutex); 2455 mutex_lock(&module_mutex);
2456 /* Drop initial reference. */ 2456 /* Drop initial reference. */
2457 module_put(mod); 2457 module_put(mod);
2458 trim_init_extable(mod);
2458 module_free(mod, mod->module_init); 2459 module_free(mod, mod->module_init);
2459 mod->module_init = NULL; 2460 mod->module_init = NULL;
2460 mod->init_size = 0; 2461 mod->init_size = 0;
diff --git a/kernel/params.c b/kernel/params.c
index de273ec85bd2..7f6912ced2ba 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -24,9 +24,6 @@
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26 26
27/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */
28#define KPARAM_KMALLOCED 0x80000000
29
30#if 0 27#if 0
31#define DEBUGP printk 28#define DEBUGP printk
32#else 29#else
@@ -220,13 +217,13 @@ int param_set_charp(const char *val, struct kernel_param *kp)
220 return -ENOSPC; 217 return -ENOSPC;
221 } 218 }
222 219
223 if (kp->perm & KPARAM_KMALLOCED) 220 if (kp->flags & KPARAM_KMALLOCED)
224 kfree(*(char **)kp->arg); 221 kfree(*(char **)kp->arg);
225 222
226 /* This is a hack. We can't need to strdup in early boot, and we 223 /* This is a hack. We can't need to strdup in early boot, and we
227 * don't need to; this mangled commandline is preserved. */ 224 * don't need to; this mangled commandline is preserved. */
228 if (slab_is_available()) { 225 if (slab_is_available()) {
229 kp->perm |= KPARAM_KMALLOCED; 226 kp->flags |= KPARAM_KMALLOCED;
230 *(char **)kp->arg = kstrdup(val, GFP_KERNEL); 227 *(char **)kp->arg = kstrdup(val, GFP_KERNEL);
231 if (!kp->arg) 228 if (!kp->arg)
232 return -ENOMEM; 229 return -ENOMEM;
@@ -241,44 +238,63 @@ int param_get_charp(char *buffer, struct kernel_param *kp)
241 return sprintf(buffer, "%s", *((char **)kp->arg)); 238 return sprintf(buffer, "%s", *((char **)kp->arg));
242} 239}
243 240
241/* Actually could be a bool or an int, for historical reasons. */
244int param_set_bool(const char *val, struct kernel_param *kp) 242int param_set_bool(const char *val, struct kernel_param *kp)
245{ 243{
244 bool v;
245
246 /* No equals means "set"... */ 246 /* No equals means "set"... */
247 if (!val) val = "1"; 247 if (!val) val = "1";
248 248
249 /* One of =[yYnN01] */ 249 /* One of =[yYnN01] */
250 switch (val[0]) { 250 switch (val[0]) {
251 case 'y': case 'Y': case '1': 251 case 'y': case 'Y': case '1':
252 *(int *)kp->arg = 1; 252 v = true;
253 return 0; 253 break;
254 case 'n': case 'N': case '0': 254 case 'n': case 'N': case '0':
255 *(int *)kp->arg = 0; 255 v = false;
256 return 0; 256 break;
257 default:
258 return -EINVAL;
257 } 259 }
258 return -EINVAL; 260
261 if (kp->flags & KPARAM_ISBOOL)
262 *(bool *)kp->arg = v;
263 else
264 *(int *)kp->arg = v;
265 return 0;
259} 266}
260 267
261int param_get_bool(char *buffer, struct kernel_param *kp) 268int param_get_bool(char *buffer, struct kernel_param *kp)
262{ 269{
270 bool val;
271 if (kp->flags & KPARAM_ISBOOL)
272 val = *(bool *)kp->arg;
273 else
274 val = *(int *)kp->arg;
275
263 /* Y and N chosen as being relatively non-coder friendly */ 276 /* Y and N chosen as being relatively non-coder friendly */
264 return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'Y' : 'N'); 277 return sprintf(buffer, "%c", val ? 'Y' : 'N');
265} 278}
266 279
280/* This one must be bool. */
267int param_set_invbool(const char *val, struct kernel_param *kp) 281int param_set_invbool(const char *val, struct kernel_param *kp)
268{ 282{
269 int boolval, ret; 283 int ret;
284 bool boolval;
270 struct kernel_param dummy; 285 struct kernel_param dummy;
271 286
272 dummy.arg = &boolval; 287 dummy.arg = &boolval;
288 dummy.flags = KPARAM_ISBOOL;
273 ret = param_set_bool(val, &dummy); 289 ret = param_set_bool(val, &dummy);
274 if (ret == 0) 290 if (ret == 0)
275 *(int *)kp->arg = !boolval; 291 *(bool *)kp->arg = !boolval;
276 return ret; 292 return ret;
277} 293}
278 294
279int param_get_invbool(char *buffer, struct kernel_param *kp) 295int param_get_invbool(char *buffer, struct kernel_param *kp)
280{ 296{
281 return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'N' : 'Y'); 297 return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
282} 298}
283 299
284/* We break the rule and mangle the string. */ 300/* We break the rule and mangle the string. */
@@ -591,7 +607,7 @@ void destroy_params(const struct kernel_param *params, unsigned num)
591 unsigned int i; 607 unsigned int i;
592 608
593 for (i = 0; i < num; i++) 609 for (i = 0; i < num; i++)
594 if (params[i].perm & KPARAM_KMALLOCED) 610 if (params[i].flags & KPARAM_KMALLOCED)
595 kfree(*(char **)params[i].arg); 611 kfree(*(char **)params[i].arg);
596} 612}
597 613
diff --git a/lib/extable.c b/lib/extable.c
index 179c08745595..4cac81ec225e 100644
--- a/lib/extable.c
+++ b/lib/extable.c
@@ -39,7 +39,26 @@ void sort_extable(struct exception_table_entry *start,
39 sort(start, finish - start, sizeof(struct exception_table_entry), 39 sort(start, finish - start, sizeof(struct exception_table_entry),
40 cmp_ex, NULL); 40 cmp_ex, NULL);
41} 41}
42#endif 42
43#ifdef CONFIG_MODULES
44/*
45 * If the exception table is sorted, any referring to the module init
46 * will be at the beginning or the end.
47 */
48void trim_init_extable(struct module *m)
49{
50 /*trim the beginning*/
51 while (m->num_exentries && within_module_init(m->extable[0].insn, m)) {
52 m->extable++;
53 m->num_exentries--;
54 }
55 /*trim the end*/
56 while (m->num_exentries &&
57 within_module_init(m->extable[m->num_exentries-1].insn, m))
58 m->num_exentries--;
59}
60#endif /* CONFIG_MODULES */
61#endif /* !ARCH_HAS_SORT_EXTABLE */
43 62
44#ifndef ARCH_HAS_SEARCH_EXTABLE 63#ifndef ARCH_HAS_SEARCH_EXTABLE
45/* 64/*