summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2012-04-01 22:51:07 +0200
committerMarcin Slusarz <marcin.slusarz@gmail.com>2012-04-01 22:51:07 +0200
commitd23202f0c9ac3980efe932beefe5b6da8e546871 (patch)
treea17537c88d26aae99e4000093dd87e744b3a8968
parent302525b65c21d14d89c813677efa7bcc1ac04b93 (diff)
mmt: add support for tracing nouveau ioctls
-rw-r--r--mmt/Makefile.am3
-rw-r--r--mmt/mmt_main.c11
-rw-r--r--mmt/mmt_nouveau_ioctl.c87
-rw-r--r--mmt/mmt_nouveau_ioctl.h15
-rw-r--r--mmt/mmt_trace.c9
5 files changed, 123 insertions, 2 deletions
diff --git a/mmt/Makefile.am b/mmt/Makefile.am
index 279a1f67..d742e66b 100644
--- a/mmt/Makefile.am
+++ b/mmt/Makefile.am
@@ -5,7 +5,8 @@ if VGCONF_HAVE_PLATFORM_SEC
noinst_PROGRAMS += mmt-@VGCONF_ARCH_SEC@-@VGCONF_OS@
endif
-MMT_SOURCES_COMMON = mmt_main.c mmt_nv_ioctl.c mmt_instrument.c mmt_trace.c
+MMT_SOURCES_COMMON = mmt_main.c mmt_nv_ioctl.c mmt_instrument.c mmt_trace.c \
+ mmt_nouveau_ioctl.c
mmt_@VGCONF_ARCH_PRI@_@VGCONF_OS@_SOURCES = \
$(MMT_SOURCES_COMMON)
diff --git a/mmt/mmt_main.c b/mmt/mmt_main.c
index d86f3033..4ae9dc5a 100644
--- a/mmt/mmt_main.c
+++ b/mmt/mmt_main.c
@@ -33,6 +33,7 @@
#include "pub_tool_mallocfree.h"
#include "mmt_nv_ioctl.h"
+#include "mmt_nouveau_ioctl.h"
#include "mmt_instrument.h"
#include "mmt_trace.h"
@@ -41,6 +42,7 @@
#define TO_OPT "--mmt-trace-all-opens"
#define TA_OPT "--mmt-trace-all-files"
#define TM_OPT "--mmt-trace-marks"
+#define TV_OPT "--mmt-trace-nouveau-ioctls"
static Bool mmt_process_cmd_line_option(Char * arg)
{
@@ -79,6 +81,11 @@ static Bool mmt_process_cmd_line_option(Char * arg)
mmt_trace_marks = True;
return True;
}
+ else if (VG_(strcmp)(arg, TV_OPT) == 0)
+ {
+ mmt_trace_nouveau_ioctls = True;
+ return True;
+ }
return False;
}
@@ -89,7 +96,8 @@ static void mmt_print_usage(void)
" this file (e.g. /dev/nvidia0) (you can pass \n"
" this option multiple times)\n");
VG_(printf)(" " TA_OPT " trace loads and store to memory mapped for all files\n");
- VG_(printf)(" " TN_OPT " trace ioctls on /dev/nvidiactl and /dev/nvidia0\n");
+ VG_(printf)(" " TN_OPT " trace nvidia ioctls on /dev/nvidiactl and /dev/nvidia0\n");
+ VG_(printf)(" " TV_OPT " trace nouveau ioctls on /dev/dri/cardX\n");
VG_(printf)(" " TO_OPT " trace all 'open' syscalls\n");
VG_(printf)(" " TM_OPT " send mmiotrace marks before and after ioctls\n");
}
@@ -130,6 +138,7 @@ static void mmt_pre_clo_init(void)
FD_ZERO(&mmt_trace_files[i].fds);
mmt_nv_ioctl_pre_clo_init();
+ mmt_nouveau_ioctl_pre_clo_init();
}
VG_DETERMINE_INTERFACE_VERSION(mmt_pre_clo_init)
diff --git a/mmt/mmt_nouveau_ioctl.c b/mmt/mmt_nouveau_ioctl.c
new file mode 100644
index 00000000..dfe8e877
--- /dev/null
+++ b/mmt/mmt_nouveau_ioctl.c
@@ -0,0 +1,87 @@
+/*
+ Copyright (C) 2012 Marcin Slusarz <marcin.slusarz@gmail.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "mmt_nouveau_ioctl.h"
+#include "pub_tool_libcbase.h"
+#include "pub_tool_libcprint.h"
+#include "vki/vki-linux.h"
+
+#include <sys/select.h>
+
+static fd_set nouveau_fds;
+int mmt_trace_nouveau_ioctls = False;
+
+void mmt_nouveau_ioctl_post_open(UWord *args, SysRes res)
+{
+ const char *path = (const char *)args[0];
+
+ if (mmt_trace_nouveau_ioctls)
+ {
+ if (VG_(strncmp)(path, "/dev/dri/card", 13) == 0)
+ FD_SET(res._val, &nouveau_fds);
+ }
+}
+
+void mmt_nouveau_ioctl_post_close(UWord *args)
+{
+ int fd = (int)args[0];
+
+ if (mmt_trace_nouveau_ioctls)
+ FD_CLR(fd, &nouveau_fds);
+}
+
+void mmt_nouveau_ioctl_pre(UWord *args)
+{
+ int fd = args[0];
+// UInt id = args[1];
+// UInt *data = (UInt *) args[2];
+
+ if (!FD_ISSET(fd, &nouveau_fds))
+ return;
+}
+
+void mmt_nouveau_ioctl_post(UWord *args)
+{
+ int fd = args[0];
+ UInt id = args[1];
+ void *data = (void *) args[2];
+
+ if (!FD_ISSET(fd, &nouveau_fds))
+ return;
+
+ if (id == VKI_DRM_IOCTL_NOUVEAU_GROBJ_ALLOC)
+ {
+ struct vki_drm_nouveau_grobj_alloc *arg = data;
+ VG_(message) (Vg_DebugMsg,
+ "create gpu object 0x%08x:0x%08x type 0x%04x (%s)\n",
+ 0, arg->handle, arg->class, "");
+ }
+ else if (id == VKI_DRM_IOCTL_NOUVEAU_GPUOBJ_FREE)
+ {
+ struct vki_drm_nouveau_gpuobj_free *arg = data;
+ VG_(message) (Vg_DebugMsg, "destroy object 0x%08x:0x%08x\n", 0, arg->handle);
+ }
+}
+
+void mmt_nouveau_ioctl_pre_clo_init(void)
+{
+ FD_ZERO(&nouveau_fds);
+}
diff --git a/mmt/mmt_nouveau_ioctl.h b/mmt/mmt_nouveau_ioctl.h
new file mode 100644
index 00000000..c6ed0a30
--- /dev/null
+++ b/mmt/mmt_nouveau_ioctl.h
@@ -0,0 +1,15 @@
+#ifndef MMT_NOUVEAU_IOCTL_H_
+#define MMT_NOUVEAU_IOCTL_H_
+
+#include "pub_tool_basics.h"
+
+extern int mmt_trace_nouveau_ioctls;
+
+void mmt_nouveau_ioctl_post_open(UWord *args, SysRes res);
+void mmt_nouveau_ioctl_post_close(UWord *args);
+void mmt_nouveau_ioctl_pre(UWord *args);
+void mmt_nouveau_ioctl_post(UWord *args);
+void mmt_nouveau_ioctl_pre_clo_init(void);
+
+
+#endif
diff --git a/mmt/mmt_trace.c b/mmt/mmt_trace.c
index 820dcf91..20340838 100644
--- a/mmt/mmt_trace.c
+++ b/mmt/mmt_trace.c
@@ -23,6 +23,7 @@
#include "mmt_trace.h"
#include "mmt_nv_ioctl.h"
+#include "mmt_nouveau_ioctl.h"
#include "pub_tool_libcbase.h"
#include "pub_tool_libcprint.h"
@@ -1070,7 +1071,10 @@ void mmt_trace_load_4_4_4_4_ia(Addr addr, UWord value1, UWord value2,
void mmt_pre_syscall(ThreadId tid, UInt syscallno, UWord *args, UInt nArgs)
{
if (syscallno == __NR_ioctl)
+ {
mmt_nv_ioctl_pre(args);
+ mmt_nouveau_ioctl_pre(args);
+ }
}
static void post_open(ThreadId tid, UWord *args, UInt nArgs, SysRes res)
@@ -1102,6 +1106,7 @@ static void post_open(ThreadId tid, UWord *args, UInt nArgs, SysRes res)
}
mmt_nv_ioctl_post_open(args, res);
+ mmt_nouveau_ioctl_post_open(args, res);
}
static void post_close(ThreadId tid, UWord *args, UInt nArgs, SysRes res)
@@ -1120,6 +1125,7 @@ static void post_close(ThreadId tid, UWord *args, UInt nArgs, SysRes res)
}
mmt_nv_ioctl_post_close(args);
+ mmt_nouveau_ioctl_post_close(args);
}
static void post_mmap(ThreadId tid, UWord *args, UInt nArgs, SysRes res, int offset_unit)
@@ -1216,7 +1222,10 @@ void mmt_post_syscall(ThreadId tid, UInt syscallno, UWord *args,
UInt nArgs, SysRes res)
{
if (syscallno == __NR_ioctl)
+ {
mmt_nv_ioctl_post(args);
+ mmt_nouveau_ioctl_post(args);
+ }
else if (syscallno == __NR_open)
post_open(tid, args, nArgs, res);
else if (syscallno == __NR_close)