Index: cpukit/posix/src/mutexgetprioceiling.c
===================================================================
--- cpukit/posix/src/mutexgetprioceiling.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/posix/src/mutexgetprioceiling.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -47,5 +47,5 @@
 
   *prioceiling = _POSIX_Priority_From_core(
-    the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
+    the_mutex->Mutex.priority_ceiling
   );
 
Index: cpukit/posix/src/mutexinit.c
===================================================================
--- cpukit/posix/src/mutexinit.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/posix/src/mutexinit.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -120,5 +120,10 @@
   the_mutex->is_recursive = ( the_attr->type == PTHREAD_MUTEX_RECURSIVE );
 
-  if ( protocol == POSIX_MUTEX_NO_PROTOCOL ) {
+  if ( protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
+    _CORE_ceiling_mutex_Initialize(
+      &the_mutex->Mutex,
+      _POSIX_Priority_To_core( the_attr->prio_ceiling )
+    );
+  } else if ( protocol == POSIX_MUTEX_NO_PROTOCOL ) {
     _CORE_recursive_mutex_Initialize(
       &the_mutex->Mutex.Recursive
@@ -131,13 +136,4 @@
     } else {
       the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
-    }
-
-    the_mutex_attr.priority_ceiling =
-      _POSIX_Priority_To_core( the_attr->prio_ceiling );
-
-    if ( protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
-      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
-    } else {
-      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
     }
 
Index: cpukit/posix/src/mutexlocksupp.c
===================================================================
--- cpukit/posix/src/mutexlocksupp.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/posix/src/mutexlocksupp.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -66,4 +66,14 @@
 
   switch ( the_mutex->protocol ) {
+    case POSIX_MUTEX_PRIORITY_CEILING:
+      status = _CORE_ceiling_mutex_Seize(
+        &the_mutex->Mutex,
+        executing,
+        wait,
+        timeout,
+        _POSIX_Mutex_Lock_nested,
+        &queue_context
+      );
+      break;
     case POSIX_MUTEX_NO_PROTOCOL:
       status = _CORE_recursive_mutex_Seize_no_protocol(
@@ -78,4 +88,5 @@
       break;
     default:
+      _Assert( the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT );
       status = _CORE_mutex_Seize(
         &the_mutex->Mutex.Recursive.Mutex,
Index: cpukit/posix/src/mutexsetprioceiling.c
===================================================================
--- cpukit/posix/src/mutexsetprioceiling.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/posix/src/mutexsetprioceiling.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -58,8 +58,7 @@
 
   *old_ceiling = _POSIX_Priority_From_core(
-    the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
+    the_mutex->Mutex.priority_ceiling
   );
-  the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling =
-    the_priority;
+  the_mutex->Mutex.priority_ceiling = the_priority;
 
   error = pthread_mutex_unlock( mutex );
Index: cpukit/posix/src/mutexunlock.c
===================================================================
--- cpukit/posix/src/mutexunlock.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/posix/src/mutexunlock.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -46,4 +46,11 @@
 
   switch ( the_mutex->protocol ) {
+    case POSIX_MUTEX_PRIORITY_CEILING:
+      status = _CORE_ceiling_mutex_Surrender(
+        &the_mutex->Mutex,
+        executing,
+        &queue_context
+      );
+      break;
     case POSIX_MUTEX_NO_PROTOCOL:
       status = _CORE_recursive_mutex_Surrender_no_protocol(
@@ -55,4 +62,5 @@
       break;
     default:
+      _Assert( the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT );
       status = _CORE_mutex_Surrender(
         &the_mutex->Mutex.Recursive.Mutex,
Index: cpukit/rtems/include/rtems/rtems/semimpl.h
===================================================================
--- cpukit/rtems/include/rtems/rtems/semimpl.h	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/rtems/include/rtems/rtems/semimpl.h	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -34,4 +34,5 @@
 typedef enum {
   SEMAPHORE_VARIANT_MUTEX,
+  SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING,
   SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL,
   SEMAPHORE_VARIANT_SIMPLE_BINARY,
Index: cpukit/rtems/src/semcreate.c
===================================================================
--- cpukit/rtems/src/semcreate.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/rtems/src/semcreate.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -137,4 +137,5 @@
 #endif
 
+  priority_ceiling = _RTEMS_tasks_Priority_to_Core( priority_ceiling );
   the_semaphore->attribute_set = attribute_set;
   executing = _Thread_Get_executing();
@@ -170,8 +171,30 @@
     );
 #endif
-  } else if (
-    !_Attributes_Is_inherit_priority( attribute_set )
-      && !_Attributes_Is_priority_ceiling( attribute_set )
-  ) {
+  } else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
+    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
+    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING;
+    _CORE_ceiling_mutex_Initialize(
+      &the_semaphore->Core_control.Mutex,
+      priority_ceiling
+    );
+
+    if ( count == 0 ) {
+      Thread_queue_Context queue_context;
+
+      _Thread_queue_Context_initialize( &queue_context );
+      _ISR_lock_ISR_disable( &queue_context.Lock_context );
+      _CORE_mutex_Acquire_critical(
+        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
+        &queue_context
+      );
+      status = _CORE_ceiling_mutex_Set_owner(
+        &the_semaphore->Core_control.Mutex,
+        executing,
+        &queue_context
+      );
+    } else {
+      status = STATUS_SUCCESSFUL;
+    }
+  } else if ( !_Attributes_Is_inherit_priority( attribute_set ) ) {
     _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
     the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL;
@@ -190,16 +213,8 @@
   } else {
     _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
+    _Assert( _Attributes_Is_inherit_priority( attribute_set ) );
     the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
 
-    the_mutex_attr.priority_ceiling =
-      _RTEMS_tasks_Priority_to_Core( priority_ceiling );
     the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
-
-    if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
-      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
-    } else {
-      _Assert( _Attributes_Is_priority_ceiling( attribute_set ) );
-      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
-    }
 
     status = _CORE_mutex_Initialize(
Index: cpukit/rtems/src/semdelete.c
===================================================================
--- cpukit/rtems/src/semdelete.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/rtems/src/semdelete.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -52,4 +52,5 @@
   switch ( the_semaphore->variant ) {
     case SEMAPHORE_VARIANT_MUTEX:
+    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
     case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
       if (
@@ -98,4 +99,5 @@
       _Assert(
         the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
+          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING
           || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
           || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
Index: cpukit/rtems/src/semflush.c
===================================================================
--- cpukit/rtems/src/semflush.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/rtems/src/semflush.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -59,4 +59,5 @@
       _Assert(
         the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
+          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING
           || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
           || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
Index: cpukit/rtems/src/semobtain.c
===================================================================
--- cpukit/rtems/src/semobtain.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/rtems/src/semobtain.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -91,4 +91,14 @@
       );
       break;
+    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
+      status = _CORE_ceiling_mutex_Seize(
+        &the_semaphore->Core_control.Mutex,
+        executing,
+        wait,
+        timeout,
+        _CORE_recursive_mutex_Seize_nested,
+        &queue_context
+      );
+      break;
     case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
       status = _CORE_recursive_mutex_Seize_no_protocol(
Index: cpukit/rtems/src/semrelease.c
===================================================================
--- cpukit/rtems/src/semrelease.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/rtems/src/semrelease.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -29,4 +29,5 @@
   Semaphore_Control    *the_semaphore;
   Thread_queue_Context  queue_context;
+  Thread_Control       *executing;
   Status_Control        status;
 
@@ -41,4 +42,6 @@
   }
 
+  executing = _Thread_Executing;
+
   _Thread_queue_Context_set_MP_callout(
     &queue_context,
@@ -51,5 +54,5 @@
       status = _MRSP_Surrender(
         &the_semaphore->Core_control.mrsp,
-        _Thread_Executing,
+        executing,
         &queue_context
       );
@@ -59,4 +62,11 @@
       status = _CORE_mutex_Surrender(
         &the_semaphore->Core_control.Mutex.Recursive.Mutex,
+        &queue_context
+      );
+      break;
+    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
+      status = _CORE_ceiling_mutex_Surrender(
+        &the_semaphore->Core_control.Mutex,
+        executing,
         &queue_context
       );
Index: cpukit/rtems/src/semsetpriority.c
===================================================================
--- cpukit/rtems/src/semsetpriority.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/rtems/src/semsetpriority.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -18,5 +18,4 @@
 
 #include <rtems/rtems/semimpl.h>
-#include <rtems/rtems/attrimpl.h>
 #include <rtems/rtems/tasksimpl.h>
 #include <rtems/score/schedulerimpl.h>
@@ -30,49 +29,60 @@
 )
 {
-  rtems_status_code   sc;
-  rtems_attribute     attribute_set = the_semaphore->attribute_set;
-  rtems_task_priority old_priority;
+  rtems_status_code    sc;
+  rtems_task_priority  old_priority;
+#if defined(RTEMS_SMP)
+  MRSP_Control        *mrsp;
+  uint32_t             scheduler_index;
+#endif
 
   new_priority = _RTEMS_tasks_Priority_to_Core( new_priority );
 
+  switch ( the_semaphore->variant ) {
+    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
+      _CORE_mutex_Acquire_critical(
+        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
+        queue_context
+      );
+
+      old_priority = the_semaphore->Core_control.Mutex.priority_ceiling;
+
+      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
+        the_semaphore->Core_control.Mutex.priority_ceiling = new_priority;
+      }
+
+      _CORE_mutex_Release(
+        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
+        queue_context
+      );
+      sc = RTEMS_SUCCESSFUL;
+      break;
 #if defined(RTEMS_SMP)
-  if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
-    MRSP_Control *mrsp = &the_semaphore->Core_control.mrsp;
-    uint32_t scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
+    case SEMAPHORE_VARIANT_MRSP:
+      mrsp = &the_semaphore->Core_control.mrsp;
+      scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
 
-    _MRSP_Acquire_critical( mrsp, queue_context );
+      _MRSP_Acquire_critical( mrsp, queue_context );
 
-    old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
+      old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
 
-    if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
-      _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority );
-    }
+      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
+        _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority );
+      }
 
-    _MRSP_Release( mrsp, queue_context );
-
-    sc = RTEMS_SUCCESSFUL;
-  } else
+      _MRSP_Release( mrsp, queue_context );
+      sc = RTEMS_SUCCESSFUL;
+      break;
 #endif
-  if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
-    CORE_mutex_Control *mutex;
-
-    mutex = &the_semaphore->Core_control.Mutex.Recursive.Mutex;
-    _CORE_mutex_Acquire_critical( mutex, queue_context );
-
-    old_priority = mutex->Attributes.priority_ceiling;
-
-    if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
-      mutex->Attributes.priority_ceiling = new_priority;
-    }
-
-    _CORE_mutex_Release( mutex, queue_context );
-
-    sc = RTEMS_SUCCESSFUL;
-  } else {
-    _ISR_lock_ISR_enable( &queue_context->Lock_context );
-
-    old_priority = 0;
-
-    sc = RTEMS_NOT_DEFINED;
+    default:
+      _Assert(
+        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
+          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
+          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
+          || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
+      );
+      _ISR_lock_ISR_enable( &queue_context->Lock_context );
+      old_priority = 0;
+      sc = RTEMS_NOT_DEFINED;
+      break;
   }
 
Index: cpukit/score/include/rtems/score/coremutex.h
===================================================================
--- cpukit/score/include/rtems/score/coremutex.h	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/score/include/rtems/score/coremutex.h	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -43,20 +43,4 @@
 
 /**
- *  @brief The blocking disciplines for a mutex.
- *
- *  This enumerated type defines the blocking disciplines for a mutex.
- */
-typedef enum {
-  /** This specifies that threads will wait for the mutex in priority order.
-   *  Additionally, the Priority Inheritance Protocol will be in effect.
-   */
-  CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT,
-  /** This specifies that threads will wait for the mutex in priority order.
-   *  Additionally, the Priority Ceiling Protocol will be in effect.
-   */
-  CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
-}   CORE_mutex_Disciplines;
-
-/**
  *  @brief The possible behaviors for lock nesting.
  *
@@ -97,12 +81,4 @@
    */
   CORE_mutex_Nesting_behaviors lock_nesting_behavior;
-  /** This field indicates whether threads waiting on the mutex block in
-   *  FIFO or priority order.
-   */
-  CORE_mutex_Disciplines       discipline;
-  /** This field contains the ceiling priority to be used if that protocol
-   *  is selected.
-   */
-  Priority_Control             priority_ceiling;
 }   CORE_mutex_Attributes;
 
Index: cpukit/score/include/rtems/score/coremuteximpl.h
===================================================================
--- cpukit/score/include/rtems/score/coremuteximpl.h	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/score/include/rtems/score/coremuteximpl.h	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -129,40 +129,4 @@
 
 /**
- * @brief Does mutex use priority inheritance.
- *
- * This routine returns true if the mutex's wait discipline is
- * INHERIT_PRIORITY and false otherwise.
- *
- * @param[in] the_attribute is the attribute set of the mutex.
- *
- * @retval true The mutex is using priority inheritance.
- * @retval false The mutex is not using priority inheritance.
- */
-RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
-  const CORE_mutex_Attributes *the_attribute
-)
-{
-  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
-}
-
-/**
- * @brief Does mutex use priority ceiling.
- *
- * This routine returns true if the mutex's wait discipline is
- * PRIORITY_CEILING and false otherwise.
- *
- * @param[in] the_attribute is the attribute set of the mutex.
- *
- * @retval true The mutex is using priority ceiling.
- * @retval false The mutex is not using priority ceiling.
- */
-RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
-  const CORE_mutex_Attributes *the_attribute
-)
-{
-  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
-}
-
-/**
  *  @brief Attempt to receive a unit from the_mutex.
  *
@@ -192,38 +156,5 @@
     ++executing->resource_count;
 
-    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
-      _CORE_mutex_Release( the_mutex, queue_context );
-    } else {
-      /*
-       * must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
-       *
-       * we possibly bump the priority of the current holder -- which
-       * happens to be _Thread_Executing.
-       */
-      Priority_Control  ceiling;
-      Priority_Control  current;
-
-      ceiling = the_mutex->Attributes.priority_ceiling;
-      current = executing->current_priority;
-      if ( current == ceiling ) {
-        _CORE_mutex_Release( the_mutex, queue_context );
-      } else if ( current > ceiling ) {
-        Per_CPU_Control *cpu_self;
-
-        cpu_self = _Thread_Dispatch_disable_critical(
-          &queue_context->Lock_context
-        );
-        _CORE_mutex_Release( the_mutex, queue_context );
-        _Thread_Raise_priority( executing, ceiling );
-        _Thread_Dispatch_enable( cpu_self );
-      } else /* if ( current < ceiling ) */ {
-        the_mutex->holder = NULL;
-        the_mutex->nest_count = 0;     /* undo locking above */
-        executing->resource_count--;   /* undo locking above */
-        _CORE_mutex_Release( the_mutex, queue_context );
-        return STATUS_MUTEX_CEILING_VIOLATED;
-      }
-    }
-
+    _CORE_mutex_Release( the_mutex, queue_context );
     return STATUS_SUCCESSFUL;
   }
@@ -346,4 +277,30 @@
 }
 
+RTEMS_INLINE_ROUTINE void _CORE_mutex_Restore_priority(
+  Thread_Control *executing
+)
+{
+  /*
+   *  Whether or not someone is waiting for the mutex, an
+   *  inherited priority must be lowered if this is the last
+   *  mutex (i.e. resource) this task has.
+   */
+  if ( !_Thread_Owns_resources( executing ) ) {
+    /*
+     * Ensure that the executing resource count is visible to all other
+     * processors and that we read the latest priority restore hint.
+     */
+    _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
+
+    if ( executing->priority_restore_hint ) {
+      Per_CPU_Control *cpu_self;
+
+      cpu_self = _Thread_Dispatch_disable();
+      _Thread_Restore_priority( executing );
+      _Thread_Dispatch_enable( cpu_self );
+    }
+  }
+}
+
 RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Initialize(
   CORE_recursive_mutex_Control *the_mutex
@@ -480,4 +437,157 @@
 }
 
+RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Initialize(
+  CORE_ceiling_mutex_Control *the_mutex,
+  Priority_Control            priority_ceiling
+)
+{
+  _CORE_recursive_mutex_Initialize( &the_mutex->Recursive );
+  the_mutex->priority_ceiling = priority_ceiling;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Set_owner(
+  CORE_ceiling_mutex_Control *the_mutex,
+  Thread_Control             *owner,
+  Thread_queue_Context       *queue_context
+)
+{
+  Priority_Control  priority_ceiling;
+  Priority_Control  current_priority;
+  Per_CPU_Control  *cpu_self;
+
+  priority_ceiling = the_mutex->priority_ceiling;
+  current_priority = owner->current_priority;
+
+  if ( current_priority < priority_ceiling ) {
+    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+    return STATUS_MUTEX_CEILING_VIOLATED;
+  }
+
+  _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, owner );
+  ++owner->resource_count;
+
+  if ( current_priority == priority_ceiling ) {
+    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+    return STATUS_SUCCESSFUL;
+  }
+
+  cpu_self = _Thread_Dispatch_disable_critical( &queue_context->Lock_context );
+  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+  _Thread_Raise_priority( owner, priority_ceiling );
+  _Thread_Dispatch_enable( cpu_self );
+  return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Seize(
+  CORE_ceiling_mutex_Control    *the_mutex,
+  Thread_Control                *executing,
+  bool                           wait,
+  Watchdog_Interval              timeout,
+  Status_Control              ( *nested )( CORE_recursive_mutex_Control * ),
+  Thread_queue_Context          *queue_context
+)
+{
+  Thread_Control *owner;
+
+  _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
+
+  owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
+
+  if ( owner == NULL ) {
+    return _CORE_ceiling_mutex_Set_owner(
+      the_mutex,
+      executing,
+      queue_context
+    );
+  }
+
+  if ( owner == executing ) {
+    Status_Control status;
+
+    status = ( *nested )( &the_mutex->Recursive );
+    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+    return status;
+  }
+
+  return _CORE_mutex_Seize_no_protocol_slow(
+    &the_mutex->Recursive.Mutex,
+    CORE_MUTEX_TQ_OPERATIONS,
+    executing,
+    wait,
+    timeout,
+    queue_context
+  );
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Surrender(
+  CORE_ceiling_mutex_Control *the_mutex,
+  Thread_Control             *executing,
+  Thread_queue_Context       *queue_context
+)
+{
+  unsigned int    nest_level;
+  Thread_Control *new_owner;
+
+  _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
+
+  if ( !_CORE_mutex_Is_owner( &the_mutex->Recursive.Mutex, executing ) ) {
+    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+    return STATUS_NOT_OWNER;
+  }
+
+  nest_level = the_mutex->Recursive.nest_level;
+
+  if ( nest_level > 0 ) {
+    the_mutex->Recursive.nest_level = nest_level - 1;
+    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+    return STATUS_SUCCESSFUL;
+  }
+
+  --executing->resource_count;
+
+  new_owner = _Thread_queue_First_locked(
+    &the_mutex->Recursive.Mutex.Wait_queue,
+    CORE_MUTEX_TQ_OPERATIONS
+  );
+  _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, new_owner );
+
+  if ( new_owner != NULL ) {
+    bool unblock;
+
+    /*
+     * We must extract the thread now since this will restore its default
+     * thread lock.  This is necessary to avoid a deadlock in the
+     * _Thread_Change_priority() below due to a recursive thread queue lock
+     * acquire.
+     */
+    unblock = _Thread_queue_Extract_locked(
+      &the_mutex->Recursive.Mutex.Wait_queue.Queue,
+      CORE_MUTEX_TQ_OPERATIONS,
+      new_owner,
+      queue_context
+    );
+
+#if defined(RTEMS_MULTIPROCESSING)
+    if ( _Objects_Is_local_id( new_owner->Object.id ) )
+#endif
+    {
+      ++new_owner->resource_count;
+      _Thread_Raise_priority( new_owner, the_mutex->priority_ceiling );
+    }
+
+    _Thread_queue_Unblock_critical(
+      unblock,
+      &the_mutex->Recursive.Mutex.Wait_queue.Queue,
+      new_owner,
+      &queue_context->Lock_context
+    );
+  } else {
+    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+  }
+
+  _CORE_mutex_Restore_priority( executing );
+  return STATUS_SUCCESSFUL;
+}
+
 /** @} */
 
Index: cpukit/score/src/apimutex.c
===================================================================
--- cpukit/score/src/apimutex.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/score/src/apimutex.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -49,7 +49,5 @@
 
   CORE_mutex_Attributes attr =  {
-    CORE_MUTEX_NESTING_ACQUIRES,
-    CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT,
-    0
+    CORE_MUTEX_NESTING_ACQUIRES
   };
 
Index: cpukit/score/src/coremutex.c
===================================================================
--- cpukit/score/src/coremutex.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/score/src/coremutex.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -40,39 +40,7 @@
 
   if ( initially_locked ) {
-    bool              is_priority_ceiling;
-    Priority_Control  ceiling;
-    Per_CPU_Control  *cpu_self;
-
     the_mutex->nest_count = 1;
     the_mutex->holder     = executing;
-
-    /* The mutex initialization is only protected by the allocator lock */
-    cpu_self = _Thread_Dispatch_disable();
-
-    is_priority_ceiling =
-      _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
-    ceiling = the_mutex->Attributes.priority_ceiling;
-
-    /*
-     * The test to check for a ceiling violation is a bit arbitrary.  In case
-     * this thread is the owner of a priority inheritance mutex, then it may
-     * get a higher priority later or anytime on SMP configurations.
-     */
-    if ( is_priority_ceiling && executing->current_priority < ceiling ) {
-      /*
-       * There is no need to undo the previous work since this error aborts
-       * the object creation.
-       */
-      _Thread_Dispatch_enable( cpu_self );
-      return STATUS_MUTEX_CEILING_VIOLATED;
-    }
-
     executing->resource_count++;
-
-    if ( is_priority_ceiling ) {
-      _Thread_Raise_priority( executing, ceiling );
-    }
-
-    _Thread_Dispatch_enable( cpu_self );
   } else {
     the_mutex->nest_count = 0;
Index: cpukit/score/src/coremutexseize.c
===================================================================
--- cpukit/score/src/coremutexseize.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/score/src/coremutexseize.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -30,4 +30,6 @@
 )
 {
+  Thread_Control *holder;
+
 #if !defined(RTEMS_SMP)
   /*
@@ -38,30 +40,25 @@
 #endif
 
-  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
-    Thread_Control *holder = the_mutex->holder;
+  holder = the_mutex->holder;
 
 #if !defined(RTEMS_SMP)
-    /*
-     * To enable interrupts here works only since exactly one executing thread
-     * exists and only threads are allowed to seize and surrender mutexes with
-     * the priority inheritance protocol.  On SMP configurations more than one
-     * executing thread may exist, so here we must not release the lock, since
-     * otherwise the current holder may be no longer the holder of the mutex
-     * once we released the lock.
-     */
-    _CORE_mutex_Release( the_mutex, queue_context );
+  /*
+   * To enable interrupts here works only since exactly one executing thread
+   * exists and only threads are allowed to seize and surrender mutexes with
+   * the priority inheritance protocol.  On SMP configurations more than one
+   * executing thread may exist, so here we must not release the lock, since
+   * otherwise the current holder may be no longer the holder of the mutex
+   * once we released the lock.
+   */
+  _CORE_mutex_Release( the_mutex, queue_context );
 #endif
 
-    _Thread_Inherit_priority( holder, executing );
-
-#if !defined(RTEMS_SMP)
-    _ISR_lock_ISR_disable( &queue_context->Lock_context );
-    _CORE_mutex_Acquire_critical( the_mutex, queue_context );
-#endif
-  }
+  _Thread_Inherit_priority( holder, executing );
 
 #if defined(RTEMS_SMP)
   _Thread_queue_Context_set_expected_level( queue_context, 1 );
 #else
+  _ISR_lock_ISR_disable( &queue_context->Lock_context );
+  _CORE_mutex_Acquire_critical( the_mutex, queue_context );
   _Thread_queue_Context_set_expected_level( queue_context, 2 );
 #endif
Index: cpukit/score/src/coremutexsurrender.c
===================================================================
--- cpukit/score/src/coremutexsurrender.c	(revision 5a598ac99b0de720a04afc5e2ac6764117589b90)
+++ cpukit/score/src/coremutexsurrender.c	(revision 33e250c9fa370f620ddbc5850342d5a90b123524)
@@ -119,17 +119,6 @@
 #endif
     {
-      switch ( the_mutex->Attributes.discipline ) {
-        case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
-          the_thread->resource_count++;
-          _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );
-          break;
-        case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
-          the_thread->resource_count++;
-          _Thread_Raise_priority(
-            the_thread,
-            the_mutex->Attributes.priority_ceiling
-          );
-          break;
-      }
+      the_thread->resource_count++;
+      _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );
     }
 
@@ -165,4 +154,5 @@
   }
 
+  _CORE_mutex_Restore_priority( holder );
   return STATUS_SUCCESSFUL;
 }
