diff --git a/cpu-all.h b/cpu-all.h
index 88970a2..2e666e4 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -697,21 +697,24 @@ extern unsigned long reserved_va;
 
 #if defined(CONFIG_USER_ONLY)
 
+/* XXX: INSTRUMENT can capture these when enabled. */
+/* TODO: INSTRUMENT might find a NULL 'cpu_single_env', should check... */
+
 /* if user mode, no other memory access functions */
-#define ldub(p) ldub_raw(p)
-#define ldsb(p) ldsb_raw(p)
-#define lduw(p) lduw_raw(p)
-#define ldsw(p) ldsw_raw(p)
-#define ldl(p) ldl_raw(p)
-#define ldq(p) ldq_raw(p)
-#define ldfl(p) ldfl_raw(p)
-#define ldfq(p) ldfq_raw(p)
-#define stb(p, v) stb_raw(p, v)
-#define stw(p, v) stw_raw(p, v)
-#define stl(p, v) stl_raw(p, v)
-#define stq(p, v) stq_raw(p, v)
-#define stfl(p, v) stfl_raw(p, v)
-#define stfq(p, v) stfq_raw(p, v)
+#define ldub(p)    ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_RD); ldub_raw(p);    })
+#define ldsb(p)    ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_RD); ldsb_raw(p);    })
+#define lduw(p)    ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_RD); lduw_raw(p);    })
+#define ldsw(p)    ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_RD); ldsw_raw(p);    })
+#define ldl(p)     ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_RD); ldl_raw(p);     })
+#define ldq(p)     ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_RD); ldq_raw(p);     })
+#define ldfl(p)    ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_RD); ldfl_raw(p);    })
+#define ldfq(p)    ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_RD); ldfq_raw(p);    })
+#define stb(p, v)  ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_WR); stb_raw(p, v);  })
+#define stw(p, v)  ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_WR); stw_raw(p, v);  })
+#define stl(p, v)  ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_WR); stl_raw(p, v);  })
+#define stq(p, v)  ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_WR); stq_raw(p, v);  })
+#define stfl(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_WR); stfl_raw(p, v); })
+#define stfq(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_WR); stfq_raw(p, v); })
 
 #define ldub_code(p) ldub_raw(p)
 #define ldsb_code(p) ldsb_raw(p)
@@ -720,20 +723,20 @@ extern unsigned long reserved_va;
 #define ldl_code(p) ldl_raw(p)
 #define ldq_code(p) ldq_raw(p)
 
-#define ldub_kernel(p) ldub_raw(p)
-#define ldsb_kernel(p) ldsb_raw(p)
-#define lduw_kernel(p) lduw_raw(p)
-#define ldsw_kernel(p) ldsw_raw(p)
-#define ldl_kernel(p) ldl_raw(p)
-#define ldq_kernel(p) ldq_raw(p)
-#define ldfl_kernel(p) ldfl_raw(p)
-#define ldfq_kernel(p) ldfq_raw(p)
-#define stb_kernel(p, v) stb_raw(p, v)
-#define stw_kernel(p, v) stw_raw(p, v)
-#define stl_kernel(p, v) stl_raw(p, v)
-#define stq_kernel(p, v) stq_raw(p, v)
-#define stfl_kernel(p, v) stfl_raw(p, v)
-#define stfq_kernel(p, vt) stfq_raw(p, v)
+#define ldub_kernel(p)     ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_RD); ldub_raw(p);    })
+#define ldsb_kernel(p)     ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_RD); ldsb_raw(p);    })
+#define lduw_kernel(p)     ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_RD); lduw_raw(p);    })
+#define ldsw_kernel(p)     ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_RD); ldsw_raw(p);    })
+#define ldl_kernel(p)      ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_RD); ldl_raw(p);     })
+#define ldq_kernel(p)      ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_RD); ldq_raw(p);     })
+#define ldfl_kernel(p)     ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_RD); ldfl_raw(p);    })
+#define ldfq_kernel(p)     ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_RD); ldfq_raw(p);    })
+#define stb_kernel(p, v)   ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_WR); stb_raw(p, v);  })
+#define stw_kernel(p, v)   ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_WR); stw_raw(p, v);  })
+#define stl_kernel(p, v)   ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_WR); stl_raw(p, v);  })
+#define stq_kernel(p, v)   ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_WR); stq_raw(p, v);  })
+#define stfl_kernel(p, v)  ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_WR); stfl_raw(p, v); })
+#define stfq_kernel(p, vt) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_WR); stfq_raw(p, v); })
 
 #endif /* defined(CONFIG_USER_ONLY) */
 
diff --git a/exec-all.h b/exec-all.h
index 35d2a57..4c2c1d2 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -288,6 +288,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
 #include "softmmu_defs.h"
 
 #define ACCESS_TYPE (NB_MMU_MODES + 1)
+#define INSTR_CODE_ACCESSOR 1          /* do not instrument '*_code' accesses */
 #define MEMSUFFIX _code
 #define env cpu_single_env
 
@@ -304,6 +305,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
 #include "softmmu_header.h"
 
 #undef ACCESS_TYPE
+#undef INSTR_CODE_ACCESSOR
 #undef MEMSUFFIX
 #undef env
 
diff --git a/linux-user/main.c b/linux-user/main.c
index dbba8be..b82d53c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2948,6 +2948,12 @@ int main(int argc, char **argv, char **envp)
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+
+#if defined(CONFIG_INSTRUMENT)
+    /* hack around 'env' vs 'cpu_single_env' */
+    cpu_single_env = env;
+#endif
+
 #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
     cpu_reset(env);
 #endif
@@ -3369,6 +3375,12 @@ int main(int argc, char **argv, char **envp)
         gdbserver_start (gdbstub_port);
         gdb_handlesig(env, 0);
     }
+
+#if defined(CONFIG_INSTRUMENT)
+    /* hack around 'env' vs 'cpu_single_env' */
+    cpu_single_env = NULL;
+#endif
+
     cpu_loop(env);
     /* never exits */
     return 0;
diff --git a/softmmu_header.h b/softmmu_header.h
index 2f95c33..b6052f3 100644
--- a/softmmu_header.h
+++ b/softmmu_header.h
@@ -79,6 +79,11 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
     unsigned long physaddr;
     int mmu_idx;
 
+#if !defined(INSTR_CODE_ACCESSOR)       /* XXX: kind of hackish, but couldn't
+                                         * find another way */
+    INSTR_DO_VMEM(env, ptr, DATA_SIZE, INSTR_MEM_RD);
+#endif
+
     addr = ptr;
     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     mmu_idx = CPU_MMU_INDEX;
@@ -100,6 +105,11 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
     unsigned long physaddr;
     int mmu_idx;
 
+#if !defined(INSTR_CODE_ACCESSOR)       /* XXX: kind of hackish, but couldn't
+                                         * find another way */
+    INSTR_DO_VMEM(env, ptr, DATA_SIZE, INSTR_MEM_RD);
+#endif
+
     addr = ptr;
     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     mmu_idx = CPU_MMU_INDEX;
@@ -125,6 +135,11 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
     unsigned long physaddr;
     int mmu_idx;
 
+#if !defined(INSTR_CODE_ACCESSOR)       /* XXX: kind of hackish, but couldn't
+                                         * find another way */
+    INSTR_DO_VMEM(env, ptr, DATA_SIZE, INSTR_MEM_WR);
+#endif
+
     addr = ptr;
     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     mmu_idx = CPU_MMU_INDEX;
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 3a1c625..1e7e66b 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -32,6 +32,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 #undef ALPHA_DEBUG_DISAS
 #define CONFIG_SOFTFLOAT_INLINE
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index a9fbe5b..8c47e34 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -34,6 +34,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 #define ENABLE_ARCH_5J    0
 #define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
 #define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 8361369..8f43ae5 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -41,6 +41,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 #define DISAS_CRIS 0
 #if DISAS_CRIS
 #  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 02a93a4..aa3b307 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -33,6 +33,10 @@
 #include "helper.h"
 
 #if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
+#if defined(CONFIG_INSTRUMENT)
 static inline void
 mem_exchange (void * tmp, void * start1, size_t size1,
               void * start2, size_t size2)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0c6f0e2..e212392 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -34,6 +34,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 //#define DEBUG_DISPATCH 1
 
 /* Fake floating point.  */
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 9dcc78a..0adf173 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -35,6 +35,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 #define SIM_COMPAT 0
 #define DISAS_GNU 1
 #define DISAS_MB 1
diff --git a/target-mips/translate.c b/target-mips/translate.c
index d62c615..a92ac7f 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -36,6 +36,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fd06861..555658c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -33,6 +33,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 #define CPU_SINGLE_STEP 0x1
 #define CPU_BRANCH_STEP 0x2
 #define GDBSTUB_SINGLE_STEP 0x4
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 44dfa65..168017f 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -23,6 +23,10 @@
 #include "tcg-op.h"
 #include "qemu-log.h"
 
+#ifdef CONFIG_INSTRUMENT
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 void cpu_dump_state(CPUState *env, FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags)
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index deee939..5e232e5 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -36,6 +36,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 typedef struct DisasContext {
     struct TranslationBlock *tb;
     target_ulong pc;
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 23f9519..2c2c505 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -33,6 +33,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
 #define DEBUG_DISAS
 
 #define DYNAMIC_PC  1 /* dynamic pc value */
