kern/163268: [acpi_hp] fix driver detach in absence of CMI

Yuri Pankov yuri.pankov at gmail.com
Tue Dec 13 23:50:11 UTC 2011


>Number:         163268
>Category:       kern
>Synopsis:       [acpi_hp] fix driver detach in absence of CMI
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 13 23:50:10 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Yuri Pankov
>Release:        FreeBSD 9.0-RC3 amd64
>Organization:
>Environment:
System: FreeBSD procyon.xvoid.org 9.0-RC3 FreeBSD 9.0-RC3 #1 r228385: Sat Dec 10 07:29:02 MSK 2011 yuri at procyon.xvoid.org:/usr/obj/data/src/freebsd/releng/9.0/sys/GENERIC amd64
>Description:
Unloading acpi_hp driver in absence of CMI (e.g., on HP Pavilion DV8, not sure if laptop doesn't have it or driver just doesn't recognize its presence, but anyway.. ) leads to "panic: sbuf_delete called with uninitialized or corrupt sbuf". We shouldn't try to free CMI-related resources if we didn't allocate them, fix logic here a bit.
>How-To-Repeat:
>Fix:
--- acpi_hp.c.diff begins here ---
Index: sys/dev/acpi_support/acpi_hp.c
===================================================================
--- sys/dev/acpi_support/acpi_hp.c	(revision 228481)
+++ sys/dev/acpi_support/acpi_hp.c	(working copy)
@@ -573,25 +573,25 @@
 static int
 acpi_hp_detach(device_t dev)
 {
-	int	ret;
-	
+	int			ret = 0;
+	struct acpi_hp_softc	*sc = device_get_softc(dev);
+
 	ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
-	struct acpi_hp_softc *sc = device_get_softc(dev);
-	if (sc->has_cmi && sc->hpcmi_open_pid != 0) {
-		ret = EBUSY;
-	}
-	else {
-		if (sc->has_notify) {
-			ACPI_WMI_REMOVE_EVENT_HANDLER(dev,
-			    ACPI_HP_WMI_EVENT_GUID);
+
+	if (sc->has_notify)
+		ACPI_WMI_REMOVE_EVENT_HANDLER(dev, ACPI_HP_WMI_EVENT_GUID);
+
+	if (sc->has_cmi) {
+		if (sc->hpcmi_open_pid != 0) {
+			ret = EBUSY;
+		} else {
+			if (sc->hpcmi_bufptr != -1) {
+				sbuf_delete(&sc->hpcmi_sbuf);
+				sc->hpcmi_bufptr = -1;
+			}
+			sc->hpcmi_open_pid = 0;
+			destroy_dev(sc->hpcmi_dev_t);
 		}
-		if (sc->hpcmi_bufptr != -1) {
-			sbuf_delete(&sc->hpcmi_sbuf);
-			sc->hpcmi_bufptr = -1;
-		}
-		sc->hpcmi_open_pid = 0;
-		destroy_dev(sc->hpcmi_dev_t);
-		ret = 0;
 	}
 
 	return (ret);
--- acpi_hp.c.diff ends here ---


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


More information about the freebsd-bugs mailing list