nv_wr32(falcon, falcon->addr + addr, data);
 }
 
+static void *
+vmemdup(const void *src, size_t len)
+{
+       void *p = vmalloc(len);
+
+       if (p)
+               memcpy(p, src, len);
+       return p;
+}
+
 int
 _nouveau_falcon_init(struct nouveau_object *object)
 {
 
                ret = request_firmware(&fw, name, &device->pdev->dev);
                if (ret == 0) {
-                       falcon->code.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+                       falcon->code.data = vmemdup(fw->data, fw->size);
                        falcon->code.size = fw->size;
                        falcon->data.data = NULL;
                        falcon->data.size = 0;
                        return ret;
                }
 
-               falcon->data.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+               falcon->data.data = vmemdup(fw->data, fw->size);
                falcon->data.size = fw->size;
                release_firmware(fw);
                if (!falcon->data.data)
                        return ret;
                }
 
-               falcon->code.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+               falcon->code.data = vmemdup(fw->data, fw->size);
                falcon->code.size = fw->size;
                release_firmware(fw);
                if (!falcon->code.data)
        if (!suspend) {
                nouveau_gpuobj_ref(NULL, &falcon->core);
                if (falcon->external) {
-                       kfree(falcon->data.data);
-                       kfree(falcon->code.data);
+                       vfree(falcon->data.data);
+                       vfree(falcon->code.data);
                        falcon->code.data = NULL;
                }
        }