diff --git a/miosix/arch/cpu/common/cortexMx_interrupts.cpp b/miosix/arch/cpu/common/cortexMx_interrupts.cpp
index 4f230b772271085fdc81a44bf10a3548d101d313..9de478f0c05fed8346e54758cea30e39ee8eb72c 100644
--- a/miosix/arch/cpu/common/cortexMx_interrupts.cpp
+++ b/miosix/arch/cpu/common/cortexMx_interrupts.cpp
@@ -403,15 +403,22 @@ void NMI_Handler()
     IRQsystemReboot();
 }
 
-void HardFault_Handler()
+#ifdef WITH_PROCESSES
+void __attribute__((naked)) HardFault_Handler()
+{
+    saveContext();
+    asm volatile("bl _ZN6miosix13hardfaultImplEv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) hardfaultImpl()
 {
-    #ifdef WITH_PROCESSES
     if(Thread::IRQreportFault(FaultData(fault::HARDFAULT,getProgramCounter())))
-    {
-        IRQinvokeScheduler();
         return;
-    }
-    #endif //WITH_PROCESSES
+#else //WITH_PROCESSES
+void HardFault_Handler()
+{
+#endif //WITH_PROCESSES
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected HardFault @ ");
     printUnsignedInt(getProgramCounter());
@@ -429,7 +436,18 @@ void HardFault_Handler()
 // Cortex M0/M0+ architecture does not have these interrupt handlers
 #if __CORTEX_M != 0
 
+#ifdef WITH_PROCESSES
+void __attribute__((naked)) MemManage_Handler()
+{
+    saveContext();
+    asm volatile("bl _ZN6miosix13memManageImplEv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) memManageImpl()
+#else //WITH_PROCESSES
 void MemManage_Handler()
+#endif //WITH_PROCESSES
 {
     #if defined(WITH_PROCESSES) || defined(WITH_ERRLOG)
     unsigned int cfsr=SCB->CFSR;
@@ -442,7 +460,6 @@ void MemManage_Handler()
     if(Thread::IRQreportFault(FaultData(id,getProgramCounter(),arg)))
     {
         SCB->SHCSR &= ~(1<<13); //Clear MEMFAULTPENDED bit
-        IRQinvokeScheduler();
         return;
     }
     #endif //WITH_PROCESSES
@@ -466,7 +483,18 @@ void MemManage_Handler()
     IRQsystemReboot();
 }
 
+#ifdef WITH_PROCESSES
+void __attribute__((naked)) BusFault_Handler()
+{
+    saveContext();
+    asm volatile("bl _ZN6miosix12busFaultImplEv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) busFaultImpl()
+#else //WITH_PROCESSES
 void BusFault_Handler()
+#endif //WITH_PROCESSES
 {
     #if defined(WITH_PROCESSES) || defined(WITH_ERRLOG)
     unsigned int cfsr=SCB->CFSR;
@@ -504,7 +532,18 @@ void BusFault_Handler()
     IRQsystemReboot();
 }
 
+#ifdef WITH_PROCESSES
+void __attribute__((naked)) UsageFault_Handler()
+{
+    saveContext();
+    asm volatile("bl _ZN6miosix14usageFaultImplEv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) usageFaultImpl()
+#else //WITH_PROCESSES
 void UsageFault_Handler()
+#endif //WITH_PROCESSES
 {
     #if defined(WITH_PROCESSES) || defined(WITH_ERRLOG)
     unsigned int cfsr=SCB->CFSR;
@@ -521,7 +560,6 @@ void UsageFault_Handler()
     if(Thread::IRQreportFault(FaultData(id,getProgramCounter())))
     {
         SCB->SHCSR &= ~(1<<12); //Clear USGFAULTPENDED bit
-        IRQinvokeScheduler();
         return;
     }
     #endif //WITH_PROCESSES
@@ -555,10 +593,16 @@ void DebugMon_Handler()
 
 #endif //__CORTEX_M != 0
 
-void SVC_Handler()
+#ifdef WITH_PROCESSES
+void __attribute__((naked)) SVC_Handler()
+{
+    saveContext();
+    asm volatile("bl _ZN6miosix7svcImplEv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) svcImpl()
 {
-    #ifdef WITH_PROCESSES
-    // WARNING: Temporary fix. Rationale:
     // This fix is intended to avoid kernel or process faulting due to
     // another process actions. Consider the case in which a process statically
     // allocates a big array such that there is no space left for saving
@@ -583,25 +627,27 @@ void SVC_Handler()
             return;
         }
     }
-    Thread::IRQstackOverflowCheck(); //BUG! here we check the stack but we haven't saved the context!
+    Thread::IRQstackOverflowCheck();
 
-    //If processes are enabled, check the content of r3. If zero then it
-    //it is a simple yield, otherwise handle the syscall
+    //Miosix on ARM uses r3 for the syscall number.
     //Note that it is required to use ctxsave and not cur->ctxsave because
     //at this time we do not know if the active context is user or kernel
     unsigned int threadSp=ctxsave[0];
     unsigned int *processStack=reinterpret_cast<unsigned int*>(threadSp);
-    if(processStack[3]!=static_cast<unsigned int>(Syscall::YIELD))
-        Thread::IRQhandleSvc(processStack[3]);
-    IRQinvokeScheduler(); //TODO: is it right to invoke the scheduler always? Check
-    #else //WITH_PROCESSES
+    if(processStack[3]==static_cast<unsigned int>(Syscall::YIELD))
+        Scheduler::IRQrunScheduler();
+    else Thread::IRQhandleSvc(processStack[3]);
+}
+#else //WITH_PROCESSES
+void SVC_Handler()
+{
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected SVC @ ");
     printUnsignedInt(getProgramCounter());
     #endif //WITH_ERRLOG
     IRQsystemReboot();
-    #endif //WITH_PROCESSES
 }
+#endif //WITH_PROCESSES
 
 /**
  * \internal
@@ -618,8 +664,9 @@ void __attribute__((noinline)) pendsvImpl()
 
 void __attribute__((naked)) PendSV_Handler()
 {
-    //In Miosix 3.0, this is the only interrupt from where it is possible to
-    //perform a context switch. If there is the need to perform a context switch
+    //In Miosix 3.0, a context switch is possible only from this interrupt,
+    //unless processes are enabled in which case also fault handlers and the SVC
+    //handler can do so. If there is the need to perform a context switch
     //from within another interrupt, such as if a peripheral driver interrupt
     //has woken up a thread whose priority is higher than the one that was
     //running when the interrupt occurred, the interrupt must call