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

exstorob.c (5392B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: exstorob - AML object store support, store to object
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acinterp.h"
     13
     14#define _COMPONENT          ACPI_EXECUTER
     15ACPI_MODULE_NAME("exstorob")
     16
     17/*******************************************************************************
     18 *
     19 * FUNCTION:    acpi_ex_store_buffer_to_buffer
     20 *
     21 * PARAMETERS:  source_desc         - Source object to copy
     22 *              target_desc         - Destination object of the copy
     23 *
     24 * RETURN:      Status
     25 *
     26 * DESCRIPTION: Copy a buffer object to another buffer object.
     27 *
     28 ******************************************************************************/
     29acpi_status
     30acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
     31			       union acpi_operand_object *target_desc)
     32{
     33	u32 length;
     34	u8 *buffer;
     35
     36	ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
     37
     38	/* If Source and Target are the same, just return */
     39
     40	if (source_desc == target_desc) {
     41		return_ACPI_STATUS(AE_OK);
     42	}
     43
     44	/* We know that source_desc is a buffer by now */
     45
     46	buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
     47	length = source_desc->buffer.length;
     48
     49	/*
     50	 * If target is a buffer of length zero or is a static buffer,
     51	 * allocate a new buffer of the proper length
     52	 */
     53	if ((target_desc->buffer.length == 0) ||
     54	    (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
     55		target_desc->buffer.pointer = ACPI_ALLOCATE(length);
     56		if (!target_desc->buffer.pointer) {
     57			return_ACPI_STATUS(AE_NO_MEMORY);
     58		}
     59
     60		target_desc->buffer.length = length;
     61	}
     62
     63	/* Copy source buffer to target buffer */
     64
     65	if (length <= target_desc->buffer.length) {
     66
     67		/* Clear existing buffer and copy in the new one */
     68
     69		memset(target_desc->buffer.pointer, 0,
     70		       target_desc->buffer.length);
     71		memcpy(target_desc->buffer.pointer, buffer, length);
     72
     73#ifdef ACPI_OBSOLETE_BEHAVIOR
     74		/*
     75		 * NOTE: ACPI versions up to 3.0 specified that the buffer must be
     76		 * truncated if the string is smaller than the buffer. However, "other"
     77		 * implementations of ACPI never did this and thus became the defacto
     78		 * standard. ACPI 3.0A changes this behavior such that the buffer
     79		 * is no longer truncated.
     80		 */
     81
     82		/*
     83		 * OBSOLETE BEHAVIOR:
     84		 * If the original source was a string, we must truncate the buffer,
     85		 * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
     86		 * copy must not truncate the original buffer.
     87		 */
     88		if (original_src_type == ACPI_TYPE_STRING) {
     89
     90			/* Set the new length of the target */
     91
     92			target_desc->buffer.length = length;
     93		}
     94#endif
     95	} else {
     96		/* Truncate the source, copy only what will fit */
     97
     98		memcpy(target_desc->buffer.pointer, buffer,
     99		       target_desc->buffer.length);
    100
    101		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    102				  "Truncating source buffer from %X to %X\n",
    103				  length, target_desc->buffer.length));
    104	}
    105
    106	/* Copy flags */
    107
    108	target_desc->buffer.flags = source_desc->buffer.flags;
    109	target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
    110	return_ACPI_STATUS(AE_OK);
    111}
    112
    113/*******************************************************************************
    114 *
    115 * FUNCTION:    acpi_ex_store_string_to_string
    116 *
    117 * PARAMETERS:  source_desc         - Source object to copy
    118 *              target_desc         - Destination object of the copy
    119 *
    120 * RETURN:      Status
    121 *
    122 * DESCRIPTION: Copy a String object to another String object
    123 *
    124 ******************************************************************************/
    125
    126acpi_status
    127acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
    128			       union acpi_operand_object *target_desc)
    129{
    130	u32 length;
    131	u8 *buffer;
    132
    133	ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
    134
    135	/* If Source and Target are the same, just return */
    136
    137	if (source_desc == target_desc) {
    138		return_ACPI_STATUS(AE_OK);
    139	}
    140
    141	/* We know that source_desc is a string by now */
    142
    143	buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
    144	length = source_desc->string.length;
    145
    146	/*
    147	 * Replace existing string value if it will fit and the string
    148	 * pointer is not a static pointer (part of an ACPI table)
    149	 */
    150	if ((length < target_desc->string.length) &&
    151	    (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
    152		/*
    153		 * String will fit in existing non-static buffer.
    154		 * Clear old string and copy in the new one
    155		 */
    156		memset(target_desc->string.pointer, 0,
    157		       (acpi_size)target_desc->string.length + 1);
    158		memcpy(target_desc->string.pointer, buffer, length);
    159	} else {
    160		/*
    161		 * Free the current buffer, then allocate a new buffer
    162		 * large enough to hold the value
    163		 */
    164		if (target_desc->string.pointer &&
    165		    (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
    166
    167			/* Only free if not a pointer into the DSDT */
    168
    169			ACPI_FREE(target_desc->string.pointer);
    170		}
    171
    172		target_desc->string.pointer =
    173		    ACPI_ALLOCATE_ZEROED((acpi_size)length + 1);
    174
    175		if (!target_desc->string.pointer) {
    176			return_ACPI_STATUS(AE_NO_MEMORY);
    177		}
    178
    179		target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
    180		memcpy(target_desc->string.pointer, buffer, length);
    181	}
    182
    183	/* Set the new target length */
    184
    185	target_desc->string.length = length;
    186	return_ACPI_STATUS(AE_OK);
    187}