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

dsdebug.c (5388B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: dsdebug - Parser/Interpreter interface - debugging
      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 "acnamesp.h"
     14#ifdef ACPI_DISASSEMBLER
     15#include "acdisasm.h"
     16#endif
     17#include "acinterp.h"
     18
     19#define _COMPONENT          ACPI_DISPATCHER
     20ACPI_MODULE_NAME("dsdebug")
     21
     22#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
     23/* Local prototypes */
     24static void
     25acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
     26			    const char *message);
     27
     28/*******************************************************************************
     29 *
     30 * FUNCTION:    acpi_ds_print_node_pathname
     31 *
     32 * PARAMETERS:  node            - Object
     33 *              message         - Prefix message
     34 *
     35 * DESCRIPTION: Print an object's full namespace pathname
     36 *              Manages allocation/freeing of a pathname buffer
     37 *
     38 ******************************************************************************/
     39
     40static void
     41acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
     42			    const char *message)
     43{
     44	struct acpi_buffer buffer;
     45	acpi_status status;
     46
     47	ACPI_FUNCTION_TRACE(ds_print_node_pathname);
     48
     49	if (!node) {
     50		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]"));
     51		return_VOID;
     52	}
     53
     54	/* Convert handle to full pathname and print it (with supplied message) */
     55
     56	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
     57
     58	status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
     59	if (ACPI_SUCCESS(status)) {
     60		if (message) {
     61			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ",
     62					      message));
     63		}
     64
     65		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[%s] (Node %p)",
     66				      (char *)buffer.pointer, node));
     67		ACPI_FREE(buffer.pointer);
     68	}
     69
     70	return_VOID;
     71}
     72
     73/*******************************************************************************
     74 *
     75 * FUNCTION:    acpi_ds_dump_method_stack
     76 *
     77 * PARAMETERS:  status          - Method execution status
     78 *              walk_state      - Current state of the parse tree walk
     79 *              op              - Executing parse op
     80 *
     81 * RETURN:      None
     82 *
     83 * DESCRIPTION: Called when a method has been aborted because of an error.
     84 *              Dumps the method execution stack.
     85 *
     86 ******************************************************************************/
     87
     88void
     89acpi_ds_dump_method_stack(acpi_status status,
     90			  struct acpi_walk_state *walk_state,
     91			  union acpi_parse_object *op)
     92{
     93	union acpi_parse_object *next;
     94	struct acpi_thread_state *thread;
     95	struct acpi_walk_state *next_walk_state;
     96	struct acpi_namespace_node *previous_method = NULL;
     97	union acpi_operand_object *method_desc;
     98
     99	ACPI_FUNCTION_TRACE(ds_dump_method_stack);
    100
    101	/* Ignore control codes, they are not errors */
    102
    103	if (ACPI_CNTL_EXCEPTION(status)) {
    104		return_VOID;
    105	}
    106
    107	/* We may be executing a deferred opcode */
    108
    109	if (walk_state->deferred_node) {
    110		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    111				  "Executing subtree for Buffer/Package/Region\n"));
    112		return_VOID;
    113	}
    114
    115	/*
    116	 * If there is no Thread, we are not actually executing a method.
    117	 * This can happen when the iASL compiler calls the interpreter
    118	 * to perform constant folding.
    119	 */
    120	thread = walk_state->thread;
    121	if (!thread) {
    122		return_VOID;
    123	}
    124
    125	/* Display exception and method name */
    126
    127	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    128			  "\n**** Exception %s during execution of method ",
    129			  acpi_format_exception(status)));
    130
    131	acpi_ds_print_node_pathname(walk_state->method_node, NULL);
    132
    133	/* Display stack of executing methods */
    134
    135	ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
    136			      "\n\nMethod Execution Stack:\n"));
    137	next_walk_state = thread->walk_state_list;
    138
    139	/* Walk list of linked walk states */
    140
    141	while (next_walk_state) {
    142		method_desc = next_walk_state->method_desc;
    143		if (method_desc) {
    144			acpi_ex_stop_trace_method((struct acpi_namespace_node *)
    145						  method_desc->method.node,
    146						  method_desc, walk_state);
    147		}
    148
    149		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
    150				  "    Method [%4.4s] executing: ",
    151				  acpi_ut_get_node_name(next_walk_state->
    152							method_node)));
    153
    154		/* First method is the currently executing method */
    155
    156		if (next_walk_state == walk_state) {
    157			if (op) {
    158
    159				/* Display currently executing ASL statement */
    160
    161				next = op->common.next;
    162				op->common.next = NULL;
    163
    164#ifdef ACPI_DISASSEMBLER
    165				if (walk_state->method_node !=
    166				    acpi_gbl_root_node) {
    167
    168					/* More verbose if not module-level code */
    169
    170					acpi_os_printf("Failed at ");
    171					acpi_dm_disassemble(next_walk_state, op,
    172							    ACPI_UINT32_MAX);
    173				}
    174#endif
    175				op->common.next = next;
    176			}
    177		} else {
    178			/*
    179			 * This method has called another method
    180			 * NOTE: the method call parse subtree is already deleted at
    181			 * this point, so we cannot disassemble the method invocation.
    182			 */
    183			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
    184					      "Call to method "));
    185			acpi_ds_print_node_pathname(previous_method, NULL);
    186		}
    187
    188		previous_method = next_walk_state->method_node;
    189		next_walk_state = next_walk_state->next;
    190		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n"));
    191	}
    192
    193	return_VOID;
    194}
    195
    196#else
    197void
    198acpi_ds_dump_method_stack(acpi_status status,
    199			  struct acpi_walk_state *walk_state,
    200			  union acpi_parse_object *op)
    201{
    202	return;
    203}
    204
    205#endif