diff --git a/gdb/nios2-linux-tdep.c b/gdb/nios2-linux-tdep.c
index 0a837b0..c73d8af 100644
--- a/gdb/nios2-linux-tdep.c
+++ b/gdb/nios2-linux-tdep.c
@@ -29,6 +29,7 @@
 #include "linux-tdep.h"
 #include "glibc-tdep.h"
 #include "nios2-tdep.h"
+#include "breakpoint.h"
 
 #include "features/nios2-linux.c"
 
@@ -185,6 +186,32 @@ nios2_linux_syscall_next_pc (struct frame_info *frame)
   return pc + NIOS2_OPCODE_SIZE;
 }
 
+/* Override the bare-metal software_single_step gdbarch method.
+   If the PC where we'd ordinarily want to set the breakpoint is
+   the signal trampoline at 0x1044, the kernel will not let us set a
+   breakpoint at that location.  So, treat it as if it were a function call
+   and set the breakpoint on its return address instead.  */
+
+static int
+nios2_linux_software_single_step (struct frame_info *frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct address_space *aspace;
+  CORE_ADDR next_pc = nios2_get_next_pc (frame, get_frame_pc (frame));
+
+  if (next_pc == NIOS2_SIGRETURN_TRAMP_ADDR)
+    {
+      frame = get_prev_frame (frame);
+      next_pc = frame_unwind_caller_pc (frame);
+    }
+
+  aspace = get_frame_address_space (frame);
+  insert_single_step_breakpoint (gdbarch, aspace, next_pc);
+
+  return 1;
+}
+
+
 /* Hook function for gdbarch_register_osabi.  */
 
 static void
@@ -210,6 +237,8 @@ nios2_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tramp_frame_prepend_unwinder (gdbarch,
                                 &nios2_linux_rt_sigreturn_tramp_frame);
 
+  /* Single stepping.  */
+  set_gdbarch_software_single_step (gdbarch, nios2_linux_software_single_step);
   tdep->syscall_next_pc = nios2_linux_syscall_next_pc;
 
   /* Index of target address word in glibc jmp_buf.  */
diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
index 988b9fc..4d9c415 100644
--- a/gdb/nios2-tdep.c
+++ b/gdb/nios2-tdep.c
@@ -1576,7 +1576,7 @@ static const struct frame_unwind nios2_stub_frame_unwind =
 /* Determine where to set a single step breakpoint while considering
    branch prediction.  */
 
-static CORE_ADDR
+CORE_ADDR
 nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
diff --git a/gdb/nios2-tdep.h b/gdb/nios2-tdep.h
index af36c41..46eb3e2 100644
--- a/gdb/nios2-tdep.h
+++ b/gdb/nios2-tdep.h
@@ -77,4 +77,6 @@ struct gdbarch_tdep
 extern struct target_desc *tdesc_nios2_linux;
 extern struct target_desc *tdesc_nios2;
 
+extern CORE_ADDR nios2_get_next_pc (struct frame_info *, CORE_ADDR);
+
 #endif /* NIOS2_TDEP_H */
diff --git a/gdb/testsuite/gdb.base/sigaltstack.exp b/gdb/testsuite/gdb.base/sigaltstack.exp
index b65ea48..59a6c17 100644
--- a/gdb/testsuite/gdb.base/sigaltstack.exp
+++ b/gdb/testsuite/gdb.base/sigaltstack.exp
@@ -76,6 +76,7 @@ proc finish_test { pattern msg } {
 	    # don't gracefully fall back to single-stepping.
 	    setup_kfail gdb/8841 "i?86-*-linux*"
 	    setup_kfail gdb/8841 "*-*-openbsd*"
+	    setup_kfail gdb/8841 "nios2-*-linux*"
 	    fail "$msg (could not set breakpoint)"
 	}
 	-re "$pattern.*${gdb_prompt} $" {
diff --git a/gdb/testsuite/gdb.base/sigstep.exp b/gdb/testsuite/gdb.base/sigstep.exp
index 3c9454c..800fa08 100644
--- a/gdb/testsuite/gdb.base/sigstep.exp
+++ b/gdb/testsuite/gdb.base/sigstep.exp
@@ -161,6 +161,14 @@ set in_handler_map {
 		fail "$test (spurious SIGTRAP)"
 		return
 	    }
+	    -re "Cannot insert breakpoint 0.*${gdb_prompt} $" {
+		# Some platforms use a special read-only page for signal
+		# trampolines.  We can't set a breakpoint there, and we
+		# don't gracefully fall back to single-stepping.
+		setup_kfail gdb/8841 "nios2-*-linux*"
+		fail "$test (could not set breakpoint)"
+		return
+	    }
 	    -re "other handler location.*$gdb_prompt $" {
 		pass $test
 	    }
@@ -203,6 +211,7 @@ proc advancei { cmd } {
 		# don't gracefully fall back to single-stepping.
 		setup_kfail gdb/8841 "i?86-*-linux*"
 		setup_kfail gdb/8841 "*-*-openbsd*"
+		setup_kfail gdb/8841 "nios2-*-linux*"
 		fail "$test (could not set breakpoint)"
 		return
 	    }
@@ -225,6 +234,10 @@ proc advancei { cmd } {
 		pass "$test"
 	    }
 	    -re "main .*${gdb_prompt} $" {
+	    # Some targets cannot set single-step breakpoints on a
+	    # signal trampoline and step over the trampoline
+	    # instead of through it.
+	    setup_kfail gdb/8841 "nios2-*-linux*"
 		fail "$test (in main)"
 	    }
 	    -re "$inferior_exited_re normally.*${gdb_prompt} $" {
