Skip to content

Commit e9c449a

Browse files
dcpleungcarlescufi
authored andcommitted
xtensa: mmu: do not fault for known exceptions
There are known exceptions which are not fatal, and we need to handle them properly by returning to the fixup addresses as indicated. This adds the code necessary in the exception handler for this situation. Signed-off-by: Daniel Leung <[email protected]> Signed-off-by: Flavio Ceolin <[email protected]>
1 parent bc0656a commit e9c449a

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

arch/xtensa/core/fatal.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,6 @@ void z_xtensa_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
121121
z_fatal_error(reason, esf);
122122
}
123123

124-
#ifdef CONFIG_USERSPACE
125-
Z_EXC_DECLARE(z_xtensa_user_string_nlen);
126-
127-
static const struct z_exc_handle exceptions[] = {
128-
Z_EXC_HANDLE(z_xtensa_user_string_nlen)
129-
};
130-
#endif /* CONFIG_USERSPACE */
131-
132124
#ifdef XT_SIMULATOR
133125
void exit(int return_code)
134126
{

arch/xtensa/core/xtensa-asm2.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,20 @@
1515
#include <zephyr/logging/log.h>
1616
#include <offsets.h>
1717
#include <zsr.h>
18+
#include <zephyr/arch/common/exc_handle.h>
1819

1920
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
2021

2122
extern char xtensa_arch_except_epc[];
2223

24+
#ifdef CONFIG_USERSPACE
25+
Z_EXC_DECLARE(z_xtensa_user_string_nlen);
26+
27+
static const struct z_exc_handle exceptions[] = {
28+
Z_EXC_HANDLE(z_xtensa_user_string_nlen)
29+
};
30+
#endif /* CONFIG_USERSPACE */
31+
2332
void *xtensa_init_stack(struct k_thread *thread, int *stack_top,
2433
void (*entry)(void *, void *, void *),
2534
void *arg1, void *arg2, void *arg3)
@@ -335,6 +344,21 @@ void *xtensa_excint1_c(int *interrupted_stack)
335344
ps = bsa->ps;
336345
pc = (void *)bsa->pc;
337346

347+
#ifdef CONFIG_USERSPACE
348+
/* If the faulting address is from one of the known
349+
* exceptions that should not be fatal, return to
350+
* the fixup address.
351+
*/
352+
for (int i = 0; i < ARRAY_SIZE(exceptions); i++) {
353+
if ((pc >= exceptions[i].start) &&
354+
(pc < exceptions[i].end)) {
355+
bsa->pc = (uintptr_t)exceptions[i].fixup;
356+
357+
goto fixup_out;
358+
}
359+
}
360+
#endif /* CONFIG_USERSPACE */
361+
338362
__asm__ volatile("rsr.excvaddr %0" : "=r"(vaddr));
339363

340364
/* Default for exception */
@@ -397,10 +421,6 @@ void *xtensa_excint1_c(int *interrupted_stack)
397421
is_fatal_error = true;
398422
break;
399423
}
400-
401-
if (is_dblexc) {
402-
__asm__ volatile("wsr.depc %0" : : "r"(0));
403-
}
404424
#endif /* CONFIG_XTENSA_MMU */
405425

406426
if (is_dblexc || is_fatal_error) {
@@ -432,6 +452,16 @@ void *xtensa_excint1_c(int *interrupted_stack)
432452
_current_cpu->nested = 1;
433453
}
434454

455+
#ifdef CONFIG_XTENSA_MMU
456+
#ifdef CONFIG_USERSPACE
457+
fixup_out:
458+
#endif
459+
if (is_dblexc) {
460+
__asm__ volatile("wsr.depc %0" : : "r"(0));
461+
}
462+
#endif /* CONFIG_XTENSA_MMU */
463+
464+
435465
return return_to(interrupted_stack);
436466
}
437467

0 commit comments

Comments
 (0)