|
15 | 15 | #include <zephyr/logging/log.h>
|
16 | 16 | #include <offsets.h>
|
17 | 17 | #include <zsr.h>
|
| 18 | +#include <zephyr/arch/common/exc_handle.h> |
18 | 19 |
|
19 | 20 | LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
20 | 21 |
|
21 | 22 | extern char xtensa_arch_except_epc[];
|
22 | 23 |
|
| 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 | + |
23 | 32 | void *xtensa_init_stack(struct k_thread *thread, int *stack_top,
|
24 | 33 | void (*entry)(void *, void *, void *),
|
25 | 34 | void *arg1, void *arg2, void *arg3)
|
@@ -335,6 +344,21 @@ void *xtensa_excint1_c(int *interrupted_stack)
|
335 | 344 | ps = bsa->ps;
|
336 | 345 | pc = (void *)bsa->pc;
|
337 | 346 |
|
| 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 | + |
338 | 362 | __asm__ volatile("rsr.excvaddr %0" : "=r"(vaddr));
|
339 | 363 |
|
340 | 364 | /* Default for exception */
|
@@ -397,10 +421,6 @@ void *xtensa_excint1_c(int *interrupted_stack)
|
397 | 421 | is_fatal_error = true;
|
398 | 422 | break;
|
399 | 423 | }
|
400 |
| - |
401 |
| - if (is_dblexc) { |
402 |
| - __asm__ volatile("wsr.depc %0" : : "r"(0)); |
403 |
| - } |
404 | 424 | #endif /* CONFIG_XTENSA_MMU */
|
405 | 425 |
|
406 | 426 | if (is_dblexc || is_fatal_error) {
|
@@ -432,6 +452,16 @@ void *xtensa_excint1_c(int *interrupted_stack)
|
432 | 452 | _current_cpu->nested = 1;
|
433 | 453 | }
|
434 | 454 |
|
| 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 | + |
435 | 465 | return return_to(interrupted_stack);
|
436 | 466 | }
|
437 | 467 |
|
|
0 commit comments