From nobody@FreeBSD.org  Mon Feb  1 15:34:03 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id BABB4106566C
	for <freebsd-gnats-submit@FreeBSD.org>; Mon,  1 Feb 2010 15:34:03 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id A84868FC15
	for <freebsd-gnats-submit@FreeBSD.org>; Mon,  1 Feb 2010 15:34:03 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o11FY3nW033657
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 1 Feb 2010 15:34:03 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o11FY3aI033656;
	Mon, 1 Feb 2010 15:34:03 GMT
	(envelope-from nobody)
Message-Id: <201002011534.o11FY3aI033656@www.freebsd.org>
Date: Mon, 1 Feb 2010 15:34:03 GMT
From: Vladislav Shabanov <vlad.shabanov@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Two bugs in acpica in AcpiExReleaseMutex
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         143432
>Category:       kern
>Synopsis:       [acpi] [patch] Two bugs in acpica in AcpiExReleaseMutex
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    avg
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 01 15:40:03 UTC 2010
>Closed-Date:    Tue Mar 09 07:15:55 UTC 2010
>Last-Modified:  Tue Mar 09 07:15:55 UTC 2010
>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@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:
Responsible-Changed-From-To: freebsd-bugs->freebsd-acpi 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Tue Feb 2 00:07:42 UTC 2010 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=143432 
Responsible-Changed-From-To: freebsd-acpi->avg 
Responsible-Changed-By: avg 
Responsible-Changed-When: Tue Feb 2 11:49:10 UTC 2010 
Responsible-Changed-Why:  
I will take this as I've been working on these issues. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=143432 
State-Changed-From-To: open->patched 
State-Changed-By: avg 
State-Changed-When: Tue Feb 2 14:25:38 UTC 2010 
State-Changed-Why:  
The first issue is already fixed in head by vendor import 
of ACPICA 20091214 (presently at 20100121). 
The second issue is a duplicate of kern/140979 and will 
not be tracked here. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=143432 

From: Lin Ming <ming.m.lin@intel.com>
To: linimon@freebsd.org, freebsd-bugs@freebsd.org, freebsd-acpi@freebsd.org
Cc: "Moore, Robert" <robert.moore@intel.com>
Subject: Re: kern/143432: [acpi] [patch] Two bugs in acpica in
 AcpiExReleaseMutex
Date: Tue, 02 Feb 2010 10:40:23 +0800

 --=-+akFnwk/NjPxo18vPa8t
 Content-Type: text/plain
 Content-Transfer-Encoding: 7bit
 
 Problem 1 was already fixed in release 20091214, see 
 http://git.moblin.org/cgit.cgi/acpica/commit/?id=93324dd734d70c4aa451c3aa24dfe91b7b8ef7f9
 
 Problem 2 is same with http://www.freebsd.org/cgi/query-pr.cgi?pr=140979
 and fixed by the attached patch. We will merge it into next release.
 
 Lin Ming
 
 > -----Original Message-----
 > From: owner-freebsd-acpi@freebsd.org [mailto:owner-freebsd-acpi@freebsd.org] On Behalf Of linimon@FreeBSD.org
 > Sent: Monday, February 01, 2010 4:08 PM
 > To: linimon@FreeBSD.org; freebsd-bugs@FreeBSD.org; freebsd-acpi@FreeBSD.org
 > Subject: Re: kern/143432: [acpi] [patch] Two bugs in acpica in AcpiExReleaseMutex
 > 
 > Old Synopsis: Two bugs in acpica in AcpiExReleaseMutex
 > New Synopsis: [acpi] [patch] Two bugs in acpica in AcpiExReleaseMutex
 > 
 > Responsible-Changed-From-To: freebsd-bugs->freebsd-acpi
 > Responsible-Changed-By: linimon
 > Responsible-Changed-When: Tue Feb 2 00:07:42 UTC 2010
 > Responsible-Changed-Why: 
 > Over to maintainer(s).
 > 
 > http://www.freebsd.org/cgi/query-pr.cgi?pr=143432
 > _______________________________________________
 > freebsd-acpi@freebsd.org mailing list
 > http://lists.freebsd.org/mailman/listinfo/freebsd-acpi
 > To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org"
 
 --=-+akFnwk/NjPxo18vPa8t
 Content-Disposition: attachment; filename="mutex.patch"
 Content-Type: text/x-patch; name="mutex.patch"; charset="UTF-8"
 Content-Transfer-Encoding: 7bit
 
 diff --git a/source/components/executer/exmutex.c b/source/components/executer/exmutex.c
 index d0aa9de..0a4048d 100644
 --- a/source/components/executer/exmutex.c
 +++ b/source/components/executer/exmutex.c
 @@ -471,6 +471,7 @@ AcpiExReleaseMutex (
  {
      ACPI_STATUS             Status = AE_OK;
      UINT8                   PreviousSyncLevel;
 +    ACPI_THREAD_STATE       *OwnerThread;
  
  
      ACPI_FUNCTION_TRACE (ExReleaseMutex);
 @@ -481,9 +482,11 @@ AcpiExReleaseMutex (
          return_ACPI_STATUS (AE_BAD_PARAMETER);
      }
  
 +    OwnerThread = ObjDesc->Mutex.OwnerThread;
 +
      /* The mutex must have been previously acquired in order to release it */
  
 -    if (!ObjDesc->Mutex.OwnerThread)
 +    if (!OwnerThread)
      {
          ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired",
              AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
 @@ -503,14 +506,14 @@ AcpiExReleaseMutex (
       * The Mutex is owned, but this thread must be the owner.
       * Special case for Global Lock, any thread can release
       */
 -    if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
 +    if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
          (ObjDesc != AcpiGbl_GlobalLockMutex))
      {
          ACPI_ERROR ((AE_INFO,
              "Thread %p cannot release Mutex [%4.4s] acquired by thread %p",
              ACPI_CAST_PTR (void, WalkState->Thread->ThreadId),
              AcpiUtGetNodeName (ObjDesc->Mutex.Node),
 -            ACPI_CAST_PTR (void, ObjDesc->Mutex.OwnerThread->ThreadId)));
 +            ACPI_CAST_PTR (void, OwnerThread->ThreadId)));
          return_ACPI_STATUS (AE_AML_NOT_OWNER);
      }
  
 @@ -521,7 +524,7 @@ AcpiExReleaseMutex (
       * different level can only mean that the mutex ordering rule is being
       * violated. This behavior is clarified in ACPI 4.0 specification.
       */
 -    if (ObjDesc->Mutex.SyncLevel != WalkState->Thread->CurrentSyncLevel)
 +    if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
      {
          ACPI_ERROR ((AE_INFO,
              "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
 @@ -536,7 +539,7 @@ AcpiExReleaseMutex (
       * acquired, but are not released in reverse order.
       */
      PreviousSyncLevel =
 -        WalkState->Thread->AcquiredMutexList->Mutex.OriginalSyncLevel;
 +        OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
  
      Status = AcpiExReleaseMutexObject (ObjDesc);
      if (ACPI_FAILURE (Status))
 @@ -548,7 +551,7 @@ AcpiExReleaseMutex (
      {
          /* Restore the previous SyncLevel */
  
 -        WalkState->Thread->CurrentSyncLevel = PreviousSyncLevel;
 +        OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
      }
      return_ACPI_STATUS (Status);
  }
 
 --=-+akFnwk/NjPxo18vPa8t
 Content-Type: text/plain; charset="us-ascii"
 MIME-Version: 1.0
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline
 
 _______________________________________________
 freebsd-bugs@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
 To unsubscribe, send any mail to "freebsd-bugs-unsubscribe@freebsd.org"
 --=-+akFnwk/NjPxo18vPa8t--
 
 

From: Andriy Gapon <avg@freebsd.org>
To: bug-followup@freebsd.org, vlad.shabanov@gmail.com
Cc:  
Subject: Re: kern/143432: [acpi] [patch] Two bugs in acpica in AcpiExReleaseMutex
Date: Wed, 10 Feb 2010 20:07:08 +0200

 Vlad,
 
 could you please test the patches provided by Lin Ming and let us know what you
 get with them?
 
 -- 
 Andriy Gapon
State-Changed-From-To: patched->closed  
State-Changed-By: brucec 
State-Changed-When: Tue Mar 9 07:14:47 UTC 2010 
State-Changed-Why:  
ACPICA 20100121 has been merged to stable/8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=143432 
>Unformatted:
