Import 2.3.41pre2
[davej-history.git] / arch / sparc64 / mm / modutil.c
blob6d68d7468761509108e265d9277a9c0ecc90c5b0
1 /* $Id: modutil.c,v 1.4 1998/07/26 06:29:08 davem Exp $
2 * arch/sparc64/mm/modutil.c
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Based upon code written by Linus Torvalds and others.
6 */
8 #include <linux/malloc.h>
9 #include <linux/vmalloc.h>
11 #include <asm/uaccess.h>
12 #include <asm/system.h>
13 #include <asm/vaddrs.h>
15 static struct vm_struct * modvmlist = NULL;
17 void module_unmap (void * addr)
19 struct vm_struct **p, *tmp;
21 if (!addr)
22 return;
23 if ((PAGE_SIZE-1) & (unsigned long) addr) {
24 printk("Trying to unmap module with bad address (%p)\n", addr);
25 return;
27 for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) {
28 if (tmp->addr == addr) {
29 *p = tmp->next;
30 vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size);
31 kfree(tmp);
32 return;
35 printk("Trying to unmap nonexistent module vm area (%p)\n", addr);
38 void * module_map (unsigned long size)
40 void * addr;
41 struct vm_struct **p, *tmp, *area;
43 size = PAGE_ALIGN(size);
44 if (!size || size > MODULES_LEN) return NULL;
46 addr = (void *) MODULES_VADDR;
47 for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) {
48 if (size + (unsigned long) addr < (unsigned long) tmp->addr)
49 break;
50 addr = (void *) (tmp->size + (unsigned long) tmp->addr);
52 if ((unsigned long) addr + size >= MODULES_END) return NULL;
54 area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
55 if (!area) return NULL;
56 area->size = size + PAGE_SIZE;
57 area->addr = addr;
58 area->next = *p;
59 *p = area;
61 if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size)) {
62 vfree(addr);
63 return NULL;
65 return addr;