drm_calloc_large: check right size, check integer overflow, use GFP_ZERO
Kristian Høgsberg [Mon, 8 Jun 2009 15:50:41 +0000 (01:50 +1000)]
Previously we would check size instead of size * nmemb, and so would
never hit the vmalloc path.  Also add integer overflow check as in kcalloc,
and allocate GFP_ZERO pages instead of memset()ing them.

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

include/drm/drmP.h

index afc2168..1cc51a0 100644 (file)
@@ -1573,18 +1573,14 @@ static __inline__ void *drm_calloc(size_t nmemb, size_t size, int area)
 
 static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
 {
-       u8 *addr;
-
-       if (size <= PAGE_SIZE)
+       if (size * nmemb <= PAGE_SIZE)
            return kcalloc(nmemb, size, GFP_KERNEL);
 
-       addr = vmalloc(nmemb * size);
-       if (!addr)
+       if (size != 0 && nmemb > ULONG_MAX / size)
                return NULL;
 
-       memset(addr, 0, nmemb * size);
-
-       return addr;
+       return __vmalloc(size * nmemb,
+                        GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
 }
 
 static __inline void drm_free_large(void *ptr)