From 117a0098f370ea898da5a3f83fa2e74bf3b5bf92 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Wed, 25 Sep 2024 11:25:46 +0200 Subject: [PATCH] drivers: flash: simulator: fix address resolution The flash simulator assumes that flash is being addressed with absolute addresses by clients. But this is not the case. Given addresses are relative to the flash base address. The existing code only worked because the base address was always zero. Testing with non-zero base addresses caused a mem fault/page fault. (Reproducible e.g. when using the NVS settings subsystem on QEMU x86 with a non-zero base address in the soc-nv-flash node.) Fixes #79082 Signed-off-by: Florian Grandel --- drivers/flash/flash_simulator.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 1041bc3423b..d8ee0ce0935 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -48,7 +48,7 @@ #error "Erase unit must be a multiple of program unit" #endif -#define MOCK_FLASH(addr) (mock_flash + (addr) - FLASH_SIMULATOR_BASE_OFFSET) +#define MOCK_FLASH(offset) (mock_flash + (offset)) /* maximum number of pages that can be tracked by the stats module */ #define STATS_PAGE_COUNT_THRESHOLD 256 @@ -174,9 +174,9 @@ static int flash_range_is_valid(const struct device *dev, off_t offset, size_t len) { ARG_UNUSED(dev); - if ((offset + len > FLASH_SIMULATOR_FLASH_SIZE + - FLASH_SIMULATOR_BASE_OFFSET) || - (offset < FLASH_SIMULATOR_BASE_OFFSET)) { + + if ((offset < 0 || offset >= FLASH_SIMULATOR_FLASH_SIZE || + (FLASH_SIMULATOR_FLASH_SIZE - offset) < len)) { return 0; } @@ -299,8 +299,7 @@ static int flash_sim_write(const struct device *dev, const off_t offset, static void unit_erase(const uint32_t unit) { - const off_t unit_addr = FLASH_SIMULATOR_BASE_OFFSET + - (unit * FLASH_SIMULATOR_ERASE_UNIT); + const off_t unit_addr = unit * FLASH_SIMULATOR_ERASE_UNIT; /* erase the memory unit by setting it to erase value */ memset(MOCK_FLASH(unit_addr), FLASH_SIMULATOR_ERASE_VALUE, @@ -332,8 +331,7 @@ static int flash_sim_erase(const struct device *dev, const off_t offset, } #endif /* the first unit to be erased */ - uint32_t unit_start = (offset - FLASH_SIMULATOR_BASE_OFFSET) / - FLASH_SIMULATOR_ERASE_UNIT; + uint32_t unit_start = offset / FLASH_SIMULATOR_ERASE_UNIT; /* erase as many units as necessary and increase their erase counter */ for (uint32_t i = 0; i < len / FLASH_SIMULATOR_ERASE_UNIT; i++) {