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

utcopy.c (26888B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: utcopy - Internal to external object translation utilities
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acnamesp.h"
     13
     14
     15#define _COMPONENT          ACPI_UTILITIES
     16ACPI_MODULE_NAME("utcopy")
     17
     18/* Local prototypes */
     19static acpi_status
     20acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
     21				union acpi_object *external_object,
     22				u8 *data_space, acpi_size *buffer_space_used);
     23
     24static acpi_status
     25acpi_ut_copy_ielement_to_ielement(u8 object_type,
     26				  union acpi_operand_object *source_object,
     27				  union acpi_generic_state *state,
     28				  void *context);
     29
     30static acpi_status
     31acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
     32				  u8 *buffer, acpi_size *space_used);
     33
     34static acpi_status
     35acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
     36				union acpi_operand_object **return_obj);
     37
     38static acpi_status
     39acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
     40				  union acpi_operand_object **internal_object);
     41
     42static acpi_status
     43acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
     44			   union acpi_operand_object *dest_desc);
     45
     46static acpi_status
     47acpi_ut_copy_ielement_to_eelement(u8 object_type,
     48				  union acpi_operand_object *source_object,
     49				  union acpi_generic_state *state,
     50				  void *context);
     51
     52static acpi_status
     53acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
     54				  union acpi_operand_object *dest_obj,
     55				  struct acpi_walk_state *walk_state);
     56
     57/*******************************************************************************
     58 *
     59 * FUNCTION:    acpi_ut_copy_isimple_to_esimple
     60 *
     61 * PARAMETERS:  internal_object     - Source object to be copied
     62 *              external_object     - Where to return the copied object
     63 *              data_space          - Where object data is returned (such as
     64 *                                    buffer and string data)
     65 *              buffer_space_used   - Length of data_space that was used
     66 *
     67 * RETURN:      Status
     68 *
     69 * DESCRIPTION: This function is called to copy a simple internal object to
     70 *              an external object.
     71 *
     72 *              The data_space buffer is assumed to have sufficient space for
     73 *              the object.
     74 *
     75 ******************************************************************************/
     76
     77static acpi_status
     78acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
     79				union acpi_object *external_object,
     80				u8 *data_space, acpi_size *buffer_space_used)
     81{
     82	acpi_status status = AE_OK;
     83
     84	ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);
     85
     86	*buffer_space_used = 0;
     87
     88	/*
     89	 * Check for NULL object case (could be an uninitialized
     90	 * package element)
     91	 */
     92	if (!internal_object) {
     93		return_ACPI_STATUS(AE_OK);
     94	}
     95
     96	/* Always clear the external object */
     97
     98	memset(external_object, 0, sizeof(union acpi_object));
     99
    100	/*
    101	 * In general, the external object will be the same type as
    102	 * the internal object
    103	 */
    104	external_object->type = internal_object->common.type;
    105
    106	/* However, only a limited number of external types are supported */
    107
    108	switch (internal_object->common.type) {
    109	case ACPI_TYPE_STRING:
    110
    111		external_object->string.pointer = (char *)data_space;
    112		external_object->string.length = internal_object->string.length;
    113		*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
    114								  internal_object->
    115								  string.
    116								  length + 1);
    117
    118		memcpy((void *)data_space,
    119		       (void *)internal_object->string.pointer,
    120		       (acpi_size)internal_object->string.length + 1);
    121		break;
    122
    123	case ACPI_TYPE_BUFFER:
    124
    125		external_object->buffer.pointer = data_space;
    126		external_object->buffer.length = internal_object->buffer.length;
    127		*buffer_space_used =
    128		    ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
    129						 length);
    130
    131		memcpy((void *)data_space,
    132		       (void *)internal_object->buffer.pointer,
    133		       internal_object->buffer.length);
    134		break;
    135
    136	case ACPI_TYPE_INTEGER:
    137
    138		external_object->integer.value = internal_object->integer.value;
    139		break;
    140
    141	case ACPI_TYPE_LOCAL_REFERENCE:
    142
    143		/* This is an object reference. */
    144
    145		switch (internal_object->reference.class) {
    146		case ACPI_REFCLASS_NAME:
    147			/*
    148			 * For namepath, return the object handle ("reference")
    149			 * We are referring to the namespace node
    150			 */
    151			external_object->reference.handle =
    152			    internal_object->reference.node;
    153			external_object->reference.actual_type =
    154			    acpi_ns_get_type(internal_object->reference.node);
    155			break;
    156
    157		default:
    158
    159			/* All other reference types are unsupported */
    160
    161			return_ACPI_STATUS(AE_TYPE);
    162		}
    163		break;
    164
    165	case ACPI_TYPE_PROCESSOR:
    166
    167		external_object->processor.proc_id =
    168		    internal_object->processor.proc_id;
    169		external_object->processor.pblk_address =
    170		    internal_object->processor.address;
    171		external_object->processor.pblk_length =
    172		    internal_object->processor.length;
    173		break;
    174
    175	case ACPI_TYPE_POWER:
    176
    177		external_object->power_resource.system_level =
    178		    internal_object->power_resource.system_level;
    179
    180		external_object->power_resource.resource_order =
    181		    internal_object->power_resource.resource_order;
    182		break;
    183
    184	default:
    185		/*
    186		 * There is no corresponding external object type
    187		 */
    188		ACPI_ERROR((AE_INFO,
    189			    "Unsupported object type, cannot convert to external object: %s",
    190			    acpi_ut_get_type_name(internal_object->common.
    191						  type)));
    192
    193		return_ACPI_STATUS(AE_SUPPORT);
    194	}
    195
    196	return_ACPI_STATUS(status);
    197}
    198
    199/*******************************************************************************
    200 *
    201 * FUNCTION:    acpi_ut_copy_ielement_to_eelement
    202 *
    203 * PARAMETERS:  acpi_pkg_callback
    204 *
    205 * RETURN:      Status
    206 *
    207 * DESCRIPTION: Copy one package element to another package element
    208 *
    209 ******************************************************************************/
    210
    211static acpi_status
    212acpi_ut_copy_ielement_to_eelement(u8 object_type,
    213				  union acpi_operand_object *source_object,
    214				  union acpi_generic_state *state,
    215				  void *context)
    216{
    217	acpi_status status = AE_OK;
    218	struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
    219	acpi_size object_space;
    220	u32 this_index;
    221	union acpi_object *target_object;
    222
    223	ACPI_FUNCTION_ENTRY();
    224
    225	this_index = state->pkg.index;
    226	target_object = (union acpi_object *)&((union acpi_object *)
    227					       (state->pkg.dest_object))->
    228	    package.elements[this_index];
    229
    230	switch (object_type) {
    231	case ACPI_COPY_TYPE_SIMPLE:
    232		/*
    233		 * This is a simple or null object
    234		 */
    235		status = acpi_ut_copy_isimple_to_esimple(source_object,
    236							 target_object,
    237							 info->free_space,
    238							 &object_space);
    239		if (ACPI_FAILURE(status)) {
    240			return (status);
    241		}
    242		break;
    243
    244	case ACPI_COPY_TYPE_PACKAGE:
    245		/*
    246		 * Build the package object
    247		 */
    248		target_object->type = ACPI_TYPE_PACKAGE;
    249		target_object->package.count = source_object->package.count;
    250		target_object->package.elements =
    251		    ACPI_CAST_PTR(union acpi_object, info->free_space);
    252
    253		/*
    254		 * Pass the new package object back to the package walk routine
    255		 */
    256		state->pkg.this_target_obj = target_object;
    257
    258		/*
    259		 * Save space for the array of objects (Package elements)
    260		 * update the buffer length counter
    261		 */
    262		object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
    263							    target_object->
    264							    package.count *
    265							    sizeof(union
    266								   acpi_object));
    267		break;
    268
    269	default:
    270
    271		return (AE_BAD_PARAMETER);
    272	}
    273
    274	info->free_space += object_space;
    275	info->length += object_space;
    276	return (status);
    277}
    278
    279/*******************************************************************************
    280 *
    281 * FUNCTION:    acpi_ut_copy_ipackage_to_epackage
    282 *
    283 * PARAMETERS:  internal_object     - Pointer to the object we are returning
    284 *              buffer              - Where the object is returned
    285 *              space_used          - Where the object length is returned
    286 *
    287 * RETURN:      Status
    288 *
    289 * DESCRIPTION: This function is called to place a package object in a user
    290 *              buffer. A package object by definition contains other objects.
    291 *
    292 *              The buffer is assumed to have sufficient space for the object.
    293 *              The caller must have verified the buffer length needed using
    294 *              the acpi_ut_get_object_size function before calling this function.
    295 *
    296 ******************************************************************************/
    297
    298static acpi_status
    299acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
    300				  u8 *buffer, acpi_size *space_used)
    301{
    302	union acpi_object *external_object;
    303	acpi_status status;
    304	struct acpi_pkg_info info;
    305
    306	ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage);
    307
    308	/*
    309	 * First package at head of the buffer
    310	 */
    311	external_object = ACPI_CAST_PTR(union acpi_object, buffer);
    312
    313	/*
    314	 * Free space begins right after the first package
    315	 */
    316	info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
    317	info.free_space = buffer +
    318	    ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
    319	info.object_space = 0;
    320	info.num_packages = 1;
    321
    322	external_object->type = internal_object->common.type;
    323	external_object->package.count = internal_object->package.count;
    324	external_object->package.elements =
    325	    ACPI_CAST_PTR(union acpi_object, info.free_space);
    326
    327	/*
    328	 * Leave room for an array of ACPI_OBJECTS in the buffer
    329	 * and move the free space past it
    330	 */
    331	info.length += (acpi_size)external_object->package.count *
    332	    ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
    333	info.free_space += external_object->package.count *
    334	    ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
    335
    336	status = acpi_ut_walk_package_tree(internal_object, external_object,
    337					   acpi_ut_copy_ielement_to_eelement,
    338					   &info);
    339
    340	*space_used = info.length;
    341	return_ACPI_STATUS(status);
    342}
    343
    344/*******************************************************************************
    345 *
    346 * FUNCTION:    acpi_ut_copy_iobject_to_eobject
    347 *
    348 * PARAMETERS:  internal_object     - The internal object to be converted
    349 *              ret_buffer          - Where the object is returned
    350 *
    351 * RETURN:      Status
    352 *
    353 * DESCRIPTION: This function is called to build an API object to be returned
    354 *              to the caller.
    355 *
    356 ******************************************************************************/
    357
    358acpi_status
    359acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
    360				struct acpi_buffer *ret_buffer)
    361{
    362	acpi_status status;
    363
    364	ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
    365
    366	if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
    367		/*
    368		 * Package object:  Copy all subobjects (including
    369		 * nested packages)
    370		 */
    371		status = acpi_ut_copy_ipackage_to_epackage(internal_object,
    372							   ret_buffer->pointer,
    373							   &ret_buffer->length);
    374	} else {
    375		/*
    376		 * Build a simple object (no nested objects)
    377		 */
    378		status = acpi_ut_copy_isimple_to_esimple(internal_object,
    379							 ACPI_CAST_PTR(union
    380								       acpi_object,
    381								       ret_buffer->
    382								       pointer),
    383							 ACPI_ADD_PTR(u8,
    384								      ret_buffer->
    385								      pointer,
    386								      ACPI_ROUND_UP_TO_NATIVE_WORD
    387								      (sizeof
    388								       (union
    389									acpi_object))),
    390							 &ret_buffer->length);
    391		/*
    392		 * build simple does not include the object size in the length
    393		 * so we add it in here
    394		 */
    395		ret_buffer->length += sizeof(union acpi_object);
    396	}
    397
    398	return_ACPI_STATUS(status);
    399}
    400
    401/*******************************************************************************
    402 *
    403 * FUNCTION:    acpi_ut_copy_esimple_to_isimple
    404 *
    405 * PARAMETERS:  external_object     - The external object to be converted
    406 *              ret_internal_object - Where the internal object is returned
    407 *
    408 * RETURN:      Status
    409 *
    410 * DESCRIPTION: This function copies an external object to an internal one.
    411 *              NOTE: Pointers can be copied, we don't need to copy data.
    412 *              (The pointers have to be valid in our address space no matter
    413 *              what we do with them!)
    414 *
    415 ******************************************************************************/
    416
    417static acpi_status
    418acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
    419				union acpi_operand_object **ret_internal_object)
    420{
    421	union acpi_operand_object *internal_object;
    422
    423	ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);
    424
    425	/*
    426	 * Simple types supported are: String, Buffer, Integer
    427	 */
    428	switch (external_object->type) {
    429	case ACPI_TYPE_STRING:
    430	case ACPI_TYPE_BUFFER:
    431	case ACPI_TYPE_INTEGER:
    432	case ACPI_TYPE_LOCAL_REFERENCE:
    433
    434		internal_object = acpi_ut_create_internal_object((u8)
    435								 external_object->
    436								 type);
    437		if (!internal_object) {
    438			return_ACPI_STATUS(AE_NO_MEMORY);
    439		}
    440		break;
    441
    442	case ACPI_TYPE_ANY:	/* This is the case for a NULL object */
    443
    444		*ret_internal_object = NULL;
    445		return_ACPI_STATUS(AE_OK);
    446
    447	default:
    448
    449		/* All other types are not supported */
    450
    451		ACPI_ERROR((AE_INFO,
    452			    "Unsupported object type, cannot convert to internal object: %s",
    453			    acpi_ut_get_type_name(external_object->type)));
    454
    455		return_ACPI_STATUS(AE_SUPPORT);
    456	}
    457
    458	/* Must COPY string and buffer contents */
    459
    460	switch (external_object->type) {
    461	case ACPI_TYPE_STRING:
    462
    463		internal_object->string.pointer =
    464		    ACPI_ALLOCATE_ZEROED((acpi_size)
    465					 external_object->string.length + 1);
    466
    467		if (!internal_object->string.pointer) {
    468			goto error_exit;
    469		}
    470
    471		memcpy(internal_object->string.pointer,
    472		       external_object->string.pointer,
    473		       external_object->string.length);
    474
    475		internal_object->string.length = external_object->string.length;
    476		break;
    477
    478	case ACPI_TYPE_BUFFER:
    479
    480		internal_object->buffer.pointer =
    481		    ACPI_ALLOCATE_ZEROED(external_object->buffer.length);
    482		if (!internal_object->buffer.pointer) {
    483			goto error_exit;
    484		}
    485
    486		memcpy(internal_object->buffer.pointer,
    487		       external_object->buffer.pointer,
    488		       external_object->buffer.length);
    489
    490		internal_object->buffer.length = external_object->buffer.length;
    491
    492		/* Mark buffer data valid */
    493
    494		internal_object->buffer.flags |= AOPOBJ_DATA_VALID;
    495		break;
    496
    497	case ACPI_TYPE_INTEGER:
    498
    499		internal_object->integer.value = external_object->integer.value;
    500		break;
    501
    502	case ACPI_TYPE_LOCAL_REFERENCE:
    503
    504		/* An incoming reference is defined to be a namespace node */
    505
    506		internal_object->reference.class = ACPI_REFCLASS_REFOF;
    507		internal_object->reference.object =
    508		    external_object->reference.handle;
    509		break;
    510
    511	default:
    512
    513		/* Other types can't get here */
    514
    515		break;
    516	}
    517
    518	*ret_internal_object = internal_object;
    519	return_ACPI_STATUS(AE_OK);
    520
    521error_exit:
    522	acpi_ut_remove_reference(internal_object);
    523	return_ACPI_STATUS(AE_NO_MEMORY);
    524}
    525
    526/*******************************************************************************
    527 *
    528 * FUNCTION:    acpi_ut_copy_epackage_to_ipackage
    529 *
    530 * PARAMETERS:  external_object     - The external object to be converted
    531 *              internal_object     - Where the internal object is returned
    532 *
    533 * RETURN:      Status
    534 *
    535 * DESCRIPTION: Copy an external package object to an internal package.
    536 *              Handles nested packages.
    537 *
    538 ******************************************************************************/
    539
    540static acpi_status
    541acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
    542				  union acpi_operand_object **internal_object)
    543{
    544	acpi_status status = AE_OK;
    545	union acpi_operand_object *package_object;
    546	union acpi_operand_object **package_elements;
    547	u32 i;
    548
    549	ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
    550
    551	/* Create the package object */
    552
    553	package_object =
    554	    acpi_ut_create_package_object(external_object->package.count);
    555	if (!package_object) {
    556		return_ACPI_STATUS(AE_NO_MEMORY);
    557	}
    558
    559	package_elements = package_object->package.elements;
    560
    561	/*
    562	 * Recursive implementation. Probably ok, since nested external
    563	 * packages as parameters should be very rare.
    564	 */
    565	for (i = 0; i < external_object->package.count; i++) {
    566		status =
    567		    acpi_ut_copy_eobject_to_iobject(&external_object->package.
    568						    elements[i],
    569						    &package_elements[i]);
    570		if (ACPI_FAILURE(status)) {
    571
    572			/* Truncate package and delete it */
    573
    574			package_object->package.count = i;
    575			package_elements[i] = NULL;
    576			acpi_ut_remove_reference(package_object);
    577			return_ACPI_STATUS(status);
    578		}
    579	}
    580
    581	/* Mark package data valid */
    582
    583	package_object->package.flags |= AOPOBJ_DATA_VALID;
    584
    585	*internal_object = package_object;
    586	return_ACPI_STATUS(status);
    587}
    588
    589/*******************************************************************************
    590 *
    591 * FUNCTION:    acpi_ut_copy_eobject_to_iobject
    592 *
    593 * PARAMETERS:  external_object     - The external object to be converted
    594 *              internal_object     - Where the internal object is returned
    595 *
    596 * RETURN:      Status
    597 *
    598 * DESCRIPTION: Converts an external object to an internal object.
    599 *
    600 ******************************************************************************/
    601
    602acpi_status
    603acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
    604				union acpi_operand_object **internal_object)
    605{
    606	acpi_status status;
    607
    608	ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
    609
    610	if (external_object->type == ACPI_TYPE_PACKAGE) {
    611		status =
    612		    acpi_ut_copy_epackage_to_ipackage(external_object,
    613						      internal_object);
    614	} else {
    615		/*
    616		 * Build a simple object (no nested objects)
    617		 */
    618		status = acpi_ut_copy_esimple_to_isimple(external_object,
    619							 internal_object);
    620	}
    621
    622	return_ACPI_STATUS(status);
    623}
    624
    625/*******************************************************************************
    626 *
    627 * FUNCTION:    acpi_ut_copy_simple_object
    628 *
    629 * PARAMETERS:  source_desc         - The internal object to be copied
    630 *              dest_desc           - New target object
    631 *
    632 * RETURN:      Status
    633 *
    634 * DESCRIPTION: Simple copy of one internal object to another. Reference count
    635 *              of the destination object is preserved.
    636 *
    637 ******************************************************************************/
    638
    639static acpi_status
    640acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
    641			   union acpi_operand_object *dest_desc)
    642{
    643	u16 reference_count;
    644	union acpi_operand_object *next_object;
    645	acpi_status status;
    646	acpi_size copy_size;
    647
    648	/* Save fields from destination that we don't want to overwrite */
    649
    650	reference_count = dest_desc->common.reference_count;
    651	next_object = dest_desc->common.next_object;
    652
    653	/*
    654	 * Copy the entire source object over the destination object.
    655	 * Note: Source can be either an operand object or namespace node.
    656	 */
    657	copy_size = sizeof(union acpi_operand_object);
    658	if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) {
    659		copy_size = sizeof(struct acpi_namespace_node);
    660	}
    661
    662	memcpy(ACPI_CAST_PTR(char, dest_desc),
    663	       ACPI_CAST_PTR(char, source_desc), copy_size);
    664
    665	/* Restore the saved fields */
    666
    667	dest_desc->common.reference_count = reference_count;
    668	dest_desc->common.next_object = next_object;
    669
    670	/* New object is not static, regardless of source */
    671
    672	dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
    673
    674	/* Handle the objects with extra data */
    675
    676	switch (dest_desc->common.type) {
    677	case ACPI_TYPE_BUFFER:
    678		/*
    679		 * Allocate and copy the actual buffer if and only if:
    680		 * 1) There is a valid buffer pointer
    681		 * 2) The buffer has a length > 0
    682		 */
    683		if ((source_desc->buffer.pointer) &&
    684		    (source_desc->buffer.length)) {
    685			dest_desc->buffer.pointer =
    686			    ACPI_ALLOCATE(source_desc->buffer.length);
    687			if (!dest_desc->buffer.pointer) {
    688				return (AE_NO_MEMORY);
    689			}
    690
    691			/* Copy the actual buffer data */
    692
    693			memcpy(dest_desc->buffer.pointer,
    694			       source_desc->buffer.pointer,
    695			       source_desc->buffer.length);
    696		}
    697		break;
    698
    699	case ACPI_TYPE_STRING:
    700		/*
    701		 * Allocate and copy the actual string if and only if:
    702		 * 1) There is a valid string pointer
    703		 * (Pointer to a NULL string is allowed)
    704		 */
    705		if (source_desc->string.pointer) {
    706			dest_desc->string.pointer =
    707			    ACPI_ALLOCATE((acpi_size)source_desc->string.
    708					  length + 1);
    709			if (!dest_desc->string.pointer) {
    710				return (AE_NO_MEMORY);
    711			}
    712
    713			/* Copy the actual string data */
    714
    715			memcpy(dest_desc->string.pointer,
    716			       source_desc->string.pointer,
    717			       (acpi_size)source_desc->string.length + 1);
    718		}
    719		break;
    720
    721	case ACPI_TYPE_LOCAL_REFERENCE:
    722		/*
    723		 * We copied the reference object, so we now must add a reference
    724		 * to the object pointed to by the reference
    725		 *
    726		 * DDBHandle reference (from Load/load_table) is a special reference,
    727		 * it does not have a Reference.Object, so does not need to
    728		 * increase the reference count
    729		 */
    730		if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
    731			break;
    732		}
    733
    734		acpi_ut_add_reference(source_desc->reference.object);
    735		break;
    736
    737	case ACPI_TYPE_REGION:
    738		/*
    739		 * We copied the Region Handler, so we now must add a reference
    740		 */
    741		if (dest_desc->region.handler) {
    742			acpi_ut_add_reference(dest_desc->region.handler);
    743		}
    744		break;
    745
    746		/*
    747		 * For Mutex and Event objects, we cannot simply copy the underlying
    748		 * OS object. We must create a new one.
    749		 */
    750	case ACPI_TYPE_MUTEX:
    751
    752		status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
    753		if (ACPI_FAILURE(status)) {
    754			return (status);
    755		}
    756		break;
    757
    758	case ACPI_TYPE_EVENT:
    759
    760		status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
    761						  &dest_desc->event.
    762						  os_semaphore);
    763		if (ACPI_FAILURE(status)) {
    764			return (status);
    765		}
    766		break;
    767
    768	default:
    769
    770		/* Nothing to do for other simple objects */
    771
    772		break;
    773	}
    774
    775	return (AE_OK);
    776}
    777
    778/*******************************************************************************
    779 *
    780 * FUNCTION:    acpi_ut_copy_ielement_to_ielement
    781 *
    782 * PARAMETERS:  acpi_pkg_callback
    783 *
    784 * RETURN:      Status
    785 *
    786 * DESCRIPTION: Copy one package element to another package element
    787 *
    788 ******************************************************************************/
    789
    790static acpi_status
    791acpi_ut_copy_ielement_to_ielement(u8 object_type,
    792				  union acpi_operand_object *source_object,
    793				  union acpi_generic_state *state,
    794				  void *context)
    795{
    796	acpi_status status = AE_OK;
    797	u32 this_index;
    798	union acpi_operand_object **this_target_ptr;
    799	union acpi_operand_object *target_object;
    800
    801	ACPI_FUNCTION_ENTRY();
    802
    803	this_index = state->pkg.index;
    804	this_target_ptr = (union acpi_operand_object **)
    805	    &state->pkg.dest_object->package.elements[this_index];
    806
    807	switch (object_type) {
    808	case ACPI_COPY_TYPE_SIMPLE:
    809
    810		/* A null source object indicates a (legal) null package element */
    811
    812		if (source_object) {
    813			/*
    814			 * This is a simple object, just copy it
    815			 */
    816			target_object =
    817			    acpi_ut_create_internal_object(source_object->
    818							   common.type);
    819			if (!target_object) {
    820				return (AE_NO_MEMORY);
    821			}
    822
    823			status =
    824			    acpi_ut_copy_simple_object(source_object,
    825						       target_object);
    826			if (ACPI_FAILURE(status)) {
    827				goto error_exit;
    828			}
    829
    830			*this_target_ptr = target_object;
    831		} else {
    832			/* Pass through a null element */
    833
    834			*this_target_ptr = NULL;
    835		}
    836		break;
    837
    838	case ACPI_COPY_TYPE_PACKAGE:
    839		/*
    840		 * This object is a package - go down another nesting level
    841		 * Create and build the package object
    842		 */
    843		target_object =
    844		    acpi_ut_create_package_object(source_object->package.count);
    845		if (!target_object) {
    846			return (AE_NO_MEMORY);
    847		}
    848
    849		target_object->common.flags = source_object->common.flags;
    850
    851		/* Pass the new package object back to the package walk routine */
    852
    853		state->pkg.this_target_obj = target_object;
    854
    855		/* Store the object pointer in the parent package object */
    856
    857		*this_target_ptr = target_object;
    858		break;
    859
    860	default:
    861
    862		return (AE_BAD_PARAMETER);
    863	}
    864
    865	return (status);
    866
    867error_exit:
    868	acpi_ut_remove_reference(target_object);
    869	return (status);
    870}
    871
    872/*******************************************************************************
    873 *
    874 * FUNCTION:    acpi_ut_copy_ipackage_to_ipackage
    875 *
    876 * PARAMETERS:  source_obj      - Pointer to the source package object
    877 *              dest_obj        - Where the internal object is returned
    878 *              walk_state      - Current Walk state descriptor
    879 *
    880 * RETURN:      Status
    881 *
    882 * DESCRIPTION: This function is called to copy an internal package object
    883 *              into another internal package object.
    884 *
    885 ******************************************************************************/
    886
    887static acpi_status
    888acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
    889				  union acpi_operand_object *dest_obj,
    890				  struct acpi_walk_state *walk_state)
    891{
    892	acpi_status status = AE_OK;
    893
    894	ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
    895
    896	dest_obj->common.type = source_obj->common.type;
    897	dest_obj->common.flags = source_obj->common.flags;
    898	dest_obj->package.count = source_obj->package.count;
    899
    900	/*
    901	 * Create the object array and walk the source package tree
    902	 */
    903	dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
    904							   source_obj->package.
    905							   count +
    906							   1) * sizeof(void *));
    907	if (!dest_obj->package.elements) {
    908		ACPI_ERROR((AE_INFO, "Package allocation failure"));
    909		return_ACPI_STATUS(AE_NO_MEMORY);
    910	}
    911
    912	/*
    913	 * Copy the package element-by-element by walking the package "tree".
    914	 * This handles nested packages of arbitrary depth.
    915	 */
    916	status = acpi_ut_walk_package_tree(source_obj, dest_obj,
    917					   acpi_ut_copy_ielement_to_ielement,
    918					   walk_state);
    919	if (ACPI_FAILURE(status)) {
    920
    921		/* On failure, delete the destination package object */
    922
    923		acpi_ut_remove_reference(dest_obj);
    924	}
    925
    926	return_ACPI_STATUS(status);
    927}
    928
    929/*******************************************************************************
    930 *
    931 * FUNCTION:    acpi_ut_copy_iobject_to_iobject
    932 *
    933 * PARAMETERS:  source_desc         - The internal object to be copied
    934 *              dest_desc           - Where the copied object is returned
    935 *              walk_state          - Current walk state
    936 *
    937 * RETURN:      Status
    938 *
    939 * DESCRIPTION: Copy an internal object to a new internal object
    940 *
    941 ******************************************************************************/
    942
    943acpi_status
    944acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
    945				union acpi_operand_object **dest_desc,
    946				struct acpi_walk_state *walk_state)
    947{
    948	acpi_status status = AE_OK;
    949
    950	ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);
    951
    952	/* Create the top level object */
    953
    954	*dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
    955	if (!*dest_desc) {
    956		return_ACPI_STATUS(AE_NO_MEMORY);
    957	}
    958
    959	/* Copy the object and possible subobjects */
    960
    961	if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
    962		status =
    963		    acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
    964						      walk_state);
    965	} else {
    966		status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
    967	}
    968
    969	/* Delete the allocated object if copy failed */
    970
    971	if (ACPI_FAILURE(status)) {
    972		acpi_ut_remove_reference(*dest_desc);
    973	}
    974
    975	return_ACPI_STATUS(status);
    976}