* Re: [PATCH] extable cleanup
@ 2003-01-03 22:06 Manfred Spraul
2003-01-04 6:03 ` Rusty Russell
0 siblings, 1 reply; 6+ messages in thread
From: Manfred Spraul @ 2003-01-03 22:06 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kernel, Rusty Russell
>
>
>On Fri, 3 Jan 2003, Rusty Russell wrote:
>>
>> Fairly straightforward consolidation of extable handling. Sparc64 is
>> trickiest, with its extable range stuff (ideally, the ranges would be
>> in a separate __extable_range section, then the extable walking code
>> could be made common, too).
>>
>> Only tested on x86: ppc and sparc64 written untested, others broken.
>
>Did you test on a true i386, which needs exception handling very early on
>to handle the test for broken WP? In other words, are all the exception
>table data structures properly initialized?
>
>
It's the other way around: a real 80386 doesn't need the early exception
handling, all other cpus need it.
The WP test works by writing to a write-protected page while at ring 0.
A real 80386 ignores the write-protected bit, later x86 cpus honor it
and cause a page fault.
Rusty, against which kernel is the patch you have posted? I've tried
both 2.5.54 and the latest bk shapshot from www.kernel.org, I get an
patch error in kernel/extable.c.
--
Manfred
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] extable cleanup
2003-01-03 22:06 [PATCH] extable cleanup Manfred Spraul
@ 2003-01-04 6:03 ` Rusty Russell
0 siblings, 0 replies; 6+ messages in thread
From: Rusty Russell @ 2003-01-04 6:03 UTC (permalink / raw)
To: Manfred Spraul; +Cc: Linus Torvalds, linux-kernel
In message <3E160948.1060008@colorfullife.com> you write:
> Rusty, against which kernel is the patch you have posted? I've tried
> both 2.5.54 and the latest bk shapshot from www.kernel.org, I get an
> patch error in kernel/extable.c.
Either should work, but you need to apply the module license patch
first (below).
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Name: MODULE_LICENSE support for modules
Author: Rusty Russell
Status: Tested in 2.5.54
D: This implements EXPORT_SYMBOL_GPL and MODULE_LICENSE properly (so
D: restrictions are enforced). Also fixes "proprietory" spelling.
diff -urNp --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5-bk/include/linux/kernel.h working-2.5-bk-module-license/include/linux/kernel.h
--- linux-2.5-bk/include/linux/kernel.h Thu Jan 2 14:48:00 2003
+++ working-2.5-bk-module-license/include/linux/kernel.h Fri Jan 3 16:32:18 2003
@@ -105,7 +105,7 @@ extern int oops_in_progress; /* If set,
extern int tainted;
extern const char *print_tainted(void);
-#define TAINT_PROPRIETORY_MODULE (1<<0)
+#define TAINT_PROPRIETARY_MODULE (1<<0)
#define TAINT_FORCED_MODULE (1<<1)
#define TAINT_UNSAFE_SMP (1<<2)
#define TAINT_FORCED_RMMOD (1<<3)
diff -urNp --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5-bk/include/linux/module.h working-2.5-bk-module-license/include/linux/module.h
--- linux-2.5-bk/include/linux/module.h Thu Jan 2 14:48:00 2003
+++ working-2.5-bk-module-license/include/linux/module.h Fri Jan 3 17:12:33 2003
@@ -21,7 +21,6 @@
#include <asm/uaccess.h> /* For struct exception_table_entry */
/* Not Yet Implemented */
-#define MODULE_LICENSE(name)
#define MODULE_AUTHOR(name)
#define MODULE_DESCRIPTION(desc)
#define MODULE_SUPPORTED_DEVICE(name)
@@ -57,11 +56,41 @@ extern const struct gtype##_id __mod_##g
#define THIS_MODULE (&__this_module)
+/*
+ * The following license idents are currently accepted as indicating free
+ * software modules
+ *
+ * "GPL" [GNU Public License v2 or later]
+ * "GPL v2" [GNU Public License v2]
+ * "GPL and additional rights" [GNU Public License v2 rights and more]
+ * "Dual BSD/GPL" [GNU Public License v2
+ * or BSD license choice]
+ * "Dual MPL/GPL" [GNU Public License v2
+ * or Mozilla license choice]
+ *
+ * The following other idents are available
+ *
+ * "Proprietary" [Non free products]
+ *
+ * There are dual licensed components, but when running with Linux it is the
+ * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
+ * is a GPL combined work.
+ *
+ * This exists for several reasons
+ * 1. So modinfo can show license info for users wanting to vet their setup
+ * is free
+ * 2. So the community can ignore bug reports including proprietary modules
+ * 3. So vendors can do likewise based on their own policies
+ */
+#define MODULE_LICENSE(license) \
+ static const char __module_license[] \
+ __attribute__((section(".init.license"))) = license
+
#else /* !MODULE */
#define MODULE_GENERIC_TABLE(gtype,name)
#define THIS_MODULE ((struct module *)0)
-
+#define MODULE_LICENSE(license)
#endif
#define MODULE_DEVICE_TABLE(type,name) \
@@ -75,6 +104,9 @@ struct kernel_symbol_group
/* Module which owns it (if any) */
struct module *owner;
+ /* Are we internal use only? */
+ int gplonly;
+
unsigned int num_syms;
const struct kernel_symbol *syms;
};
@@ -101,7 +133,11 @@ void *__symbol_get_gpl(const char *symbo
= { (unsigned long)&sym, MODULE_SYMBOL_PREFIX #sym }
#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
-#define EXPORT_SYMBOL_GPL(sym) EXPORT_SYMBOL(sym)
+
+#define EXPORT_SYMBOL_GPL(sym) \
+ const struct kernel_symbol __ksymtab_##sym \
+ __attribute__((section("__gpl_ksymtab"))) \
+ = { (unsigned long)&sym, #sym }
struct module_ref
{
@@ -128,6 +164,9 @@ struct module
/* Exported symbols */
struct kernel_symbol_group symbols;
+ /* GPL-only exported symbols. */
+ struct kernel_symbol_group gpl_symbols;
+
/* Exception tables */
struct exception_table extable;
@@ -149,6 +188,9 @@ struct module
/* Am I unsafe to unload? */
int unsafe;
+ /* Am I GPL-compatible */
+ int license_gplok;
+
#ifdef CONFIG_MODULE_UNLOAD
/* Reference counts */
struct module_ref ref[NR_CPUS];
@@ -293,6 +335,7 @@ struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = __stringify(KBUILD_MODNAME),
.symbols = { .owner = &__this_module },
+ .gpl_symbols = { .owner = &__this_module, .gplonly = 1 },
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
diff -urNp --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5-bk/kernel/extable.c working-2.5-bk-module-license/kernel/extable.c
--- linux-2.5-bk/kernel/extable.c Thu Jan 2 12:36:08 2003
+++ working-2.5-bk-module-license/kernel/extable.c Fri Jan 3 16:29:26 2003
@@ -24,6 +24,8 @@ extern const struct exception_table_entr
extern const struct exception_table_entry __stop___ex_table[];
extern const struct kernel_symbol __start___ksymtab[];
extern const struct kernel_symbol __stop___ksymtab[];
+extern const struct kernel_symbol __start___gpl_ksymtab[];
+extern const struct kernel_symbol __stop___gpl_ksymtab[];
/* Protects extables and symbol tables */
spinlock_t modlist_lock = SPIN_LOCK_UNLOCKED;
@@ -34,13 +36,20 @@ LIST_HEAD(symbols);
static struct exception_table kernel_extable;
static struct kernel_symbol_group kernel_symbols;
+static struct kernel_symbol_group kernel_gpl_symbols;
void __init extable_init(void)
{
/* Add kernel symbols to symbol table */
kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab);
kernel_symbols.syms = __start___ksymtab;
+ kernel_symbols.gplonly = 0;
list_add(&kernel_symbols.list, &symbols);
+ kernel_gpl_symbols.num_syms = (__stop___gpl_ksymtab
+ - __start___gpl_ksymtab);
+ kernel_gpl_symbols.syms = __start___gpl_ksymtab;
+ kernel_gpl_symbols.gplonly = 1;
+ list_add(&kernel_gpl_symbols.list, &symbols);
/* Add kernel exception table to exception tables */
kernel_extable.num_entries = (__stop___ex_table -__start___ex_table);
diff -urNp --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5-bk/kernel/module.c working-2.5-bk-module-license/kernel/module.c
--- linux-2.5-bk/kernel/module.c Thu Jan 2 14:48:01 2003
+++ working-2.5-bk-module-license/kernel/module.c Fri Jan 3 16:47:20 2003
@@ -72,13 +72,16 @@ EXPORT_SYMBOL(init_module);
/* Find a symbol, return value and the symbol group */
static unsigned long __find_symbol(const char *name,
- struct kernel_symbol_group **group)
+ struct kernel_symbol_group **group,
+ int gplok)
{
struct kernel_symbol_group *ks;
list_for_each_entry(ks, &symbols, list) {
unsigned int i;
+ if (ks->gplonly && !gplok)
+ continue;
for (i = 0; i < ks->num_syms; i++) {
if (strcmp(ks->syms[i].name, name) == 0) {
*group = ks;
@@ -502,7 +505,7 @@ void __symbol_put(const char *symbol)
unsigned long flags;
spin_lock_irqsave(&modlist_lock, flags);
- if (!__find_symbol(symbol, &ksg))
+ if (!__find_symbol(symbol, &ksg, 1))
BUG();
module_put(ksg->owner);
spin_unlock_irqrestore(&modlist_lock, flags);
@@ -721,7 +724,7 @@ unsigned long find_symbol_internal(Elf_S
}
/* Look in other modules... */
spin_lock_irq(&modlist_lock);
- ret = __find_symbol(name, ksg);
+ ret = __find_symbol(name, ksg, mod->license_gplok);
if (ret) {
/* This can fail due to OOM, or module unloading */
if (!use_module(mod, (*ksg)->owner))
@@ -738,6 +741,7 @@ static void free_module(struct module *m
list_del(&mod->list);
spin_lock_irq(&modlist_lock);
list_del(&mod->symbols.list);
+ list_del(&mod->gpl_symbols.list);
list_del(&mod->extable.list);
spin_unlock_irq(&modlist_lock);
@@ -758,7 +762,7 @@ void *__symbol_get(const char *symbol)
unsigned long value, flags;
spin_lock_irqsave(&modlist_lock, flags);
- value = __find_symbol(symbol, &ksg);
+ value = __find_symbol(symbol, &ksg, 1);
if (value && !strong_try_module_get(ksg->owner))
value = 0;
spin_unlock_irqrestore(&modlist_lock, flags);
@@ -930,7 +934,34 @@ static void layout_sections(struct modul
}
}
-/* Allocate and load the module */
+static inline int license_is_gpl_compatible(const char *license)
+{
+ return (strcmp(license, "GPL") == 0
+ || strcmp(license, "GPL v2") == 0
+ || strcmp(license, "GPL and additional rights") == 0
+ || strcmp(license, "Dual BSD/GPL") == 0
+ || strcmp(license, "Dual MPL/GPL") == 0);
+}
+
+static void set_license(struct module *mod, Elf_Shdr *sechdrs, int licenseidx)
+{
+ char *license;
+
+ if (licenseidx)
+ license = (char *)sechdrs[licenseidx].sh_addr;
+ else
+ license = "unspecified";
+
+ mod->license_gplok = license_is_gpl_compatible(license);
+ if (!mod->license_gplok) {
+ printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
+ mod->name, license);
+ tainted |= TAINT_PROPRIETARY_MODULE;
+ }
+}
+
+/* Allocate and load the module: note that size of section 0 is always
+ zero, and we rely on this for optional sections. */
static struct module *load_module(void *umod,
unsigned long len,
const char *uargs)
@@ -939,7 +970,7 @@ static struct module *load_module(void *
Elf_Shdr *sechdrs;
char *secstrings, *args;
unsigned int i, symindex, exportindex, strindex, setupindex, exindex,
- modindex, obsparmindex;
+ modindex, obsparmindex, licenseindex, gplindex;
long arglen;
struct module *mod;
long err = 0;
@@ -975,7 +1006,7 @@ static struct module *load_module(void *
/* May not export symbols, or have setup params, so these may
not exist */
- exportindex = setupindex = obsparmindex = 0;
+ exportindex = setupindex = obsparmindex = gplindex = licenseindex = 0;
/* And these should exist, but gcc whinges if we don't init them */
symindex = strindex = exindex = modindex = 0;
@@ -1018,6 +1049,16 @@ static struct module *load_module(void *
/* Obsolete MODULE_PARM() table */
DEBUGP("Obsolete param found in section %u\n", i);
obsparmindex = i;
+ } else if (strcmp(secstrings+sechdrs[i].sh_name,".init.license")
+ == 0) {
+ /* MODULE_LICENSE() */
+ DEBUGP("Licence found in section %u\n", i);
+ licenseindex = i;
+ } else if (strcmp(secstrings+sechdrs[i].sh_name,
+ "__gpl_ksymtab") == 0) {
+ /* EXPORT_SYMBOL_GPL() */
+ DEBUGP("GPL symbols found in section %u\n", i);
+ gplindex = i;
}
#ifdef CONFIG_KALLSYMS
/* symbol and string tables for decoding later. */
@@ -1113,17 +1154,21 @@ static struct module *load_module(void *
/* Now we've moved module, initialize linked lists, etc. */
module_unload_init(mod);
+ /* Set up license info based on contents of section */
+ set_license(mod, sechdrs, licenseindex);
+
/* Fix up syms, so that st_value is a pointer to location. */
err = simplify_symbols(sechdrs, symindex, strindex, mod);
if (err < 0)
goto cleanup;
- /* Set up EXPORTed symbols */
- if (exportindex) {
- mod->symbols.num_syms = (sechdrs[exportindex].sh_size
- / sizeof(*mod->symbols.syms));
- mod->symbols.syms = (void *)sechdrs[exportindex].sh_addr;
- }
+ /* Set up EXPORTed & EXPORT_GPLed symbols (section 0 is 0 length) */
+ mod->symbols.num_syms = (sechdrs[exportindex].sh_size
+ / sizeof(*mod->symbols.syms));
+ mod->symbols.syms = (void *)sechdrs[exportindex].sh_addr;
+ mod->gpl_symbols.num_syms = (sechdrs[gplindex].sh_size
+ / sizeof(*mod->symbols.syms));
+ mod->gpl_symbols.syms = (void *)sechdrs[gplindex].sh_addr;
/* Set up exception table */
if (exindex) {
@@ -1228,6 +1273,7 @@ sys_init_module(void *umod,
spin_lock_irq(&modlist_lock);
list_add(&mod->extable.list, &extables);
list_add_tail(&mod->symbols.list, &symbols);
+ list_add_tail(&mod->gpl_symbols.list, &symbols);
spin_unlock_irq(&modlist_lock);
list_add(&mod->list, &modules);
diff -urNp --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5-bk/kernel/panic.c working-2.5-bk-module-license/kernel/panic.c
--- linux-2.5-bk/kernel/panic.c Thu Jan 2 12:25:16 2003
+++ working-2.5-bk-module-license/kernel/panic.c Fri Jan 3 16:32:55 2003
@@ -103,7 +103,7 @@ NORET_TYPE void panic(const char * fmt,
/**
* print_tainted - return a string to represent the kernel taint state.
*
- * 'P' - Proprietory module has been loaded.
+ * 'P' - Proprietary module has been loaded.
* 'F' - Module has been forcibly loaded.
* 'S' - SMP with CPUs not designed for SMP.
*
@@ -115,7 +115,7 @@ const char *print_tainted()
static char buf[20];
if (tainted) {
snprintf(buf, sizeof(buf), "Tainted: %c%c%c",
- tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G',
+ tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
tainted & TAINT_UNSAFE_SMP ? 'S' : ' ');
}
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] extable cleanup
@ 2003-01-03 8:07 Rusty Russell
2003-01-03 8:19 ` David S. Miller
2003-01-03 18:41 ` Linus Torvalds
0 siblings, 2 replies; 6+ messages in thread
From: Rusty Russell @ 2003-01-03 8:07 UTC (permalink / raw)
To: linux-kernel
Cc: torvalds, sfr, rth, rmk, bjornw, davidm, geert, ralf, paulus,
anton, Martin Schwidefsky, gniibe, kkojima, davem, ak
Fairly straightforward consolidation of extable handling. Sparc64 is
trickiest, with its extable range stuff (ideally, the ranges would be
in a separate __extable_range section, then the extable walking code
could be made common, too).
Only tested on x86: ppc and sparc64 written untested, others broken.
Feedback & comments welcome!
Rusty.
[ CC'd to SFR as Master Consolidator ]
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Name: extable cleanup
Author: Rusty Russell
Status: Tested on 2.5.54
Depends: Module/module-license.patch.gz
D: This patch combines the common exception table searching
D: functionality for various architectures, to avoid unneccessary (and
D: currently buggy) duplication, and so that the exception table list
D: and lock can be kept private to module.c.
D:
D: The archs provide "struct exception_table" and "search_extable":
D: the generic infrastructure drives the rest.
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/kernel/extable.c .11490-2.5-bk-extable/kernel/extable.c
--- .11490-2.5-bk-extable.pre/kernel/extable.c 2003-01-03 18:55:26.000000000 +1100
+++ .11490-2.5-bk-extable/kernel/extable.c 2003-01-03 18:55:28.000000000 +1100
@@ -16,45 +16,17 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/module.h>
-#include <linux/init.h>
-
-#include <asm/semaphore.h>
extern const struct exception_table_entry __start___ex_table[];
extern const struct exception_table_entry __stop___ex_table[];
-extern const struct kernel_symbol __start___ksymtab[];
-extern const struct kernel_symbol __stop___ksymtab[];
-extern const struct kernel_symbol __start___gpl_ksymtab[];
-extern const struct kernel_symbol __stop___gpl_ksymtab[];
-/* Protects extables and symbol tables */
-spinlock_t modlist_lock = SPIN_LOCK_UNLOCKED;
-
-/* The exception and symbol tables: start with kernel only. */
-LIST_HEAD(extables);
-LIST_HEAD(symbols);
-
-static struct exception_table kernel_extable;
-static struct kernel_symbol_group kernel_symbols;
-static struct kernel_symbol_group kernel_gpl_symbols;
-
-void __init extable_init(void)
+/* Given an address, look for it in the exception tables. */
+const struct exception_table_entry *search_exception_tables(unsigned long addr)
{
- /* Add kernel symbols to symbol table */
- kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab);
- kernel_symbols.syms = __start___ksymtab;
- kernel_symbols.gplonly = 0;
- list_add(&kernel_symbols.list, &symbols);
- kernel_gpl_symbols.num_syms = (__stop___gpl_ksymtab
- - __start___gpl_ksymtab);
- kernel_gpl_symbols.syms = __start___gpl_ksymtab;
- kernel_gpl_symbols.gplonly = 1;
- list_add(&kernel_gpl_symbols.list, &symbols);
+ const struct exception_table_entry *e;
- /* Add kernel exception table to exception tables */
- kernel_extable.num_entries = (__stop___ex_table -__start___ex_table);
- kernel_extable.entry = __start___ex_table;
- list_add(&kernel_extable.list, &extables);
+ e = search_extable(__start___ex_table, __stop___ex_table-1, addr);
+ if (!e)
+ e = search_module_extables(addr);
+ return e;
}
-
-
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/kernel/module.c .11490-2.5-bk-extable/kernel/module.c
--- .11490-2.5-bk-extable.pre/kernel/module.c 2003-01-03 18:55:26.000000000 +1100
+++ .11490-2.5-bk-extable/kernel/module.c 2003-01-03 18:55:28.000000000 +1100
@@ -51,9 +51,14 @@
#define symbol_is(literal, string) \
(strcmp(MODULE_SYMBOL_PREFIX literal, (string)) == 0)
+/* Protects extables and symbols lists */
+static spinlock_t modlist_lock = SPIN_LOCK_UNLOCKED;
+
/* List of modules, protected by module_mutex */
static DECLARE_MUTEX(module_mutex);
-LIST_HEAD(modules); /* FIXME: Accessed w/o lock on oops by some archs */
+LIST_HEAD(modules); /* FIXME: Accessed w/o lock on oops by some archs */
+static LIST_HEAD(symbols);
+static LIST_HEAD(extables);
/* We require a truly strong try_module_get() */
static inline int strong_try_module_get(struct module *mod)
@@ -1425,6 +1430,55 @@ struct seq_operations modules_op = {
.show = m_show
};
+/* Given an address, look for it in the module exception tables. */
+const struct exception_table_entry *search_module_extables(unsigned long addr)
+{
+ unsigned long flags;
+ const struct exception_table_entry *e = NULL;
+ struct exception_table *i;
+
+ spin_lock_irqsave(&modlist_lock, flags);
+ list_for_each_entry(i, &extables, list) {
+ if (i->num_entries == 0)
+ continue;
+
+ e = search_extable(i->entry, i->entry+i->num_entries-1, addr);
+ if (e)
+ break;
+ }
+ spin_unlock_irqrestore(&modlist_lock, flags);
+
+ /* Now, if we found one, we are running inside it now, hence
+ we cannot unload the module, hence no refcnt needed. */
+ return e;
+}
+
+/* Provided by the linker */
+extern const struct kernel_symbol __start___ksymtab[];
+extern const struct kernel_symbol __stop___ksymtab[];
+extern const struct kernel_symbol __start___gpl_ksymtab[];
+extern const struct kernel_symbol __stop___gpl_ksymtab[];
+
+static struct kernel_symbol_group kernel_symbols, kernel_gpl_symbols;
+
+static int __init symbols_init(void)
+{
+ /* Add kernel symbols to symbol table */
+ kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab);
+ kernel_symbols.syms = __start___ksymtab;
+ kernel_symbols.gplonly = 0;
+ list_add(&kernel_symbols.list, &symbols);
+ kernel_gpl_symbols.num_syms = (__stop___gpl_ksymtab
+ - __start___gpl_ksymtab);
+ kernel_gpl_symbols.syms = __start___gpl_ksymtab;
+ kernel_gpl_symbols.gplonly = 1;
+ list_add(&kernel_gpl_symbols.list, &symbols);
+
+ return 0;
+}
+
+__initcall(symbols_init);
+
/* Obsolete lvalue for broken code which asks about usage */
int module_dummy_usage = 1;
EXPORT_SYMBOL(module_dummy_usage);
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/include/linux/module.h .11490-2.5-bk-extable/include/linux/module.h
--- .11490-2.5-bk-extable.pre/include/linux/module.h 2003-01-03 18:55:26.000000000 +1100
+++ .11490-2.5-bk-extable/include/linux/module.h 2003-01-03 18:55:28.000000000 +1100
@@ -43,6 +43,12 @@ struct kernel_symbol
extern int init_module(void);
extern void cleanup_module(void);
+/* Archs provide a method of finding the correct exception table. */
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value);
+
#ifdef MODULE
/* For replacement modutils, use an alias not a pointer. */
@@ -111,6 +117,9 @@ struct kernel_symbol_group
const struct kernel_symbol *syms;
};
+/* Given an address, look for it in the exception tables */
+const struct exception_table_entry *search_exception_tables(unsigned long add);
+
struct exception_table
{
struct list_head list;
@@ -300,11 +309,21 @@ const char *module_address_lookup(unsign
unsigned long *offset,
char **modname);
+/* For extable.c to search modules' exception tables. */
+const struct exception_table_entry *search_module_extables(unsigned long addr);
+
#else /* !CONFIG_MODULES... */
#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym)
#define EXPORT_SYMBOL_NOVERS(sym)
+/* Given an address, look for it in the exception tables. */
+static inline const struct exception_table_entry *
+search_module_extables(unsigned long addr)
+{
+ return NULL;
+}
+
/* Get/put a kernel symbol (calls should be symmetric) */
#define symbol_get(x) (&(x))
#define symbol_put(x) do { } while(0)
@@ -344,10 +363,6 @@ __attribute__((section(".gnu.linkonce.th
#endif /* KBUILD_MODNAME */
#endif /* MODULE */
-/* For archs to search exception tables */
-extern struct list_head extables;
-extern spinlock_t modlist_lock;
-
#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
/* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/i386/kernel/traps.c .11490-2.5-bk-extable/arch/i386/kernel/traps.c
--- .11490-2.5-bk-extable.pre/arch/i386/kernel/traps.c 2003-01-02 14:47:57.000000000 +1100
+++ .11490-2.5-bk-extable/arch/i386/kernel/traps.c 2003-01-03 18:55:27.000000000 +1100
@@ -338,7 +338,7 @@ static inline void do_trap(int trapnr, i
}
kernel_trap: {
- unsigned long fixup;
+ const struct exception_table_entry *fixup;
#ifdef CONFIG_PNPBIOS
if (unlikely((regs->xcs | 8) == 0x88)) /* 0x80 or 0x88 */
{
@@ -354,9 +354,9 @@ static inline void do_trap(int trapnr, i
}
#endif
- fixup = search_exception_table(regs->eip);
+ fixup = search_exception_tables(regs->eip);
if (fixup)
- regs->eip = fixup;
+ regs->eip = fixup->fixup;
else
die(str, regs, error_code);
return;
@@ -435,10 +435,10 @@ gp_in_vm86:
gp_in_kernel:
{
- unsigned long fixup;
- fixup = search_exception_table(regs->eip);
+ const struct exception_table_entry *fixup;
+ fixup = search_exception_tables(regs->eip);
if (fixup) {
- regs->eip = fixup;
+ regs->eip = fixup->fixup;
return;
}
die("general protection fault", regs, error_code);
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/i386/mm/extable.c .11490-2.5-bk-extable/arch/i386/mm/extable.c
--- .11490-2.5-bk-extable.pre/arch/i386/mm/extable.c 2003-01-02 12:35:07.000000000 +1100
+++ .11490-2.5-bk-extable/arch/i386/mm/extable.c 2003-01-03 18:55:27.000000000 +1100
@@ -7,13 +7,11 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
-extern const struct exception_table_entry __start___ex_table[];
-extern const struct exception_table_entry __stop___ex_table[];
-
-static inline unsigned long
-search_one_table(const struct exception_table_entry *first,
- const struct exception_table_entry *last,
- unsigned long value)
+/* Simple binary search */
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value)
{
while (first <= last) {
const struct exception_table_entry *mid;
@@ -22,43 +20,11 @@ search_one_table(const struct exception_
mid = (last - first) / 2 + first;
diff = mid->insn - value;
if (diff == 0)
- return mid->fixup;
+ return mid;
else if (diff < 0)
first = mid+1;
else
last = mid-1;
}
- return 0;
-}
-
-extern spinlock_t modlist_lock;
-
-unsigned long
-search_exception_table(unsigned long addr)
-{
- unsigned long ret = 0;
-
-#ifndef CONFIG_MODULES
- /* There is only the kernel to search. */
- ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
- return ret;
-#else
- unsigned long flags;
- struct list_head *i;
-
- /* The kernel is the last "module" -- no need to treat it special. */
- spin_lock_irqsave(&modlist_lock, flags);
- list_for_each(i, &extables) {
- struct exception_table *ex
- = list_entry(i, struct exception_table, list);
- if (ex->num_entries == 0)
- continue;
- ret = search_one_table(ex->entry,
- ex->entry + ex->num_entries - 1, addr);
- if (ret)
- break;
- }
- spin_unlock_irqrestore(&modlist_lock, flags);
- return ret;
-#endif
+ return NULL;
}
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/i386/mm/fault.c .11490-2.5-bk-extable/arch/i386/mm/fault.c
--- .11490-2.5-bk-extable.pre/arch/i386/mm/fault.c 2003-01-02 12:46:12.000000000 +1100
+++ .11490-2.5-bk-extable/arch/i386/mm/fault.c 2003-01-03 18:55:27.000000000 +1100
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
+#include <linux/module.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -154,7 +155,7 @@ asmlinkage void do_page_fault(struct pt_
struct vm_area_struct * vma;
unsigned long address;
unsigned long page;
- unsigned long fixup;
+ const struct exception_table_entry *fixup;
int write;
siginfo_t info;
@@ -310,8 +311,8 @@ bad_area:
no_context:
/* Are we prepared to handle this kernel fault? */
- if ((fixup = search_exception_table(regs->eip)) != 0) {
- regs->eip = fixup;
+ if ((fixup = search_exception_tables(regs->eip)) != NULL) {
+ regs->eip = fixup->fixup;
return;
}
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/ppc/kernel/traps.c .11490-2.5-bk-extable/arch/ppc/kernel/traps.c
--- .11490-2.5-bk-extable.pre/arch/ppc/kernel/traps.c 2003-01-02 12:27:43.000000000 +1100
+++ .11490-2.5-bk-extable/arch/ppc/kernel/traps.c 2003-01-03 18:55:27.000000000 +1100
@@ -29,6 +29,7 @@
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -115,7 +116,7 @@ void
MachineCheckException(struct pt_regs *regs)
{
#ifdef CONFIG_ALL_PPC
- unsigned long fixup;
+ const struct exception_table_entry *entry;
#endif /* CONFIG_ALL_PPC */
unsigned long msr = regs->msr;
@@ -148,7 +149,7 @@ MachineCheckException(struct pt_regs *re
* -- paulus.
*/
if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000)))
- && (fixup = search_exception_table(regs->nip)) != 0) {
+ && (entry = search_exception_tables(regs->nip)) != NULL) {
/*
* Check that it's a sync instruction, or somewhere
* in the twi; isync; nop sequence that inb/inw/inl uses.
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/ppc/mm/extable.c .11490-2.5-bk-extable/arch/ppc/mm/extable.c
--- .11490-2.5-bk-extable.pre/arch/ppc/mm/extable.c 2003-01-02 12:35:59.000000000 +1100
+++ .11490-2.5-bk-extable/arch/ppc/mm/extable.c 2003-01-03 18:55:27.000000000 +1100
@@ -6,6 +6,7 @@
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
extern struct exception_table_entry __start___ex_table[];
@@ -40,16 +41,17 @@ sort_ex_table(struct exception_table_ent
}
}
-void
+void __init
sort_exception_table(void)
{
sort_ex_table(__start___ex_table, __stop___ex_table);
}
-static inline unsigned long
-search_one_table(const struct exception_table_entry *first,
- const struct exception_table_entry *last,
- unsigned long value)
+/* Simple binary search */
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value)
{
while (first <= last) {
const struct exception_table_entry *mid;
@@ -58,41 +60,11 @@ search_one_table(const struct exception_
mid = (last - first) / 2 + first;
diff = mid->insn - value;
if (diff == 0)
- return mid->fixup;
+ return mid;
else if (diff < 0)
first = mid+1;
else
last = mid-1;
}
- return 0;
-}
-
-unsigned long
-search_exception_table(unsigned long addr)
-{
- unsigned long ret = 0;
-
-#ifndef CONFIG_MODULES
- /* There is only the kernel to search. */
- ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-#else
- unsigned long flags;
- struct list_head *i;
-
- /* The kernel is the last "module" -- no need to treat it special. */
- spin_lock_irqsave(&modlist_lock, flags);
- list_for_each(i, &extables) {
- struct exception_table *ex
- = list_entry(i, struct exception_table, list);
- if (ex->num_entries == 0)
- continue;
- ret = search_one_table(ex->entry,
- ex->entry + ex->num_entries - 1, addr);
- if (ret)
- break;
- }
- spin_unlock_irqrestore(&modlist_lock, flags);
-#endif
-
- return ret;
+ return NULL;
}
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/ppc/mm/fault.c .11490-2.5-bk-extable/arch/ppc/mm/fault.c
--- .11490-2.5-bk-extable.pre/arch/ppc/mm/fault.c 2003-01-02 12:27:43.000000000 +1100
+++ .11490-2.5-bk-extable/arch/ppc/mm/fault.c 2003-01-03 18:55:27.000000000 +1100
@@ -27,6 +27,7 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
+#include <linux/module.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -263,12 +264,11 @@ void
bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
{
extern void die(const char *,struct pt_regs *,long);
-
- unsigned long fixup;
+ const struct exception_table_entry *entry;
/* Are we prepared to handle this fault? */
- if ((fixup = search_exception_table(regs->nip)) != 0) {
- regs->nip = fixup;
+ if ((entry = search_exception_tables(regs->nip)) != NULL) {
+ regs->nip = entry->fixup;
return;
}
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/sparc64/kernel/traps.c .11490-2.5-bk-extable/arch/sparc64/kernel/traps.c
--- .11490-2.5-bk-extable.pre/arch/sparc64/kernel/traps.c 2003-01-02 12:34:03.000000000 +1100
+++ .11490-2.5-bk-extable/arch/sparc64/kernel/traps.c 2003-01-03 18:55:27.000000000 +1100
@@ -149,17 +149,17 @@ void data_access_exception (struct pt_re
if (regs->tstate & TSTATE_PRIV) {
/* Test if this comes from uaccess places. */
- unsigned long fixup, g2;
+ const struct exception_table_entry *entry;
+ unsigned long g2 = regs->u_regs[UREG_G2];
- g2 = regs->u_regs[UREG_G2];
- if ((fixup = search_exception_table (regs->tpc, &g2))) {
+ if ((entry = search_extables_range(regs->tpc, &g2))) {
/* Ouch, somebody is trying ugly VM hole tricks on us... */
#ifdef DEBUG_EXCEPTIONS
printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc);
printk("EX_TABLE: insn<%016lx> fixup<%016lx> "
- "g2<%016lx>\n", regs->tpc, fixup, g2);
+ "g2<%016lx>\n", regs->tpc, entry->fixup, g2);
#endif
- regs->tpc = fixup;
+ regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
regs->u_regs[UREG_G2] = g2;
return;
@@ -1370,7 +1370,7 @@ void cheetah_deferred_handler(struct pt_
recoverable = 1;
} else {
unsigned long g2 = regs->u_regs[UREG_G2];
- unsigned long fixup = search_exception_table(regs->tpc, &g2);
+ unsigned long fixup = search_extables_range(regs->tpc, &g2);
if (fixup != 0UL) {
/* OK, kernel access to userspace. */
@@ -1390,8 +1390,8 @@ void cheetah_deferred_handler(struct pt_
/* Only perform fixup if we still have a
* recoverable condition.
*/
- if (fixup != 0UL && recoverable) {
- regs->tpc = fixup;
+ if (entry && recoverable) {
+ regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
regs->u_regs[UREG_G2] = g2;
}
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/sparc64/kernel/unaligned.c .11490-2.5-bk-extable/arch/sparc64/kernel/unaligned.c
--- .11490-2.5-bk-extable.pre/arch/sparc64/kernel/unaligned.c 2003-01-02 12:30:39.000000000 +1100
+++ .11490-2.5-bk-extable/arch/sparc64/kernel/unaligned.c 2003-01-03 18:55:27.000000000 +1100
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/module.h>
#include <asm/asi.h>
#include <asm/ptrace.h>
#include <asm/pstate.h>
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/sparc64/mm/extable.c .11490-2.5-bk-extable/arch/sparc64/mm/extable.c
--- .11490-2.5-bk-extable.pre/arch/sparc64/mm/extable.c 2003-01-02 12:35:08.000000000 +1100
+++ .11490-2.5-bk-extable/arch/sparc64/mm/extable.c 2003-01-03 18:55:27.000000000 +1100
@@ -9,10 +9,11 @@
extern const struct exception_table_entry __start___ex_table[];
extern const struct exception_table_entry __stop___ex_table[];
-static unsigned long
-search_one_table(const struct exception_table_entry *start,
- const struct exception_table_entry *end,
- unsigned long value, unsigned long *g2)
+/* Caller knows they are in a range if ret->fixup == 0 */
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *start,
+ const struct exception_table_entry *last,
+ unsigned long value)
{
const struct exception_table_entry *walk;
@@ -38,7 +39,7 @@ search_one_table(const struct exception_
}
if (walk->insn == value)
- return walk->fixup;
+ return walk;
}
/* 2. Try to find a range match. */
@@ -46,47 +47,29 @@ search_one_table(const struct exception_
if (walk->fixup)
continue;
- if (walk[0].insn <= value &&
- walk[1].insn > value) {
- *g2 = (value - walk[0].insn) / 4;
- return walk[1].fixup;
- }
+ if (walk[0].insn <= value && walk[1].insn > value)
+ return walk;
+
walk++;
}
- return 0;
+ return NULL;
}
-extern spinlock_t modlist_lock;
-
-unsigned long
-search_exception_table(unsigned long addr, unsigned long *g2)
+/* Special extable search, which handles ranges. Returns fixup */
+unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
{
- unsigned long ret = 0;
+ const struct exception_table_entry *entry;
-#ifndef CONFIG_MODULES
- /* There is only the kernel to search. */
- ret = search_one_table(__start___ex_table,
- __stop___ex_table-1, addr, g2);
- return ret;
-#else
- unsigned long flags;
- struct list_head *i;
+ entry = search_exception_tables(addr);
+ if (!entry)
+ return 0;
- /* The kernel is the last "module" -- no need to treat it special. */
- spin_lock_irqsave(&modlist_lock, flags);
- list_for_each(i, &extables) {
- struct exception_table *ex =
- list_entry(i, struct exception_table, list);
- if (ex->num_entries == 0)
- continue;
- ret = search_one_table(ex->entry,
- ex->entry + ex->num_entries - 1,
- addr, g2);
- if (ret)
- break;
+ /* Inside range? Fix g2 and return correct fixup */
+ if (!entry->fixup) {
+ *g2 = (addr - entry->insn) / 4;
+ return (entry + 1)->fixup;
}
- spin_unlock_irqrestore(&modlist_lock, flags);
- return ret;
-#endif
+
+ return entry->fixup;
}
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/arch/sparc64/mm/fault.c .11490-2.5-bk-extable/arch/sparc64/mm/fault.c
--- .11490-2.5-bk-extable.pre/arch/sparc64/mm/fault.c 2003-01-02 12:30:39.000000000 +1100
+++ .11490-2.5-bk-extable/arch/sparc64/mm/fault.c 2003-01-03 18:55:27.000000000 +1100
@@ -14,6 +14,7 @@
#include <linux/mman.h>
#include <linux/signal.h>
#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -285,7 +286,7 @@ static void do_kernel_fault(struct pt_re
/* Look in asi.h: All _S asis have LS bit set */
if ((asi & 0x1) &&
- (fixup = search_exception_table (regs->tpc, &g2))) {
+ (fizup = search_extables_range(regs->tpc, &g2))) {
regs->tpc = fixup;
regs->tnpc = regs->tpc + 4;
regs->u_regs[UREG_G2] = g2;
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/include/asm-i386/uaccess.h .11490-2.5-bk-extable/include/asm-i386/uaccess.h
--- .11490-2.5-bk-extable.pre/include/asm-i386/uaccess.h 2003-01-02 14:48:00.000000000 +1100
+++ .11490-2.5-bk-extable/include/asm-i386/uaccess.h 2003-01-03 18:55:27.000000000 +1100
@@ -92,10 +92,6 @@ struct exception_table_entry
unsigned long insn, fixup;
};
-/* Returns 0 if exception not found and fixup otherwise. */
-extern unsigned long search_exception_table(unsigned long);
-
-
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/include/asm-ppc/uaccess.h .11490-2.5-bk-extable/include/asm-ppc/uaccess.h
--- .11490-2.5-bk-extable.pre/include/asm-ppc/uaccess.h 2003-01-02 12:27:50.000000000 +1100
+++ .11490-2.5-bk-extable/include/asm-ppc/uaccess.h 2003-01-03 18:55:27.000000000 +1100
@@ -56,8 +56,6 @@ struct exception_table_entry
unsigned long insn, fixup;
};
-/* Returns 0 if exception not found and fixup otherwise. */
-extern unsigned long search_exception_table(unsigned long);
extern void sort_exception_table(void);
/*
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/include/asm-sparc64/uaccess.h .11490-2.5-bk-extable/include/asm-sparc64/uaccess.h
--- .11490-2.5-bk-extable.pre/include/asm-sparc64/uaccess.h 2003-01-02 12:29:33.000000000 +1100
+++ .11490-2.5-bk-extable/include/asm-sparc64/uaccess.h 2003-01-03 18:55:27.000000000 +1100
@@ -84,8 +84,8 @@ struct exception_table_entry
unsigned insn, fixup;
};
-/* Returns 0 if exception not found and fixup otherwise. */
-extern unsigned long search_exception_table(unsigned long, unsigned long *);
+/* Special exable search, which handles ranges. Returns fixup */
+unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
extern void __ret_efault(void);
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11490-2.5-bk-extable.pre/init/main.c .11490-2.5-bk-extable/init/main.c
--- .11490-2.5-bk-extable.pre/init/main.c 2003-01-02 14:48:01.000000000 +1100
+++ .11490-2.5-bk-extable/init/main.c 2003-01-03 18:55:28.000000000 +1100
@@ -61,7 +61,6 @@ extern void init_IRQ(void);
extern void init_modules(void);
extern void sock_init(void);
extern void fork_init(unsigned long);
-extern void extable_init(void);
extern void mca_init(void);
extern void sbus_init(void);
extern void sysctl_init(void);
@@ -391,7 +390,6 @@ asmlinkage void __init start_kernel(void
&__stop___param - &__start___param,
&unknown_bootoption);
trap_init();
- extable_init();
rcu_init();
init_IRQ();
sched_init();
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] extable cleanup
2003-01-03 8:07 Rusty Russell
@ 2003-01-03 8:19 ` David S. Miller
2003-01-03 18:41 ` Linus Torvalds
1 sibling, 0 replies; 6+ messages in thread
From: David S. Miller @ 2003-01-03 8:19 UTC (permalink / raw)
To: rusty
Cc: linux-kernel, torvalds, sfr, rth, rmk, bjornw, davidm, geert,
ralf, paulus, anton, schwidefsky, gniibe, kkojima, ak
From: Rusty Russell <rusty@rustcorp.com.au>
Date: Fri, 03 Jan 2003 19:07:28 +1100
Fairly straightforward consolidation of extable handling. Sparc64 is
trickiest, with its extable range stuff (ideally, the ranges would be
in a separate __extable_range section, then the extable walking code
could be made common, too).
I'm fine with this.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] extable cleanup
2003-01-03 8:07 Rusty Russell
2003-01-03 8:19 ` David S. Miller
@ 2003-01-03 18:41 ` Linus Torvalds
2003-01-04 5:33 ` Rusty Russell
1 sibling, 1 reply; 6+ messages in thread
From: Linus Torvalds @ 2003-01-03 18:41 UTC (permalink / raw)
To: Rusty Russell
Cc: linux-kernel, sfr, rth, rmk, bjornw, davidm, geert, ralf, paulus,
anton, Martin Schwidefsky, gniibe, kkojima, David S. Miller, ak
On Fri, 3 Jan 2003, Rusty Russell wrote:
>
> Fairly straightforward consolidation of extable handling. Sparc64 is
> trickiest, with its extable range stuff (ideally, the ranges would be
> in a separate __extable_range section, then the extable walking code
> could be made common, too).
>
> Only tested on x86: ppc and sparc64 written untested, others broken.
Did you test on a true i386, which needs exception handling very early on
to handle the test for broken WP? In other words, are all the exception
table data structures properly initialized?
And did you check that an oops in the init handling works correctly before
the kallsyms table has been initialized? That "initcall(symbol_init)"
makes me suspect it won't..
There was a reason why "extable_init()" was in init/main.c, and was done
_early_.
Linus
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] extable cleanup
2003-01-03 18:41 ` Linus Torvalds
@ 2003-01-04 5:33 ` Rusty Russell
0 siblings, 0 replies; 6+ messages in thread
From: Rusty Russell @ 2003-01-04 5:33 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, sfr, rth, rmk, bjornw, davidm, geert, ralf, paulus,
anton, Martin Schwidefsky, gniibe, kkojima, David S. Miller, ak
In message <Pine.LNX.4.44.0301031036560.2750-100000@home.transmeta.com> you wri
te:
>
> On Fri, 3 Jan 2003, Rusty Russell wrote:
> >
> > Fairly straightforward consolidation of extable handling. Sparc64 is
> > trickiest, with its extable range stuff (ideally, the ranges would be
> > in a separate __extable_range section, then the extable walking code
> > could be made common, too).
> >
> > Only tested on x86: ppc and sparc64 written untested, others broken.
>
> Did you test on a true i386, which needs exception handling very early on
> to handle the test for broken WP? In other words, are all the exception
> table data structures properly initialized?
That's not a problem: the exception table search code looks like:
/* Given an address, look for it in the exception tables. */
const struct exception_table_entry *search_exception_tables(unsigned long addr)
{
const struct exception_table_entry *e;
e = search_extable(__start___ex_table, __stop___ex_table-1, addr);
if (!e)
e = search_module_extables(addr);
return e;
}
search_extable is arch specific, and requires no setup on any arch.
The list containing the modules is initialized using the LIST_HEAD, so
is empty, so search_module_extables is a noop.
> And did you check that an oops in the init handling works correctly before
> the kallsyms table has been initialized? That "initcall(symbol_init)"
> makes me suspect it won't..
Once again, no initialization required. "symbol_init" initializes the
EXPORT'ed symbol tables for module loading: kallsyms doesn't need
initialization.
> There was a reason why "extable_init()" was in init/main.c, and was done
> _early_.
Yes, because archs iterated through the extable list to find even core
kernel exception tables. The patch changes that: the lookup for core
kernel is done first, then the module code looks through a linked
list, meaning you don't need an extable list for !CONFIG_MODULES, etc.
Hope that clarifies,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2003-01-04 5:56 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-01-03 22:06 [PATCH] extable cleanup Manfred Spraul
2003-01-04 6:03 ` Rusty Russell
-- strict thread matches above, loose matches on Subject: below --
2003-01-03 8:07 Rusty Russell
2003-01-03 8:19 ` David S. Miller
2003-01-03 18:41 ` Linus Torvalds
2003-01-04 5:33 ` Rusty Russell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox