1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4 * Copyright 2016-2019 HabanaLabs, Ltd.
5 * All Rights Reserved.
6 */
7
8 #include <uapi/misc/habanalabs.h>
9 #include "habanalabs.h"
10
11 #include <linux/fs.h>
12 #include <linux/uaccess.h>
13 #include <linux/slab.h>
14
15 static u32 hl_debug_struct_size[HL_DEBUG_OP_TIMESTAMP + 1] = {
16 [HL_DEBUG_OP_ETR] = sizeof(struct hl_debug_params_etr),
17 [HL_DEBUG_OP_ETF] = sizeof(struct hl_debug_params_etf),
18 [HL_DEBUG_OP_STM] = sizeof(struct hl_debug_params_stm),
19 [HL_DEBUG_OP_FUNNEL] = 0,
20 [HL_DEBUG_OP_BMON] = sizeof(struct hl_debug_params_bmon),
21 [HL_DEBUG_OP_SPMU] = sizeof(struct hl_debug_params_spmu),
22 [HL_DEBUG_OP_TIMESTAMP] = 0
23
24 };
25
device_status_info(struct hl_device * hdev,struct hl_info_args * args)26 static int device_status_info(struct hl_device *hdev, struct hl_info_args *args)
27 {
28 struct hl_info_device_status dev_stat = {0};
29 u32 size = args->return_size;
30 void __user *out = (void __user *) (uintptr_t) args->return_pointer;
31
32 if ((!size) || (!out))
33 return -EINVAL;
34
35 dev_stat.status = hl_device_status(hdev);
36
37 return copy_to_user(out, &dev_stat,
38 min((size_t)size, sizeof(dev_stat))) ? -EFAULT : 0;
39 }
40
hw_ip_info(struct hl_device * hdev,struct hl_info_args * args)41 static int hw_ip_info(struct hl_device *hdev, struct hl_info_args *args)
42 {
43 struct hl_info_hw_ip_info hw_ip = {0};
44 u32 size = args->return_size;
45 void __user *out = (void __user *) (uintptr_t) args->return_pointer;
46 struct asic_fixed_properties *prop = &hdev->asic_prop;
47 u64 sram_kmd_size, dram_kmd_size;
48
49 if ((!size) || (!out))
50 return -EINVAL;
51
52 sram_kmd_size = (prop->sram_user_base_address -
53 prop->sram_base_address);
54 dram_kmd_size = (prop->dram_user_base_address -
55 prop->dram_base_address);
56
57 hw_ip.device_id = hdev->asic_funcs->get_pci_id(hdev);
58 hw_ip.sram_base_address = prop->sram_user_base_address;
59 hw_ip.dram_base_address = prop->dram_user_base_address;
60 hw_ip.tpc_enabled_mask = prop->tpc_enabled_mask;
61 hw_ip.sram_size = prop->sram_size - sram_kmd_size;
62 hw_ip.dram_size = prop->dram_size - dram_kmd_size;
63 if (hw_ip.dram_size > 0)
64 hw_ip.dram_enabled = 1;
65 hw_ip.num_of_events = prop->num_of_events;
66 memcpy(hw_ip.armcp_version,
67 prop->armcp_info.armcp_version, VERSION_MAX_LEN);
68 hw_ip.armcp_cpld_version = le32_to_cpu(prop->armcp_info.cpld_version);
69 hw_ip.psoc_pci_pll_nr = prop->psoc_pci_pll_nr;
70 hw_ip.psoc_pci_pll_nf = prop->psoc_pci_pll_nf;
71 hw_ip.psoc_pci_pll_od = prop->psoc_pci_pll_od;
72 hw_ip.psoc_pci_pll_div_factor = prop->psoc_pci_pll_div_factor;
73
74 return copy_to_user(out, &hw_ip,
75 min((size_t)size, sizeof(hw_ip))) ? -EFAULT : 0;
76 }
77
hw_events_info(struct hl_device * hdev,bool aggregate,struct hl_info_args * args)78 static int hw_events_info(struct hl_device *hdev, bool aggregate,
79 struct hl_info_args *args)
80 {
81 u32 size, max_size = args->return_size;
82 void __user *out = (void __user *) (uintptr_t) args->return_pointer;
83 void *arr;
84
85 if ((!max_size) || (!out))
86 return -EINVAL;
87
88 arr = hdev->asic_funcs->get_events_stat(hdev, aggregate, &size);
89
90 return copy_to_user(out, arr, min(max_size, size)) ? -EFAULT : 0;
91 }
92
dram_usage_info(struct hl_fpriv * hpriv,struct hl_info_args * args)93 static int dram_usage_info(struct hl_fpriv *hpriv, struct hl_info_args *args)
94 {
95 struct hl_device *hdev = hpriv->hdev;
96 struct hl_info_dram_usage dram_usage = {0};
97 u32 max_size = args->return_size;
98 void __user *out = (void __user *) (uintptr_t) args->return_pointer;
99 struct asic_fixed_properties *prop = &hdev->asic_prop;
100 u64 dram_kmd_size;
101
102 if ((!max_size) || (!out))
103 return -EINVAL;
104
105 dram_kmd_size = (prop->dram_user_base_address -
106 prop->dram_base_address);
107 dram_usage.dram_free_mem = (prop->dram_size - dram_kmd_size) -
108 atomic64_read(&hdev->dram_used_mem);
109 if (hpriv->ctx)
110 dram_usage.ctx_dram_mem =
111 atomic64_read(&hpriv->ctx->dram_phys_mem);
112
113 return copy_to_user(out, &dram_usage,
114 min((size_t) max_size, sizeof(dram_usage))) ? -EFAULT : 0;
115 }
116
hw_idle(struct hl_device * hdev,struct hl_info_args * args)117 static int hw_idle(struct hl_device *hdev, struct hl_info_args *args)
118 {
119 struct hl_info_hw_idle hw_idle = {0};
120 u32 max_size = args->return_size;
121 void __user *out = (void __user *) (uintptr_t) args->return_pointer;
122
123 if ((!max_size) || (!out))
124 return -EINVAL;
125
126 hw_idle.is_idle = hdev->asic_funcs->is_device_idle(hdev,
127 &hw_idle.busy_engines_mask, NULL);
128
129 return copy_to_user(out, &hw_idle,
130 min((size_t) max_size, sizeof(hw_idle))) ? -EFAULT : 0;
131 }
132
debug_coresight(struct hl_device * hdev,struct hl_debug_args * args)133 static int debug_coresight(struct hl_device *hdev, struct hl_debug_args *args)
134 {
135 struct hl_debug_params *params;
136 void *input = NULL, *output = NULL;
137 int rc;
138
139 params = kzalloc(sizeof(*params), GFP_KERNEL);
140 if (!params)
141 return -ENOMEM;
142
143 params->reg_idx = args->reg_idx;
144 params->enable = args->enable;
145 params->op = args->op;
146
147 if (args->input_ptr && args->input_size) {
148 input = kzalloc(hl_debug_struct_size[args->op], GFP_KERNEL);
149 if (!input) {
150 rc = -ENOMEM;
151 goto out;
152 }
153
154 if (copy_from_user(input, u64_to_user_ptr(args->input_ptr),
155 args->input_size)) {
156 rc = -EFAULT;
157 dev_err(hdev->dev, "failed to copy input debug data\n");
158 goto out;
159 }
160
161 params->input = input;
162 }
163
164 if (args->output_ptr && args->output_size) {
165 output = kzalloc(args->output_size, GFP_KERNEL);
166 if (!output) {
167 rc = -ENOMEM;
168 goto out;
169 }
170
171 params->output = output;
172 params->output_size = args->output_size;
173 }
174
175 rc = hdev->asic_funcs->debug_coresight(hdev, params);
176 if (rc) {
177 dev_err(hdev->dev,
178 "debug coresight operation failed %d\n", rc);
179 goto out;
180 }
181
182 if (output) {
183 if (copy_to_user((void __user *) (uintptr_t) args->output_ptr,
184 output,
185 args->output_size)) {
186 dev_err(hdev->dev,
187 "copy to user failed in debug ioctl\n");
188 rc = -EFAULT;
189 goto out;
190 }
191 }
192
193 out:
194 kfree(params);
195 kfree(output);
196 kfree(input);
197
198 return rc;
199 }
200
device_utilization(struct hl_device * hdev,struct hl_info_args * args)201 static int device_utilization(struct hl_device *hdev, struct hl_info_args *args)
202 {
203 struct hl_info_device_utilization device_util = {0};
204 u32 max_size = args->return_size;
205 void __user *out = (void __user *) (uintptr_t) args->return_pointer;
206
207 if ((!max_size) || (!out))
208 return -EINVAL;
209
210 if ((args->period_ms < 100) || (args->period_ms > 1000) ||
211 (args->period_ms % 100)) {
212 dev_err(hdev->dev,
213 "period %u must be between 100 - 1000 and must be divisible by 100\n",
214 args->period_ms);
215 return -EINVAL;
216 }
217
218 device_util.utilization = hl_device_utilization(hdev, args->period_ms);
219
220 return copy_to_user(out, &device_util,
221 min((size_t) max_size, sizeof(device_util))) ? -EFAULT : 0;
222 }
223
_hl_info_ioctl(struct hl_fpriv * hpriv,void * data,struct device * dev)224 static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data,
225 struct device *dev)
226 {
227 struct hl_info_args *args = data;
228 struct hl_device *hdev = hpriv->hdev;
229 int rc;
230
231 /*
232 * Information is returned for the following opcodes even if the device
233 * is disabled or in reset.
234 */
235 switch (args->op) {
236 case HL_INFO_HW_IP_INFO:
237 return hw_ip_info(hdev, args);
238
239 case HL_INFO_DEVICE_STATUS:
240 return device_status_info(hdev, args);
241
242 default:
243 break;
244 }
245
246 if (hl_device_disabled_or_in_reset(hdev)) {
247 dev_warn_ratelimited(dev,
248 "Device is %s. Can't execute INFO IOCTL\n",
249 atomic_read(&hdev->in_reset) ? "in_reset" : "disabled");
250 return -EBUSY;
251 }
252
253 switch (args->op) {
254 case HL_INFO_HW_EVENTS:
255 rc = hw_events_info(hdev, false, args);
256 break;
257
258 case HL_INFO_DRAM_USAGE:
259 rc = dram_usage_info(hpriv, args);
260 break;
261
262 case HL_INFO_HW_IDLE:
263 rc = hw_idle(hdev, args);
264 break;
265
266 case HL_INFO_DEVICE_UTILIZATION:
267 rc = device_utilization(hdev, args);
268 break;
269
270 case HL_INFO_HW_EVENTS_AGGREGATE:
271 rc = hw_events_info(hdev, true, args);
272 break;
273
274 default:
275 dev_err(dev, "Invalid request %d\n", args->op);
276 rc = -ENOTTY;
277 break;
278 }
279
280 return rc;
281 }
282
hl_info_ioctl(struct hl_fpriv * hpriv,void * data)283 static int hl_info_ioctl(struct hl_fpriv *hpriv, void *data)
284 {
285 return _hl_info_ioctl(hpriv, data, hpriv->hdev->dev);
286 }
287
hl_info_ioctl_control(struct hl_fpriv * hpriv,void * data)288 static int hl_info_ioctl_control(struct hl_fpriv *hpriv, void *data)
289 {
290 return _hl_info_ioctl(hpriv, data, hpriv->hdev->dev_ctrl);
291 }
292
hl_debug_ioctl(struct hl_fpriv * hpriv,void * data)293 static int hl_debug_ioctl(struct hl_fpriv *hpriv, void *data)
294 {
295 struct hl_debug_args *args = data;
296 struct hl_device *hdev = hpriv->hdev;
297 int rc = 0;
298
299 if (hl_device_disabled_or_in_reset(hdev)) {
300 dev_warn_ratelimited(hdev->dev,
301 "Device is %s. Can't execute DEBUG IOCTL\n",
302 atomic_read(&hdev->in_reset) ? "in_reset" : "disabled");
303 return -EBUSY;
304 }
305
306 switch (args->op) {
307 case HL_DEBUG_OP_ETR:
308 case HL_DEBUG_OP_ETF:
309 case HL_DEBUG_OP_STM:
310 case HL_DEBUG_OP_FUNNEL:
311 case HL_DEBUG_OP_BMON:
312 case HL_DEBUG_OP_SPMU:
313 case HL_DEBUG_OP_TIMESTAMP:
314 if (!hdev->in_debug) {
315 dev_err_ratelimited(hdev->dev,
316 "Rejecting debug configuration request because device not in debug mode\n");
317 return -EFAULT;
318 }
319 args->input_size =
320 min(args->input_size, hl_debug_struct_size[args->op]);
321 rc = debug_coresight(hdev, args);
322 break;
323 case HL_DEBUG_OP_SET_MODE:
324 rc = hl_device_set_debug_mode(hdev, (bool) args->enable);
325 break;
326 default:
327 dev_err(hdev->dev, "Invalid request %d\n", args->op);
328 rc = -ENOTTY;
329 break;
330 }
331
332 return rc;
333 }
334
335 #define HL_IOCTL_DEF(ioctl, _func) \
336 [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func}
337
338 static const struct hl_ioctl_desc hl_ioctls[] = {
339 HL_IOCTL_DEF(HL_IOCTL_INFO, hl_info_ioctl),
340 HL_IOCTL_DEF(HL_IOCTL_CB, hl_cb_ioctl),
341 HL_IOCTL_DEF(HL_IOCTL_CS, hl_cs_ioctl),
342 HL_IOCTL_DEF(HL_IOCTL_WAIT_CS, hl_cs_wait_ioctl),
343 HL_IOCTL_DEF(HL_IOCTL_MEMORY, hl_mem_ioctl),
344 HL_IOCTL_DEF(HL_IOCTL_DEBUG, hl_debug_ioctl)
345 };
346
347 static const struct hl_ioctl_desc hl_ioctls_control[] = {
348 HL_IOCTL_DEF(HL_IOCTL_INFO, hl_info_ioctl_control)
349 };
350
_hl_ioctl(struct file * filep,unsigned int cmd,unsigned long arg,const struct hl_ioctl_desc * ioctl,struct device * dev)351 static long _hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg,
352 const struct hl_ioctl_desc *ioctl, struct device *dev)
353 {
354 struct hl_fpriv *hpriv = filep->private_data;
355 struct hl_device *hdev = hpriv->hdev;
356 unsigned int nr = _IOC_NR(cmd);
357 char stack_kdata[128] = {0};
358 char *kdata = NULL;
359 unsigned int usize, asize;
360 hl_ioctl_t *func;
361 u32 hl_size;
362 int retcode;
363
364 if (hdev->hard_reset_pending) {
365 dev_crit_ratelimited(hdev->dev_ctrl,
366 "Device HARD reset pending! Please close FD\n");
367 return -ENODEV;
368 }
369
370 /* Do not trust userspace, use our own definition */
371 func = ioctl->func;
372
373 if (unlikely(!func)) {
374 dev_dbg(dev, "no function\n");
375 retcode = -ENOTTY;
376 goto out_err;
377 }
378
379 hl_size = _IOC_SIZE(ioctl->cmd);
380 usize = asize = _IOC_SIZE(cmd);
381 if (hl_size > asize)
382 asize = hl_size;
383
384 cmd = ioctl->cmd;
385
386 if (cmd & (IOC_IN | IOC_OUT)) {
387 if (asize <= sizeof(stack_kdata)) {
388 kdata = stack_kdata;
389 } else {
390 kdata = kzalloc(asize, GFP_KERNEL);
391 if (!kdata) {
392 retcode = -ENOMEM;
393 goto out_err;
394 }
395 }
396 }
397
398 if (cmd & IOC_IN) {
399 if (copy_from_user(kdata, (void __user *)arg, usize)) {
400 retcode = -EFAULT;
401 goto out_err;
402 }
403 } else if (cmd & IOC_OUT) {
404 memset(kdata, 0, usize);
405 }
406
407 retcode = func(hpriv, kdata);
408
409 if (cmd & IOC_OUT)
410 if (copy_to_user((void __user *)arg, kdata, usize))
411 retcode = -EFAULT;
412
413 out_err:
414 if (retcode)
415 dev_dbg(dev, "error in ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n",
416 task_pid_nr(current), cmd, nr);
417
418 if (kdata != stack_kdata)
419 kfree(kdata);
420
421 return retcode;
422 }
423
hl_ioctl(struct file * filep,unsigned int cmd,unsigned long arg)424 long hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
425 {
426 struct hl_fpriv *hpriv = filep->private_data;
427 struct hl_device *hdev = hpriv->hdev;
428 const struct hl_ioctl_desc *ioctl = NULL;
429 unsigned int nr = _IOC_NR(cmd);
430
431 if ((nr >= HL_COMMAND_START) && (nr < HL_COMMAND_END)) {
432 ioctl = &hl_ioctls[nr];
433 } else {
434 dev_err(hdev->dev, "invalid ioctl: pid=%d, nr=0x%02x\n",
435 task_pid_nr(current), nr);
436 return -ENOTTY;
437 }
438
439 return _hl_ioctl(filep, cmd, arg, ioctl, hdev->dev);
440 }
441
hl_ioctl_control(struct file * filep,unsigned int cmd,unsigned long arg)442 long hl_ioctl_control(struct file *filep, unsigned int cmd, unsigned long arg)
443 {
444 struct hl_fpriv *hpriv = filep->private_data;
445 struct hl_device *hdev = hpriv->hdev;
446 const struct hl_ioctl_desc *ioctl = NULL;
447 unsigned int nr = _IOC_NR(cmd);
448
449 if (nr == _IOC_NR(HL_IOCTL_INFO)) {
450 ioctl = &hl_ioctls_control[nr];
451 } else {
452 dev_err(hdev->dev_ctrl, "invalid ioctl: pid=%d, nr=0x%02x\n",
453 task_pid_nr(current), nr);
454 return -ENOTTY;
455 }
456
457 return _hl_ioctl(filep, cmd, arg, ioctl, hdev->dev_ctrl);
458 }
459