Index: arch/ia32/include/interrupt.h
===================================================================
--- arch/ia32/include/interrupt.h	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ arch/ia32/include/interrupt.h	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -77,4 +77,5 @@
 extern void null_interrupt(__u8 n, __u32 stack[]);
 extern void gp_fault(__u8 n, __u32 stack[]);
+extern void nm_fault(__u8 n, __u32 stack[]);
 extern void page_fault(__u8 n, __u32 stack[]);
 extern void syscall(__u8 n, __u32 stack[]);
Index: arch/ia32/src/fpu_context.c
===================================================================
--- arch/ia32/src/fpu_context.c	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ arch/ia32/src/fpu_context.c	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -41,6 +41,6 @@
 void fpu_context_restore(fpu_context_t *fctx)
 {
-	if(THREAD==CPU->arch.fpu_owner) reset_TS_flag();
-	else set_TS_flag();
+	if(THREAD==CPU->arch.fpu_owner) {reset_TS_flag(); }
+	else {set_TS_flag(); ((CPU->arch).fpu_owner)->fpu_context_engaged=1;}
 }
 
@@ -48,21 +48,31 @@
 void fpu_lazy_context_save(fpu_context_t *fctx)
 {
-/*
-	pushl %eax
-        mov 8(%esp),%eax
-        fxsave (%eax)
-        popl %eax
-        ret
-*/	
+    asm(
+        "mov %0,%%eax;"
+        "fxsave (%%eax);"
+        "ret;"
+	:"=m"(fctx)
+	:
+	:"%eax"
+    );	
 }
 
 void fpu_lazy_context_restore(fpu_context_t *fctx)
 {
-/*
-	pushl %eax
-        mov 8(%esp),%eax
-        fxrstor (%eax)
-        popl %eax
-        ret
-*/	
+    asm(
+        "mov %0,%%eax;"
+        "fxrstor (%%eax);"
+        "ret;"
+	:"=m"(fctx)
+	:
+	:"%eax"
+    );
 }
+
+void fpu_init(void)
+{
+    asm(
+        "fninit;"
+    );
+}
+
Index: arch/ia32/src/interrupt.c
===================================================================
--- arch/ia32/src/interrupt.c	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ arch/ia32/src/interrupt.c	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -86,4 +86,25 @@
 }
 
+void nm_fault(__u8 n, __u32 stack[])
+{
+
+        if (((CPU->arch).fpu_owner)!=NULL) 
+	{  
+		fpu_lazy_context_save(&(((CPU->arch).fpu_owner)->saved_fpu_context));
+		((CPU->arch).fpu_owner)->fpu_context_engaged=0; /* Enables migration */
+	}
+	
+	if(THREAD->fpu_context_exists) fpu_lazy_context_restore(&(THREAD->saved_fpu_context));
+        else {fpu_init();THREAD->fpu_context_exists=1;}
+
+	(CPU->arch).fpu_owner=THREAD;
+
+	reset_TS_flag();
+	
+//	panic("#NM fault\n");
+}
+
+
+
 void page_fault(__u8 n, __u32 stack[])
 {
Index: arch/ia32/src/pm.c
===================================================================
--- arch/ia32/src/pm.c	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ arch/ia32/src/pm.c	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -121,4 +121,5 @@
 	}
 	trap_register(13, gp_fault);
+	trap_register( 7, nm_fault);
 }
 
Index: doc/TODO
===================================================================
--- doc/TODO	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ doc/TODO	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -12,4 +12,5 @@
 + save/restore floating point context on context switch 
   + [ia32] lazy context switch using TS flag
++ [ia32] MMX,SSE1-.. initialization
 + [ia32] review privilege separation
   + zero IOPL in EFLAGS
@@ -19,2 +20,4 @@
 + make emulated architectures also work on real hardware
 + bring in support for other architectures (e.g. PowerPC)
+
+
Index: include/fpu_context.h
===================================================================
--- include/fpu_context.h	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ include/fpu_context.h	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -11,5 +11,5 @@
 extern void fpu_lazy_context_save(fpu_context_t *);
 extern void fpu_lazy_context_restore(fpu_context_t *);
-
+extern void fpu_init(void);
 
 
Index: include/proc/thread.h
===================================================================
--- include/proc/thread.h	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ include/proc/thread.h	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -75,4 +75,7 @@
 	context_t sleep_timeout_context;
 	fpu_context_t saved_fpu_context;	               
+	int fpu_context_exists;	               
+	int fpu_context_engaged;               /* Defined only if thread doesn't run. It means that fpu context is in CPU 
+						that last time executes this thread. This disables migration */          
 	
 	
Index: src/proc/scheduler.c
===================================================================
--- src/proc/scheduler.c	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ src/proc/scheduler.c	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -268,4 +268,9 @@
 			    list_remove(&THREAD->threads_link);
 			    spinlock_unlock(&threads_lock);
+
+			    spinlock_lock(&THREAD->cpu->lock);
+			    if(THREAD->cpu->arch.fpu_owner==THREAD) THREAD->cpu->arch.fpu_owner=NULL;
+			    spinlock_unlock(&THREAD->cpu->lock);
+
 			    
 			    free(THREAD);
@@ -428,7 +433,8 @@
 		    		 * We don't want to steal CPU-wired threads neither threads already stolen.
 				 * The latter prevents threads from migrating between CPU's without ever being run.
-		        	 */
+		        	 * We don't want to steal threads whose FPU context is still in CPU
+				 */
 				spinlock_lock(&t->lock);
-				if (!(t->flags & (X_WIRED | X_STOLEN))) {
+				if ( (!(t->flags & (X_WIRED | X_STOLEN))) && (!(t->fpu_context_engaged)) ) {
 					/*
 					 * Remove t from r.
Index: src/proc/thread.c
===================================================================
--- src/proc/thread.c	(revision 6ba143dce31ac1490fdc2b36456012f4baadf10c)
+++ src/proc/thread.c	(revision 6a27d63e7b18736b0881629dbb6394d379111ab4)
@@ -190,4 +190,7 @@
 		t->task = task;
 		
+		t->fpu_context_exists=0;
+		t->fpu_context_engaged=0;
+		
 		/*
 		 * Register this thread in the system-wide list.
