Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /* |
2 | * This confidential and proprietary software may be used only as | |
3 | * authorised by a licensing agreement from ARM Limited | |
4 | * (C) COPYRIGHT 2010-2013 ARM Limited | |
5 | * ALL RIGHTS RESERVED | |
6 | * The entire notice above must be reproduced on all authorised | |
7 | * copies and copies may only be made to the extent permitted | |
8 | * by a licensing agreement from ARM Limited. | |
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_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs) | |
21 | { | |
22 | _mali_uk_profiling_start_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_start_s))) { | |
28 | return -EFAULT; | |
29 | } | |
30 | ||
31 | kargs.ctx = session_data; | |
32 | err = _mali_ukk_profiling_start(&kargs); | |
33 | if (_MALI_OSK_ERR_OK != err) { | |
34 | return map_errcode(err); | |
35 | } | |
36 | ||
37 | if (0 != put_user(kargs.limit, &uargs->limit)) { | |
38 | return -EFAULT; | |
39 | } | |
40 | ||
41 | return 0; | |
42 | } | |
43 | ||
44 | int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs) | |
45 | { | |
46 | _mali_uk_profiling_add_event_s kargs; | |
47 | _mali_osk_errcode_t err; | |
48 | ||
49 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
50 | ||
51 | if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s))) { | |
52 | return -EFAULT; | |
53 | } | |
54 | ||
55 | kargs.ctx = session_data; | |
56 | err = _mali_ukk_profiling_add_event(&kargs); | |
57 | if (_MALI_OSK_ERR_OK != err) { | |
58 | return map_errcode(err); | |
59 | } | |
60 | ||
61 | return 0; | |
62 | } | |
63 | ||
64 | int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs) | |
65 | { | |
66 | _mali_uk_profiling_stop_s kargs; | |
67 | _mali_osk_errcode_t err; | |
68 | ||
69 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
70 | ||
71 | kargs.ctx = session_data; | |
72 | err = _mali_ukk_profiling_stop(&kargs); | |
73 | if (_MALI_OSK_ERR_OK != err) { | |
74 | return map_errcode(err); | |
75 | } | |
76 | ||
77 | if (0 != put_user(kargs.count, &uargs->count)) { | |
78 | return -EFAULT; | |
79 | } | |
80 | ||
81 | return 0; | |
82 | } | |
83 | ||
84 | int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs) | |
85 | { | |
86 | _mali_uk_profiling_get_event_s kargs; | |
87 | _mali_osk_errcode_t err; | |
88 | ||
89 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
90 | ||
91 | if (0 != get_user(kargs.index, &uargs->index)) { | |
92 | return -EFAULT; | |
93 | } | |
94 | ||
95 | kargs.ctx = session_data; | |
96 | ||
97 | err = _mali_ukk_profiling_get_event(&kargs); | |
98 | if (_MALI_OSK_ERR_OK != err) { | |
99 | return map_errcode(err); | |
100 | } | |
101 | ||
102 | kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ | |
103 | if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_get_event_s))) { | |
104 | return -EFAULT; | |
105 | } | |
106 | ||
107 | return 0; | |
108 | } | |
109 | ||
110 | int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs) | |
111 | { | |
112 | _mali_uk_profiling_clear_s kargs; | |
113 | _mali_osk_errcode_t err; | |
114 | ||
115 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
116 | ||
117 | kargs.ctx = session_data; | |
118 | err = _mali_ukk_profiling_clear(&kargs); | |
119 | if (_MALI_OSK_ERR_OK != err) { | |
120 | return map_errcode(err); | |
121 | } | |
122 | ||
123 | return 0; | |
124 | } | |
125 | ||
126 | int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs) | |
127 | { | |
128 | _mali_uk_sw_counters_report_s kargs; | |
129 | _mali_osk_errcode_t err; | |
130 | u32 *counter_buffer; | |
131 | ||
132 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
133 | ||
134 | if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s))) { | |
135 | return -EFAULT; | |
136 | } | |
137 | ||
138 | /* make sure that kargs.num_counters is [at least somewhat] sane */ | |
139 | if (kargs.num_counters > 10000) { | |
140 | MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n")); | |
141 | return -EINVAL; | |
142 | } | |
143 | ||
144 | counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL); | |
145 | if (NULL == counter_buffer) { | |
146 | return -ENOMEM; | |
147 | } | |
148 | ||
149 | if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters)) { | |
150 | kfree(counter_buffer); | |
151 | return -EFAULT; | |
152 | } | |
153 | ||
154 | kargs.ctx = session_data; | |
155 | kargs.counters = counter_buffer; | |
156 | ||
157 | err = _mali_ukk_sw_counters_report(&kargs); | |
158 | ||
159 | kfree(counter_buffer); | |
160 | ||
161 | if (_MALI_OSK_ERR_OK != err) { | |
162 | return map_errcode(err); | |
163 | } | |
164 | ||
165 | return 0; | |
166 | } | |
167 | ||
168 |