summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/sysc_shim.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/sysc_shim.c')
-rw-r--r--tools/guest-diag/sysc_shim.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/tools/guest-diag/sysc_shim.c b/tools/guest-diag/sysc_shim.c
new file mode 100644
index 0000000..9b07e4c
--- /dev/null
+++ b/tools/guest-diag/sysc_shim.c
@@ -0,0 +1,73 @@
+/* sysc_shim.c - intercept syscall() so we can dump ioctl buffer *results*
+ * for UVM ioctls (libcuda calls syscall(SYS_ioctl, ...) directly, so an
+ * ioctl() wrapper is bypassed but syscall() is not).
+ * Build in guest: gcc -shared -fPIC -O1 -o /tmp/sysc.so sysc_shim.c -ldl
+ * Run: LD_PRELOAD=/tmp/sysc.so /tmp/cdt
+ */
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+static long (*real_syscall)(long, ...);
+
+static void dump(const char *tag, unsigned long req, void *arg, long ret)
+{
+ unsigned int *p = (unsigned int *)arg;
+ char buf[512];
+ int n, i;
+ long *vp = (long *)arg;
+
+ if (!p)
+ return;
+ n = 0;
+ n += __builtin_snprintf(buf + n, sizeof(buf) - n,
+ "SYSC[%s] req=0x%lx ret=%ld dwords: ", tag, req,
+ ret);
+ for (i = 0; i < 16 && n < (int)sizeof(buf) - 16; i++)
+ n += __builtin_snprintf(buf + n, sizeof(buf) - n, "%08x ",
+ p[i]);
+ (void)vp;
+ write(2, buf, n);
+ write(2, "\n", 1);
+}
+
+long syscall(long nr, ...)
+{
+ va_list ap;
+ long a1, a2, a3, a4, a5, a6;
+ long ret;
+
+ if (!real_syscall)
+ real_syscall = dlsym(RTLD_NEXT, "syscall");
+
+ va_start(ap, nr);
+ a1 = va_arg(ap, long);
+ a2 = va_arg(ap, long);
+ a3 = va_arg(ap, long);
+ a4 = va_arg(ap, long);
+ a5 = va_arg(ap, long);
+ a6 = va_arg(ap, long);
+ va_end(ap);
+
+ ret = real_syscall(nr, a1, a2, a3, a4, a5, a6);
+
+ if (nr == SYS_ioctl) {
+ unsigned long req = (unsigned long)a2;
+ switch (req) {
+ case 0x1: /* UVM_RESERVE_VA */
+ case 0x2: /* UVM_RELEASE_VA */
+ case 0x25: /* UVM_REGISTER_GPU */
+ case 0x27: /* UVM_PAGEABLE_MEM_ACCESS */
+ case 0x17: /* UVM_EVENT_CTRL */
+ case 0x19: /* UVM_REGISTER_MPS_CLIENT */
+ dump("uvmioctl", req, (void *)a3, ret);
+ break;
+ default:
+ break;
+ }
+ }
+ return ret;
+}