LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - nspredef.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 37 54 68.5 %
Date: 2022-03-28 16:04:14 Functions: 4 4 100.0 %
Branches: 23 44 52.3 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: nspredef - Validation of ACPI predefined methods and objects
       5                 :            :  *
       6                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       7                 :            :  *
       8                 :            :  *****************************************************************************/
       9                 :            : 
      10                 :            : #define ACPI_CREATE_PREDEFINED_TABLE
      11                 :            : 
      12                 :            : #include <acpi/acpi.h>
      13                 :            : #include "accommon.h"
      14                 :            : #include "acnamesp.h"
      15                 :            : #include "acpredef.h"
      16                 :            : 
      17                 :            : #define _COMPONENT          ACPI_NAMESPACE
      18                 :            : ACPI_MODULE_NAME("nspredef")
      19                 :            : 
      20                 :            : /*******************************************************************************
      21                 :            :  *
      22                 :            :  * This module validates predefined ACPI objects that appear in the namespace,
      23                 :            :  * at the time they are evaluated (via acpi_evaluate_object). The purpose of this
      24                 :            :  * validation is to detect problems with BIOS-exposed predefined ACPI objects
      25                 :            :  * before the results are returned to the ACPI-related drivers.
      26                 :            :  *
      27                 :            :  * There are several areas that are validated:
      28                 :            :  *
      29                 :            :  *  1) The number of input arguments as defined by the method/object in the
      30                 :            :  *     ASL is validated against the ACPI specification.
      31                 :            :  *  2) The type of the return object (if any) is validated against the ACPI
      32                 :            :  *     specification.
      33                 :            :  *  3) For returned package objects, the count of package elements is
      34                 :            :  *     validated, as well as the type of each package element. Nested
      35                 :            :  *     packages are supported.
      36                 :            :  *
      37                 :            :  * For any problems found, a warning message is issued.
      38                 :            :  *
      39                 :            :  ******************************************************************************/
      40                 :            : /* Local prototypes */
      41                 :            : static acpi_status
      42                 :            : acpi_ns_check_reference(struct acpi_evaluate_info *info,
      43                 :            :                         union acpi_operand_object *return_object);
      44                 :            : 
      45                 :            : static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object);
      46                 :            : 
      47                 :            : /*******************************************************************************
      48                 :            :  *
      49                 :            :  * FUNCTION:    acpi_ns_check_return_value
      50                 :            :  *
      51                 :            :  * PARAMETERS:  node            - Namespace node for the method/object
      52                 :            :  *              info            - Method execution information block
      53                 :            :  *              user_param_count - Number of parameters actually passed
      54                 :            :  *              return_status   - Status from the object evaluation
      55                 :            :  *              return_object_ptr - Pointer to the object returned from the
      56                 :            :  *                                evaluation of a method or object
      57                 :            :  *
      58                 :            :  * RETURN:      Status
      59                 :            :  *
      60                 :            :  * DESCRIPTION: Check the value returned from a predefined name.
      61                 :            :  *
      62                 :            :  ******************************************************************************/
      63                 :            : 
      64                 :            : acpi_status
      65                 :       7982 : acpi_ns_check_return_value(struct acpi_namespace_node *node,
      66                 :            :                            struct acpi_evaluate_info *info,
      67                 :            :                            u32 user_param_count,
      68                 :            :                            acpi_status return_status,
      69                 :            :                            union acpi_operand_object **return_object_ptr)
      70                 :            : {
      71                 :       7982 :         acpi_status status;
      72                 :       7982 :         const union acpi_predefined_info *predefined;
      73                 :            : 
      74                 :            :         /* If not a predefined name, we cannot validate the return object */
      75                 :            : 
      76                 :       7982 :         predefined = info->predefined;
      77         [ +  + ]:       7982 :         if (!predefined) {
      78                 :            :                 return (AE_OK);
      79                 :            :         }
      80                 :            : 
      81                 :            :         /*
      82                 :            :          * If the method failed or did not actually return an object, we cannot
      83                 :            :          * validate the return object
      84                 :            :          */
      85         [ +  - ]:       7943 :         if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) {
      86                 :            :                 return (AE_OK);
      87                 :            :         }
      88                 :            : 
      89                 :            :         /*
      90                 :            :          * Return value validation and possible repair.
      91                 :            :          *
      92                 :            :          * 1) Don't perform return value validation/repair if this feature
      93                 :            :          * has been disabled via a global option.
      94                 :            :          *
      95                 :            :          * 2) We have a return value, but if one wasn't expected, just exit,
      96                 :            :          * this is not a problem. For example, if the "Implicit Return"
      97                 :            :          * feature is enabled, methods will always return a value.
      98                 :            :          *
      99                 :            :          * 3) If the return value can be of any type, then we cannot perform
     100                 :            :          * any validation, just exit.
     101                 :            :          */
     102         [ +  - ]:       7943 :         if (acpi_gbl_disable_auto_repair ||
     103   [ +  +  +  - ]:       7943 :             (!predefined->info.expected_btypes) ||
     104                 :            :             (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
     105                 :            :                 return (AE_OK);
     106                 :            :         }
     107                 :            : 
     108                 :            :         /*
     109                 :            :          * Check that the type of the main return object is what is expected
     110                 :            :          * for this predefined name
     111                 :            :          */
     112                 :       7852 :         status = acpi_ns_check_object_type(info, return_object_ptr,
     113                 :            :                                            predefined->info.expected_btypes,
     114                 :            :                                            ACPI_NOT_PACKAGE_ELEMENT);
     115         [ -  + ]:       7852 :         if (ACPI_FAILURE(status)) {
     116                 :          0 :                 goto exit;
     117                 :            :         }
     118                 :            : 
     119                 :            :         /*
     120                 :            :          *
     121                 :            :          * 4) If there is no return value and it is optional, just return
     122                 :            :          * AE_OK (_WAK).
     123                 :            :          */
     124         [ -  + ]:       7852 :         if (!(*return_object_ptr)) {
     125                 :          0 :                 goto exit;
     126                 :            :         }
     127                 :            : 
     128                 :            :         /*
     129                 :            :          * For returned Package objects, check the type of all sub-objects.
     130                 :            :          * Note: Package may have been newly created by call above.
     131                 :            :          */
     132         [ +  + ]:       7852 :         if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) {
     133                 :         65 :                 info->parent_package = *return_object_ptr;
     134                 :         65 :                 status = acpi_ns_check_package(info, return_object_ptr);
     135         [ -  + ]:         65 :                 if (ACPI_FAILURE(status)) {
     136                 :            : 
     137                 :            :                         /* We might be able to fix some errors */
     138                 :            : 
     139         [ #  # ]:          0 :                         if ((status != AE_AML_OPERAND_TYPE) &&
     140                 :            :                             (status != AE_AML_OPERAND_VALUE)) {
     141                 :          0 :                                 goto exit;
     142                 :            :                         }
     143                 :            :                 }
     144                 :            :         }
     145                 :            : 
     146                 :            :         /*
     147                 :            :          * The return object was OK, or it was successfully repaired above.
     148                 :            :          * Now make some additional checks such as verifying that package
     149                 :            :          * objects are sorted correctly (if required) or buffer objects have
     150                 :            :          * the correct data width (bytes vs. dwords). These repairs are
     151                 :            :          * performed on a per-name basis, i.e., the code is specific to
     152                 :            :          * particular predefined names.
     153                 :            :          */
     154                 :       7852 :         status = acpi_ns_complex_repairs(info, node, status, return_object_ptr);
     155                 :            : 
     156                 :       7852 : exit:
     157                 :            :         /*
     158                 :            :          * If the object validation failed or if we successfully repaired one
     159                 :            :          * or more objects, mark the parent node to suppress further warning
     160                 :            :          * messages during the next evaluation of the same method/object.
     161                 :            :          */
     162   [ +  -  -  + ]:       7852 :         if (ACPI_FAILURE(status) || (info->return_flags & ACPI_OBJECT_REPAIRED)) {
     163                 :          0 :                 node->flags |= ANOBJ_EVALUATED;
     164                 :            :         }
     165                 :            : 
     166                 :            :         return (status);
     167                 :            : }
     168                 :            : 
     169                 :            : /*******************************************************************************
     170                 :            :  *
     171                 :            :  * FUNCTION:    acpi_ns_check_object_type
     172                 :            :  *
     173                 :            :  * PARAMETERS:  info            - Method execution information block
     174                 :            :  *              return_object_ptr - Pointer to the object returned from the
     175                 :            :  *                                evaluation of a method or object
     176                 :            :  *              expected_btypes - Bitmap of expected return type(s)
     177                 :            :  *              package_index   - Index of object within parent package (if
     178                 :            :  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
     179                 :            :  *                                otherwise)
     180                 :            :  *
     181                 :            :  * RETURN:      Status
     182                 :            :  *
     183                 :            :  * DESCRIPTION: Check the type of the return object against the expected object
     184                 :            :  *              type(s). Use of Btype allows multiple expected object types.
     185                 :            :  *
     186                 :            :  ******************************************************************************/
     187                 :            : 
     188                 :            : acpi_status
     189                 :      24648 : acpi_ns_check_object_type(struct acpi_evaluate_info *info,
     190                 :            :                           union acpi_operand_object **return_object_ptr,
     191                 :            :                           u32 expected_btypes, u32 package_index)
     192                 :            : {
     193                 :      24648 :         union acpi_operand_object *return_object = *return_object_ptr;
     194                 :      24648 :         acpi_status status = AE_OK;
     195                 :      24648 :         char type_buffer[96];   /* Room for 10 types */
     196                 :            : 
     197                 :            :         /* A Namespace node should not get here, but make sure */
     198                 :            : 
     199         [ +  - ]:      24648 :         if (return_object &&
     200         [ -  + ]:      24648 :             ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
     201                 :          0 :                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
     202                 :            :                                       info->node_flags,
     203                 :            :                                       "Invalid return type - Found a Namespace node [%4.4s] type %s",
     204                 :            :                                       return_object->node.name.ascii,
     205                 :            :                                       acpi_ut_get_type_name(return_object->node.
     206                 :            :                                                             type)));
     207                 :          0 :                 return (AE_AML_OPERAND_TYPE);
     208                 :            :         }
     209                 :            : 
     210                 :            :         /*
     211                 :            :          * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
     212                 :            :          * The bitmapped type allows multiple possible return types.
     213                 :            :          *
     214                 :            :          * Note, the cases below must handle all of the possible types returned
     215                 :            :          * from all of the predefined names (including elements of returned
     216                 :            :          * packages)
     217                 :            :          */
     218                 :      24648 :         info->return_btype = acpi_ns_get_bitmapped_type(return_object);
     219         [ -  + ]:      24648 :         if (info->return_btype == ACPI_RTYPE_ANY) {
     220                 :            : 
     221                 :            :                 /* Not one of the supported objects, must be incorrect */
     222                 :          0 :                 goto type_error_exit;
     223                 :            :         }
     224                 :            : 
     225                 :            :         /* For reference objects, check that the reference type is correct */
     226                 :            : 
     227         [ +  + ]:      24648 :         if ((info->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
     228                 :       3328 :                 status = acpi_ns_check_reference(info, return_object);
     229                 :       3328 :                 return (status);
     230                 :            :         }
     231                 :            : 
     232                 :            :         /* Attempt simple repair of the returned object if necessary */
     233                 :            : 
     234                 :      21320 :         status = acpi_ns_simple_repair(info, expected_btypes,
     235                 :            :                                        package_index, return_object_ptr);
     236         [ -  + ]:      21320 :         if (ACPI_SUCCESS(status)) {
     237                 :            :                 return (AE_OK); /* Successful repair */
     238                 :            :         }
     239                 :            : 
     240                 :          0 : type_error_exit:
     241                 :            : 
     242                 :            :         /* Create a string with all expected types for this predefined object */
     243                 :            : 
     244                 :          0 :         acpi_ut_get_expected_return_types(type_buffer, expected_btypes);
     245                 :            : 
     246         [ #  # ]:          0 :         if (!return_object) {
     247                 :          0 :                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
     248                 :            :                                       info->node_flags,
     249                 :            :                                       "Expected return object of type %s",
     250                 :            :                                       type_buffer));
     251         [ #  # ]:          0 :         } else if (package_index == ACPI_NOT_PACKAGE_ELEMENT) {
     252                 :          0 :                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
     253                 :            :                                       info->node_flags,
     254                 :            :                                       "Return type mismatch - found %s, expected %s",
     255                 :            :                                       acpi_ut_get_object_type_name
     256                 :            :                                       (return_object), type_buffer));
     257                 :            :         } else {
     258                 :          0 :                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
     259                 :            :                                       info->node_flags,
     260                 :            :                                       "Return Package type mismatch at index %u - "
     261                 :            :                                       "found %s, expected %s", package_index,
     262                 :            :                                       acpi_ut_get_object_type_name
     263                 :            :                                       (return_object), type_buffer));
     264                 :            :         }
     265                 :            : 
     266                 :            :         return (AE_AML_OPERAND_TYPE);
     267                 :            : }
     268                 :            : 
     269                 :            : /*******************************************************************************
     270                 :            :  *
     271                 :            :  * FUNCTION:    acpi_ns_check_reference
     272                 :            :  *
     273                 :            :  * PARAMETERS:  info            - Method execution information block
     274                 :            :  *              return_object   - Object returned from the evaluation of a
     275                 :            :  *                                method or object
     276                 :            :  *
     277                 :            :  * RETURN:      Status
     278                 :            :  *
     279                 :            :  * DESCRIPTION: Check a returned reference object for the correct reference
     280                 :            :  *              type. The only reference type that can be returned from a
     281                 :            :  *              predefined method is a named reference. All others are invalid.
     282                 :            :  *
     283                 :            :  ******************************************************************************/
     284                 :            : 
     285                 :            : static acpi_status
     286                 :       3328 : acpi_ns_check_reference(struct acpi_evaluate_info *info,
     287                 :            :                         union acpi_operand_object *return_object)
     288                 :            : {
     289                 :            : 
     290                 :            :         /*
     291                 :            :          * Check the reference object for the correct reference type (opcode).
     292                 :            :          * The only type of reference that can be converted to a union acpi_object is
     293                 :            :          * a reference to a named object (reference class: NAME)
     294                 :            :          */
     295         [ -  + ]:       3328 :         if (return_object->reference.class == ACPI_REFCLASS_NAME) {
     296                 :            :                 return (AE_OK);
     297                 :            :         }
     298                 :            : 
     299                 :          0 :         ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
     300                 :            :                               "Return type mismatch - unexpected reference object type [%s] %2.2X",
     301                 :            :                               acpi_ut_get_reference_name(return_object),
     302                 :            :                               return_object->reference.class));
     303                 :            : 
     304                 :          0 :         return (AE_AML_OPERAND_TYPE);
     305                 :            : }
     306                 :            : 
     307                 :            : /*******************************************************************************
     308                 :            :  *
     309                 :            :  * FUNCTION:    acpi_ns_get_bitmapped_type
     310                 :            :  *
     311                 :            :  * PARAMETERS:  return_object   - Object returned from method/obj evaluation
     312                 :            :  *
     313                 :            :  * RETURN:      Object return type. ACPI_RTYPE_ANY indicates that the object
     314                 :            :  *              type is not supported. ACPI_RTYPE_NONE indicates that no
     315                 :            :  *              object was returned (return_object is NULL).
     316                 :            :  *
     317                 :            :  * DESCRIPTION: Convert object type into a bitmapped object return type.
     318                 :            :  *
     319                 :            :  ******************************************************************************/
     320                 :            : 
     321                 :      24648 : static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object)
     322                 :            : {
     323                 :      24648 :         u32 return_btype;
     324                 :            : 
     325         [ +  - ]:      24648 :         if (!return_object) {
     326                 :            :                 return (ACPI_RTYPE_NONE);
     327                 :            :         }
     328                 :            : 
     329                 :            :         /* Map acpi_object_type to internal bitmapped type */
     330                 :            : 
     331         [ -  + ]:      24648 :         switch (return_object->common.type) {
     332                 :            :         case ACPI_TYPE_INTEGER:
     333                 :            : 
     334                 :            :                 return_btype = ACPI_RTYPE_INTEGER;
     335                 :            :                 break;
     336                 :            : 
     337                 :            :         case ACPI_TYPE_BUFFER:
     338                 :            : 
     339                 :            :                 return_btype = ACPI_RTYPE_BUFFER;
     340                 :            :                 break;
     341                 :            : 
     342                 :            :         case ACPI_TYPE_STRING:
     343                 :            : 
     344                 :            :                 return_btype = ACPI_RTYPE_STRING;
     345                 :            :                 break;
     346                 :            : 
     347                 :            :         case ACPI_TYPE_PACKAGE:
     348                 :            : 
     349                 :            :                 return_btype = ACPI_RTYPE_PACKAGE;
     350                 :            :                 break;
     351                 :            : 
     352                 :            :         case ACPI_TYPE_LOCAL_REFERENCE:
     353                 :            : 
     354                 :            :                 return_btype = ACPI_RTYPE_REFERENCE;
     355                 :            :                 break;
     356                 :            : 
     357                 :            :         default:
     358                 :            : 
     359                 :            :                 /* Not one of the supported objects, must be incorrect */
     360                 :            : 
     361                 :            :                 return_btype = ACPI_RTYPE_ANY;
     362                 :            :                 break;
     363                 :            :         }
     364                 :            : 
     365                 :            :         return (return_btype);
     366                 :            : }

Generated by: LCOV version 1.14