Author: mav
Date: Wed Aug 12 02:05:33 2020
New Revision: 364136
URL: https://svnweb.freebsd.org/changeset/base/364136

Log:
  MFC r364037: Add some more checks to make APEI driver more robust.

Modified:
  stable/12/sys/dev/acpica/acpi_apei.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/acpica/acpi_apei.c
==============================================================================
--- stable/12/sys/dev/acpica/acpi_apei.c        Wed Aug 12 00:32:31 2020        
(r364135)
+++ stable/12/sys/dev/acpica/acpi_apei.c        Wed Aug 12 02:05:33 2020        
(r364136)
@@ -348,7 +348,7 @@ apei_ge_handler(struct apei_ge *ge, bool copy)
        uint32_t sev;
        int i, c, off;
 
-       if (ges->BlockStatus == 0)
+       if (ges == NULL || ges->BlockStatus == 0)
                return (0);
 
        c = (ges->BlockStatus >> 4) & 0x3ff;
@@ -363,7 +363,8 @@ apei_ge_handler(struct apei_ge *ge, bool copy)
 
        /* Acknowledge the error has been processed. */
        ges->BlockStatus = 0;
-       if (!copy && ge->v1.Header.Type == ACPI_HEST_TYPE_GENERIC_ERROR_V2) {
+       if (!copy && ge->v1.Header.Type == ACPI_HEST_TYPE_GENERIC_ERROR_V2 &&
+           ge->res2) {
                uint64_t val = READ8(ge->res2, 0);
                val &= ge->v2.ReadAckPreserve;
                val |= ge->v2.ReadAckWrite;
@@ -395,7 +396,7 @@ apei_nmi_handler(void)
                return (0);
 
        ges = (ACPI_HEST_GENERIC_STATUS *)ge->buf;
-       if (ges->BlockStatus == 0)
+       if (ges == NULL || ges->BlockStatus == 0)
                return (0);
 
        /* If ACPI told the error is fatal -- make it so. */
@@ -409,7 +410,8 @@ apei_nmi_handler(void)
 
        /* Acknowledge the error has been processed. */
        ges->BlockStatus = 0;
-       if (ge->v1.Header.Type == ACPI_HEST_TYPE_GENERIC_ERROR_V2) {
+       if (ge->v1.Header.Type == ACPI_HEST_TYPE_GENERIC_ERROR_V2 &&
+           ge->res2) {
                uint64_t val = READ8(ge->res2, 0);
                val &= ge->v2.ReadAckPreserve;
                val |= ge->v2.ReadAckWrite;
@@ -608,13 +610,19 @@ apei_attach(device_t dev)
                ge->res_rid = rid++;
                acpi_bus_alloc_gas(dev, &ge->res_type, &ge->res_rid,
                    &ge->v1.ErrorStatusAddress, &ge->res, 0);
+               if (ge->res) {
+                       ge->buf = pmap_mapdev_attr(READ8(ge->res, 0),
+                           ge->v1.ErrorBlockLength, 
VM_MEMATTR_WRITE_COMBINING);
+               } else {
+                       device_printf(dev, "Can't allocate status resource.\n");
+               }
                if (ge->v1.Header.Type == ACPI_HEST_TYPE_GENERIC_ERROR_V2) {
                        ge->res2_rid = rid++;
                        acpi_bus_alloc_gas(dev, &ge->res2_type, &ge->res2_rid,
                            &ge->v2.ReadAckRegister, &ge->res2, 0);
+                       if (ge->res2 == NULL)
+                               device_printf(dev, "Can't allocate ack 
resource.\n");
                }
-               ge->buf = pmap_mapdev_attr(READ8(ge->res, 0),
-                   ge->v1.ErrorBlockLength, VM_MEMATTR_WRITE_COMBINING);
                if (ge->v1.Notify.Type == ACPI_HEST_NOTIFY_POLLED) {
                        callout_init(&ge->poll, 1);
                        callout_reset(&ge->poll,
@@ -652,7 +660,10 @@ apei_detach(device_t dev)
 
        while ((ge = TAILQ_FIRST(&sc->ges)) != NULL) {
                TAILQ_REMOVE(&sc->ges, ge, link);
-               bus_release_resource(dev, ge->res_type, ge->res_rid, ge->res);
+               if (ge->res) {
+                       bus_release_resource(dev, ge->res_type,
+                           ge->res_rid, ge->res);
+               }
                if (ge->res2) {
                        bus_release_resource(dev, ge->res2_type,
                            ge->res2_rid, ge->res2);
@@ -663,7 +674,10 @@ apei_detach(device_t dev)
                        swi_remove(&ge->swi_ih);
                        free(ge->copybuf, M_DEVBUF);
                }
-               pmap_unmapdev((vm_offset_t)ge->buf, ge->v1.ErrorBlockLength);
+               if (ge->buf) {
+                       pmap_unmapdev((vm_offset_t)ge->buf,
+                           ge->v1.ErrorBlockLength);
+               }
                free(ge, M_DEVBUF);
        }
        return (0);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to