- if ((unsigned long)addr + size >= MODULES_END) {
- write_unlock(&vmlist_lock);
- kfree(area);
- return NULL;
- }
- DEBUGP("addr %p\n", addr);
-
- area->next = *p;
- *p = area;
- area->size = size + PAGE_SIZE;
- area->addr = addr;
- write_unlock(&vmlist_lock);
-
- 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 < nr_pages; i++) {
- area->pages[i] = alloc_page(GFP_KERNEL);
- if (area->pages[i] == NULL)
- goto fail;
- }
-
- if (map_vm_area(area, PAGE_KERNEL_EXEC, &pages))
- goto fail;
-
- memset(addr, 0, size);
- DEBUGP("module_alloc size %lu = %p\n", size, addr);
- return addr;
-
-fail:
- module_free(NULL, addr);
- return NULL;