mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 02:47:31 -04:00
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: Ilia Mirkin <imirkin@alum.mit.edu> Cc: stable@vger.kernel.org
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user