Commit ea7b8e05 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo

Merge

parents 272436d9 c2ef76af
......@@ -90,7 +90,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
me->name, strtab + sym->st_name);
return -ENOENT;
}
v += rel->r_addend;
v += rel[i].r_addend;
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_SPARC_32:
......@@ -126,7 +126,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
me->name,
(int) (ELF32_R_TYPE(rel[i].r_info) & 0xff));
return -ENOEXEC;
}
};
}
return 0;
}
......
......@@ -10,6 +10,113 @@
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
static struct vm_struct * modvmlist = NULL;
static void module_unmap(void * addr)
{
struct vm_struct **p, *tmp;
int i;
if (!addr)
return;
if ((PAGE_SIZE-1) & (unsigned long) addr) {
printk("Trying to unmap module with bad address (%p)\n", addr);
return;
}
for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) {
if (tmp->addr == addr) {
*p = tmp->next;
goto found;
}
}
printk("Trying to unmap nonexistent module vm area (%p)\n", addr);
return;
found:
unmap_vm_area(tmp);
for (i = 0; i < tmp->nr_pages; i++) {
if (unlikely(!tmp->pages[i]))
BUG();
__free_page(tmp->pages[i]);
}
kfree(tmp->pages);
kfree(tmp);
}
static void *module_map(unsigned long size)
{
struct vm_struct **p, *tmp, *area;
struct page **pages;
void * addr;
unsigned int nr_pages, array_size, i;
size = PAGE_ALIGN(size);
if (!size || size > MODULES_LEN)
return NULL;
addr = (void *) MODULES_VADDR;
for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) {
if (size + (unsigned long) addr < (unsigned long) tmp->addr)
break;
addr = (void *) (tmp->size + (unsigned long) tmp->addr);
}
if ((unsigned long) addr + size >= MODULES_END)
return NULL;
area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
if (!area)
return NULL;
area->size = size + PAGE_SIZE;
area->addr = addr;
area->next = *p;
area->pages = NULL;
area->nr_pages = 0;
area->phys_addr = 0;
*p = area;
nr_pages = size >> PAGE_SHIFT;
array_size = (nr_pages * sizeof(struct page *));
area->nr_pages = nr_pages;
area->pages = pages = kmalloc(array_size, GFP_KERNEL);
if (!area->pages)
goto fail;
memset(area->pages, 0, array_size);
for (i = 0; i < area->nr_pages; i++) {
area->pages[i] = alloc_page(GFP_KERNEL);
if (unlikely(!area->pages[i]))
goto fail;
}
if (map_vm_area(area, PAGE_KERNEL, &pages)) {
unmap_vm_area(area);
goto fail;
}
return area->addr;
fail:
if (area->pages) {
for (i = 0; i < area->nr_pages; i++) {
if (area->pages[i])
__free_page(area->pages[i]);
}
kfree(area->pages);
}
kfree(area);
return NULL;
}
static void *alloc_and_zero(unsigned long size)
{
......@@ -19,7 +126,7 @@ static void *alloc_and_zero(unsigned long size)
if (size == 0)
return NULL;
ret = vmalloc(size);
ret = module_map(size);
if (!ret)
ret = ERR_PTR(-ENOMEM);
else
......@@ -31,7 +138,7 @@ static void *alloc_and_zero(unsigned long size)
/* Free memory returned from module_core_alloc/module_init_alloc */
void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
module_unmap(module_region);
/* FIXME: If module_region == mod->init_region, trim exception
table entries. */
}
......@@ -82,6 +189,9 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
location = (u8 *)sechdrs[sechdrs[relsec].sh_info].sh_offset
+ rel[i].r_offset;
loc32 = (u32 *) location;
BUG_ON(((u64)location >> (u64)32) != (u64)0);
/* This is the symbol it is referring to */
sym = (Elf64_Sym *)sechdrs[symindex].sh_offset
+ ELF64_R_SYM(rel[i].r_info);
......@@ -90,7 +200,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
me->name, strtab + sym->st_name);
return -ENOENT;
}
v += rel->r_addend;
v += rel[i].r_addend;
switch (ELF64_R_TYPE(rel[i].r_info) & 0xff) {
case R_SPARC_64:
......@@ -137,7 +247,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
me->name,
(int) (ELF64_R_TYPE(rel[i].r_info) & 0xff));
return -ENOEXEC;
}
};
}
return 0;
}
......
......@@ -3113,24 +3113,18 @@ asmlinkage int sparc32_execve(struct pt_regs *regs)
#ifdef CONFIG_MODULES
extern asmlinkage long sys_init_module(const char *name_user,
struct module *mod_user);
extern asmlinkage long sys_init_module(void *, unsigned long, const char *);
/* Hey, when you're trying to init module, take time and prepare us a nice
* 64bit module structure, even if from 32bit modutils... Why to pollute
* kernel... :))
*/
asmlinkage int sys32_init_module(const char *name_user,
struct module *mod_user)
asmlinkage int sys32_init_module(void *umod, u32 len, const char *uargs)
{
return sys_init_module(name_user, mod_user);
return sys_init_module(umod, len, uargs);
}
extern asmlinkage long sys_delete_module(const char *name_user);
extern asmlinkage long sys_delete_module(const char *, unsigned int);
asmlinkage int sys32_delete_module(const char *name_user)
asmlinkage int sys32_delete_module(const char *name_user, unsigned int flags)
{
return sys_delete_module(name_user);
return sys_delete_module(name_user, flags);
}
#else /* CONFIG_MODULES */
......
......@@ -263,8 +263,7 @@ static int c_show(struct seq_file *m, void *p)
struct crypto_alg *alg = (struct crypto_alg *)p;
seq_printf(m, "name : %s\n", alg->cra_name);
seq_printf(m, "module : %s\n", alg->cra_module ?
alg->cra_module->name : "[static]");
seq_printf(m, "module : %s\n", module_name(alg->cra_module));
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
......
......@@ -242,6 +242,13 @@ static inline void module_put(struct module *module)
#endif /* CONFIG_MODULE_UNLOAD */
/* This is a #define so the string doesn't get put in every .o file */
#define module_name(mod) \
({ \
struct module *__mod = (mod); \
__mod ? __mod->name : "kernel"; \
})
#define __unsafe(mod) \
do { \
if (mod && !(mod)->unsafe) { \
......@@ -265,6 +272,8 @@ do { \
#define try_module_get(module) 1
#define module_put(module) do { } while(0)
#define module_name(mod) "kernel"
#define __unsafe(mod)
#endif /* CONFIG_MODULES */
......
......@@ -210,13 +210,8 @@ get_exec_domain_list(char *page)
read_lock(&exec_domains_lock);
for (ep = exec_domains; ep && len < PAGE_SIZE - 80; ep = ep->next)
len += sprintf(page + len, "%d-%d\t%-16s\t[%s]\n",
ep->pers_low, ep->pers_high, ep->name,
#ifdef CONFIG_MODULES
ep->module ? ep->module->name : "kernel"
#else
"kernel"
#endif
);
ep->pers_low, ep->pers_high, ep->name,
module_name(ep->module));
read_unlock(&exec_domains_lock);
return (len);
}
......
......@@ -361,8 +361,6 @@ helper_cmp(const struct ip_nat_helper *helper,
return ip_ct_tuple_mask_cmp(tuple, &helper->tuple, &helper->mask);
}
#define MODULE_MAX_NAMELEN 32
int ip_nat_helper_register(struct ip_nat_helper *me)
{
int ret = 0;
......@@ -374,14 +372,13 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
&& ct_helper->me) {
__MOD_INC_USE_COUNT(ct_helper->me);
} else {
#ifdef CONFIG_MODULES
/* We are a NAT helper for protocol X. If we need
* respective conntrack helper for protoccol X, compute
* conntrack helper name and try to load module */
char name[MODULE_MAX_NAMELEN];
const char *tmp = me->me->name;
char name[MODULE_NAME_LEN];
const char *tmp = module_name(me->me);
if (strlen(tmp) + 6 > MODULE_MAX_NAMELEN) {
if (strlen(tmp) + 6 > MODULE_NAME_LEN) {
printk("%s: unable to "
"compute conntrack helper name "
"from %s\n", __FUNCTION__, tmp);
......@@ -403,7 +400,6 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
"because kernel was compiled without kernel "
"module loader support\n", name);
return -EBUSY;
#endif
#endif
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment