diff options
author | Marcin Slusarz <marcin.slusarz@gmail.com> | 2012-12-10 15:59:52 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-01-13 03:07:44 -0500 |
commit | dd5700ea98ad0b375a72525ce7d7edddf15b2693 (patch) | |
tree | fe03dceda8c142e5d18adcb0619afeeafd3f06e9 | |
parent | 82c805abb20946dcb343cd607327e4d720bf6b28 (diff) |
drm/nouveau: fix nouveau_client allocation failure path
Depending on the point of failure, freed object would be returned
or memory leak would happen.
Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/core/core/client.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/client.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 7 |
3 files changed, 10 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c index c617f0480071..8bbb58f94a19 100644 --- a/drivers/gpu/drm/nouveau/core/core/client.c +++ b/drivers/gpu/drm/nouveau/core/core/client.c | |||
@@ -66,10 +66,8 @@ nouveau_client_create_(const char *name, u64 devname, const char *cfg, | |||
66 | 66 | ||
67 | ret = nouveau_handle_create(nv_object(client), ~0, ~0, | 67 | ret = nouveau_handle_create(nv_object(client), ~0, ~0, |
68 | nv_object(client), &client->root); | 68 | nv_object(client), &client->root); |
69 | if (ret) { | 69 | if (ret) |
70 | nouveau_namedb_destroy(&client->base); | ||
71 | return ret; | 70 | return ret; |
72 | } | ||
73 | 71 | ||
74 | /* prevent init/fini being called, os in in charge of this */ | 72 | /* prevent init/fini being called, os in in charge of this */ |
75 | atomic_set(&nv_object(client)->usecount, 2); | 73 | atomic_set(&nv_object(client)->usecount, 2); |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h index 0193532ceac9..63acc0346ff2 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/client.h +++ b/drivers/gpu/drm/nouveau/core/include/core/client.h | |||
@@ -36,6 +36,9 @@ nouveau_client(void *obj) | |||
36 | 36 | ||
37 | int nouveau_client_create_(const char *name, u64 device, const char *cfg, | 37 | int nouveau_client_create_(const char *name, u64 device, const char *cfg, |
38 | const char *dbg, int, void **); | 38 | const char *dbg, int, void **); |
39 | #define nouveau_client_destroy(p) \ | ||
40 | nouveau_namedb_destroy(&(p)->base) | ||
41 | |||
39 | int nouveau_client_init(struct nouveau_client *); | 42 | int nouveau_client_init(struct nouveau_client *); |
40 | int nouveau_client_fini(struct nouveau_client *, bool suspend); | 43 | int nouveau_client_fini(struct nouveau_client *, bool suspend); |
41 | 44 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 01c403ddb99b..efcfefa04123 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -84,11 +84,16 @@ nouveau_cli_create(struct pci_dev *pdev, const char *name, | |||
84 | struct nouveau_cli *cli; | 84 | struct nouveau_cli *cli; |
85 | int ret; | 85 | int ret; |
86 | 86 | ||
87 | *pcli = NULL; | ||
87 | ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config, | 88 | ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config, |
88 | nouveau_debug, size, pcli); | 89 | nouveau_debug, size, pcli); |
89 | cli = *pcli; | 90 | cli = *pcli; |
90 | if (ret) | 91 | if (ret) { |
92 | if (cli) | ||
93 | nouveau_client_destroy(&cli->base); | ||
94 | *pcli = NULL; | ||
91 | return ret; | 95 | return ret; |
96 | } | ||
92 | 97 | ||
93 | mutex_init(&cli->mutex); | 98 | mutex_init(&cli->mutex); |
94 | return 0; | 99 | return 0; |