diff options
author | Alex Waterman <alexw@nvidia.com> | 2016-08-05 19:47:17 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2016-08-30 13:04:31 -0400 |
commit | 9e43258438a48eb23c6e65ad91ce88518d6a617a (patch) | |
tree | cbfcf7089ca51044c4b186f5b6995af3f51fafdf | |
parent | 9eac0fd84921359ded2acdf920de5592322ad93c (diff) |
gpu: nvgpu: Add checking in allocator functions
Add checks to make sure function pointers are valid before attempting
to call said function.
Also, ensure that any allocator created defines the following 3 functions
at minimum:
alloc()
free()
fini()
Bug 1799159
Change-Id: I4cd3d5746ccb721c723a161c9487564846027572
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: http://git-master/r/1200059
(cherry picked from commit e26557a49d7ca6629ada24f12a3be396b0ae22cd)
Reviewed-on: http://git-master/r/1208476
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_allocator.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c b/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c index 25d15d0f..d9e38200 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c | |||
@@ -29,17 +29,23 @@ static struct dentry *gk20a_alloc_debugfs_root; | |||
29 | 29 | ||
30 | u64 gk20a_alloc_length(struct gk20a_allocator *a) | 30 | u64 gk20a_alloc_length(struct gk20a_allocator *a) |
31 | { | 31 | { |
32 | return a->ops->length(a); | 32 | if (a->ops->length) |
33 | return a->ops->length(a); | ||
34 | |||
35 | return 0; | ||
33 | } | 36 | } |
34 | 37 | ||
35 | u64 gk20a_alloc_base(struct gk20a_allocator *a) | 38 | u64 gk20a_alloc_base(struct gk20a_allocator *a) |
36 | { | 39 | { |
37 | return a->ops->base(a); | 40 | if (a->ops->base) |
41 | return a->ops->base(a); | ||
42 | |||
43 | return 0; | ||
38 | } | 44 | } |
39 | 45 | ||
40 | u64 gk20a_alloc_initialized(struct gk20a_allocator *a) | 46 | u64 gk20a_alloc_initialized(struct gk20a_allocator *a) |
41 | { | 47 | { |
42 | if (!a->ops) | 48 | if (!a->ops || !a->ops->inited) |
43 | return 0; | 49 | return 0; |
44 | 50 | ||
45 | return a->ops->inited(a); | 51 | return a->ops->inited(a); |
@@ -47,7 +53,10 @@ u64 gk20a_alloc_initialized(struct gk20a_allocator *a) | |||
47 | 53 | ||
48 | u64 gk20a_alloc_end(struct gk20a_allocator *a) | 54 | u64 gk20a_alloc_end(struct gk20a_allocator *a) |
49 | { | 55 | { |
50 | return a->ops->end(a); | 56 | if (a->ops->end) |
57 | return a->ops->end(a); | ||
58 | |||
59 | return 0; | ||
51 | } | 60 | } |
52 | 61 | ||
53 | u64 gk20a_alloc(struct gk20a_allocator *a, u64 len) | 62 | u64 gk20a_alloc(struct gk20a_allocator *a, u64 len) |
@@ -62,7 +71,10 @@ void gk20a_free(struct gk20a_allocator *a, u64 addr) | |||
62 | 71 | ||
63 | u64 gk20a_alloc_fixed(struct gk20a_allocator *a, u64 base, u64 len) | 72 | u64 gk20a_alloc_fixed(struct gk20a_allocator *a, u64 base, u64 len) |
64 | { | 73 | { |
65 | return a->ops->alloc_fixed(a, base, len); | 74 | if (a->ops->alloc_fixed) |
75 | return a->ops->alloc_fixed(a, base, len); | ||
76 | |||
77 | return 0; | ||
66 | } | 78 | } |
67 | 79 | ||
68 | void gk20a_free_fixed(struct gk20a_allocator *a, u64 base, u64 len) | 80 | void gk20a_free_fixed(struct gk20a_allocator *a, u64 base, u64 len) |
@@ -92,6 +104,13 @@ int __gk20a_alloc_common_init(struct gk20a_allocator *a, | |||
92 | if (!ops) | 104 | if (!ops) |
93 | return -EINVAL; | 105 | return -EINVAL; |
94 | 106 | ||
107 | /* | ||
108 | * This is the bare minimum operations required for a sensible | ||
109 | * allocator. | ||
110 | */ | ||
111 | if (!ops->alloc || !ops->free || !ops->fini) | ||
112 | return -EINVAL; | ||
113 | |||
95 | a->ops = ops; | 114 | a->ops = ops; |
96 | a->priv = priv; | 115 | a->priv = priv; |
97 | a->debug = dbg; | 116 | a->debug = dbg; |