clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name linux_radix.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/pci/drm/linux_radix.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | #include <sys/param.h> |
33 | #include <sys/systm.h> |
34 | #include <sys/malloc.h> |
35 | #include <sys/kernel.h> |
36 | #include <sys/sysctl.h> |
37 | |
38 | #include <linux/radix-tree.h> |
39 | |
40 | #define M_RADIX M_DRM |
41 | |
42 | static inline unsigned long |
43 | radix_max(struct radix_tree_root *root) |
44 | { |
45 | return ((1UL << (root->height * RADIX_TREE_MAP_SHIFT)) - 1UL); |
46 | } |
47 | |
48 | static inline int |
49 | radix_pos(long id, int height) |
50 | { |
51 | return (id >> (RADIX_TREE_MAP_SHIFT * height)) & RADIX_TREE_MAP_MASK; |
52 | } |
53 | |
54 | void * |
55 | radix_tree_lookup(struct radix_tree_root *root, unsigned long index) |
56 | { |
57 | struct radix_tree_node *node; |
58 | void *item; |
59 | int height; |
60 | |
61 | item = NULL; |
62 | node = root->rnode; |
63 | height = root->height - 1; |
64 | if (index > radix_max(root)) |
65 | goto out; |
66 | while (height && node) |
67 | node = node->slots[radix_pos(index, height--)]; |
68 | if (node) |
69 | item = node->slots[radix_pos(index, 0)]; |
70 | |
71 | out: |
72 | return (item); |
73 | } |
74 | |
75 | bool |
76 | radix_tree_iter_find(struct radix_tree_root *root, struct radix_tree_iter *iter, |
77 | void ***pppslot) |
78 | { |
79 | struct radix_tree_node *node; |
80 | unsigned long index = iter->index; |
81 | int height; |
82 | |
83 | restart: |
84 | node = root->rnode; |
85 | if (node == NULL) |
86 | return (false); |
87 | height = root->height - 1; |
88 | if (height == -1 || index > radix_max(root)) |
89 | return (false); |
90 | do { |
91 | unsigned long mask = RADIX_TREE_MAP_MASK << (RADIX_TREE_MAP_SHIFT * height); |
92 | unsigned long step = 1UL << (RADIX_TREE_MAP_SHIFT * height); |
93 | int pos = radix_pos(index, height); |
94 | struct radix_tree_node *next; |
95 | |
96 | |
97 | *pppslot = node->slots + pos; |
98 | |
99 | next = node->slots[pos]; |
100 | if (next == NULL) { |
101 | index += step; |
102 | index &= -step; |
103 | if ((index & mask) == 0) |
104 | goto restart; |
105 | } else { |
106 | node = next; |
107 | height--; |
108 | } |
109 | } while (height != -1); |
110 | iter->index = index; |
111 | return (true); |
112 | } |
113 | |
114 | void * |
115 | radix_tree_delete(struct radix_tree_root *root, unsigned long index) |
116 | { |
117 | struct radix_tree_node *stack[RADIX_TREE_MAX_HEIGHT]; |
118 | struct radix_tree_node *node; |
119 | void *item; |
120 | int height; |
121 | int idx; |
122 | |
123 | item = NULL; |
124 | node = root->rnode; |
125 | height = root->height - 1; |
126 | if (index > radix_max(root)) |
127 | goto out; |
128 | |
129 | |
130 | |
131 | while (height && node) { |
132 | stack[height] = node; |
133 | node = node->slots[radix_pos(index, height--)]; |
134 | } |
135 | idx = radix_pos(index, 0); |
136 | if (node) |
137 | item = node->slots[idx]; |
138 | |
139 | |
140 | |
141 | if (item) |
142 | for (;;) { |
143 | node->slots[idx] = NULL; |
144 | node->count--; |
145 | if (node->count > 0) |
146 | break; |
147 | free(node, M_RADIX, sizeof(*node)); |
148 | if (node == root->rnode) { |
149 | root->rnode = NULL; |
150 | root->height = 0; |
151 | break; |
152 | } |
153 | height++; |
154 | node = stack[height]; |
155 | idx = radix_pos(index, height); |
156 | } |
157 | out: |
158 | return (item); |
159 | } |
160 | |
161 | void |
162 | radix_tree_iter_delete(struct radix_tree_root *root, |
163 | struct radix_tree_iter *iter, void **slot) |
164 | { |
165 | radix_tree_delete(root, iter->index); |
166 | } |
167 | |
168 | int |
169 | radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item) |
170 | { |
171 | struct radix_tree_node *node; |
172 | struct radix_tree_node *temp[RADIX_TREE_MAX_HEIGHT - 1]; |
173 | int height; |
174 | int idx; |
175 | |
176 | |
177 | if (item == NULL) |
| 1 | Assuming 'item' is not equal to NULL | |
|
| |
178 | return (-EINVAL); |
179 | |
180 | |
181 | node = root->rnode; |
182 | |
183 | |
184 | if (node == NULL) { |
| 3 | | Assuming 'node' is equal to NULL | |
|
| |
185 | node = malloc(sizeof(*node), M_RADIX, root->gfp_mask | M_ZERO); |
| 5 | | Uninitialized value stored to field 'count' | |
|
186 | if (node == NULL) |
| 6 | | Assuming 'node' is not equal to NULL | |
|
| |
187 | return (-ENOMEM); |
188 | root->rnode = node; |
189 | root->height++; |
190 | } |
191 | |
192 | |
193 | while (radix_max(root) < index) { |
| 8 | | Assuming the condition is true | |
|
| 9 | | Loop condition is true. Entering loop body | |
|
194 | |
195 | |
196 | if (root->height == RADIX_TREE_MAX_HEIGHT) |
| 10 | | Assuming the condition is false | |
|
| |
197 | return (-E2BIG); |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | if (node->count != 0) { |
| 12 | | The left operand of '!=' is a garbage value |
|
204 | node = malloc(sizeof(*node), M_RADIX, root->gfp_mask | M_ZERO); |
205 | if (node == NULL) |
206 | return (-ENOMEM); |
207 | node->slots[0] = root->rnode; |
208 | node->count++; |
209 | root->rnode = node; |
210 | } |
211 | root->height++; |
212 | } |
213 | |
214 | |
215 | height = root->height - 1; |
216 | |
217 | |
218 | for ( ; height != 0; height--) { |
219 | idx = radix_pos(index, height); |
220 | if (node->slots[idx] == NULL) |
221 | break; |
222 | node = node->slots[idx]; |
223 | } |
224 | |
225 | |
226 | for (idx = 0; idx != height; idx++) { |
227 | temp[idx] = malloc(sizeof(*node), M_RADIX, |
228 | root->gfp_mask | M_ZERO); |
229 | if (temp[idx] == NULL) { |
230 | while(idx--) |
231 | free(temp[idx], M_RADIX, sizeof(*node)); |
232 | |
233 | if (root->rnode->count == 0) { |
234 | free(root->rnode, M_RADIX, sizeof(*root->rnode)); |
235 | root->rnode = NULL; |
236 | root->height = 0; |
237 | } |
238 | return (-ENOMEM); |
239 | } |
240 | } |
241 | |
242 | |
243 | for ( ; height != 0; height--) { |
244 | idx = radix_pos(index, height); |
245 | node->slots[idx] = temp[height - 1]; |
246 | node->count++; |
247 | node = node->slots[idx]; |
248 | } |
249 | |
250 | |
251 | |
252 | |
253 | idx = radix_pos(index, 0); |
254 | if (node->slots[idx]) |
255 | return (-EEXIST); |
256 | node->slots[idx] = item; |
257 | node->count++; |
258 | |
259 | return (0); |
260 | } |