diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index 2956211..567ab98 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -571,6 +571,14 @@ aarch64_supports_range_stepping (void)
   return 1;
 }
 
+/* Support for hardware single step.  */
+
+static int
+aarch64_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 struct linux_target_ops the_low_target =
 {
   aarch64_arch_setup,
@@ -603,6 +611,7 @@ struct linux_target_ops the_low_target =
   NULL, /* emit_ops */
   NULL, /* get_min_fast_tracepoint_insn_len */
   aarch64_supports_range_stepping,
+  aarch64_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index eb98a36..a9ed91d 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -1112,6 +1112,14 @@ arm_arch_setup (void)
   arm_set_byte_order ();
 }
 
+/* Support for hardware single step.  */
+
+static int
+arm_supports_hardware_single_step (void)
+{
+  return 0;
+}
+
 /* Register sets without using PTRACE_GETREGSET.  */
 
 static struct regset_info arm_regsets[] = {
@@ -1190,6 +1198,7 @@ struct linux_target_ops the_low_target = {
   NULL, /* emit_ops */
   NULL, /* get_min_fast_tracepoint_insn_len */
   NULL, /* supports_range_stepping */
+  arm_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-bfin-low.c b/gdb/gdbserver/linux-bfin-low.c
index 3032a34..18b8e43 100644
--- a/gdb/gdbserver/linux-bfin-low.c
+++ b/gdb/gdbserver/linux-bfin-low.c
@@ -103,6 +103,14 @@ bfin_arch_setup (void)
   current_process ()->tdesc = tdesc_bfin;
 }
 
+/* Support for hardware single step.  */
+
+static int
+bfin_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 static struct usrregs_info bfin_usrregs_info =
   {
     bfin_num_regs,
@@ -133,6 +141,26 @@ struct linux_target_ops the_low_target = {
   NULL, /* get_next_pcs */
   2,
   bfin_breakpoint_at,
+  NULL, /* supports_z_point_type */
+  NULL, /* insert_point */
+  NULL, /* remove_point */
+  NULL, /* stopped_by_watchpoint */
+  NULL, /* stopped_data_address */
+  NULL, /* collect_ptrace_register */
+  NULL, /* supply_ptrace_register */
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  bfin_supports_hardware_single_step,
 };
 
 
diff --git a/gdb/gdbserver/linux-cris-low.c b/gdb/gdbserver/linux-cris-low.c
index cd1ae4d..b56827e 100644
--- a/gdb/gdbserver/linux-cris-low.c
+++ b/gdb/gdbserver/linux-cris-low.c
@@ -104,18 +104,6 @@ cris_breakpoint_at (CORE_ADDR where)
   return 0;
 }
 
-/* We only place breakpoints in empty marker functions, and thread locking
-   is outside of the function.  So rather than importing software single-step,
-   we can just run until exit.  */
-static void
-cris_get_next_pcs (struct get_next_pcs *next_pcs)
-{
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
-  CORE_ADDR pc;
-  collect_register_by_name (regcache, "srp", &pc);
-  VEC_safe_push (CORE_ADDR, next_pcs->result, pc);
-}
-
 static void
 cris_arch_setup (void)
 {
@@ -149,13 +137,9 @@ struct linux_target_ops the_low_target = {
   cris_get_pc,
   cris_set_pc,
   cris_breakpoint_from_pc,
-  cris_get_next_pcs,
+  NULL,
   0,
   cris_breakpoint_at,
-  0,
-  0,
-  0,
-  0,
 };
 
 void
diff --git a/gdb/gdbserver/linux-crisv32-low.c b/gdb/gdbserver/linux-crisv32-low.c
index 05ad85a..4e9ebc1 100644
--- a/gdb/gdbserver/linux-crisv32-low.c
+++ b/gdb/gdbserver/linux-crisv32-low.c
@@ -100,22 +100,6 @@ cris_breakpoint_at (CORE_ADDR where)
   return 0;
 }
 
-/* We only place breakpoints in empty marker functions, and thread locking
-   is outside of the function.  So rather than importing software single-step,
-   we can just run until exit.  */
-
-/* FIXME: This function should not be needed, since we have PTRACE_SINGLESTEP
-   for CRISv32.  Without it, td_ta_event_getmsg in thread_db_create_event
-   will fail when debugging multi-threaded applications.  */
-static void
-cris_get_next_pcs (struct get_next_pcs *next_pcs)
-{
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
-  CORE_ADDR pc;
-  collect_register_by_name (regcache, "srp", &pc);
-  VEC_safe_push (CORE_ADDR, next_pcs->result, pc);
-}
-
 static void
 cris_write_data_breakpoint (struct regcache *regcache,
 			    int bp, unsigned long start, unsigned long end)
@@ -386,6 +370,14 @@ cris_arch_setup (void)
   current_process ()->tdesc = tdesc_crisv32;
 }
 
+/* Support for hardware single step.  */
+
+static int
+cris_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 static struct regset_info cris_regsets[] = {
   { PTRACE_GETREGS, PTRACE_SETREGS, 0, cris_num_regs * 4,
     GENERAL_REGS, cris_fill_gregset, cris_store_gregset },
@@ -428,7 +420,7 @@ struct linux_target_ops the_low_target = {
   cris_get_pc,
   cris_set_pc,
   cris_breakpoint_from_pc,
-  cris_get_next_pcs,
+  NULL,
   0,
   cris_breakpoint_at,
   cris_supports_z_point_type,
@@ -436,6 +428,21 @@ struct linux_target_ops the_low_target = {
   cris_remove_point,
   cris_stopped_by_watchpoint,
   cris_stopped_data_address,
+  NULL, /* collect_ptrace_register */
+  NULL, /* supply_ptrace_register */
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  cris_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 229df46..f19769d 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -272,22 +272,35 @@ static void complete_ongoing_step_over (void);
    being stepped.  */
 ptid_t step_over_bkpt;
 
-/* True if the low target can hardware single-step.  Such targets
-   don't need a GET_NEXT_PCS callback.  */
+/* True if the low target can hardware single-step.  */
 
 static int
 can_hardware_single_step (void)
 {
-  return (the_low_target.get_next_pcs == NULL);
+  if (the_low_target.supports_hardware_single_step != NULL)
+    return the_low_target.supports_hardware_single_step ();
+  else
+    return 0;
+}
+
+/* True if the low target can software single-step.  Such targets
+   implement the GET_NEXT_PCS callback.  */
+
+static int
+can_software_single_step (void)
+{
+  return (the_low_target.get_next_pcs != NULL);
 }
 
-/* True if the low target supports memory breakpoints.  If so, we'll
-   have a GET_PC implementation.  */
+/* True if the low target supports memory breakpoints.  If so, we'll have a
+   GET_PC implementation. We will also need to support hardware or software
+   single stepping. */
 
 static int
 supports_breakpoints (void)
 {
-  return (the_low_target.get_pc != NULL);
+  return (the_low_target.get_pc != NULL &&
+	  (can_hardware_single_step () || can_software_single_step ()));
 }
 
 /* Returns true if this target can support fast tracepoints.  This
@@ -4026,10 +4039,16 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
       {
 	step = 1;
       }
-    else {
-      install_software_single_step_breakpoints (lwp);
-      step = 0;
-    }
+    else if (can_software_single_step ())
+      {
+	install_software_single_step_breakpoints (lwp);
+	step = 0;
+      }
+    else
+      {
+	internal_error (__FILE__, __LINE__,
+			"stepping is not implemented on this target");
+      }
   }
 
   if (proc->tdesc != NULL && the_low_target.get_pc != NULL)
@@ -4439,11 +4458,16 @@ start_step_over (struct lwp_info *lwp)
     {
       step = 1;
     }
-  else
+  else if (can_software_single_step ())
     {
       install_software_single_step_breakpoints (lwp);
       step = 0;
     }
+  else
+    {
+      internal_error (__FILE__, __LINE__,
+		      "stepping is not implemented on this target");
+    }
 
   current_thread = saved_thread;
 
@@ -5638,6 +5662,12 @@ linux_supports_hardware_single_step (void)
 }
 
 static int
+linux_supports_software_single_step (void)
+{
+  return can_software_single_step ();
+}
+
+static int
 linux_stopped_by_watchpoint (void)
 {
   struct lwp_info *lwp = get_thread_lwp (current_thread);
@@ -7064,6 +7094,7 @@ static struct target_ops linux_target_ops = {
   linux_mntns_unlink,
   linux_mntns_readlink,
   linux_breakpoint_from_pc,
+  linux_supports_software_single_step,
 };
 
 static void
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 597c36d..b6f8175 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -240,6 +240,9 @@ struct linux_target_ops
 
   /* Returns true if the low target supports range stepping.  */
   int (*supports_range_stepping) (void);
+
+  /* Returns true if the low target supports hardware single step.  */
+  int (*supports_hardware_single_step) (void);
 };
 
 extern struct linux_target_ops the_low_target;
diff --git a/gdb/gdbserver/linux-m32r-low.c b/gdb/gdbserver/linux-m32r-low.c
index 4712a32..3767f35 100644
--- a/gdb/gdbserver/linux-m32r-low.c
+++ b/gdb/gdbserver/linux-m32r-low.c
@@ -101,6 +101,14 @@ m32r_arch_setup (void)
   current_process ()->tdesc = tdesc_m32r;
 }
 
+/* Support for hardware single step.  */
+
+static int
+m32r_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 static struct usrregs_info m32r_usrregs_info =
   {
     m32r_num_regs,
@@ -131,6 +139,26 @@ struct linux_target_ops the_low_target = {
   NULL,
   0,
   m32r_breakpoint_at,
+  NULL, /* supports_z_point_type */
+  NULL, /* insert_point */
+  NULL, /* remove_point */
+  NULL, /* stopped_by_watchpoint */
+  NULL, /* stopped_data_address */
+  NULL, /* collect_ptrace_register */
+  NULL, /* supply_ptrace_register */
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  m32r_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c
index d462f2c..e752b7e 100644
--- a/gdb/gdbserver/linux-mips-low.c
+++ b/gdb/gdbserver/linux-mips-low.c
@@ -274,21 +274,6 @@ mips_breakpoint_from_pc (CORE_ADDR *pcptr, int *len)
   return (const unsigned char *) &mips_breakpoint;
 }
 
-/* We only place breakpoints in empty marker functions, and thread locking
-   is outside of the function.  So rather than importing software single-step,
-   we can just run until exit.  */
-static void
-mips_get_next_pcs (struct get_next_pcs *next_pcs)
-{
-  CORE_ADDR result;
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
-  union mips_register ra;
-  collect_register_by_name (regcache, "r31", ra.buf);
-  result = register_size (regcache->tdesc, 0) == 4 ? ra.reg32 : ra.reg64;
-
-  VEC_safe_push (CORE_ADDR, next_pcs->result, result);
-}
-
 static int
 mips_breakpoint_at (CORE_ADDR where)
 {
@@ -893,7 +878,7 @@ struct linux_target_ops the_low_target = {
   mips_get_pc,
   mips_set_pc,
   mips_breakpoint_from_pc,
-  mips_get_next_pcs,
+  NULL, /* get_next_pcs */
   0,
   mips_breakpoint_at,
   mips_supports_z_point_type,
diff --git a/gdb/gdbserver/linux-nios2-low.c b/gdb/gdbserver/linux-nios2-low.c
index a24eb23..cb3addd 100644
--- a/gdb/gdbserver/linux-nios2-low.c
+++ b/gdb/gdbserver/linux-nios2-low.c
@@ -146,18 +146,6 @@ nios2_breakpoint_from_pc (CORE_ADDR *pcptr, int *len)
   return (const unsigned char *) &nios2_breakpoint;
 }
 
-/* Implement the get_next_pcs linux_target_ops method.  */
-
-static void
-nios2_get_next_pcs (struct get_next_pcs *next_pcs)
-{
-  union nios2_register ra;
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
-
-  collect_register_by_name (regcache, "ra", ra.buf);
-  VEC_safe_push (CORE_ADDR, next_pcs->result, ra.reg32);
-}
-
 /* Implement the breakpoint_at linux_target_ops method.  */
 
 static int
@@ -280,7 +268,7 @@ struct linux_target_ops the_low_target =
   nios2_get_pc,
   nios2_set_pc,
   nios2_breakpoint_from_pc,
-  nios2_get_next_pcs,
+  NULL, /* get_next_pcs */
   0,
   nios2_breakpoint_at,
 };
diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c
index fa87e19..4939cfa 100644
--- a/gdb/gdbserver/linux-ppc-low.c
+++ b/gdb/gdbserver/linux-ppc-low.c
@@ -641,6 +641,14 @@ ppc_store_evrregset (struct regcache *regcache, const void *buf)
   supply_register_by_name (regcache, "spefscr", &regset->spefscr);
 }
 
+/* Support for hardware single step.  */
+
+static int
+ppc_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 static struct regset_info ppc_regsets[] = {
   /* List the extra register sets before GENERAL_REGS.  That way we will
      fetch them every time, but still fall back to PTRACE_PEEKUSER for the
@@ -701,6 +709,19 @@ struct linux_target_ops the_low_target = {
   NULL,
   ppc_collect_ptrace_register,
   ppc_supply_ptrace_register,
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  ppc_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c
index 44d3f26..794a621 100644
--- a/gdb/gdbserver/linux-s390-low.c
+++ b/gdb/gdbserver/linux-s390-low.c
@@ -611,6 +611,14 @@ s390_breakpoint_at (CORE_ADDR pc)
   return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
 }
 
+/* Support for hardware single step.  */
+
+static int
+s390_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 static struct usrregs_info s390_usrregs_info =
   {
     s390_num_regs,
@@ -687,6 +695,19 @@ struct linux_target_ops the_low_target = {
   NULL,
   s390_collect_ptrace_register,
   s390_supply_ptrace_register,
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  s390_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-sh-low.c b/gdb/gdbserver/linux-sh-low.c
index 5c11fd7..6a210bf 100644
--- a/gdb/gdbserver/linux-sh-low.c
+++ b/gdb/gdbserver/linux-sh-low.c
@@ -98,6 +98,14 @@ sh_breakpoint_at (CORE_ADDR where)
   return 0;
 }
 
+/* Support for hardware single step.  */
+
+static int
+sh_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 /* Provide only a fill function for the general register set.  ps_lgetregs
    will use this for NPTL support.  */
 
@@ -159,6 +167,26 @@ struct linux_target_ops the_low_target = {
   NULL,
   0,
   sh_breakpoint_at,
+  NULL, /* supports_z_point_type */
+  NULL, /* insert_point */
+  NULL, /* remove_point */
+  NULL, /* stopped_by_watchpoint */
+  NULL, /* stopped_data_address */
+  NULL, /* collect_ptrace_register */
+  NULL, /* supply_ptrace_register */
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  sh_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-sparc-low.c b/gdb/gdbserver/linux-sparc-low.c
index e804281..25546e3 100644
--- a/gdb/gdbserver/linux-sparc-low.c
+++ b/gdb/gdbserver/linux-sparc-low.c
@@ -264,19 +264,6 @@ sparc_breakpoint_at (CORE_ADDR where)
   return 0;
 }
 
-/* We only place breakpoints in empty marker functions, and thread locking
-   is outside of the function.  So rather than importing software single-step,
-   we can just run until exit.  */
-static void
-sparc_get_next_pcs (struct get_next_pcs *next_pcs)
-{
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
-  CORE_ADDR lr;
-  /* O7 is the equivalent to the 'lr' of other archs.  */
-  collect_register_by_name (regcache, "o7", &lr);
-  VEC_safe_push (CORE_ADDR, next_pcs->result, lr);
-}
-
 static void
 sparc_arch_setup (void)
 {
@@ -331,7 +318,7 @@ struct linux_target_ops the_low_target = {
   /* No sparc_set_pc is needed.  */
   NULL,
   sparc_breakpoint_from_pc,
-  sparc_get_next_pcs,
+  NULL,
   0,
   sparc_breakpoint_at,
   NULL,  /* supports_z_point_type */
diff --git a/gdb/gdbserver/linux-tic6x-low.c b/gdb/gdbserver/linux-tic6x-low.c
index 86b433c..22bffe2 100644
--- a/gdb/gdbserver/linux-tic6x-low.c
+++ b/gdb/gdbserver/linux-tic6x-low.c
@@ -339,6 +339,14 @@ tic6x_arch_setup (void)
   current_process ()->tdesc = tic6x_read_description ();
 }
 
+/* Support for hardware single step.  */
+
+static int
+tic6x_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 static struct regsets_info tic6x_regsets_info =
   {
     tic6x_regsets, /* regsets */
@@ -377,6 +385,26 @@ struct linux_target_ops the_low_target = {
   NULL,
   0,
   tic6x_breakpoint_at,
+  NULL, /* supports_z_point_type */
+  NULL, /* insert_point */
+  NULL, /* remove_point */
+  NULL, /* stopped_by_watchpoint */
+  NULL, /* stopped_data_address */
+  NULL, /* collect_ptrace_register */
+  NULL, /* supply_ptrace_register */
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  tic6x_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-tile-low.c b/gdb/gdbserver/linux-tile-low.c
index 802812b..b712b81 100644
--- a/gdb/gdbserver/linux-tile-low.c
+++ b/gdb/gdbserver/linux-tile-low.c
@@ -179,6 +179,14 @@ tile_arch_setup (void)
     current_process ()->tdesc = tdesc_tilegx;
 }
 
+/* Support for hardware single step.  */
+
+static int
+tile_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 
 struct linux_target_ops the_low_target =
 {
@@ -190,9 +198,29 @@ struct linux_target_ops the_low_target =
   tile_get_pc,
   tile_set_pc,
   tile_breakpoint_from_pc,
-  NULL,
+  NULL, /* get_next_pcs */
   0,
   tile_breakpoint_at,
+  NULL, /* supports_z_point_type */
+  NULL, /* insert_point */
+  NULL, /* remove_point */
+  NULL, /* stopped_by_watchpoint */
+  NULL, /* stopped_data_address */
+  NULL, /* collect_ptrace_register */
+  NULL, /* supply_ptrace_register */
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  tile_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 0731141..0c5b6a2 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -3256,6 +3256,14 @@ x86_supports_range_stepping (void)
   return 1;
 }
 
+/* Support for hardware single step.  */
+
+static int
+x86_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 /* This is initialized assuming an amd64 target.
    x86_arch_setup will correct it for i386 or amd64 targets.  */
 
@@ -3295,6 +3303,7 @@ struct linux_target_ops the_low_target =
   x86_emit_ops,
   x86_get_min_fast_tracepoint_insn_len,
   x86_supports_range_stepping,
+  x86_supports_hardware_single_step,
 };
 
 void
diff --git a/gdb/gdbserver/linux-xtensa-low.c b/gdb/gdbserver/linux-xtensa-low.c
index 1e2cf94..432b1b7 100644
--- a/gdb/gdbserver/linux-xtensa-low.c
+++ b/gdb/gdbserver/linux-xtensa-low.c
@@ -227,6 +227,14 @@ xtensa_arch_setup (void)
   current_process ()->tdesc = tdesc_xtensa;
 }
 
+/* Support for hardware single step.  */
+
+static int
+xtensa_supports_hardware_single_step (void)
+{
+  return 1;
+}
+
 static const struct regs_info *
 xtensa_regs_info (void)
 {
@@ -245,6 +253,26 @@ struct linux_target_ops the_low_target = {
   NULL,
   0,
   xtensa_breakpoint_at,
+  NULL, /* supports_z_point_type */
+  NULL, /* insert_point */
+  NULL, /* remove_point */
+  NULL, /* stopped_by_watchpoint */
+  NULL, /* stopped_data_address */
+  NULL, /* collect_ptrace_register */
+  NULL, /* supply_ptrace_register */
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* new_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  xtensa_supports_hardware_single_step,
 };
 
 
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 5c0d83d..fb0e843 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -2192,13 +2192,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 	  strcat (own_buf, ";tracenz+");
 	}
 
-      if (target_supports_hardware_single_step ())
+      if (target_supports_hardware_single_step () ||
+	  target_supports_software_single_step () )
 	{
-	  /* Support target-side breakpoint conditions and commands.
-	     GDBserver needs to step over the breakpoint if the condition
-	     is false.  GDBserver software single step is too simple, so
-	     disable conditional breakpoints if the target doesn't have
-	     hardware single step.  */
 	  strcat (own_buf, ";ConditionalBreakpoints+");
 	}
       strcat (own_buf, ";BreakpointCommands+");
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index 17ff7a6..1ae42cc 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -224,3 +224,10 @@ target_can_do_hardware_single_step (void)
 {
   return 1;
 }
+
+/* Target can do software single step.  */
+int
+target_can_do_software_single_step (void)
+{
+  return 0;
+}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index fc2dbd7..aa40c4a 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -443,6 +443,9 @@ struct target_ops
      can be NULL, the default breakpoint for the target should be returned in
      this case.  */
   const unsigned char *(*breakpoint_from_pc) (CORE_ADDR *pcptr, int *lenptr);
+
+  /* Returns true if the target can do software single step.  */
+  int (*supports_software_single_step) (void);
 };
 
 extern struct target_ops *the_target;
@@ -621,6 +624,10 @@ int kill_inferior (int);
   (the_target->stopped_by_hw_breakpoint ? \
    (*the_target->stopped_by_hw_breakpoint) () : 0)
 
+#define target_supports_software_single_step() \
+  (the_target->supports_software_single_step ? \
+   (*the_target->supports_software_single_step) () : 0)
+
 /* Start non-stop mode, returns 0 on success, -1 on failure.   */
 
 int start_non_stop (int nonstop);
@@ -655,4 +662,6 @@ const char *target_pid_to_str (ptid_t);
 
 int target_can_do_hardware_single_step (void);
 
+int target_can_do_software_single_step (void);
+
 #endif /* TARGET_H */
