1 /*
2 * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>.
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7
8 #include "defs.h"
9
10 #include <linux/ioctl.h>
11 #include <linux/counter.h>
12
13 #include "xlat/counter_ioctl_component_types.h"
14 #include "xlat/counter_ioctl_event_types.h"
15 #include "xlat/counter_ioctl_scopes.h"
16
17
18 static void
19 print_struct_counter_component(const struct counter_component *const cc)
20 {
21 tprint_struct_begin();
22 PRINT_FIELD_XVAL(*cc, type, counter_ioctl_component_types,
23 "COUNTER_COMPONENT_???");
24 tprint_struct_next();
25 PRINT_FIELD_XVAL(*cc, scope, counter_ioctl_scopes,
26 "COUNTER_SCOPE_???");
27 tprint_struct_next();
28 PRINT_FIELD_U(*cc, parent);
29 tprint_struct_next();
30 PRINT_FIELD_U(*cc, id);
31 tprint_struct_end();
32 }
33
34 static void
35 print_struct_counter_watch(struct tcb *const tcp, const kernel_ulong_t addr)
36 {
37 CHECK_IOCTL_SIZE(COUNTER_ADD_WATCH_IOCTL, 6);
38 CHECK_TYPE_SIZE(struct counter_watch, 6);
39 struct counter_watch w;
40
41 if (umove_or_printaddr(tcp, addr, &w))
42 return;
43
44 tprint_struct_begin();
45 PRINT_FIELD_OBJ_PTR(w, component, print_struct_counter_component);
46 tprint_struct_next();
47 PRINT_FIELD_XVAL(w, event, counter_ioctl_event_types,
48 "COUNTER_EVENT_???");
49 tprint_struct_next();
50 PRINT_FIELD_U(w, channel);
51 tprint_struct_end();
52 }
53
54 int
55 counter_ioctl(struct tcb *const tcp, const unsigned int code,
56 const kernel_ulong_t arg)
57 {
58 switch (code) {
59 case COUNTER_ADD_WATCH_IOCTL:
60 tprint_arg_next();
61 print_struct_counter_watch(tcp, arg);
62 return RVAL_IOCTL_DECODED;
63
64 case COUNTER_ENABLE_EVENTS_IOCTL:
65 case COUNTER_DISABLE_EVENTS_IOCTL:
66 return RVAL_IOCTL_DECODED;
67
68 default:
69 return RVAL_DECODED;
70 }
71 }