xref: /OK3568_Linux_fs/kernel/drivers/gpu/arm/mali400/mali/linux/mali_ukk_profiling.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2010-2017 ARM Limited. All rights reserved.
3  *
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  *
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10 #include <linux/fs.h>       /* file system operations */
11 #include <linux/uaccess.h>  /* user space access */
12 #include <linux/slab.h>
13 
14 #include "mali_ukk.h"
15 #include "mali_osk.h"
16 #include "mali_kernel_common.h"
17 #include "mali_session.h"
18 #include "mali_ukk_wrappers.h"
19 
profiling_add_event_wrapper(struct mali_session_data * session_data,_mali_uk_profiling_add_event_s __user * uargs)20 int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs)
21 {
22 	_mali_uk_profiling_add_event_s kargs;
23 	_mali_osk_errcode_t err;
24 
25 	MALI_CHECK_NON_NULL(uargs, -EINVAL);
26 
27 	if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s))) {
28 		return -EFAULT;
29 	}
30 
31 	kargs.ctx = (uintptr_t)session_data;
32 	err = _mali_ukk_profiling_add_event(&kargs);
33 	if (_MALI_OSK_ERR_OK != err) {
34 		return map_errcode(err);
35 	}
36 
37 	return 0;
38 }
39 
profiling_report_sw_counters_wrapper(struct mali_session_data * session_data,_mali_uk_sw_counters_report_s __user * uargs)40 int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs)
41 {
42 	_mali_uk_sw_counters_report_s kargs;
43 	_mali_osk_errcode_t err;
44 	u32 *counter_buffer;
45 	u32 __user *counters;
46 
47 	MALI_CHECK_NON_NULL(uargs, -EINVAL);
48 
49 	if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s))) {
50 		return -EFAULT;
51 	}
52 
53 	/* make sure that kargs.num_counters is [at least somewhat] sane */
54 	if (kargs.num_counters > 10000) {
55 		MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n"));
56 		return -EINVAL;
57 	}
58 
59 	counter_buffer = (u32 *)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL);
60 	if (NULL == counter_buffer) {
61 		return -ENOMEM;
62 	}
63 
64 	counters = (u32 *)(uintptr_t)kargs.counters;
65 
66 	if (0 != copy_from_user(counter_buffer, counters, sizeof(u32) * kargs.num_counters)) {
67 		kfree(counter_buffer);
68 		return -EFAULT;
69 	}
70 
71 	kargs.ctx = (uintptr_t)session_data;
72 	kargs.counters = (uintptr_t)counter_buffer;
73 
74 	err = _mali_ukk_sw_counters_report(&kargs);
75 
76 	kfree(counter_buffer);
77 
78 	if (_MALI_OSK_ERR_OK != err) {
79 		return map_errcode(err);
80 	}
81 
82 	return 0;
83 }
84 
profiling_get_stream_fd_wrapper(struct mali_session_data * session_data,_mali_uk_profiling_stream_fd_get_s __user * uargs)85 int profiling_get_stream_fd_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stream_fd_get_s __user *uargs)
86 {
87 	_mali_uk_profiling_stream_fd_get_s kargs;
88 	_mali_osk_errcode_t err;
89 
90 	MALI_CHECK_NON_NULL(uargs, -EINVAL);
91 
92 	if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_stream_fd_get_s))) {
93 		return -EFAULT;
94 	}
95 
96 	kargs.ctx = (uintptr_t)session_data;
97 	err = _mali_ukk_profiling_stream_fd_get(&kargs);
98 	if (_MALI_OSK_ERR_OK != err) {
99 		return map_errcode(err);
100 	}
101 
102 	if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_stream_fd_get_s))) {
103 		return -EFAULT;
104 	}
105 
106 	return 0;
107 }
108 
profiling_control_set_wrapper(struct mali_session_data * session_data,_mali_uk_profiling_control_set_s __user * uargs)109 int profiling_control_set_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_control_set_s __user *uargs)
110 {
111 	_mali_uk_profiling_control_set_s kargs;
112 	_mali_osk_errcode_t err;
113 	u8 *kernel_control_data = NULL;
114 	u8 *kernel_response_data = NULL;
115 
116 	MALI_CHECK_NON_NULL(uargs, -EINVAL);
117 
118 	if (0 != get_user(kargs.control_packet_size, &uargs->control_packet_size)) return -EFAULT;
119 	if (0 != get_user(kargs.response_packet_size, &uargs->response_packet_size)) return -EFAULT;
120 
121 	kargs.ctx = (uintptr_t)session_data;
122 
123 
124 	/* Sanity check about the size */
125 	if (kargs.control_packet_size > PAGE_SIZE || kargs.response_packet_size > PAGE_SIZE)
126 		return -EINVAL;
127 
128 	if (0 !=  kargs.control_packet_size) {
129 
130 		if (0 == kargs.response_packet_size)
131 			return -EINVAL;
132 
133 		kernel_control_data = _mali_osk_calloc(1, kargs.control_packet_size);
134 		if (NULL == kernel_control_data) {
135 			return -ENOMEM;
136 		}
137 
138 		kernel_response_data = _mali_osk_calloc(1, kargs.response_packet_size);
139 		if (NULL == kernel_response_data) {
140 			_mali_osk_free(kernel_control_data);
141 			return -ENOMEM;
142 		}
143 
144 		kargs.control_packet_data = (uintptr_t)kernel_control_data;
145 		kargs.response_packet_data = (uintptr_t)kernel_response_data;
146 
147 		if (0 != copy_from_user((void *)(uintptr_t)kernel_control_data, (void *)(uintptr_t)uargs->control_packet_data, kargs.control_packet_size)) {
148 			_mali_osk_free(kernel_control_data);
149 			_mali_osk_free(kernel_response_data);
150 			return -EFAULT;
151 		}
152 
153 		err = _mali_ukk_profiling_control_set(&kargs);
154 		if (_MALI_OSK_ERR_OK != err) {
155 			_mali_osk_free(kernel_control_data);
156 			_mali_osk_free(kernel_response_data);
157 			return map_errcode(err);
158 		}
159 
160 		if (0 != kargs.response_packet_size && 0 != copy_to_user(((void *)(uintptr_t)uargs->response_packet_data), ((void *)(uintptr_t)kargs.response_packet_data), kargs.response_packet_size)) {
161 			_mali_osk_free(kernel_control_data);
162 			_mali_osk_free(kernel_response_data);
163 			return -EFAULT;
164 		}
165 
166 		if (0 != put_user(kargs.response_packet_size, &uargs->response_packet_size)) {
167 			_mali_osk_free(kernel_control_data);
168 			_mali_osk_free(kernel_response_data);
169 			return -EFAULT;
170 		}
171 
172 		_mali_osk_free(kernel_control_data);
173 		_mali_osk_free(kernel_response_data);
174 	} else {
175 
176 		err = _mali_ukk_profiling_control_set(&kargs);
177 		if (_MALI_OSK_ERR_OK != err) {
178 			return map_errcode(err);
179 		}
180 
181 	}
182 	return 0;
183 }
184