lkml.org 
[lkml]   [2002]   [Nov]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] Fix sparc64 alloc problem.
Date
Dave beat it into my head that sparc64 really needs the struct module
in the low 32-bits of the kernel (it's turned into the symbol
__this_module when linking), so tweak the arch interface slightly so
they provide a "module_alloc" routine.

Compiles on x86, compiles and works on ppc32. On top of
moduleloader.h patch.

Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

Name: Allocate struct module using special allocator
Author: Rusty Russell
Status: Experimental
Depends: Module/moduleloader_h.patch.gz

D: Sparc64 (and probably others) need all the kernel symbols within
D: 32-bits, which includes the manufactured "__this_module" which refers
D: to the struct module *.
D:
D: This changes the interface back to its old style: the arch-specific code
D: manipulates the init and core sizes, and we call module_alloc() ourselves.

diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5-bk-moduleloader_h/arch/i386/kernel/module.c working-2.5-bk-sparcfixes/arch/i386/kernel/module.c
--- working-2.5-bk-moduleloader_h/arch/i386/kernel/module.c 2002-11-14 20:47:30.000000000 +1100
+++ working-2.5-bk-sparcfixes/arch/i386/kernel/module.c 2002-11-14 20:47:50.000000000 +1100
@@ -28,22 +28,15 @@
#define DEBUGP(fmt , ...)
#endif

-static void *alloc_and_zero(unsigned long size)
+void *module_alloc(unsigned long size)
{
- void *ret;
-
- /* We handle the zero case fine, unlike vmalloc */
if (size == 0)
return NULL;
-
- ret = vmalloc(size);
- if (!ret) ret = ERR_PTR(-ENOMEM);
- else memset(ret, 0, size);
-
- return ret;
+ return vmalloc(size);
}

-/* Free memory returned from module_core_alloc/module_init_alloc */
+
+/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
@@ -51,20 +44,21 @@ void module_free(struct module *mod, voi
table entries. */
}

-void *module_core_alloc(const Elf32_Ehdr *hdr,
- const Elf32_Shdr *sechdrs,
- const char *secstrings,
- struct module *module)
+/* We don't need anything special. */
+long module_core_size(const Elf32_Ehdr *hdr,
+ const Elf32_Shdr *sechdrs,
+ const char *secstrings,
+ struct module *module)
{
- return alloc_and_zero(module->core_size);
+ return module->core_size;
}

-void *module_init_alloc(const Elf32_Ehdr *hdr,
- const Elf32_Shdr *sechdrs,
- const char *secstrings,
- struct module *module)
+long module_init_size(const Elf32_Ehdr *hdr,
+ const Elf32_Shdr *sechdrs,
+ const char *secstrings,
+ struct module *module)
{
- return alloc_and_zero(module->init_size);
+ return module->init_size;
}

int apply_relocate(Elf32_Shdr *sechdrs,
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5-bk-moduleloader_h/include/linux/moduleloader.h working-2.5-bk-sparcfixes/include/linux/moduleloader.h
--- working-2.5-bk-moduleloader_h/include/linux/moduleloader.h 2002-11-14 20:47:30.000000000 +1100
+++ working-2.5-bk-sparcfixes/include/linux/moduleloader.h 2002-11-14 20:47:50.000000000 +1100
@@ -15,20 +15,26 @@ unsigned long find_symbol_internal(Elf_S

/* These must be implemented by the specific architecture */

-/* vmalloc AND zero for the non-releasable code; return ERR_PTR() on error. */
-void *module_core_alloc(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs,
- const char *secstrings,
- struct module *mod);
+/* Total size to allocate for the non-releasable code; return len or
+ -error. mod->core_size is the current generic tally. */
+long module_core_size(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ const char *secstrings,
+ struct module *mod);

-/* vmalloc and zero (if any) for sections to be freed after init.
- Return ERR_PTR() on error. */
-void *module_init_alloc(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs,
- const char *secstrings,
- struct module *mod);
+/* Total size of (if any) sections to be freed after init. Return 0
+ for none, len, or -error. mod->init_size is the current generic
+ tally. */
+long module_init_size(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ const char *secstrings,
+ struct module *mod);

-/* Free memory returned from module_core_alloc/module_init_alloc */
+/* Allocator used for allocating struct module, core sections and init
+ sections. Returns NULL on failure. */
+void *module_alloc(unsigned long size);
+
+/* Free memory returned from module_alloc. */
void module_free(struct module *mod, void *module_region);

/* Apply the given relocation to the (simplified) ELF. Return -error
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5-bk-moduleloader_h/kernel/module.c working-2.5-bk-sparcfixes/kernel/module.c
--- working-2.5-bk-moduleloader_h/kernel/module.c 2002-11-14 20:47:30.000000000 +1100
+++ working-2.5-bk-sparcfixes/kernel/module.c 2002-11-14 20:47:50.000000000 +1100
@@ -557,7 +557,7 @@ static void free_module(struct module *m
module_unload_free(mod);

/* Finally, free the module structure */
- kfree(mod);
+ module_free(mod, mod);
}

void *__symbol_get(const char *symbol)
@@ -805,7 +805,7 @@ static struct module *load_module(void *
unsigned long common_length;
struct sizes sizes, used;
struct module *mod;
- int err = 0;
+ long err = 0;
void *ptr = NULL; /* Stops spurious gcc uninitialized warning */

DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -894,7 +894,7 @@ static struct module *load_module(void *
goto free_hdr;
arglen = err;

- mod = kmalloc(sizeof(*mod) + arglen+1, GFP_KERNEL);
+ mod = module_alloc(sizeof(*mod) + arglen+1);
if (!mod) {
err = -ENOMEM;
goto free_hdr;
@@ -925,20 +925,36 @@ static struct module *load_module(void *
common_length = read_commons(hdr, &sechdrs[symindex]);
sizes.core_size += common_length;

- /* Set these up: arch's can add to them */
+ /* Set these up, and allow archs to manipulate them. */
mod->core_size = sizes.core_size;
mod->init_size = sizes.init_size;

- /* Allocate (this is arch specific) */
- ptr = module_core_alloc(hdr, sechdrs, secstrings, mod);
- if (IS_ERR(ptr))
+ /* Allow archs to add to them. */
+ err = module_init_size(hdr, sechdrs, secstrings, mod);
+ if (err < 0)
+ goto free_mod;
+ mod->init_size = err;
+
+ err = module_core_size(hdr, sechdrs, secstrings, mod);
+ if (err < 0)
goto free_mod;
+ mod->core_size = err;

+ /* Do the allocs. */
+ ptr = module_alloc(mod->core_size);
+ if (!ptr) {
+ err = -ENOMEM;
+ goto free_mod;
+ }
+ memset(ptr, 0, mod->core_size);
mod->module_core = ptr;

- ptr = module_init_alloc(hdr, sechdrs, secstrings, mod);
- if (IS_ERR(ptr))
+ ptr = module_alloc(mod->init_size);
+ if (!ptr) {
+ err = -ENOMEM;
goto free_core;
+ }
+ memset(ptr, 0, mod->init_size);
mod->module_init = ptr;

/* Transfer each section which requires ALLOC, and set sh_offset
@@ -1015,7 +1031,7 @@ static struct module *load_module(void *
free_core:
module_free(mod, mod->module_core);
free_mod:
- kfree(mod);
+ module_free(mod, mod);
free_hdr:
vfree(hdr);
if (err < 0) return ERR_PTR(err);


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:31    [W:0.020 / U:0.328 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site