Commit 90d6db16 authored by Ilia Mirkin's avatar Ilia Mirkin Committed by Ben Skeggs
Browse files

drm/nouveau/falcon: use vmalloc to create firwmare copies



Some firmware images may be large (64K), so using kmalloc memory is
inappropriate for them. Use vmalloc instead, to avoid high-order
allocation failures.

Signed-off-by: default avatarIlia Mirkin <imirkin@alum.mit.edu>
Cc: stable@vger.kernel.org
parent d96bf437
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -56,6 +56,16 @@ _nouveau_falcon_wr32(struct nouveau_object *object, u64 addr, u32 data)
	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)
{
@@ -111,7 +121,7 @@ _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;
@@ -134,7 +144,7 @@ _nouveau_falcon_init(struct nouveau_object *object)
			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)
@@ -149,7 +159,7 @@ _nouveau_falcon_init(struct nouveau_object *object)
			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)
@@ -235,8 +245,8 @@ _nouveau_falcon_fini(struct nouveau_object *object, bool suspend)
	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;
		}
	}