Index: kernel/fiasco/src/Kconfig
===================================================================
--- kernel/fiasco/src/Kconfig	(revision 38)
+++ kernel/fiasco/src/Kconfig	(working copy)
@@ -694,6 +694,14 @@
 	  prevent some P4 processors from being overheated. This option
 	  requires a working timer IRQ to wakeup getchar periodically.
 
+config USER_SINGLE_STEP
+	bool "Enable user level single stepping support"
+	depends on IA32
+	default n
+	help
+	  This option enables single stepping of user level applications outside of
+	  JDB.
+
 choice
 	prompt "Warn levels"
 	default WARN_WARNING
Index: kernel/fiasco/src/kern/ia32/config-ia32.cpp
===================================================================
--- kernel/fiasco/src/kern/ia32/config-ia32.cpp	(revision 38)
+++ kernel/fiasco/src/kern/ia32/config-ia32.cpp	(working copy)
@@ -98,6 +98,12 @@
   static const bool kinfo_timer_uses_rdtsc = false;
 #endif
 
+#ifdef CONFIG_USER_SINGLE_STEP
+  static const bool user_single_step = true;
+#else
+  static const bool user_single_step = false;
+#endif
+
   static const bool old_sigma0_adapter_hack = false;
 
   // the default uart to use for serial console
Index: kernel/fiasco/src/kern/ia32/32/entry-native.S
===================================================================
--- kernel/fiasco/src/kern/ia32/32/entry-native.S	(revision 38)
+++ kernel/fiasco/src/kern/ia32/32/entry-native.S	(working copy)
@@ -46,6 +46,30 @@
 	jmp	slowtraps
 .endm
 
+#ifdef CONFIG_USER_SINGLE_STEP
+.macro HANDLE_USER_TRAP1
+	/* Save EFLAGS, this may trap if user task had single stepping activated
+	 * test for single stepping
+	 */
+	pushf
+	addl	$4, %esp
+	testl	$EFLAGS_TF, -4(%esp)
+.endm
+
+.macro RESTORE_USER_TRAP1
+	/* Restore single stepping if it has been set */
+	je 1f
+	orl $EFLAGS_TF, (%esp)
+1:
+.endm
+#else
+.macro HANDLE_USER_TRAP1
+.endm
+
+.macro RESTORE_USER_TRAP1
+.endm
+#endif
+
 	.p2align 4
 	.globl	entry_vec01_debug
 entry_vec01_debug:
@@ -55,6 +79,15 @@
 	cmpl	$VAL__MEM_LAYOUT__TCBS_END, %esp
 	jbe	2f
 #endif
+
+	/* test if trap was raised within kernel */
+	testl $3, 4(%esp)
+	jne   1f
+
+	/* turn of EFLAGS.TF */
+	btrl $7, 8(%esp) 
+	iret
+
 1:	pushl	$0
 	pushl	$1
 	pusha
@@ -214,11 +247,17 @@
 	.p2align(4)
 	.global entry_sys_fast_ipc_c
 entry_sys_fast_ipc_c:
+
+	HANDLE_USER_TRAP1
+
 	pop	%esp
 	pushl	$(GDT_DATA_USER|SEL_PL_U)	/* user ss */
 	pushl	%ebp				// push user SP (get in ebp)
 	// Fake user eflags, set IOPL to 3
 	pushl	$(EFLAGS_IOPL_U | EFLAGS_IF)
+
+	RESTORE_USER_TRAP1
+
 	cld
 	// Fake user cs. This cs value is never used with exception
 	// that the thread is ex_regs'd before we leave with sysexit.
Index: kernel/fiasco/src/kern/ia32/thread-ia32.cpp
===================================================================
--- kernel/fiasco/src/kern/ia32/thread-ia32.cpp	(revision 38)
+++ kernel/fiasco/src/kern/ia32/thread-ia32.cpp	(working copy)
@@ -196,12 +196,19 @@
   Address ip;
   int from_user = ts->cs() & 3;
 
+  //if (ts->_trapno != 3)
+  //  LOG_MSG_3VAL(this, "trap", ts->_trapno, from_user, ts->ip());
+
   if (EXPECT_FALSE(ts->_trapno == 0xee)) //debug IPI
     {
       Ipi::eoi(Ipi::Debug);
       goto generic_debug;
     }
 
+  if (Config::user_single_step && ts->_trapno == 1 && from_user)
+    if (send_exception(ts))
+      goto success;
+
   if (from_user && _space.user_mode())
     {
       if (ts->_trapno == 14 && Kmem::is_io_bitmap_page_fault(ts->_cr2))
@@ -521,7 +528,8 @@
   // thread (not alien) and it's a debug trap,
   // debug traps for aliens are always reflected as exception IPCs
   if (!(state() & Thread_alien)
-      && (ts->_trapno == 1 || ts->_trapno == 3))
+      && ((ts->_trapno == 1 && !Config::user_single_step)
+      ||   ts->_trapno == 3))
     return 0; // we do not handle this
 
   if (ts->_trapno == 3)
@@ -574,6 +582,11 @@
     }
 }
 
+IMPLEMENT inline
+void
+Thread::user_single_step(bool)
+{}
+
 //----------------------------------------------------------------------------
 IMPLEMENTATION [ia32]:
 
@@ -586,6 +599,16 @@
   _gs = _fs = Utcb_init::utcb_segment();
 }
 
+IMPLEMENT inline
+void
+Thread::user_single_step(bool enable)
+{
+  if (!Config::user_single_step)
+    return;
+
+  regs()->flags(enable ? user_flags() | EFLAGS_TF : user_flags() & ~EFLAGS_TF);
+}
+
 //----------------------------------------------------------------------------
 IMPLEMENTATION [amd64]:
 
Index: kernel/fiasco/src/kern/thread_object.cpp
===================================================================
--- kernel/fiasco/src/kern/thread_object.cpp	(revision 38)
+++ kernel/fiasco/src/kern/thread_object.cpp	(working copy)
@@ -524,6 +524,8 @@
   if (o_ip) *o_ip = user_ip();
   if (o_flags) *o_flags = user_flags();
 
+  (ops & Exr_single_step) ? user_single_step(true) : user_single_step(false);
+
   // Changing the run state is only possible when the thread is not in
   // an exception.
   if (!(ops & Exr_cancel) && (state() & Thread_in_exception))
Index: kernel/fiasco/src/kern/thread.cpp
===================================================================
--- kernel/fiasco/src/kern/thread.cpp	(revision 38)
+++ kernel/fiasco/src/kern/thread.cpp	(working copy)
@@ -70,6 +70,7 @@
   {
     Exr_cancel            = 0x10000,
     Exr_trigger_exception = 0x20000,
+    Exr_single_step       = 0x40000,
   };
 
   enum Vcpu_ctl_flags
@@ -137,6 +138,8 @@
 
   inline Mword user_flags() const;
 
+  inline void user_single_step(bool);
+
   /** nesting level in debugger (always critical) if >1 */
   static Per_cpu<unsigned long> nested_trap_recover;
   static void handle_remote_requests_irq() asm ("handle_remote_cpu_requests");
Index: kernel/fiasco/src/kern/arm/thread-arm.cpp
===================================================================
--- kernel/fiasco/src/kern/arm/thread-arm.cpp	(revision 38)
+++ kernel/fiasco/src/kern/arm/thread-arm.cpp	(working copy)
@@ -549,6 +549,10 @@
   return (v[insn >> 28] >> (psr >> 28)) & 1;
 }
 
+IMPLEMENT inline
+void Thread::user_single_step(bool)
+{}
+
 // ------------------------------------------------------------------------
 IMPLEMENTATION [arm && armv6plus]:
 
Index: kernel/fiasco/src/kern/ppc32/thread-ppc32.cpp
===================================================================
--- kernel/fiasco/src/kern/ppc32/thread-ppc32.cpp	(revision 38)
+++ kernel/fiasco/src/kern/ppc32/thread-ppc32.cpp	(working copy)
@@ -307,6 +307,10 @@
     }
 }
 
+IMPLEMENT inline
+void Thread::user_single_step(bool)
+{}
+
 PUBLIC inline NEEDS ["trap_state.h"]
 int
 Thread::send_exception_arch(Trap_state * /*ts*/)
