diff --git a/core/arch/mangle_shared.c b/core/arch/mangle_shared.c
index d72cb8f917574da1f5a196f05c419da0d73520b4..1b547052c3d81ec665be505234cbfcafef932bd2 100644
--- a/core/arch/mangle_shared.c
+++ b/core/arch/mangle_shared.c
@@ -988,6 +988,7 @@ mangle_rseq_insert_native_sequence(dcontext_t *dcontext, instrlist_t *ilist,
         int i;
         for (i = 0; i < DR_NUM_GPR_REGS; i++) {
             if (reg_written[i]) {
+                /* XXX: Keep this consistent with instr_is_rseq_load() in translate.c. */
                 size_t offs = offsetof(dcontext_t, rseq_entry_state) + sizeof(reg_t) * i;
                 PRE(ilist, insert_at,
                     XINST_CREATE_load(dcontext,
diff --git a/core/translate.c b/core/translate.c
index 0c2991d3080f7ede5b6a53cf8d91de10703ca5aa..deb6c2726a1c912db0718782f514d644c24d88d4 100644
--- a/core/translate.c
+++ b/core/translate.c
@@ -1,5 +1,5 @@
 /* **********************************************************
- * Copyright (c) 2010-2019 Google, Inc.  All rights reserved.
+ * Copyright (c) 2010-2020 Google, Inc.  All rights reserved.
  * Copyright (c) 2000-2010 VMware, Inc.  All rights reserved.
  * **********************************************************/
 
@@ -159,6 +159,31 @@ instr_is_seg_ref_load(dcontext_t *dcontext, instr_t *inst)
 #    endif /* X86 */
     return false;
 }
+
+static inline bool
+instr_is_rseq_load(dcontext_t *dcontext, instr_t *inst)
+{
+    /* TODO i#2350: Add non-x86 support. */
+#    if defined(LINUX) && defined(X86)
+    /* This won't fault but we don't want it marked as unsupported. */
+    if (!instr_is_our_mangling(inst))
+        return false;
+    /* XXX: Keep this consistent with mangle_rseq_* in mangle_shared.c. */
+    if (instr_get_opcode(inst) == OP_mov_ld && opnd_is_reg(instr_get_dst(inst, 0)) &&
+        opnd_is_base_disp(instr_get_src(inst, 0))) {
+        reg_id_t dst = opnd_get_reg(instr_get_dst(inst, 0));
+        opnd_t memref = instr_get_src(inst, 0);
+        int disp = opnd_get_disp(memref);
+        if (reg_is_gpr(dst) && reg_is_pointer_sized(dst) &&
+            opnd_get_index(memref) == DR_REG_NULL &&
+            disp ==
+                offsetof(dcontext_t, rseq_entry_state) +
+                    sizeof(reg_t) * (dst - DR_REG_START_GPR))
+            return true;
+    }
+#    endif
+    return false;
+}
 #endif /* UNIX */
 
 #ifdef ARM
@@ -394,6 +419,8 @@ translate_walk_track(dcontext_t *tdcontext, instr_t *inst, translate_walk_t *wal
             /* nothing to do */
         } else if (instr_is_seg_ref_load(tdcontext, inst)) {
             /* nothing to do */
+        } else if (instr_is_rseq_load(tdcontext, inst)) {
+            /* nothing to do */
         }
 #endif
 #ifdef ARM
diff --git a/suite/tests/linux/rseq.c b/suite/tests/linux/rseq.c
index 1405d611fbf237c56609fbc9c9f2aa63e7059f3c..a57a03cd7206970dafbec334750c8978df770487 100644
--- a/suite/tests/linux/rseq.c
+++ b/suite/tests/linux/rseq.c
@@ -1,5 +1,5 @@
 /* **********************************************************
- * Copyright (c) 2019 Google, Inc.  All rights reserved.
+ * Copyright (c) 2019-2020 Google, Inc.  All rights reserved.
  * **********************************************************/
 
 /*
@@ -190,8 +190,6 @@ test_rseq_call(void)
 static void
 test_rseq_branches_once(bool force_restart, int *completions_out, int *restarts_out)
 {
-    /* We use static to avoid stack reference issues with our extra frame inside the asm.
-     */
     __u32 id = RSEQ_CPU_ID_UNINITIALIZED;
     int completions = 0;
     int restarts = 0;
@@ -271,6 +269,71 @@ test_rseq_branches(void)
     assert(completions == 1 && restarts > 0 && sigill_count == 1);
 }
 
+/* Tests that DR handles a signal inside its native rseq copy.
+ * Any synchronous signal is going to pretty much never happen for real, since
+ * it would happen on the instrumentation execution and never make it to the
+ * native run, but an asynchronous signal could arrive.
+ * It's complicated to set up an asynchronous signal at the right spot, so
+ * we cheat and take advantage of DR not restoring XMM state to have different
+ * behavior in the two DR executions of the rseq code.
+ */
+static void
+test_rseq_native_fault(void)
+{
+    int restarts = 0;
+    __asm__ __volatile__(
+        /* clang-format off */ /* (avoid indenting next few lines) */
+        RSEQ_ADD_TABLE_ENTRY(fault, 2f, 3f, 4f)
+        /* clang-format on */
+
+        "6:\n\t"
+        /* Store the entry into the ptr. */
+        "leaq rseq_cs_fault(%%rip), %%rax\n\t"
+        "movq %%rax, %[rseq_tls]\n\t"
+        "pxor %%xmm0, %%xmm0\n\t"
+        "mov $1,%%rcx\n\t"
+        "movq %%rcx, %%xmm1\n\t"
+
+        /* Restartable sequence. */
+        "2:\n\t"
+        /* Increase xmm0 every time.  DR (currently) won't restore xmm inputs
+         * to rseq sequences, nor does it detect that it needs to.
+         */
+        "paddq %%xmm1,%%xmm0\n\t"
+        "movq %%xmm0, %%rax\n\t"
+        /* Only raise the signal on the 2nd run == native run. */
+        "cmp $2, %%rax\n\t"
+        "jne 11f\n\t"
+        /* Raise a signal on the native run. */
+        "ud2a\n\t"
+        "11:\n\t"
+        "nop\n\t"
+
+        /* Post-commit. */
+        "3:\n\t"
+        "jmp 5f\n\t"
+
+        /* Abort handler. */
+        /* clang-format off */ /* (avoid indenting next few lines) */
+        ".long " STRINGIFY(RSEQ_SIG) "\n\t"
+        "4:\n\t"
+        "addl $1, %[restarts]\n\t"
+        "jmp 2b\n\t"
+
+        /* Clear the ptr. */
+        "13:\n\t"
+        "12:\n\t"
+        "5:\n\t"
+        "movq $0, %[rseq_tls]\n\t"
+        /* clang-format on */
+
+        : [rseq_tls] "=m"(rseq_tls.rseq_cs), [restarts] "=m"(restarts)
+        :
+        : "rax", "rcx", "rdx", "xmm0", "xmm1", "memory");
+    /* This is expected to fail on a native run where restarts will be 0. */
+    assert(restarts > 0);
+}
+
 #ifdef RSEQ_TEST_ATTACH
 void *
 rseq_thread_loop(void *arg)
@@ -356,6 +419,8 @@ main()
         test_rseq_call();
         /* Test variations inside the sequence. */
         test_rseq_branches();
+        /* Test a fault in the native run. */
+        test_rseq_native_fault();
         /* Test a trace. */
         int i;
         for (i = 0; i < 200; i++)