Index: cpukit/rtems/src/semobtain.c
===================================================================
--- cpukit/rtems/src/semobtain.c	(revision 80f376db6c32bb4d01c93f5a2d7044798262d359)
+++ cpukit/rtems/src/semobtain.c	(revision a816f08478e2fe395062a8114c0654d0624906ae)
@@ -60,14 +60,11 @@
         MRSP_Status mrsp_status;
 
-        _Thread_Disable_dispatch();
-        _ISR_lock_ISR_enable( &lock_context );
         mrsp_status = _MRSP_Obtain(
           &the_semaphore->Core_control.mrsp,
           executing,
           wait,
-          timeout
+          timeout,
+          &lock_context
         );
-        _Thread_Enable_dispatch();
-        _Objects_Put_for_get_isr_disable( &the_semaphore->Object );
         return _Semaphore_Translate_MRSP_status_code( mrsp_status );
       } else
Index: cpukit/rtems/src/semrelease.c
===================================================================
--- cpukit/rtems/src/semrelease.c	(revision 80f376db6c32bb4d01c93f5a2d7044798262d359)
+++ cpukit/rtems/src/semrelease.c	(revision a816f08478e2fe395062a8114c0654d0624906ae)
@@ -76,11 +76,11 @@
 #if defined(RTEMS_SMP)
       if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
-        _Thread_Disable_dispatch();
-        _ISR_lock_ISR_enable( &lock_context );
-        MRSP_Status mrsp_status = _MRSP_Release(
+        MRSP_Status mrsp_status;
+
+        mrsp_status = _MRSP_Release(
           &the_semaphore->Core_control.mrsp,
-          _Thread_Get_executing()
+          _Thread_Executing,
+          &lock_context
         );
-        _Thread_Enable_dispatch();
         return _Semaphore_Translate_MRSP_status_code( mrsp_status );
       } else
Index: cpukit/score/include/rtems/score/mrsp.h
===================================================================
--- cpukit/score/include/rtems/score/mrsp.h	(revision 80f376db6c32bb4d01c93f5a2d7044798262d359)
+++ cpukit/score/include/rtems/score/mrsp.h	(revision a816f08478e2fe395062a8114c0654d0624906ae)
@@ -21,4 +21,5 @@
 
 #include <rtems/score/chain.h>
+#include <rtems/score/isrlock.h>
 #include <rtems/score/scheduler.h>
 #include <rtems/score/thread.h>
@@ -76,20 +77,26 @@
 } MRSP_Status;
 
+typedef struct MRSP_Control MRSP_Control;
+
 /**
  * @brief MrsP rival.
  *
  * The rivals are used by threads waiting for resource ownership.  They are
- * registered in the MRSP control block.
+ * registered in the MrsP control block.
  */
 typedef struct {
   /**
-   * @brief The node for registration in the MRSP rival chain.
+   * @brief The node for registration in the MrsP rival chain.
    *
-   * The chain operations are protected by the Giant lock and disabled
-   * interrupts.
+   * The chain operations are protected by the MrsP control lock.
    *
    * @see MRSP_Control::Rivals.
    */
   Chain_Node Node;
+
+  /**
+   * @brief The corresponding MrsP control block.
+   */
+  MRSP_Control *resource;
 
   /**
@@ -119,6 +126,5 @@
    * Initially the status is set to MRSP_WAIT_FOR_OWNERSHIP.  The rival will
    * busy wait until a status change happens.  This can be MRSP_SUCCESSFUL or
-   * MRSP_TIMEOUT.  State changes are protected by the Giant lock and disabled
-   * interrupts.
+   * MRSP_TIMEOUT.  State changes are protected by the MrsP control lock.
    */
   volatile MRSP_Status status;
@@ -128,5 +134,5 @@
  * @brief MrsP control block.
  */
-typedef struct {
+struct MRSP_Control {
   /**
    * @brief Basic resource control.
@@ -142,4 +148,9 @@
 
   /**
+   * @brief Lock to protect the resource dependency tree.
+   */
+  ISR_LOCK_MEMBER( Lock )
+
+  /**
    * @brief The initial priority of the owner before it was elevated to the
    * ceiling priority.
@@ -151,5 +162,5 @@
    */
   Priority_Control *ceiling_priorities;
-} MRSP_Control;
+};
 
 /** @} */
Index: cpukit/score/include/rtems/score/mrspimpl.h
===================================================================
--- cpukit/score/include/rtems/score/mrspimpl.h	(revision 80f376db6c32bb4d01c93f5a2d7044798262d359)
+++ cpukit/score/include/rtems/score/mrspimpl.h	(revision a816f08478e2fe395062a8114c0654d0624906ae)
@@ -37,4 +37,21 @@
  */
 
+/*
+ * FIXME: Operations with the resource dependency tree are protected by the
+ * global scheduler lock.  Since the scheduler lock should be scheduler
+ * instance specific in the future this will only work temporarily.  A more
+ * sophisticated locking strategy is necessary.
+ */
+
+RTEMS_INLINE_ROUTINE void _MRSP_Giant_acquire( ISR_lock_Context *lock_context )
+{
+  _ISR_lock_Acquire( &_Scheduler_Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _MRSP_Giant_release( ISR_lock_Context *lock_context )
+{
+  _ISR_lock_Release( &_Scheduler_Lock, lock_context );
+}
+
 RTEMS_INLINE_ROUTINE bool _MRSP_Restore_priority_filter(
   Thread_Control   *thread,
@@ -75,12 +92,21 @@
   Thread_Control   *new_owner,
   Priority_Control  initial_priority,
-  Priority_Control  ceiling_priority
-)
-{
+  Priority_Control  ceiling_priority,
+  ISR_lock_Context *lock_context
+)
+{
+  Per_CPU_Control *cpu_self;
+
   _Resource_Node_add_resource( &new_owner->Resource_node, &mrsp->Resource );
   _Resource_Set_owner( &mrsp->Resource, &new_owner->Resource_node );
   mrsp->initial_priority_of_owner = initial_priority;
+  _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
+
+  cpu_self = _Thread_Dispatch_disable_critical();
+  _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
+
   _Thread_Raise_priority( new_owner, ceiling_priority );
-  _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
+
+  _Thread_Dispatch_enable( cpu_self );
 }
 
@@ -112,4 +138,5 @@
   _Resource_Initialize( &mrsp->Resource );
   _Chain_Initialize_empty( &mrsp->Rivals );
+  _ISR_lock_Initialize( &mrsp->Lock, "MrsP" );
 
   return MRSP_SUCCESSFUL;
@@ -139,25 +166,30 @@
 {
   MRSP_Rival *rival = arg;
+  MRSP_Control *mrsp = rival->resource;
   Thread_Control *thread = rival->thread;
-  ISR_Level level;
+  ISR_lock_Context lock_context;
 
   (void) id;
 
-  _ISR_Disable( level );
+  _ISR_lock_ISR_disable_and_acquire( &mrsp->Lock, &lock_context );
 
   if ( rival->status == MRSP_WAIT_FOR_OWNERSHIP ) {
-    rival->status = MRSP_TIMEOUT;
+    ISR_lock_Context giant_lock_context;
+
+    _MRSP_Giant_acquire( &giant_lock_context );
 
     _Chain_Extract_unprotected( &rival->Node );
     _Resource_Node_extract( &thread->Resource_node );
     _Resource_Node_set_dependency( &thread->Resource_node, NULL );
-
-    _ISR_Enable( level );
-
     _Scheduler_Thread_change_help_state( thread, rival->initial_help_state );
     _Scheduler_Thread_change_resource_root( thread, thread );
-    _MRSP_Restore_priority( thread, rival->initial_priority );
+
+    _MRSP_Giant_release( &giant_lock_context );
+
+    rival->status = MRSP_TIMEOUT;
+
+    _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, &lock_context );
   } else {
-    _ISR_Enable( level );
+    _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, &lock_context );
   }
 }
@@ -169,5 +201,6 @@
   Priority_Control   initial_priority,
   Priority_Control   ceiling_priority,
-  Watchdog_Interval  timeout
+  Watchdog_Interval  timeout,
+  ISR_lock_Context  *lock_context
 )
 {
@@ -175,26 +208,31 @@
   MRSP_Rival rival;
   bool initial_life_protection;
-  ISR_Level level;
+  Per_CPU_Control *cpu_self;
+  ISR_lock_Context giant_lock_context;
 
   rival.thread = executing;
+  rival.resource = mrsp;
   rival.initial_priority = initial_priority;
+
+  _MRSP_Giant_acquire( &giant_lock_context );
+
   rival.initial_help_state =
     _Scheduler_Thread_change_help_state( executing, SCHEDULER_HELP_ACTIVE_RIVAL );
   rival.status = MRSP_WAIT_FOR_OWNERSHIP;
 
-  _Thread_Raise_priority( executing, ceiling_priority );
-
-  _ISR_Disable( level );
-
   _Chain_Append_unprotected( &mrsp->Rivals, &rival.Node );
   _Resource_Add_rival( &mrsp->Resource, &executing->Resource_node );
   _Resource_Node_set_dependency( &executing->Resource_node, &mrsp->Resource );
-
-  _ISR_Enable( level );
-
   _Scheduler_Thread_change_resource_root(
     executing,
     THREAD_RESOURCE_NODE_TO_THREAD( _Resource_Node_get_root( owner ) )
   );
+
+  _MRSP_Giant_release( &giant_lock_context );
+
+  cpu_self = _Thread_Dispatch_disable_critical();
+  _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
+
+  _Thread_Raise_priority( executing, ceiling_priority );
 
   if ( timeout > 0 ) {
@@ -209,5 +247,5 @@
 
   initial_life_protection = _Thread_Set_life_protection( true );
-  _Thread_Enable_dispatch();
+  _Thread_Dispatch_enable( cpu_self );
 
   _Assert( _Debug_Is_thread_dispatching_allowed() );
@@ -218,9 +256,12 @@
   } while ( status == MRSP_WAIT_FOR_OWNERSHIP );
 
-  _Thread_Disable_dispatch();
   _Thread_Set_life_protection( initial_life_protection );
 
   if ( timeout > 0 ) {
     _Watchdog_Remove_ticks( &executing->Timer );
+
+    if ( status == MRSP_TIMEOUT ) {
+      _MRSP_Restore_priority( executing, initial_priority );
+    }
   }
 
@@ -232,5 +273,6 @@
   Thread_Control    *executing,
   bool               wait,
-  Watchdog_Interval  timeout
+  Watchdog_Interval  timeout,
+  ISR_lock_Context  *lock_context
 )
 {
@@ -248,7 +290,9 @@
 
   if ( !priority_ok) {
+    _ISR_lock_ISR_enable( lock_context );
     return MRSP_INVALID_PRIORITY;
   }
 
+  _ISR_lock_Acquire( &mrsp->Lock, lock_context );
   owner = _Resource_Get_owner( &mrsp->Resource );
   if ( owner == NULL ) {
@@ -257,11 +301,12 @@
       executing,
       initial_priority,
-      ceiling_priority
+      ceiling_priority,
+      lock_context
     );
     status = MRSP_SUCCESSFUL;
-  } else if ( _Resource_Node_get_root( owner ) == &executing->Resource_node ) {
-    /* Nested access or deadlock */
-    status = MRSP_UNSATISFIED;
-  } else if ( wait ) {
+  } else if (
+    wait
+      && _Resource_Node_get_root( owner ) != &executing->Resource_node
+  ) {
     status = _MRSP_Wait_for_ownership(
       mrsp,
@@ -270,7 +315,10 @@
       initial_priority,
       ceiling_priority,
-      timeout
+      timeout,
+      lock_context
     );
   } else {
+    _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
+    /* Not available, nested access or deadlock */
     status = MRSP_UNSATISFIED;
   }
@@ -280,11 +328,15 @@
 
 RTEMS_INLINE_ROUTINE MRSP_Status _MRSP_Release(
-  MRSP_Control   *mrsp,
-  Thread_Control *executing
-)
-{
-  ISR_Level level;
+  MRSP_Control     *mrsp,
+  Thread_Control   *executing,
+  ISR_lock_Context *lock_context
+)
+{
+  Priority_Control initial_priority;
+  Per_CPU_Control *cpu_self;
+  ISR_lock_Context giant_lock_context;
 
   if ( _Resource_Get_owner( &mrsp->Resource ) != &executing->Resource_node ) {
+    _ISR_lock_ISR_enable( lock_context );
     return MRSP_NOT_OWNER_OF_RESOURCE;
   }
@@ -296,16 +348,17 @@
     )
   ) {
+    _ISR_lock_ISR_enable( lock_context );
     return MRSP_INCORRECT_STATE;
   }
 
-  _MRSP_Restore_priority( executing, mrsp->initial_priority_of_owner );
-
-  _ISR_Disable( level );
+  initial_priority = mrsp->initial_priority_of_owner;
+
+  _ISR_lock_Acquire( &mrsp->Lock, lock_context );
+
+  _MRSP_Giant_acquire( &giant_lock_context );
 
   _Resource_Extract( &mrsp->Resource );
 
   if ( _Chain_Is_empty( &mrsp->Rivals ) ) {
-    _ISR_Enable( level );
-
     _Resource_Set_owner( &mrsp->Resource, NULL );
   } else {
@@ -326,7 +379,4 @@
     _Resource_Node_add_resource( &new_owner->Resource_node, &mrsp->Resource );
     _Resource_Set_owner( &mrsp->Resource, &new_owner->Resource_node );
-
-    _ISR_Enable( level );
-
     _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
     _Scheduler_Thread_change_resource_root( new_owner, new_owner );
@@ -337,4 +387,13 @@
   }
 
+  _MRSP_Giant_release( &giant_lock_context );
+
+  cpu_self = _Thread_Dispatch_disable_critical();
+  _ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
+
+  _MRSP_Restore_priority( executing, initial_priority );
+
+  _Thread_Dispatch_enable( cpu_self );
+
   return MRSP_SUCCESSFUL;
 }
@@ -346,4 +405,5 @@
   }
 
+  _ISR_lock_Destroy( &mrsp->Lock );
   _Workspace_Free( mrsp->ceiling_priorities );
 
Index: cpukit/score/src/schedulerchangeroot.c
===================================================================
--- cpukit/score/src/schedulerchangeroot.c	(revision 80f376db6c32bb4d01c93f5a2d7044798262d359)
+++ cpukit/score/src/schedulerchangeroot.c	(revision a816f08478e2fe395062a8114c0654d0624906ae)
@@ -62,7 +62,4 @@
   Scheduler_Node *offers_help_node;
   Thread_Control *offers_help_too;
-  ISR_Level level;
-
-  _ISR_Disable( level );
 
   offers_help_node = _Scheduler_Thread_get_node( offers_help );
@@ -81,5 +78,3 @@
     _Scheduler_Ask_for_help( ctx.needs_help );
   }
-
-  _ISR_Enable( level );
 }
