feat(context-mgmt): report context memory usage

This patch provides a reporting functionality to display the memory
consumed by the context in each security state and for each exception
level. Flag PLATFORM_REPORT_CTX_MEM_USE enables or disables this
feature.

Change-Id: I1515366bf87561dcedf2b3206be167804df681d4
Signed-off-by: Juan Pablo Conde <juanpablo.conde@arm.com>
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
This commit is contained in:
Juan Pablo Conde 2023-11-08 16:14:28 -06:00 committed by Jayanth Dodderi Chidanand
parent e631ac3b21
commit bfef8b908e
7 changed files with 208 additions and 0 deletions

View file

@ -1244,6 +1244,7 @@ $(eval $(call assert_booleans,\
PSA_CRYPTO \
ENABLE_CONSOLE_GETC \
INIT_UNUSED_NS_EL2 \
PLATFORM_REPORT_CTX_MEM_USE \
)))
# Numeric_Flags
@ -1437,8 +1438,16 @@ $(eval $(call add_defines,\
PSA_CRYPTO \
ENABLE_CONSOLE_GETC \
INIT_UNUSED_NS_EL2 \
PLATFORM_REPORT_CTX_MEM_USE \
)))
ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
ifeq (${DEBUG}, 0)
$(warning "PLATFORM_REPORT_CTX_MEM_USE can be applied when DEBUG=1 only")
override PLATFORM_REPORT_CTX_MEM_USE := 0
endif
endif
ifeq (${SANITIZE_UB},trap)
$(eval $(call add_define,MONITOR_TRAPS))
endif #(SANITIZE_UB)

View file

@ -61,6 +61,10 @@ ifeq (${USE_DEBUGFS},1)
BL31_SOURCES += $(DEBUGFS_SRCS)
endif
ifeq (${PLATFORM_REPORT_CTX_MEM_USE},1)
BL31_SOURCES += lib/el3_runtime/aarch64/context_debug.c
endif
ifeq (${EL3_EXCEPTION_HANDLING},1)
BL31_SOURCES += bl31/ehf.c
endif

View file

@ -18,6 +18,7 @@
#include <common/runtime_svc.h>
#include <drivers/console.h>
#include <lib/bootmarker_capture.h>
#include <lib/el3_runtime/context_debug.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/pmf/pmf.h>
#include <lib/runtime_instr.h>
@ -106,6 +107,9 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
*/
assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
/* Prints context_memory allocated for all the security states */
report_ctx_memory_usage();
}
/*******************************************************************************

View file

@ -722,6 +722,11 @@ Common build options
platform makefile named ``platform.mk``. For example, to build TF-A for the
Arm Juno board, select PLAT=juno.
- ``PLATFORM_REPORT_CTX_MEM_USE``: Reports the context memory allocated for
each core as well as the global context. The data includes the memory used
by each world and each privileged exception level. This build option is
applicable only for ``ARCH=aarch64`` builds. The default value is 0.
- ``PRELOADED_BL33_BASE``: This option enables booting a preloaded BL33 image
instead of the normal boot flow. When defined, it must specify the entry
point address for the preloaded BL33 image. This option is incompatible with

View file

@ -0,0 +1,19 @@
/*
* Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef CONTEXT_DEBUG_H
#define CONTEXT_DEBUG_H
#if PLATFORM_REPORT_CTX_MEM_USE && defined(__aarch64__)
/********************************************************************************
* Reports the allocated memory for every security state and then reports the
* total system-wide allocated memory.
*******************************************************************************/
void report_ctx_memory_usage(void);
#else
static inline void report_ctx_memory_usage(void) {}
#endif /* PLATFORM_REPORT_CTX_MEM_USE */
#endif /* CONTEXT_DEBUG_H */

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <string.h>
#include <common/debug.h>
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/el3_runtime/cpu_data.h>
/********************************************************************************
* Function that returns the corresponding string constant for a security state
* index.
*******************************************************************************/
static const char *get_context_name_by_idx(unsigned int security_state_idx)
{
assert(security_state_idx < CPU_CONTEXT_NUM);
static const char * const state_names[] = {
"Secure",
"Non Secure"
#if ENABLE_RME
, "Realm"
#endif /* ENABLE_RME */
};
return state_names[security_state_idx];
}
#if CTX_INCLUDE_EL2_REGS
#define PRINT_MEM_USAGE_SEPARATOR() \
do { \
printf("+-----------+-----------+-----------" \
"+-----------+-----------+-----------+\n"); \
} while (false)
#else
#define PRINT_MEM_USAGE_SEPARATOR() \
do { \
printf("+-----------+-----------" \
"+-----------+-----------+-----------+\n"); \
} while (false)
#endif /* CTX_INCLUDE_EL2_REGS */
#define NAME_PLACEHOLDER_LEN 14
#define PRINT_DASH(n) \
for (; n > 0; n--) { \
putchar('-'); \
}
/********************************************************************************
* This function prints the allocated memory for a specific security state.
* Values are grouped by exception level and core. The memory usage for the
* global context and the total memory for the security state are also computed.
*******************************************************************************/
static size_t report_allocated_memory(unsigned int security_state_idx)
{
size_t core_total = 0U;
size_t el3_total = 0U;
#if CTX_INCLUDE_EL2_REGS
size_t el2_total = 0U;
#endif /* CTX_INCLUDE_EL2_REGS */
size_t el1_total = 0U;
size_t other_total = 0U;
size_t total = 0U;
size_t per_world_ctx_size = 0U;
PRINT_MEM_USAGE_SEPARATOR();
printf("| Core | EL3 ");
#if CTX_INCLUDE_EL2_REGS
printf("| EL2 ");
#endif /* CTX_INCLUDE_EL2_REGS */
printf("| EL1 | Other | Total |\n");
/* Compute memory usage for each core's context */
for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
size_t size_other = 0U;
size_t el3_size = 0U;
#if CTX_INCLUDE_EL2_REGS
size_t el2_size = 0U;
#endif /* CTX_INCLUDE_EL2_REGS */
size_t el1_size = 0U;
PRINT_MEM_USAGE_SEPARATOR();
cpu_context_t *ctx = (cpu_context_t *)cm_get_context_by_index(i,
security_state_idx);
core_total = sizeof(*ctx);
el3_size = sizeof(ctx->el3state_ctx);
#if CTX_INCLUDE_EL2_REGS
el2_size = sizeof(ctx->el2_sysregs_ctx);
#endif /* CTX_INCLUDE_EL2_REGS */
el1_size = sizeof(ctx->el1_sysregs_ctx);
size_other = core_total - el3_size - el1_size;
printf("| %9u | %8luB ", i, el3_size);
#if CTX_INCLUDE_EL2_REGS
size_other -= el2_size;
printf("| %8luB ", el2_size);
#endif /* CTX_INCLUDE_EL2_REGS */
printf("| %8luB | %8luB | %8luB |\n", el1_size, size_other, core_total);
el3_total += el3_size;
#if CTX_INCLUDE_EL2_REGS
el2_total += el2_size;
#endif /* CTX_INCLUDE_EL2_REGS */
el1_total += el1_size;
other_total += size_other;
total += core_total;
}
PRINT_MEM_USAGE_SEPARATOR();
PRINT_MEM_USAGE_SEPARATOR();
printf("| All | %8luB ", el3_total);
#if CTX_INCLUDE_EL2_REGS
printf("| %8luB ", el2_total);
#endif /* CTX_INCLUDE_EL2_REGS */
printf("| %8luB | %8luB | %8luB |\n", el1_total, other_total, total);
PRINT_MEM_USAGE_SEPARATOR();
printf("\n");
/* Compute memory usage for the global context */
per_world_ctx_size = sizeof(per_world_context[security_state_idx]);
total += per_world_ctx_size;
printf("Per-world context: %luB\n\n", per_world_ctx_size);
printf("TOTAL: %luB\n", total);
return total;
}
/********************************************************************************
* Reports the allocated memory for every security state and then reports the
* total system-wide allocated memory.
*******************************************************************************/
void report_ctx_memory_usage(void)
{
INFO("Context memory allocation:\n");
size_t total = 0U;
for (unsigned int i = 0U; i < CPU_CONTEXT_NUM; i++) {
const char *context_name = get_context_name_by_idx(i);
size_t len = 0U;
printf("Memory usage for %s:\n", context_name);
total += report_allocated_memory(i);
printf("------------------------"
#if CTX_INCLUDE_EL2_REGS
"------"
#endif /* CTX_INCLUDE_EL2_REGS */
);
len = NAME_PLACEHOLDER_LEN - printf("End %s", context_name);
PRINT_DASH(len);
printf(
#if CTX_INCLUDE_EL2_REGS
"------"
#endif /* CTX_INCLUDE_EL2_REGS */
"-----------------------\n\n");
}
printf("Total context memory allocated: %luB\n\n", total);
}

View file

@ -378,3 +378,6 @@ INIT_UNUSED_NS_EL2 := 0
# Disable including MPAM EL2 registers in context by default since currently
# it's only enabled for NS world
CTX_INCLUDE_MPAM_REGS := 0
# Enable context memory usage reporting during BL31 setup.
PLATFORM_REPORT_CTX_MEM_USE := 0