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 | |
02af6beb | 4 | * (C) COPYRIGHT 2010-2015 ARM Limited |
6fa3eb70 S |
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 | ||
02af6beb | 20 | int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs) |
6fa3eb70 | 21 | { |
02af6beb | 22 | _mali_uk_profiling_add_event_s kargs; |
6fa3eb70 S |
23 | _mali_osk_errcode_t err; |
24 | ||
25 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
26 | ||
02af6beb | 27 | if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s))) { |
6fa3eb70 S |
28 | return -EFAULT; |
29 | } | |
30 | ||
02af6beb S |
31 | kargs.ctx = (uintptr_t)session_data; |
32 | err = _mali_ukk_profiling_add_event(&kargs); | |
6fa3eb70 S |
33 | if (_MALI_OSK_ERR_OK != err) { |
34 | return map_errcode(err); | |
35 | } | |
36 | ||
6fa3eb70 S |
37 | return 0; |
38 | } | |
39 | ||
02af6beb | 40 | int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs) |
6fa3eb70 | 41 | { |
02af6beb | 42 | _mali_uk_sw_counters_report_s kargs; |
6fa3eb70 | 43 | _mali_osk_errcode_t err; |
02af6beb S |
44 | u32 *counter_buffer; |
45 | u32 __user *counters; | |
6fa3eb70 S |
46 | |
47 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
48 | ||
02af6beb | 49 | if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s))) { |
6fa3eb70 S |
50 | return -EFAULT; |
51 | } | |
52 | ||
02af6beb S |
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; | |
6fa3eb70 S |
57 | } |
58 | ||
02af6beb S |
59 | counter_buffer = (u32 *)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL); |
60 | if (NULL == counter_buffer) { | |
61 | return -ENOMEM; | |
62 | } | |
6fa3eb70 | 63 | |
02af6beb | 64 | counters = (u32 *)(uintptr_t)kargs.counters; |
6fa3eb70 | 65 | |
02af6beb S |
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); | |
6fa3eb70 | 77 | |
6fa3eb70 S |
78 | if (_MALI_OSK_ERR_OK != err) { |
79 | return map_errcode(err); | |
80 | } | |
81 | ||
6fa3eb70 S |
82 | return 0; |
83 | } | |
84 | ||
02af6beb | 85 | int profiling_get_stream_fd_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stream_fd_get_s __user *uargs) |
6fa3eb70 | 86 | { |
02af6beb | 87 | _mali_uk_profiling_stream_fd_get_s kargs; |
6fa3eb70 S |
88 | _mali_osk_errcode_t err; |
89 | ||
90 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
91 | ||
02af6beb | 92 | if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_stream_fd_get_s))) { |
6fa3eb70 S |
93 | return -EFAULT; |
94 | } | |
95 | ||
02af6beb S |
96 | kargs.ctx = (uintptr_t)session_data; |
97 | err = _mali_ukk_profiling_stream_fd_get(&kargs); | |
6fa3eb70 S |
98 | if (_MALI_OSK_ERR_OK != err) { |
99 | return map_errcode(err); | |
100 | } | |
101 | ||
02af6beb | 102 | if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_stream_fd_get_s))) { |
6fa3eb70 S |
103 | return -EFAULT; |
104 | } | |
105 | ||
106 | return 0; | |
107 | } | |
108 | ||
02af6beb | 109 | int profiling_control_set_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_control_set_s __user *uargs) |
6fa3eb70 | 110 | { |
02af6beb | 111 | _mali_uk_profiling_control_set_s kargs; |
6fa3eb70 | 112 | _mali_osk_errcode_t err; |
02af6beb S |
113 | u8 *kernel_control_data = NULL; |
114 | u8 *kernel_response_data = NULL; | |
6fa3eb70 S |
115 | |
116 | MALI_CHECK_NON_NULL(uargs, -EINVAL); | |
117 | ||
02af6beb S |
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; | |
6fa3eb70 | 120 | |
02af6beb | 121 | kargs.ctx = (uintptr_t)session_data; |
6fa3eb70 | 122 | |
02af6beb | 123 | if (0 != kargs.control_packet_size) { |
6fa3eb70 | 124 | |
02af6beb S |
125 | kernel_control_data = _mali_osk_calloc(1, kargs.control_packet_size); |
126 | if (NULL == kernel_control_data) { | |
127 | return -ENOMEM; | |
128 | } | |
6fa3eb70 | 129 | |
02af6beb | 130 | MALI_DEBUG_ASSERT(0 != kargs.response_packet_size); |
6fa3eb70 | 131 | |
02af6beb S |
132 | kernel_response_data = _mali_osk_calloc(1, kargs.response_packet_size); |
133 | if (NULL == kernel_response_data) { | |
134 | _mali_osk_free(kernel_control_data); | |
135 | return -ENOMEM; | |
136 | } | |
6fa3eb70 | 137 | |
02af6beb S |
138 | kargs.control_packet_data = (uintptr_t)kernel_control_data; |
139 | kargs.response_packet_data = (uintptr_t)kernel_response_data; | |
6fa3eb70 | 140 | |
02af6beb S |
141 | if (0 != copy_from_user((void *)(uintptr_t)kernel_control_data, (void *)(uintptr_t)uargs->control_packet_data, kargs.control_packet_size)) { |
142 | _mali_osk_free(kernel_control_data); | |
143 | _mali_osk_free(kernel_response_data); | |
144 | return -EFAULT; | |
145 | } | |
6fa3eb70 | 146 | |
02af6beb S |
147 | err = _mali_ukk_profiling_control_set(&kargs); |
148 | if (_MALI_OSK_ERR_OK != err) { | |
149 | _mali_osk_free(kernel_control_data); | |
150 | _mali_osk_free(kernel_response_data); | |
151 | return map_errcode(err); | |
152 | } | |
6fa3eb70 | 153 | |
02af6beb S |
154 | 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)) { |
155 | _mali_osk_free(kernel_control_data); | |
156 | _mali_osk_free(kernel_response_data); | |
157 | return -EFAULT; | |
158 | } | |
6fa3eb70 | 159 | |
02af6beb S |
160 | if (0 != put_user(kargs.response_packet_size, &uargs->response_packet_size)) { |
161 | _mali_osk_free(kernel_control_data); | |
162 | _mali_osk_free(kernel_response_data); | |
163 | return -EFAULT; | |
164 | } | |
6fa3eb70 | 165 | |
02af6beb S |
166 | _mali_osk_free(kernel_control_data); |
167 | _mali_osk_free(kernel_response_data); | |
168 | } else { | |
6fa3eb70 | 169 | |
02af6beb S |
170 | err = _mali_ukk_profiling_control_set(&kargs); |
171 | if (_MALI_OSK_ERR_OK != err) { | |
172 | return map_errcode(err); | |
173 | } | |
174 | ||
175 | } | |
6fa3eb70 S |
176 | return 0; |
177 | } |