Bug Summary

File:dev/pci/drm/amd/amdgpu/amdgpu_reset.c
Warning:line 137, column 3
Potential leak of memory pointed to by 'reset_domain'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name amdgpu_reset.c -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 -ffp-contract=on -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 -target-feature +retpoline-external-thunk -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/llvm16/lib/clang/16 -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/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -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/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -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/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -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 SUSPEND -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 -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 -fcf-protection=branch -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 /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/pci/drm/amd/amdgpu/amdgpu_reset.c

/usr/src/sys/dev/pci/drm/amd/amdgpu/amdgpu_reset.c

1/*
2 * Copyright 2021 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "amdgpu_reset.h"
25#include "aldebaran.h"
26#include "sienna_cichlid.h"
27
28int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl,
29 struct amdgpu_reset_handler *handler)
30{
31 /* TODO: Check if handler exists? */
32 list_add_tail(&handler->handler_list, &reset_ctl->reset_handlers);
33 return 0;
34}
35
36int amdgpu_reset_init(struct amdgpu_device *adev)
37{
38 int ret = 0;
39
40 switch (adev->ip_versions[MP1_HWIP][0]) {
41 case IP_VERSION(13, 0, 2)(((13) << 16) | ((0) << 8) | (2)):
42 ret = aldebaran_reset_init(adev);
43 break;
44 case IP_VERSION(11, 0, 7)(((11) << 16) | ((0) << 8) | (7)):
45 ret = sienna_cichlid_reset_init(adev);
46 break;
47 default:
48 break;
49 }
50
51 return ret;
52}
53
54int amdgpu_reset_fini(struct amdgpu_device *adev)
55{
56 int ret = 0;
57
58 switch (adev->ip_versions[MP1_HWIP][0]) {
59 case IP_VERSION(13, 0, 2)(((13) << 16) | ((0) << 8) | (2)):
60 ret = aldebaran_reset_fini(adev);
61 break;
62 case IP_VERSION(11, 0, 7)(((11) << 16) | ((0) << 8) | (7)):
63 ret = sienna_cichlid_reset_fini(adev);
64 break;
65 default:
66 break;
67 }
68
69 return ret;
70}
71
72int amdgpu_reset_prepare_hwcontext(struct amdgpu_device *adev,
73 struct amdgpu_reset_context *reset_context)
74{
75 struct amdgpu_reset_handler *reset_handler = NULL((void *)0);
76
77 if (adev->reset_cntl && adev->reset_cntl->get_reset_handler)
78 reset_handler = adev->reset_cntl->get_reset_handler(
79 adev->reset_cntl, reset_context);
80 if (!reset_handler)
81 return -ENOSYS78;
82
83 return reset_handler->prepare_hwcontext(adev->reset_cntl,
84 reset_context);
85}
86
87int amdgpu_reset_perform_reset(struct amdgpu_device *adev,
88 struct amdgpu_reset_context *reset_context)
89{
90 int ret;
91 struct amdgpu_reset_handler *reset_handler = NULL((void *)0);
92
93 if (adev->reset_cntl)
94 reset_handler = adev->reset_cntl->get_reset_handler(
95 adev->reset_cntl, reset_context);
96 if (!reset_handler)
97 return -ENOSYS78;
98
99 ret = reset_handler->perform_reset(adev->reset_cntl, reset_context);
100 if (ret)
101 return ret;
102
103 return reset_handler->restore_hwcontext(adev->reset_cntl,
104 reset_context);
105}
106
107
108void amdgpu_reset_destroy_reset_domain(struct kref *ref)
109{
110 struct amdgpu_reset_domain *reset_domain = container_of(ref,({ const __typeof( ((struct amdgpu_reset_domain *)0)->refcount
) *__mptr = (ref); (struct amdgpu_reset_domain *)( (char *)__mptr
- __builtin_offsetof(struct amdgpu_reset_domain, refcount) )
;})
111 struct amdgpu_reset_domain,({ const __typeof( ((struct amdgpu_reset_domain *)0)->refcount
) *__mptr = (ref); (struct amdgpu_reset_domain *)( (char *)__mptr
- __builtin_offsetof(struct amdgpu_reset_domain, refcount) )
;})
112 refcount)({ const __typeof( ((struct amdgpu_reset_domain *)0)->refcount
) *__mptr = (ref); (struct amdgpu_reset_domain *)( (char *)__mptr
- __builtin_offsetof(struct amdgpu_reset_domain, refcount) )
;})
;
113 if (reset_domain->wq)
114 destroy_workqueue(reset_domain->wq);
115
116 kvfree(reset_domain);
117}
118
119struct amdgpu_reset_domain *amdgpu_reset_create_reset_domain(enum amdgpu_reset_domain_type type,
120 char *wq_name)
121{
122 struct amdgpu_reset_domain *reset_domain;
123
124 reset_domain = kvzalloc(sizeof(struct amdgpu_reset_domain), GFP_KERNEL(0x0001 | 0x0004));
1
Calling 'kvzalloc'
3
Returned allocated memory
125 if (!reset_domain) {
4
Assuming 'reset_domain' is non-null
5
Taking false branch
126 DRM_ERROR("Failed to allocate amdgpu_reset_domain!")__drm_err("Failed to allocate amdgpu_reset_domain!");
127 return NULL((void *)0);
128 }
129
130 reset_domain->type = type;
131 kref_init(&reset_domain->refcount);
132
133 reset_domain->wq = create_singlethread_workqueue(wq_name);
134 if (!reset_domain->wq) {
6
Assuming field 'wq' is null
7
Taking true branch
135 DRM_ERROR("Failed to allocate wq for amdgpu_reset_domain!")__drm_err("Failed to allocate wq for amdgpu_reset_domain!");
136 amdgpu_reset_put_reset_domain(reset_domain);
137 return NULL((void *)0);
8
Potential leak of memory pointed to by 'reset_domain'
138
139 }
140
141 atomic_set(&reset_domain->in_gpu_reset, 0)({ typeof(*(&reset_domain->in_gpu_reset)) __tmp = ((0)
); *(volatile typeof(*(&reset_domain->in_gpu_reset)) *
)&(*(&reset_domain->in_gpu_reset)) = __tmp; __tmp;
})
;
142 atomic_set(&reset_domain->reset_res, 0)({ typeof(*(&reset_domain->reset_res)) __tmp = ((0)); *
(volatile typeof(*(&reset_domain->reset_res)) *)&(
*(&reset_domain->reset_res)) = __tmp; __tmp; })
;
143 rw_init(&reset_domain->sem, "agrs")_rw_init_flags(&reset_domain->sem, "agrs", 0, ((void *
)0))
;
144
145 return reset_domain;
146}
147
148void amdgpu_device_lock_reset_domain(struct amdgpu_reset_domain *reset_domain)
149{
150 atomic_set(&reset_domain->in_gpu_reset, 1)({ typeof(*(&reset_domain->in_gpu_reset)) __tmp = ((1)
); *(volatile typeof(*(&reset_domain->in_gpu_reset)) *
)&(*(&reset_domain->in_gpu_reset)) = __tmp; __tmp;
})
;
151 down_write(&reset_domain->sem)rw_enter_write(&reset_domain->sem);
152}
153
154
155void amdgpu_device_unlock_reset_domain(struct amdgpu_reset_domain *reset_domain)
156{
157 atomic_set(&reset_domain->in_gpu_reset, 0)({ typeof(*(&reset_domain->in_gpu_reset)) __tmp = ((0)
); *(volatile typeof(*(&reset_domain->in_gpu_reset)) *
)&(*(&reset_domain->in_gpu_reset)) = __tmp; __tmp;
})
;
158 up_write(&reset_domain->sem)rw_exit_write(&reset_domain->sem);
159}
160
161
162

/usr/src/sys/dev/pci/drm/include/linux/mm.h

1/* Public domain. */
2
3#ifndef _LINUX_MM_H
4#define _LINUX_MM_H
5
6#include <sys/types.h>
7#include <sys/param.h>
8#include <sys/malloc.h>
9#include <sys/stdint.h>
10#include <sys/atomic.h>
11#include <machine/cpu.h>
12#include <uvm/uvm_extern.h>
13#include <uvm/uvm_glue.h>
14#include <lib/libkern/libkern.h> /* for flsl */
15#include <linux/shrinker.h>
16#include <linux/overflow.h>
17#include <linux/pgtable.h>
18
19#define PageHighMem(x)0 0
20
21#define page_to_phys(page)(((page)->phys_addr)) (VM_PAGE_TO_PHYS(page)((page)->phys_addr))
22#define page_to_pfn(pp)(((pp)->phys_addr) / (1 << 12)) (VM_PAGE_TO_PHYS(pp)((pp)->phys_addr) / PAGE_SIZE(1 << 12))
23#define pfn_to_page(pfn)(PHYS_TO_VM_PAGE(((paddr_t)(pfn) << 12))) (PHYS_TO_VM_PAGE(ptoa(pfn)((paddr_t)(pfn) << 12)))
24#define nth_page(page, n)(&(page)[(n)]) (&(page)[(n)])
25#define offset_in_page(off)((vaddr_t)(off) & ((1 << 12) - 1)) ((vaddr_t)(off) & PAGE_MASK((1 << 12) - 1))
26#define set_page_dirty(page)x86_atomic_clearbits_u32(&page->pg_flags, 0x00000008) atomic_clearbits_intx86_atomic_clearbits_u32(&page->pg_flags, PG_CLEAN0x00000008)
27
28#define PAGE_ALIGN(addr)(((addr) + ((1 << 12) - 1)) & ~((1 << 12) - 1
))
(((addr) + PAGE_MASK((1 << 12) - 1)) & ~PAGE_MASK((1 << 12) - 1))
29
30#define PFN_UP(x)(((x) + (1 << 12)-1) >> 12) (((x) + PAGE_SIZE(1 << 12)-1) >> PAGE_SHIFT12)
31#define PFN_DOWN(x)((x) >> 12) ((x) >> PAGE_SHIFT12)
32#define PFN_PHYS(x)((x) << 12) ((x) << PAGE_SHIFT12)
33
34bool_Bool is_vmalloc_addr(const void *);
35
36static inline void *
37kvmalloc(size_t size, gfp_t flags)
38{
39 return malloc(size, M_DRM145, flags);
40}
41
42static inline void *
43kvmalloc_array(size_t n, size_t size, int flags)
44{
45 if (n != 0 && SIZE_MAX0xffffffffffffffffUL / n < size)
46 return NULL((void *)0);
47 return malloc(n * size, M_DRM145, flags);
48}
49
50static inline struct vm_page *
51vmalloc_to_page(const void *va)
52{
53 return uvm_atopg((vaddr_t)va);
54}
55
56static inline struct vm_page *
57virt_to_page(const void *va)
58{
59 return uvm_atopg((vaddr_t)va);
60}
61
62static inline void *
63kvcalloc(size_t n, size_t size, int flags)
64{
65 return kvmalloc_array(n, size, flags | M_ZERO0x0008);
66}
67
68static inline void *
69kvzalloc(size_t size, int flags)
70{
71 return malloc(size, M_DRM145, flags | M_ZERO0x0008);
2
Memory is allocated
72}
73
74static inline void
75kvfree(const void *objp)
76{
77 free((void *)objp, M_DRM145, 0);
78}
79
80static inline long
81si_mem_available(void)
82{
83 return uvmexp.free;
84}
85
86static inline unsigned int
87get_order(size_t size)
88{
89 return flsl((size - 1) >> PAGE_SHIFT12);
90}
91
92static inline int
93totalram_pages(void)
94{
95 return uvmexp.npages;
96}
97
98#endif