Implement PERF_EVENT_IOC_* decoding
authorEugene Syromyatnikov <evgsyr@gmail.com>
Tue, 15 May 2018 16:45:28 +0000 (18:45 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 28 May 2018 17:34:50 +0000 (17:34 +0000)
* perf.c (fetch_perf_event_attr, print_perf_event_attr): Remove "static"
qualifier.
* defs.h (fetch_perf_event_attr, print_perf_event_attr): New
declarations.
* perf_event_struct.h (struct perf_event_query_bpf): New type
definition.
* perf_ioctl.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* xlat/perf_ioctl_cmds.in: New file.
* xlat/perf_ioctl_flags.in: Likewise.
* ioctl.c (ioctl_decode) <case '$'>: Call perf_ioctl.
* tests/gen_tests.in (ioctl_perf): New test.
* tests/ioctl_perf.c: New file.
* tests/pure_executables.list: ioctl_perf.
* tests/.gitignore: Likewise.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
12 files changed:
Makefile.am
defs.h
ioctl.c
perf.c
perf_event_struct.h
perf_ioctl.c [new file with mode: 0644]
tests/.gitignore
tests/gen_tests.in
tests/ioctl_perf.c [new file with mode: 0644]
tests/pure_executables.list
xlat/perf_ioctl_cmds.in [new file with mode: 0644]
xlat/perf_ioctl_flags.in [new file with mode: 0644]

index 5f3eb288489323520df1f9bae30ac3781b1d8fb5..76895517b01a86c12fefeffacf424a987f5d6130 100644 (file)
@@ -235,6 +235,7 @@ strace_SOURCES =    \
        pathtrace.c     \
        perf.c          \
        perf_event_struct.h \
+       perf_ioctl.c    \
        personality.c   \
        pkeys.c         \
        poll.c          \
diff --git a/defs.h b/defs.h
index b401cccb71f4bd8858653b38a09fe41b866ad8c0..f21604ee0c563636b1fa8d995b4516fc85fa2a8d 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -845,6 +845,11 @@ print_struct_statfs(struct tcb *, kernel_ulong_t addr);
 extern void
 print_struct_statfs64(struct tcb *, kernel_ulong_t addr, kernel_ulong_t size);
 
+extern int
+fetch_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr);
+extern void
+print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr);
+
 extern void print_ifindex(unsigned int);
 
 extern void print_bpf_filter_code(const uint16_t code, bool extended);
diff --git a/ioctl.c b/ioctl.c
index 9d2f9d52586070b0c9e6249ce6e9aa066d1705ab..93fb52631c55af33f638fb5fdcec7522fa4c2f7d 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -255,6 +255,8 @@ ioctl_decode(struct tcb *tcp)
        const kernel_ulong_t arg = tcp->u_arg[2];
 
        switch (_IOC_TYPE(code)) {
+       case '$':
+               return perf_ioctl(tcp, code, arg);
 #if defined(ALPHA) || defined(POWERPC)
        case 'f': {
                int ret = file_ioctl(tcp, code, arg);
diff --git a/perf.c b/perf.c
index b37f54a2964e35c6dda45cc7228e047ea982f8fc..e66ca4d7c95f0eb5f6467c039eb56905a0bd9a23 100644 (file)
--- a/perf.c
+++ b/perf.c
@@ -60,7 +60,7 @@ free_pea_desc(void *pea_desc_ptr)
        free(desc);
 }
 
-static int
+int
 fetch_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
 {
        struct pea_desc *desc;
@@ -117,7 +117,7 @@ fetch_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
                printxval_search(xlat, x, dflt); \
        } while (0)
 
-static void
+void
 print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
 {
        static const char *precise_ip_desc[] = {
index a75b88ad76ed0f18e512e47393a3f002529b3561..57d245bf5967ec027f3ed8acd1d74259d515cb06 100644 (file)
@@ -71,4 +71,10 @@ struct perf_event_attr {
        /* End of ver 5 - 112 bytes */
 };
 
+struct perf_event_query_bpf {
+        uint32_t ids_len;
+        uint32_t prog_cnt;
+        uint32_t ids[0];
+};
+
 #endif /* !STRACE_LINUX_PERF_EVENT_STRUCT_H */
diff --git a/perf_ioctl.c b/perf_ioctl.c
new file mode 100644 (file)
index 0000000..d1b9903
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2018 The strace developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+
+#include <linux/ioctl.h>
+
+#include "perf_event_struct.h"
+
+#define XLAT_MACROS_ONLY
+# include "xlat/perf_ioctl_cmds.h"
+#undef XLAT_MACROS_ONLY
+
+#include "xlat/perf_ioctl_flags.h"
+
+#include MPERS_DEFS
+
+static int
+perf_ioctl_query_bpf(struct tcb *const tcp, const kernel_ulong_t arg)
+{
+       uint32_t info;
+
+       if (entering(tcp)) {
+               tprints(", ");
+
+               if (umove_or_printaddr(tcp, arg, &info))
+                       return RVAL_IOCTL_DECODED;
+
+               tprintf("{ids_len=%u, ", info);
+
+               return 0;
+       }
+
+       if (syserror(tcp) ||
+           umove(tcp, arg + offsetof(struct perf_event_query_bpf, prog_cnt),
+                 &info)) {
+               tprints("...}");
+
+               return RVAL_IOCTL_DECODED;
+       }
+
+       tprintf("prog_cnt=%u, ids=", info);
+
+       print_array(tcp, arg + offsetof(struct perf_event_query_bpf, ids), info,
+                   &info, sizeof(info),
+                   umoven_or_printaddr, print_uint32_array_member, NULL);
+
+       tprints("}");
+
+       return RVAL_IOCTL_DECODED;
+}
+
+static int
+perf_ioctl_modify_attributes(struct tcb *const tcp, const kernel_ulong_t arg)
+{
+       tprints(", ");
+       if (!fetch_perf_event_attr(tcp, arg))
+               print_perf_event_attr(tcp, arg);
+
+       return RVAL_IOCTL_DECODED;
+}
+
+MPERS_PRINTER_DECL(int, perf_ioctl,
+                  struct tcb *const tcp, const unsigned int code,
+                  const kernel_ulong_t arg)
+{
+       switch (code) {
+       case PERF_EVENT_IOC_ENABLE:
+       case PERF_EVENT_IOC_DISABLE:
+       case PERF_EVENT_IOC_RESET:
+               tprints(", ");
+               printflags(perf_ioctl_flags, arg, "PERF_IOC_FLAG_???");
+
+               return RVAL_IOCTL_DECODED;
+
+       case PERF_EVENT_IOC_REFRESH:
+               tprintf(", %d", (int) arg);
+
+               return RVAL_IOCTL_DECODED;
+
+       case PERF_EVENT_IOC_PERIOD:
+               tprints(", ");
+               printnum_int64(tcp, arg, "%" PRIu64);
+
+               return RVAL_IOCTL_DECODED;
+
+       case PERF_EVENT_IOC_SET_OUTPUT:
+       case PERF_EVENT_IOC_SET_BPF:
+               tprintf(", ");
+               printfd(tcp, (int) arg);
+
+               return RVAL_IOCTL_DECODED;
+
+       case PERF_EVENT_IOC_PAUSE_OUTPUT:
+               tprintf(", %" PRI_klu, arg);
+
+               return RVAL_IOCTL_DECODED;
+
+       /*
+        * The following ioctl requests are personality-specific
+        * due to the pointer size.
+        */
+       case PERF_EVENT_IOC_SET_FILTER:
+               tprints(", ");
+               printstr_ex(tcp, arg, get_pagesize(), QUOTE_0_TERMINATED);
+
+               return RVAL_IOCTL_DECODED;
+
+       case PERF_EVENT_IOC_ID:
+               if (entering(tcp)) {
+                       tprints(", ");
+
+                       return 0;
+               }
+
+               printnum_int64(tcp, arg, "%" PRIu64);
+
+               return RVAL_IOCTL_DECODED;
+
+       case PERF_EVENT_IOC_QUERY_BPF:
+               return perf_ioctl_query_bpf(tcp, arg);
+
+       case PERF_EVENT_IOC_MODIFY_ATTRIBUTES:
+               return perf_ioctl_modify_attributes(tcp, arg);
+
+       default:
+               return RVAL_DECODED;
+       }
+}
index 5c46811279fe330b975fa1156f3a597e0a15b38a..e585112fc0c13c414ed33df82d7e96f93e6283da 100644 (file)
@@ -143,6 +143,7 @@ ioctl_loop-nv
 ioctl_loop-v
 ioctl_mtd
 ioctl_nsfs
+ioctl_perf
 ioctl_ptp
 ioctl_rtc
 ioctl_rtc-v
index 9a175221a080c8c51233bd7595a646fa2dc6d508..4400c485b2d25ddf4626622b6ef7745719778c07 100644 (file)
@@ -140,6 +140,7 @@ ioctl_loop-nv       +ioctl.test -a22 -e verbose=none
 ioctl_loop-v   +ioctl.test -v
 ioctl_mtd      +ioctl.test
 ioctl_nsfs     +ioctl.test -esignal=none
+ioctl_perf     +ioctl.test
 ioctl_ptp      +ioctl.test
 ioctl_rtc      +ioctl.test
 ioctl_rtc-v    +ioctl.test -v
diff --git a/tests/ioctl_perf.c b/tests/ioctl_perf.c
new file mode 100644 (file)
index 0000000..c995a41
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Check decoding of PERF_EVENT_IOC_* commands of ioctl syscall.
+ *
+ * Copyright (c) 2018 The strace developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#ifdef HAVE_LINUX_PERF_EVENT_H
+
+# include <inttypes.h>
+# include <stdio.h>
+# include <string.h>
+# include <sys/ioctl.h>
+# include <linux/perf_event.h>
+
+/*
+ * Workaround the bug in kernel UAPI that was fixed
+ * in Linux commit v2.6.33-rc1~48^2~288^2~19.
+ */
+# ifndef u64
+#  define u64 uint64_t
+# endif
+
+# define XLAT_MACROS_ONLY
+#  include "xlat/perf_ioctl_cmds.h"
+# undef XLAT_MACROS_ONLY
+
+# define STR16 "0123456789abcdef"
+
+int
+main(void)
+{
+       static const kernel_ulong_t unknown_perf_cmd =
+               (kernel_ulong_t) 0xbadc0dedfeed24edULL;
+       static const kernel_ulong_t magic =
+               (kernel_ulong_t) 0xdeadbeefbadc0dedULL;
+       static const uint64_t magic64 = 0xfacefeeddeadc0deULL;
+       static const char str[] = STR16 STR16 STR16 STR16;
+
+       static struct {
+               unsigned int cmd;
+               const char *str;
+       } flag_iocs[] = {
+               { ARG_STR(PERF_EVENT_IOC_ENABLE) },
+               { ARG_STR(PERF_EVENT_IOC_DISABLE) },
+               { ARG_STR(PERF_EVENT_IOC_RESET) },
+       };
+
+       TAIL_ALLOC_OBJECT_CONST_PTR(uint64_t, u64_ptr);
+       uint64_t *const u64_efault = u64_ptr + 1;
+       uint32_t *const u32_arr = tail_alloc(sizeof(uint32_t) * 4);
+       uint32_t *const u32_efault = u32_arr + 4;
+       char *const str_ptr = tail_memdup(str, sizeof(str));
+       char *const str_efault = str_ptr + sizeof(str);
+       TAIL_ALLOC_OBJECT_CONST_PTR(struct perf_event_attr, pea_ptr);
+
+       *u64_ptr = magic64;
+       fill_memory_ex(pea_ptr, sizeof(*pea_ptr), 0xaa, 0x55);
+
+       /* Unknown perf commands */
+       ioctl(-1, unknown_perf_cmd, magic);
+       printf("ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE%s, 0x24, %#x, %#x), "
+              "%#lx) = -1 EBADF (%m)\n",
+              _IOC_DIR((unsigned int) unknown_perf_cmd) & _IOC_NONE ?
+              "|_IOC_NONE" : "",
+              _IOC_NR((unsigned int) unknown_perf_cmd),
+              _IOC_SIZE((unsigned int) unknown_perf_cmd),
+              (unsigned long) magic);
+
+       ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1, magic);
+       printf("ioctl(-1, _IOC(_IOC_WRITE, 0x24, %#x, %#x), %#lx)"
+              " = -1 EBADF (%m)\n",
+              (unsigned int) _IOC_NR(PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1),
+              (unsigned int) _IOC_SIZE(PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1),
+              (unsigned long) magic);
+
+       /* PERF_EVENT_IOC_{ENABLE,DISABLE,RESET} */
+       for (unsigned i = 0; i < ARRAY_SIZE(flag_iocs); i++) {
+               ioctl(-1, flag_iocs[i].cmd, 0);
+               printf("ioctl(-1, %s, 0) = -1 EBADF (%m)\n", flag_iocs[i].str);
+
+               ioctl(-1, flag_iocs[i].cmd, 1);
+               printf("ioctl(-1, %s, PERF_IOC_FLAG_GROUP) = -1 EBADF (%m)\n",
+                      flag_iocs[i].str);
+
+               ioctl(-1, flag_iocs[i].cmd, 2);
+               printf("ioctl(-1, %s, 0x2 /* PERF_IOC_FLAG_??? */) "
+                      "= -1 EBADF (%m)\n",
+                      flag_iocs[i].str);
+
+               ioctl(-1, flag_iocs[i].cmd, magic);
+               printf("ioctl(-1, %s, PERF_IOC_FLAG_GROUP|%#x) "
+                      "= -1 EBADF (%m)\n",
+                      flag_iocs[i].str, (unsigned int) magic & ~1U);
+       }
+
+       /* PERF_EVENT_IOC_REFRESH */
+       ioctl(-1, PERF_EVENT_IOC_REFRESH, magic);
+       printf("ioctl(-1, PERF_EVENT_IOC_REFRESH, %d) = -1 EBADF (%m)\n",
+              (int) magic);
+
+       /* PERF_EVENT_IOC_PERIOD */
+       ioctl(-1, PERF_EVENT_IOC_PERIOD, NULL);
+       printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, NULL) = -1 EBADF (%m)\n");
+
+       ioctl(-1, PERF_EVENT_IOC_PERIOD, u64_efault);
+       printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, %p) = -1 EBADF (%m)\n",
+             u64_efault);
+
+       ioctl(-1, PERF_EVENT_IOC_PERIOD, u64_ptr);
+       printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, [%" PRIu64 "])"
+              " = -1 EBADF (%m)\n",
+              magic64);
+
+       /* PERF_EVENT_IOC_SET_OUTPUT */
+       ioctl(-1, PERF_EVENT_IOC_SET_OUTPUT, magic);
+       printf("ioctl(-1, PERF_EVENT_IOC_SET_OUTPUT, %d) = -1 EBADF (%m)\n",
+              (int) magic);
+
+       /* PERF_EVENT_IOC_SET_FILTER */
+       ioctl(-1, PERF_EVENT_IOC_SET_FILTER, NULL);
+       printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, NULL) = -1 EBADF (%m)\n");
+
+       ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_efault);
+       printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, %p) = -1 EBADF (%m)\n",
+              str_efault);
+
+       ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr);
+       printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, \"%.32s\"...)"
+              " = -1 EBADF (%m)\n",
+              str_ptr);
+
+       ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr + 40);
+       printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, \"%.32s\")"
+              " = -1 EBADF (%m)\n",
+              str_ptr + 40);
+
+       str_ptr[sizeof(str) - 1] = '0';
+       ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr + 40);
+       printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, %p)"
+              " = -1 EBADF (%m)\n",
+              str_ptr + 40);
+
+       /* PERF_EVENT_IOC_ID */
+       /* TODO: check return path */
+       ioctl(-1, PERF_EVENT_IOC_ID, NULL);
+       printf("ioctl(-1, PERF_EVENT_IOC_ID, NULL) = -1 EBADF (%m)\n");
+
+       ioctl(-1, PERF_EVENT_IOC_ID, u64_efault);
+       printf("ioctl(-1, PERF_EVENT_IOC_ID, %p) = -1 EBADF (%m)\n",
+             u64_efault);
+
+       ioctl(-1, PERF_EVENT_IOC_ID, u64_ptr);
+       printf("ioctl(-1, PERF_EVENT_IOC_ID, %p) = -1 EBADF (%m)\n",
+              u64_ptr);
+
+       /* PERF_EVENT_IOC_SET_BPF */
+       ioctl(-1, PERF_EVENT_IOC_SET_BPF, magic);
+       printf("ioctl(-1, PERF_EVENT_IOC_SET_BPF, %d) = -1 EBADF (%m)\n",
+              (int) magic);
+
+       /* PERF_EVENT_IOC_PAUSE_OUTPUT */
+       ioctl(-1, PERF_EVENT_IOC_PAUSE_OUTPUT, magic);
+       printf("ioctl(-1, PERF_EVENT_IOC_PAUSE_OUTPUT, %lu) = -1 EBADF (%m)\n",
+              (unsigned long) magic);
+
+       /* PERF_EVENT_IOC_QUERY_BPF */
+       /* TODO: check return path */
+       ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, NULL);
+       printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, NULL) = -1 EBADF (%m)\n");
+
+       ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_efault);
+       printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, %p) = -1 EBADF (%m)\n",
+              u32_efault);
+
+       u32_arr[0] = 0xbadc0ded;
+       ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_arr);
+       printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, {ids_len=3134983661, ...})"
+              " = -1 EBADF (%m)\n");
+
+       /* PERF_EVENT_IOC_MODIFY_ATTRIBUTES */
+       ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, NULL);
+       printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, NULL)"
+              " = -1 EBADF (%m)\n");
+
+       ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, pea_ptr + 1);
+       printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, %p)"
+              " = -1 EBADF (%m)\n",
+              pea_ptr + 1);
+
+       printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES"
+              ", {type=%#x /* PERF_TYPE_??? */"
+              ", size=%#x /* PERF_ATTR_SIZE_??? */"
+              ", config=%#llx, ...}) = -1 EBADF (%m)\n",
+              (unsigned int) pea_ptr->type,
+              (unsigned int) pea_ptr->size,
+              (unsigned long long) pea_ptr->config);
+       ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, pea_ptr);
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("HAVE_LINUX_PERF_EVENT_H");
+
+#endif
index 4553c687ca2aeecb8bd70a1468a268f9f9c5b45d..80c8ae75ac013ecb49e560c7f96a34906b688504 100755 (executable)
@@ -112,6 +112,7 @@ ioctl_kvm_run
 ioctl_loop
 ioctl_mtd
 ioctl_rtc
+ioctl_perf
 ioctl_ptp
 ioctl_scsi
 ioctl_sg_io_v3
diff --git a/xlat/perf_ioctl_cmds.in b/xlat/perf_ioctl_cmds.in
new file mode 100644 (file)
index 0000000..bf7ad78
--- /dev/null
@@ -0,0 +1,12 @@
+PERF_EVENT_IOC_ENABLE                  _IO ('$', 0)
+PERF_EVENT_IOC_DISABLE                 _IO ('$', 1)
+PERF_EVENT_IOC_REFRESH                 _IO ('$', 2)
+PERF_EVENT_IOC_RESET                   _IO ('$', 3)
+PERF_EVENT_IOC_PERIOD                  _IOW('$', 4, uint64_t)
+PERF_EVENT_IOC_SET_OUTPUT              _IO ('$', 5)
+PERF_EVENT_IOC_SET_FILTER              _IOW('$', 6, char *)
+PERF_EVENT_IOC_ID                      _IOR('$', 7, uint64_t *)
+PERF_EVENT_IOC_SET_BPF                 _IOW('$', 8, uint32_t)
+PERF_EVENT_IOC_PAUSE_OUTPUT            _IOW('$', 9, uint32_t)
+PERF_EVENT_IOC_QUERY_BPF               _IOWR('$', 10, struct perf_event_query_bpf *)
+PERF_EVENT_IOC_MODIFY_ATTRIBUTES       _IOW('$', 11, struct perf_event_attr *)
diff --git a/xlat/perf_ioctl_flags.in b/xlat/perf_ioctl_flags.in
new file mode 100644 (file)
index 0000000..502f69a
--- /dev/null
@@ -0,0 +1 @@
+PERF_IOC_FLAG_GROUP    (1U << 0)