patch-2.2.18 linux/mm/vmalloc.c

Next file: linux/net/Config.in
Previous file: linux/mm/swapfile.c
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/mm/vmalloc.c linux/mm/vmalloc.c
@@ -70,11 +70,12 @@
 void vmfree_area_pages(unsigned long address, unsigned long size)
 {
 	pgd_t * dir;
+	unsigned long start = address;
 	unsigned long end = address + size;
 
 	dir = pgd_offset_k(address);
 	flush_cache_all();
-	while (address < end) {
+	while (address >= start && address < end) {
 		free_area_pmd(dir, address, end - address);
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
 		dir++;
@@ -127,11 +128,12 @@
 int vmalloc_area_pages(unsigned long address, unsigned long size)
 {
 	pgd_t * dir;
+	unsigned long start = address;
 	unsigned long end = address + size;
 
 	dir = pgd_offset_k(address);
 	flush_cache_all();
-	while (address < end) {
+	while (address >= start && address < end) {
 		pmd_t *pmd;
 		pgd_t olddir = *dir;
 		
@@ -157,8 +159,13 @@
 	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
 	if (!area)
 		return NULL;
+	size += PAGE_SIZE;
 	addr = VMALLOC_START;
 	for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
+		if ((size + addr) < addr) {
+			kfree(area);
+			return NULL;
+		}
 		if (size + addr < (unsigned long) tmp->addr)
 			break;
 		addr = tmp->size + (unsigned long) tmp->addr;
@@ -168,7 +175,7 @@
 		}
 	}
 	area->addr = (void *)addr;
-	area->size = size + PAGE_SIZE;
+	area->size = size;
 	area->next = *p;
 	*p = area;
 	return area;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)