Merge branch 'android-4.4' of https://android.googlesource.com/kernel/common
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / mali400 / mali / linux / mali_ukk_profiling.c
1 /*
2  * Copyright (C) 2010-2014 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 <asm/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
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
40 int profiling_memory_usage_get_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_memory_usage_get_s __user *uargs)
41 {
42         _mali_osk_errcode_t err;
43         _mali_uk_profiling_memory_usage_get_s kargs;
44
45         MALI_CHECK_NON_NULL(uargs, -EINVAL);
46         MALI_CHECK_NON_NULL(session_data, -EINVAL);
47
48         kargs.ctx = (uintptr_t)session_data;
49         err = _mali_ukk_profiling_memory_usage_get(&kargs);
50         if (_MALI_OSK_ERR_OK != err) {
51                 return map_errcode(err);
52         }
53
54         kargs.ctx = (uintptr_t)NULL; /* prevent kernel address to be returned to user space */
55         if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_memory_usage_get_s))) {
56                 return -EFAULT;
57         }
58
59         return 0;
60 }
61
62 int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs)
63 {
64         _mali_uk_sw_counters_report_s kargs;
65         _mali_osk_errcode_t err;
66         u32 *counter_buffer;
67         u32 __user *counters;
68
69         MALI_CHECK_NON_NULL(uargs, -EINVAL);
70
71         if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s))) {
72                 return -EFAULT;
73         }
74
75         /* make sure that kargs.num_counters is [at least somewhat] sane */
76         if (kargs.num_counters > 10000) {
77                 MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n"));
78                 return -EINVAL;
79         }
80
81         counter_buffer = (u32 *)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL);
82         if (NULL == counter_buffer) {
83                 return -ENOMEM;
84         }
85
86         counters = (u32 *)(uintptr_t)kargs.counters;
87
88         if (0 != copy_from_user(counter_buffer, counters, sizeof(u32) * kargs.num_counters)) {
89                 kfree(counter_buffer);
90                 return -EFAULT;
91         }
92
93         kargs.ctx = (uintptr_t)session_data;
94         kargs.counters = (uintptr_t)counter_buffer;
95
96         err = _mali_ukk_sw_counters_report(&kargs);
97
98         kfree(counter_buffer);
99
100         if (_MALI_OSK_ERR_OK != err) {
101                 return map_errcode(err);
102         }
103
104         return 0;
105 }