summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPekka Paalanen <pq@iki.fi>2008-05-12 21:20:56 +0200
committerThomas Gleixner <tglx@linutronix.de>2008-05-24 11:21:14 +0200
commit8b7d89d02ef3c6a7c73d6596f28cea7632850af4 (patch)
tree32601bf4f34dd9e3ec1e9610c555e10dc448006c /include
parent677aa9f77e8de3791b481a0cec6c8b84d1eec626 (diff)
downloadlwn-8b7d89d02ef3c6a7c73d6596f28cea7632850af4.tar.gz
lwn-8b7d89d02ef3c6a7c73d6596f28cea7632850af4.zip
x86: mmiotrace - trace memory mapped IO
Mmiotrace is a tool for trapping memory mapped IO (MMIO) accesses within the kernel. It is used for debugging and especially for reverse engineering evil binary drivers. Mmiotrace works by wrapping the ioremap family of kernel functions and marking the returned pages as not present. Access to the IO memory triggers a page fault, which will be handled by mmiotrace's custom page fault handler. This will single-step the faulted instruction with the MMIO page marked as present. Access logs are directed to user space via relay and debug_fs. This page fault approach is necessary, because binary drivers have readl/writel etc. calls inlined and therefore extremely difficult to trap with with e.g. kprobes. This patch depends on the custom page fault handlers patch. Signed-off-by: Pekka Paalanen <pq@iki.fi> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/mmiotrace.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h
new file mode 100644
index 000000000000..cb247825f3ec
--- /dev/null
+++ b/include/linux/mmiotrace.h
@@ -0,0 +1,62 @@
+#ifndef MMIOTRACE_H
+#define MMIOTRACE_H
+
+#include <asm/types.h>
+
+#define MMIO_VERSION 0x04
+
+/* mm_io_header.type */
+#define MMIO_OPCODE_MASK 0xff
+#define MMIO_OPCODE_SHIFT 0
+#define MMIO_WIDTH_MASK 0xff00
+#define MMIO_WIDTH_SHIFT 8
+#define MMIO_MAGIC (0x6f000000 | (MMIO_VERSION<<16))
+#define MMIO_MAGIC_MASK 0xffff0000
+
+enum mm_io_opcode { /* payload type: */
+ MMIO_READ = 0x1, /* struct mm_io_rw */
+ MMIO_WRITE = 0x2, /* struct mm_io_rw */
+ MMIO_PROBE = 0x3, /* struct mm_io_map */
+ MMIO_UNPROBE = 0x4, /* struct mm_io_map */
+ MMIO_MARKER = 0x5, /* raw char data */
+ MMIO_UNKNOWN_OP = 0x6, /* struct mm_io_rw */
+};
+
+struct mm_io_header {
+ __u32 type;
+ __u32 sec; /* timestamp */
+ __u32 nsec;
+ __u32 pid; /* PID of the process, or 0 for kernel core */
+ __u16 data_len; /* length of the following payload */
+};
+
+struct mm_io_rw {
+ __u64 address; /* virtual address of register */
+ __u64 value;
+ __u64 pc; /* optional program counter */
+};
+
+struct mm_io_map {
+ __u64 phys; /* base address in PCI space */
+ __u64 addr; /* base virtual address */
+ __u64 len; /* mapping size */
+ __u64 pc; /* optional program counter */
+};
+
+
+/*
+ * These structures are used to allow a single relay_write()
+ * call to write a full packet.
+ */
+
+struct mm_io_header_rw {
+ struct mm_io_header header;
+ struct mm_io_rw rw;
+} __attribute__((packed));
+
+struct mm_io_header_map {
+ struct mm_io_header header;
+ struct mm_io_map map;
+} __attribute__((packed));
+
+#endif /* MMIOTRACE_H */