diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
commit | e308faf24f68e262d92d294a01ddca7a17e76762 (patch) | |
tree | 22c47cb315811834861f013067878ff664e95abd /arch/sparc64/mm/modutil.c | |
parent | 30c6397ce63178fcb3e7963ac247f0a03132aca9 (diff) |
Sync with Linux 2.1.46.
Diffstat (limited to 'arch/sparc64/mm/modutil.c')
-rw-r--r-- | arch/sparc64/mm/modutil.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/arch/sparc64/mm/modutil.c b/arch/sparc64/mm/modutil.c new file mode 100644 index 000000000..a0eba8019 --- /dev/null +++ b/arch/sparc64/mm/modutil.c @@ -0,0 +1,66 @@ +/* $Id: modutil.c,v 1.1 1997/07/18 06:26:54 ralf Exp $ + * arch/sparc64/mm/modutil.c + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Based upon code written by Linus Torvalds and others. + */ + +#include <linux/malloc.h> +#include <linux/vmalloc.h> + +#include <asm/uaccess.h> +#include <asm/system.h> +#include <asm/vaddrs.h> + +static struct vm_struct * modvmlist = NULL; + +void module_unmap (void * addr) +{ + struct vm_struct **p, *tmp; + + if (!addr) + return; + if ((PAGE_SIZE-1) & (unsigned long) addr) { + printk("Trying to vfree() bad address (%p)\n", addr); + return; + } + for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) { + if (tmp->addr == addr) { + *p = tmp->next; + vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size); + kfree(tmp); + return; + } + } + printk("Trying to unmap nonexistent module vm area (%p)\n", addr); +} + +void * module_map (unsigned long size) +{ + void * addr; + struct vm_struct **p, *tmp, *area; + + 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; + *p = area; + + if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size)) { + vfree(addr); + return NULL; + } + return addr; +} |