feat(cpu_region_protect): Enable basic memory protection for SPIRAM

This commit is contained in:
harshal.patil
2025-02-18 23:28:26 +05:30
parent 49f253361e
commit ab229a34b3
20 changed files with 479 additions and 133 deletions

View File

@@ -44,6 +44,10 @@ void test_rtc_slow_reg2_execute_violation(void);
void test_irom_reg_write_violation(void);
void test_spiram_xip_irom_alignment_reg_execute_violation(void);
void test_spiram_xip_drom_alignment_reg_execute_violation(void);
void test_drom_reg_write_violation(void);
void test_drom_reg_execute_violation(void);

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -18,6 +18,9 @@
#include "test_panic.h"
#include "test_memprot.h"
#include "sdkconfig.h"
#include "soc/soc_caps.h"
/* Test Utility Functions */
#define BOOT_CMD_MAX_LEN (128)
@@ -172,6 +175,13 @@ void app_main(void)
HANDLE_TEST(test_name, test_irom_reg_write_violation);
HANDLE_TEST(test_name, test_drom_reg_write_violation);
HANDLE_TEST(test_name, test_drom_reg_execute_violation);
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
HANDLE_TEST(test_name, test_spiram_xip_irom_alignment_reg_execute_violation);
#endif
#endif
#if CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2
HANDLE_TEST(test_name, test_spiram_xip_drom_alignment_reg_execute_violation);
#endif
#ifdef CONFIG_SOC_CPU_HAS_PMA

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,6 +13,7 @@
#include "esp_system.h"
#include "esp_log.h"
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "test_memprot.h"
#include "sdkconfig.h"
@@ -24,6 +25,8 @@ extern int _iram_start;
extern int _iram_text_start;
extern int _iram_text_end;
#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1))
/* NOTE: Naming conventions for RTC_FAST_MEM are
* different for ESP32-C3 and other RISC-V targets
*/
@@ -245,8 +248,37 @@ void test_drom_reg_execute_violation(void)
func_ptr = (void(*)(void))foo_buf;
func_ptr();
}
// Check if the memory alignment gaps added to the heap are correctly configured
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
void test_spiram_xip_irom_alignment_reg_execute_violation(void)
{
extern int _instruction_reserved_end;
if (ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end)) - (uint32_t)(&_instruction_reserved_end) >= 4) {
void (*test_addr)(void) = (void(*)(void))((uint32_t)(&_instruction_reserved_end + 0x4));
printf("SPIRAM (IROM): Execute operation | Address: %p\n", test_addr);
test_addr();
} else {
printf("SPIRAM (IROM): IROM alignment gap not added into heap\n");
}
}
#endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED */
#endif
#if CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2
void test_spiram_xip_drom_alignment_reg_execute_violation(void)
{
extern int _rodata_reserved_end;
if (ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end)) - (uint32_t)(&_rodata_reserved_end) >= 4) {
void (*test_addr)(void) = (void(*)(void))((uint32_t)(&_rodata_reserved_end + 0x4));
printf("SPIRAM (DROM): Execute operation | Address: %p\n", test_addr);
test_addr();
} else {
printf("SPIRAM (DROM): DROM alignment gap not added into heap\n");
}
}
#endif /* CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2 */
#ifdef CONFIG_SOC_CPU_HAS_PMA
void test_invalid_memory_region_write_violation(void)
{

View File

@@ -163,7 +163,8 @@ def common_test(
dut.revert_log_level()
return # don't expect "Rebooting" output below
# We will only perform comparisons for ELF files, as we are not introducing any new fields to the binary file format.
# We will only perform comparisons for ELF files,
# as we are not introducing any new fields to the binary file format.
if 'bin' in config:
expected_coredump = None
@@ -719,6 +720,29 @@ CONFIGS_MEMPROT_FLASH_IDROM = list(
)
)
CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP = list(
itertools.chain(
itertools.product(
['memprot_spiram_xip_esp32c5', 'memprot_spiram_xip_esp32c61', 'memprot_spiram_xip_esp32p4'],
['esp32c5', 'esp32c61', 'esp32p4'],
)
)
)
CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP = list(
itertools.chain(
itertools.product(
[
'memprot_spiram_xip_esp32s3',
'memprot_spiram_xip_esp32c5',
'memprot_spiram_xip_esp32c61',
'memprot_spiram_xip_esp32p4',
],
['esp32s3', 'esp32c5', 'esp32c61', 'esp32p4'],
)
)
)
CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA = list(
itertools.chain(
itertools.product(
@@ -1000,6 +1024,33 @@ def test_drom_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> N
dut.expect_cpu_reset()
@pytest.mark.generic
@idf_parametrize('config, target', CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP, indirect=['config', 'target'])
def test_spiram_xip_irom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
dut.run_test_func(test_func_name)
try:
dut.expect_gme('Instruction access fault')
except Exception:
dut.expect_exact('SPIRAM (IROM): IROM alignment gap not added into heap')
dut.expect_reg_dump(0)
dut.expect_cpu_reset()
@pytest.mark.generic
@idf_parametrize('config, target', CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP, indirect=['config', 'target'])
def test_spiram_xip_drom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
dut.run_test_func(test_func_name)
try:
if dut.target == 'esp32s3':
dut.expect_gme('InstructionFetchError')
else:
dut.expect_gme('Instruction access fault')
except Exception:
dut.expect_exact('SPIRAM (DROM): DROM alignment gap not added into heap')
dut.expect_reg_dump(0)
dut.expect_cpu_reset()
@pytest.mark.generic
@idf_parametrize('config, target', CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA, indirect=['config', 'target'])
def test_invalid_memory_region_write_violation(dut: PanicTestDut, test_func_name: str) -> None:

View File

@@ -6,3 +6,7 @@ CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=y
# Enable memprot test
CONFIG_TEST_MEMPROT=y
# Enable SPIRAM to check the alignment gap's memory protection
CONFIG_SPIRAM=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y

View File

@@ -6,3 +6,7 @@ CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=y
# Enable memprot test
CONFIG_TEST_MEMPROT=y
# Enable SPIRAM to check the alignment gap's memory protection
CONFIG_SPIRAM=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y

View File

@@ -6,3 +6,7 @@ CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=y
# Enable memprot test
CONFIG_TEST_MEMPROT=y
# Enable SPIRAM to check the alignment gap's memory protection
CONFIG_SPIRAM=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y

View File

@@ -0,0 +1,13 @@
# Restricting to ESP32C5
CONFIG_IDF_TARGET="esp32c5"
# Enabling memory protection
CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=y
# Enable memprot test
CONFIG_TEST_MEMPROT=y
# Enable SPIRAM to check the alignment gap's memory protection
CONFIG_SPIRAM=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y

View File

@@ -0,0 +1,13 @@
# Restricting to ESP32C61
CONFIG_IDF_TARGET="esp32c61"
# Enabling memory protection
CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=y
# Enable memprot test
CONFIG_TEST_MEMPROT=y
# Enable SPIRAM to check the alignment gap's memory protection
CONFIG_SPIRAM=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y

View File

@@ -0,0 +1,13 @@
# Restricting to ESP32P4
CONFIG_IDF_TARGET="esp32p4"
# Enabling memory protection
CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=y
# Enable memprot test
CONFIG_TEST_MEMPROT=y
# Enable SPIRAM to check the alignment gap's memory protection
CONFIG_SPIRAM=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y

View File

@@ -0,0 +1,17 @@
# Restricting to ESP32S3
CONFIG_IDF_TARGET="esp32s3"
# Enabling memory protection
CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y
CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y
# Enabling DCACHE
CONFIG_ESP32S3_DATA_CACHE_16KB=y
# Enable memprot test
CONFIG_TEST_MEMPROT=y
# Enable SPIRAM to check the alignment gap's memory protection
CONFIG_SPIRAM=y
CONFIG_SPIRAM_USE_CAPS_ALLOC=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y