Commit dd1adaa1 authored by David S. Miller's avatar David S. Miller

arch/sparc64/mm/modutil.c: Fixup vmalloc interface changes.

parent 872d64fa
......@@ -5,10 +5,9 @@
* Based upon code written by Linus Torvalds and others.
*/
#warning "major untested changes to this file --hch (2002/08/05)"
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
#include <asm/system.h>
......@@ -30,13 +29,13 @@ void module_unmap (void * addr)
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++) {
......@@ -53,14 +52,13 @@ void module_unmap (void * addr)
void * module_map (unsigned long size)
{
struct vm_struct **p, *tmp, *area;
struct vm_struct *area;
struct page **pages;
void * addr;
unsigned int nr_pages, array_size, i;
size = PAGE_ALIGN(size);
if (!size || size > MODULES_LEN) return NULL;
if (!size || size > MODULES_LEN)
return NULL;
addr = (void *) MODULES_VADDR;
for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) {
......@@ -68,10 +66,12 @@ void * module_map (unsigned long size)
break;
addr = (void *) (tmp->size + (unsigned long) tmp->addr);
}
if ((unsigned long) addr + size >= MODULES_END) return NULL;
if ((unsigned long) addr + size >= MODULES_END)
return NULL;
area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
if (!area) return NULL;
if (!area)
return NULL;
area->size = size + PAGE_SIZE;
area->addr = addr;
area->next = *p;
......@@ -80,27 +80,38 @@ void * module_map (unsigned long size)
area->phys_addr = 0;
*p = area;
nr_pages = (size+PAGE_SIZE) >> PAGE_SHIFT;
nr_pages = size >> PAGE_SHIFT;
array_size = (nr_pages * sizeof(struct page *));
area->nr_pages = nr_pages;
area->pages = pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
area->pages = pages = kmalloc(array_size, GFP_KERNEL);
if (!area->pages)
return NULL;
goto fail;
memset(area->pages, 0, array_size);
for (i = 0; i < area->nr_pages; i++) {
area->pages[i] = alloc_page(gfp_mask);
area->pages[i] = alloc_page(GFP_KERNEL);
if (unlikely(!area->pages[i]))
goto fail;
}
if (map_vm_area(area, prot, &pages))
if (map_vm_area(area, PAGE_KERNEL, &pages)) {
unmap_vm_area(area);
goto fail;
}
return area->addr;
fail:
vfree(area->addr);
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;
}
}
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