misc/143432: Two bugs in acpica in AcpiExReleaseMutex

Vladislav Shabanov vlad.shabanov at gmail.com
Mon Feb 1 15:40:03 UTC 2010


>Number:         143432
>Category:       misc
>Synopsis:       Two bugs in acpica in AcpiExReleaseMutex
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 01 15:40:03 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Vladislav Shabanov
>Release:        Freebsd-8-stable
>Organization:
Mail.ru
>Environment:
FreeBSD vsnotebook 8.0-STABLE FreeBSD 8.0-STABLE #15: Mon Feb  1 16:24:33 MSK 2010     root at vsNotebook:/usr/src/sys/amd64/compile/VS-FERRARI  amd64
>Description:
>From time to time computer crashed during boot inside AcpiExReleaseMutex.
When I turned on ACPI_DEBUG, it crashes always.

Probjem 1:
line 

if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
        (ObjDesc != AcpiGbl_GlobalLockMutex))

goes earlier than
if (!WalkState->Thread)

if WalkState->Thread is NULL, it crashed before check. In my case it was not happened, in my case crash was because problem 2.

Problem 2:
my computer crashed when WalkState->Thread->AcquiredMutexList was NULL. 
May be this is because Mutex was acquired in one thread and released in another?


>How-To-Repeat:

>Fix:
--- exmutex.c-ORIG      2010-02-01 15:22:05.000000000 +0300                                         
+++ exmutex.c   2010-02-01 16:16:43.000000000 +0300                                                 
@@ -490,6 +490,15 @@                                                                                
         return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);                                            
     }                                                                                              
                                                                                                    
+    /* Must have a valid thread ID */                                                              
+                                                                                                   
+    if (!WalkState->Thread)                                                                        
+    {                                                                                              
+        ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+        return_ACPI_STATUS (AE_AML_INTERNAL);
+    }
+
     /*
      * The Mutex is owned, but this thread must be the owner.
      * Special case for Global Lock, any thread can release
@@ -505,15 +514,6 @@
         return_ACPI_STATUS (AE_AML_NOT_OWNER);
     }

-    /* Must have a valid thread ID */
-
-    if (!WalkState->Thread)
-    {
-        ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
-            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
-        return_ACPI_STATUS (AE_AML_INTERNAL);
-    }
-
     /*
      * The sync level of the mutex must be equal to the current sync level. In
      * other words, the current level means that at least one mutex at that
@@ -535,8 +535,16 @@
      * This handles the case where several mutexes at the same level have been
      * acquired, but are not released in reverse order.
      */
-    PreviousSyncLevel =
-        WalkState->Thread->AcquiredMutexList->Mutex.OriginalSyncLevel;
+    if (!WalkState->Thread->AcquiredMutexList)
+    {
+        ACPI_ERROR ((AE_INFO, "Thread AcquiredMutexList empty while releasing mutex Mutex [%4.4s]",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+        /* return_ACPI_STATUS (AE_AML_INTERNAL); */
+        PreviousSyncLevel = WalkState->Thread->CurrentSyncLevel;
+    }
+    else
+        PreviousSyncLevel =
+            WalkState->Thread->AcquiredMutexList->Mutex.OriginalSyncLevel;

     Status = AcpiExReleaseMutexObject (ObjDesc);
     if (ACPI_FAILURE (Status))


Patch attached with submission follows:

--- exmutex.c-ORIG	2010-02-01 15:22:05.000000000 +0300
+++ exmutex.c	2010-02-01 16:16:43.000000000 +0300
@@ -490,6 +490,15 @@
         return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
     }
 
+    /* Must have a valid thread ID */
+
+    if (!WalkState->Thread)
+    {
+        ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+        return_ACPI_STATUS (AE_AML_INTERNAL);
+    }
+
     /*
      * The Mutex is owned, but this thread must be the owner.
      * Special case for Global Lock, any thread can release
@@ -505,15 +514,6 @@
         return_ACPI_STATUS (AE_AML_NOT_OWNER);
     }
 
-    /* Must have a valid thread ID */
-
-    if (!WalkState->Thread)
-    {
-        ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
-            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
-        return_ACPI_STATUS (AE_AML_INTERNAL);
-    }
-
     /*
      * The sync level of the mutex must be equal to the current sync level. In
      * other words, the current level means that at least one mutex at that
@@ -535,8 +535,16 @@
      * This handles the case where several mutexes at the same level have been
      * acquired, but are not released in reverse order.
      */
-    PreviousSyncLevel =
-        WalkState->Thread->AcquiredMutexList->Mutex.OriginalSyncLevel;
+    if (!WalkState->Thread->AcquiredMutexList)
+    {
+        ACPI_ERROR ((AE_INFO, "Thread AcquiredMutexList empty while releasing mutex Mutex [%4.4s]",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+        /* return_ACPI_STATUS (AE_AML_INTERNAL); */
+        PreviousSyncLevel = WalkState->Thread->CurrentSyncLevel;
+    }
+    else
+        PreviousSyncLevel =
+            WalkState->Thread->AcquiredMutexList->Mutex.OriginalSyncLevel;
 
     Status = AcpiExReleaseMutexObject (ObjDesc);
     if (ACPI_FAILURE (Status))


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list