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; }
void * vmalloc_prot(unsigned long size, pgprot_t prot) { void * addr; struct vm_struct *area; size = PAGE_ALIGN(size); if (!size || size > (max_mapnr << PAGE_SHIFT)) return NULL; area = get_vm_area(size); if (!area) return NULL; addr = area->addr; if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, prot)) { vfree(addr); return NULL; } return addr; }