cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

exstore.c (16953B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: exstore - AML Interpreter object store support
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acdispat.h"
     13#include "acinterp.h"
     14#include "amlcode.h"
     15#include "acnamesp.h"
     16
     17#define _COMPONENT          ACPI_EXECUTER
     18ACPI_MODULE_NAME("exstore")
     19
     20/* Local prototypes */
     21static acpi_status
     22acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
     23			      union acpi_operand_object *dest_desc,
     24			      struct acpi_walk_state *walk_state);
     25
     26static acpi_status
     27acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
     28			     struct acpi_namespace_node *node,
     29			     struct acpi_walk_state *walk_state);
     30
     31/*******************************************************************************
     32 *
     33 * FUNCTION:    acpi_ex_store
     34 *
     35 * PARAMETERS:  *source_desc        - Value to be stored
     36 *              *dest_desc          - Where to store it. Must be an NS node
     37 *                                    or union acpi_operand_object of type
     38 *                                    Reference;
     39 *              walk_state          - Current walk state
     40 *
     41 * RETURN:      Status
     42 *
     43 * DESCRIPTION: Store the value described by source_desc into the location
     44 *              described by dest_desc. Called by various interpreter
     45 *              functions to store the result of an operation into
     46 *              the destination operand -- not just simply the actual "Store"
     47 *              ASL operator.
     48 *
     49 ******************************************************************************/
     50
     51acpi_status
     52acpi_ex_store(union acpi_operand_object *source_desc,
     53	      union acpi_operand_object *dest_desc,
     54	      struct acpi_walk_state *walk_state)
     55{
     56	acpi_status status = AE_OK;
     57	union acpi_operand_object *ref_desc = dest_desc;
     58
     59	ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
     60
     61	/* Validate parameters */
     62
     63	if (!source_desc || !dest_desc) {
     64		ACPI_ERROR((AE_INFO, "Null parameter"));
     65		return_ACPI_STATUS(AE_AML_NO_OPERAND);
     66	}
     67
     68	/* dest_desc can be either a namespace node or an ACPI object */
     69
     70	if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
     71		/*
     72		 * Dest is a namespace node,
     73		 * Storing an object into a Named node.
     74		 */
     75		status = acpi_ex_store_object_to_node(source_desc,
     76						      (struct
     77						       acpi_namespace_node *)
     78						      dest_desc, walk_state,
     79						      ACPI_IMPLICIT_CONVERSION);
     80
     81		return_ACPI_STATUS(status);
     82	}
     83
     84	/* Destination object must be a Reference or a Constant object */
     85
     86	switch (dest_desc->common.type) {
     87	case ACPI_TYPE_LOCAL_REFERENCE:
     88
     89		break;
     90
     91	case ACPI_TYPE_INTEGER:
     92
     93		/* Allow stores to Constants -- a Noop as per ACPI spec */
     94
     95		if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
     96			return_ACPI_STATUS(AE_OK);
     97		}
     98
     99		ACPI_FALLTHROUGH;
    100
    101	default:
    102
    103		/* Destination is not a Reference object */
    104
    105		ACPI_ERROR((AE_INFO,
    106			    "Target is not a Reference or Constant object - [%s] %p",
    107			    acpi_ut_get_object_type_name(dest_desc),
    108			    dest_desc));
    109
    110		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
    111	}
    112
    113	/*
    114	 * Examine the Reference class. These cases are handled:
    115	 *
    116	 * 1) Store to Name (Change the object associated with a name)
    117	 * 2) Store to an indexed area of a Buffer or Package
    118	 * 3) Store to a Method Local or Arg
    119	 * 4) Store to the debug object
    120	 */
    121	switch (ref_desc->reference.class) {
    122	case ACPI_REFCLASS_REFOF:
    123
    124		/* Storing an object into a Name "container" */
    125
    126		status = acpi_ex_store_object_to_node(source_desc,
    127						      ref_desc->reference.
    128						      object, walk_state,
    129						      ACPI_IMPLICIT_CONVERSION);
    130		break;
    131
    132	case ACPI_REFCLASS_INDEX:
    133
    134		/* Storing to an Index (pointer into a packager or buffer) */
    135
    136		status =
    137		    acpi_ex_store_object_to_index(source_desc, ref_desc,
    138						  walk_state);
    139		break;
    140
    141	case ACPI_REFCLASS_LOCAL:
    142	case ACPI_REFCLASS_ARG:
    143
    144		/* Store to a method local/arg  */
    145
    146		status =
    147		    acpi_ds_store_object_to_local(ref_desc->reference.class,
    148						  ref_desc->reference.value,
    149						  source_desc, walk_state);
    150		break;
    151
    152	case ACPI_REFCLASS_DEBUG:
    153		/*
    154		 * Storing to the Debug object causes the value stored to be
    155		 * displayed and otherwise has no effect -- see ACPI Specification
    156		 */
    157		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
    158				  "**** Write to Debug Object: Object %p [%s] ****:\n\n",
    159				  source_desc,
    160				  acpi_ut_get_object_type_name(source_desc)));
    161
    162		ACPI_DEBUG_OBJECT(source_desc, 0, 0);
    163		break;
    164
    165	default:
    166
    167		ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
    168			    ref_desc->reference.class));
    169		ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
    170
    171		status = AE_AML_INTERNAL;
    172		break;
    173	}
    174
    175	return_ACPI_STATUS(status);
    176}
    177
    178/*******************************************************************************
    179 *
    180 * FUNCTION:    acpi_ex_store_object_to_index
    181 *
    182 * PARAMETERS:  *source_desc            - Value to be stored
    183 *              *dest_desc              - Named object to receive the value
    184 *              walk_state              - Current walk state
    185 *
    186 * RETURN:      Status
    187 *
    188 * DESCRIPTION: Store the object to indexed Buffer or Package element
    189 *
    190 ******************************************************************************/
    191
    192static acpi_status
    193acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
    194			      union acpi_operand_object *index_desc,
    195			      struct acpi_walk_state *walk_state)
    196{
    197	acpi_status status = AE_OK;
    198	union acpi_operand_object *obj_desc;
    199	union acpi_operand_object *new_desc;
    200	u8 value = 0;
    201	u32 i;
    202
    203	ACPI_FUNCTION_TRACE(ex_store_object_to_index);
    204
    205	/*
    206	 * Destination must be a reference pointer, and
    207	 * must point to either a buffer or a package
    208	 */
    209	switch (index_desc->reference.target_type) {
    210	case ACPI_TYPE_PACKAGE:
    211		/*
    212		 * Storing to a package element. Copy the object and replace
    213		 * any existing object with the new object. No implicit
    214		 * conversion is performed.
    215		 *
    216		 * The object at *(index_desc->Reference.Where) is the
    217		 * element within the package that is to be modified.
    218		 * The parent package object is at index_desc->Reference.Object
    219		 */
    220		obj_desc = *(index_desc->reference.where);
    221
    222		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
    223		    source_desc->reference.class == ACPI_REFCLASS_TABLE) {
    224
    225			/* This is a DDBHandle, just add a reference to it */
    226
    227			acpi_ut_add_reference(source_desc);
    228			new_desc = source_desc;
    229		} else {
    230			/* Normal object, copy it */
    231
    232			status =
    233			    acpi_ut_copy_iobject_to_iobject(source_desc,
    234							    &new_desc,
    235							    walk_state);
    236			if (ACPI_FAILURE(status)) {
    237				return_ACPI_STATUS(status);
    238			}
    239		}
    240
    241		if (obj_desc) {
    242
    243			/* Decrement reference count by the ref count of the parent package */
    244
    245			for (i = 0; i < ((union acpi_operand_object *)
    246					 index_desc->reference.object)->common.
    247			     reference_count; i++) {
    248				acpi_ut_remove_reference(obj_desc);
    249			}
    250		}
    251
    252		*(index_desc->reference.where) = new_desc;
    253
    254		/* Increment ref count by the ref count of the parent package-1 */
    255
    256		for (i = 1; i < ((union acpi_operand_object *)
    257				 index_desc->reference.object)->common.
    258		     reference_count; i++) {
    259			acpi_ut_add_reference(new_desc);
    260		}
    261
    262		break;
    263
    264	case ACPI_TYPE_BUFFER_FIELD:
    265		/*
    266		 * Store into a Buffer or String (not actually a real buffer_field)
    267		 * at a location defined by an Index.
    268		 *
    269		 * The first 8-bit element of the source object is written to the
    270		 * 8-bit Buffer location defined by the Index destination object,
    271		 * according to the ACPI 2.0 specification.
    272		 */
    273
    274		/*
    275		 * Make sure the target is a Buffer or String. An error should
    276		 * not happen here, since the reference_object was constructed
    277		 * by the INDEX_OP code.
    278		 */
    279		obj_desc = index_desc->reference.object;
    280		if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
    281		    (obj_desc->common.type != ACPI_TYPE_STRING)) {
    282			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
    283		}
    284
    285		/*
    286		 * The assignment of the individual elements will be slightly
    287		 * different for each source type.
    288		 */
    289		switch (source_desc->common.type) {
    290		case ACPI_TYPE_INTEGER:
    291
    292			/* Use the least-significant byte of the integer */
    293
    294			value = (u8) (source_desc->integer.value);
    295			break;
    296
    297		case ACPI_TYPE_BUFFER:
    298		case ACPI_TYPE_STRING:
    299
    300			/* Note: Takes advantage of common string/buffer fields */
    301
    302			value = source_desc->buffer.pointer[0];
    303			break;
    304
    305		default:
    306
    307			/* All other types are invalid */
    308
    309			ACPI_ERROR((AE_INFO,
    310				    "Source must be type [Integer/Buffer/String], found [%s]",
    311				    acpi_ut_get_object_type_name(source_desc)));
    312			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
    313		}
    314
    315		/* Store the source value into the target buffer byte */
    316
    317		obj_desc->buffer.pointer[index_desc->reference.value] = value;
    318		break;
    319
    320	default:
    321		ACPI_ERROR((AE_INFO,
    322			    "Target is not of type [Package/BufferField]"));
    323		status = AE_AML_TARGET_TYPE;
    324		break;
    325	}
    326
    327	return_ACPI_STATUS(status);
    328}
    329
    330/*******************************************************************************
    331 *
    332 * FUNCTION:    acpi_ex_store_object_to_node
    333 *
    334 * PARAMETERS:  source_desc             - Value to be stored
    335 *              node                    - Named object to receive the value
    336 *              walk_state              - Current walk state
    337 *              implicit_conversion     - Perform implicit conversion (yes/no)
    338 *
    339 * RETURN:      Status
    340 *
    341 * DESCRIPTION: Store the object to the named object.
    342 *
    343 * The assignment of an object to a named object is handled here.
    344 * The value passed in will replace the current value (if any)
    345 * with the input value.
    346 *
    347 * When storing into an object the data is converted to the
    348 * target object type then stored in the object. This means
    349 * that the target object type (for an initialized target) will
    350 * not be changed by a store operation. A copy_object can change
    351 * the target type, however.
    352 *
    353 * The implicit_conversion flag is set to NO/FALSE only when
    354 * storing to an arg_x -- as per the rules of the ACPI spec.
    355 *
    356 * Assumes parameters are already validated.
    357 *
    358 ******************************************************************************/
    359
    360acpi_status
    361acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
    362			     struct acpi_namespace_node *node,
    363			     struct acpi_walk_state *walk_state,
    364			     u8 implicit_conversion)
    365{
    366	acpi_status status = AE_OK;
    367	union acpi_operand_object *target_desc;
    368	union acpi_operand_object *new_desc;
    369	acpi_object_type target_type;
    370
    371	ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
    372
    373	/* Get current type of the node, and object attached to Node */
    374
    375	target_type = acpi_ns_get_type(node);
    376	target_desc = acpi_ns_get_attached_object(node);
    377
    378	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
    379			  source_desc,
    380			  acpi_ut_get_object_type_name(source_desc), node,
    381			  acpi_ut_get_type_name(target_type)));
    382
    383	/* Only limited target types possible for everything except copy_object */
    384
    385	if (walk_state->opcode != AML_COPY_OBJECT_OP) {
    386		/*
    387		 * Only copy_object allows all object types to be overwritten. For
    388		 * target_ref(s), there are restrictions on the object types that
    389		 * are allowed.
    390		 *
    391		 * Allowable operations/typing for Store:
    392		 *
    393		 * 1) Simple Store
    394		 *      Integer     --> Integer (Named/Local/Arg)
    395		 *      String      --> String  (Named/Local/Arg)
    396		 *      Buffer      --> Buffer  (Named/Local/Arg)
    397		 *      Package     --> Package (Named/Local/Arg)
    398		 *
    399		 * 2) Store with implicit conversion
    400		 *      Integer     --> String or Buffer  (Named)
    401		 *      String      --> Integer or Buffer (Named)
    402		 *      Buffer      --> Integer or String (Named)
    403		 */
    404		switch (target_type) {
    405		case ACPI_TYPE_PACKAGE:
    406			/*
    407			 * Here, can only store a package to an existing package.
    408			 * Storing a package to a Local/Arg is OK, and handled
    409			 * elsewhere.
    410			 */
    411			if (walk_state->opcode == AML_STORE_OP) {
    412				if (source_desc->common.type !=
    413				    ACPI_TYPE_PACKAGE) {
    414					ACPI_ERROR((AE_INFO,
    415						    "Cannot assign type [%s] to [Package] "
    416						    "(source must be type Pkg)",
    417						    acpi_ut_get_object_type_name
    418						    (source_desc)));
    419
    420					return_ACPI_STATUS(AE_AML_TARGET_TYPE);
    421				}
    422				break;
    423			}
    424
    425			ACPI_FALLTHROUGH;
    426
    427		case ACPI_TYPE_DEVICE:
    428		case ACPI_TYPE_EVENT:
    429		case ACPI_TYPE_MUTEX:
    430		case ACPI_TYPE_REGION:
    431		case ACPI_TYPE_POWER:
    432		case ACPI_TYPE_PROCESSOR:
    433		case ACPI_TYPE_THERMAL:
    434
    435			ACPI_ERROR((AE_INFO,
    436				    "Target must be [Buffer/Integer/String/Reference]"
    437				    ", found [%s] (%4.4s)",
    438				    acpi_ut_get_type_name(node->type),
    439				    node->name.ascii));
    440
    441			return_ACPI_STATUS(AE_AML_TARGET_TYPE);
    442
    443		default:
    444			break;
    445		}
    446	}
    447
    448	/*
    449	 * Resolve the source object to an actual value
    450	 * (If it is a reference object)
    451	 */
    452	status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
    453	if (ACPI_FAILURE(status)) {
    454		return_ACPI_STATUS(status);
    455	}
    456
    457	/* Do the actual store operation */
    458
    459	switch (target_type) {
    460		/*
    461		 * The simple data types all support implicit source operand
    462		 * conversion before the store.
    463		 */
    464	case ACPI_TYPE_INTEGER:
    465	case ACPI_TYPE_STRING:
    466	case ACPI_TYPE_BUFFER:
    467
    468		if ((walk_state->opcode == AML_COPY_OBJECT_OP) ||
    469		    !implicit_conversion) {
    470			/*
    471			 * However, copy_object and Stores to arg_x do not perform
    472			 * an implicit conversion, as per the ACPI specification.
    473			 * A direct store is performed instead.
    474			 */
    475			status =
    476			    acpi_ex_store_direct_to_node(source_desc, node,
    477							 walk_state);
    478			break;
    479		}
    480
    481		/* Store with implicit source operand conversion support */
    482
    483		status =
    484		    acpi_ex_store_object_to_object(source_desc, target_desc,
    485						   &new_desc, walk_state);
    486		if (ACPI_FAILURE(status)) {
    487			return_ACPI_STATUS(status);
    488		}
    489
    490		if (new_desc != target_desc) {
    491			/*
    492			 * Store the new new_desc as the new value of the Name, and set
    493			 * the Name's type to that of the value being stored in it.
    494			 * source_desc reference count is incremented by attach_object.
    495			 *
    496			 * Note: This may change the type of the node if an explicit
    497			 * store has been performed such that the node/object type
    498			 * has been changed.
    499			 */
    500			status =
    501			    acpi_ns_attach_object(node, new_desc,
    502						  new_desc->common.type);
    503
    504			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
    505					  "Store type [%s] into [%s] via Convert/Attach\n",
    506					  acpi_ut_get_object_type_name
    507					  (source_desc),
    508					  acpi_ut_get_object_type_name
    509					  (new_desc)));
    510		}
    511		break;
    512
    513	case ACPI_TYPE_BUFFER_FIELD:
    514	case ACPI_TYPE_LOCAL_REGION_FIELD:
    515	case ACPI_TYPE_LOCAL_BANK_FIELD:
    516	case ACPI_TYPE_LOCAL_INDEX_FIELD:
    517		/*
    518		 * For all fields, always write the source data to the target
    519		 * field. Any required implicit source operand conversion is
    520		 * performed in the function below as necessary. Note, field
    521		 * objects must retain their original type permanently.
    522		 */
    523		status = acpi_ex_write_data_to_field(source_desc, target_desc,
    524						     &walk_state->result_obj);
    525		break;
    526
    527	default:
    528		/*
    529		 * copy_object operator: No conversions for all other types.
    530		 * Instead, directly store a copy of the source object.
    531		 *
    532		 * This is the ACPI spec-defined behavior for the copy_object
    533		 * operator. (Note, for this default case, all normal
    534		 * Store/Target operations exited above with an error).
    535		 */
    536		status =
    537		    acpi_ex_store_direct_to_node(source_desc, node, walk_state);
    538		break;
    539	}
    540
    541	return_ACPI_STATUS(status);
    542}
    543
    544/*******************************************************************************
    545 *
    546 * FUNCTION:    acpi_ex_store_direct_to_node
    547 *
    548 * PARAMETERS:  source_desc             - Value to be stored
    549 *              node                    - Named object to receive the value
    550 *              walk_state              - Current walk state
    551 *
    552 * RETURN:      Status
    553 *
    554 * DESCRIPTION: "Store" an object directly to a node. This involves a copy
    555 *              and an attach.
    556 *
    557 ******************************************************************************/
    558
    559static acpi_status
    560acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
    561			     struct acpi_namespace_node *node,
    562			     struct acpi_walk_state *walk_state)
    563{
    564	acpi_status status;
    565	union acpi_operand_object *new_desc;
    566
    567	ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
    568
    569	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
    570			  "Storing [%s] (%p) directly into node [%s] (%p)"
    571			  " with no implicit conversion\n",
    572			  acpi_ut_get_object_type_name(source_desc),
    573			  source_desc, acpi_ut_get_type_name(node->type),
    574			  node));
    575
    576	/* Copy the source object to a new object */
    577
    578	status =
    579	    acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
    580	if (ACPI_FAILURE(status)) {
    581		return_ACPI_STATUS(status);
    582	}
    583
    584	/* Attach the new object to the node */
    585
    586	status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
    587	acpi_ut_remove_reference(new_desc);
    588	return_ACPI_STATUS(status);
    589}