-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory Protection causing reboot loop (IDFGH-14602) #15359
Comments
Hello @paulblid , Thanks for reporting this issue, I was able to reproduce it on my side, I am going to investigate it. |
Hello, I asked my colleague @lucic71 to do some digging around, and we have found that there is some leftover state from a memprot crash. We hooked the panic handler to dump memprot registers during an unrelated crash (nullptr access) and during the memprot crash from above, we noticed the following differences:
We then tried wrapping the panic handler (gcc --wrap option) and inserted the following instruction: void __real_esp_panic_handler(void*);
void __wrap_esp_panic_handler (void* info) {
esp_memprot_clear_intr(MEMPROT_PERI2_RTCSLOW_0);
__real_esp_panic_handler(info);
} This fixed the crash loop, but it's only a proof of concept. Hope this helps investigating the issue further. |
Hello @paulblid , Sorry for not giving an update, I have already opened an internal PR to fix this issue, it is currently under review. I confirm that the source of the issue is that the memory protection interrupt state is not cleaned before re-enabling the interrupts on boot, hence the boot loop. |
Thank you for the update. For anyone else waiting for the official fix, this is our workaround for now: memprot_handler.cpp /* IDFGH-14602 */
extern "C"
{
mem_type_prot_t get_active_intr_memtype()
{
if (DPORT_GET_PERI_REG_MASK(DPORT_PMS_PRO_IRAM0_4_REG, DPORT_PMS_PRO_IRAM0_ILG_INTR) > 0) {
return MEMPROT_IRAM0_SRAM;
} else if (DPORT_GET_PERI_REG_MASK(DPORT_PMS_PRO_DRAM0_3_REG, DPORT_PMS_PRO_DRAM0_ILG_INTR) > 0) {
return MEMPROT_DRAM0_SRAM;
} else if (DPORT_GET_PERI_REG_MASK(DPORT_PMS_PRO_DPORT_6_REG, DPORT_PMS_PRO_DPORT_ILG_INTR) > 0) {
return MEMPROT_PERI1_RTCSLOW;
} else if (DPORT_GET_PERI_REG_MASK(DPORT_PMS_PRO_AHB_3_REG, DPORT_PMS_PRO_AHB_ILG_INTR) > 0) {
return MEMPROT_PERI2_RTCSLOW_0;
}
return MEMPROT_NONE;
}
esp_err_t __real_esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
esp_err_t __wrap_esp_memprot_set_prot (bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask) {
esp_memprot_clear_intr(get_active_intr_memtype());
return __real_esp_memprot_set_prot(invoke_panic_handler, lock_feature, mem_type_mask);
}
} CMakeLists.txt idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=esp_memprot_set_prot" APPEND) Additionally, I think there is a bug in the memprot implementation for esp32s2, specifically this line:
Shouldn't this be a call to Paul. |
This fix will be backported to the older versions that are still maintained |
Answers checklist.
IDF version.
v5.3, v5.4
Espressif SoC revision.
ESP32-S2 rev 1.0
Operating System used.
Windows
How did you build your project?
VS Code IDE
If you are using Windows, please specify command line type.
None
Development Kit.
Custom board
Power Supply used.
External 3.3V
What is the expected behavior?
The code should throw a memory protection fault and then reboot into user code.
What is the actual behavior?
After the first crash (with a memory protection fault), the cpu setup code encounters a Cache disabled exception, which causes a reboot loop.
Turning off memory protection avoids this behavior entirely, but is counterproductive to our app as we would like it to crash if it accesses memory in an unintended way.
Steps to reproduce.
Minimal example code:
All sdkconfig settings are identical to the official template-app.
Debug Logs.
More Information.
esp_memprot_intr_init
.The text was updated successfully, but these errors were encountered: