Skip to content

Commit 6877bc8

Browse files
dcpleungcfriedt
authored andcommitted
xtensa: userspace: handle DTLB multihit exception
This adds a function to handle DTLB multihit exception when userspace is enabled, as this exception may be raised due to the same page being able to accessed by both kernel and user threads. The auto-refill DTLBs may contain entries for same page, one for kernel and one for user under some situations. We need to invalidate those existing DTLB entries so that hardware can reload from the page table. This is an alternative to the kconfig invalidating DTLBs on every swap: CONFIG_XTENSA_MMU_FLUSH_AUTOREFILL_DTLBS_ON_SWAP. Although this does not have extra processing per context switching, exception handling itself has a high cost. So care needs to be taken on whether to enable that kconfig. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
1 parent d3a126c commit 6877bc8

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

arch/xtensa/core/ptables.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,16 @@ int arch_buffer_validate(const void *addr, size_t size, int write)
11731173
return mem_buffer_validate(addr, size, write, XTENSA_MMU_USER_RING);
11741174
}
11751175

1176+
void xtensa_exc_dtlb_multihit_handle(void)
1177+
{
1178+
/* For some unknown reasons, using xtensa_dtlb_probe() would result in
1179+
* QEMU raising privileged instruction exception. So for now, just
1180+
* invalidate all auto-refilled DTLBs.
1181+
*/
1182+
1183+
xtensa_dtlb_autorefill_invalidate();
1184+
}
1185+
11761186
bool xtensa_exc_load_store_ring_error_check(void *bsa_p)
11771187
{
11781188
uintptr_t ring, vaddr;

arch/xtensa/core/vector_handlers.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
6+
#include "xtensa/corebits.h"
67
#include <string.h>
78
#include <xtensa_asm2_context.h>
89
#include <zephyr/kernel.h>
@@ -631,6 +632,9 @@ void *xtensa_excint1_c(void *esf)
631632
break;
632633
#endif /* CONFIG_XTENSA_LAZY_HIFI_SHARING */
633634
#if defined(CONFIG_XTENSA_MMU) && defined(CONFIG_USERSPACE)
635+
case EXCCAUSE_DTLB_MULTIHIT:
636+
xtensa_exc_dtlb_multihit_handle();
637+
break;
634638
case EXCCAUSE_LOAD_STORE_RING:
635639
if (!xtensa_exc_load_store_ring_error_check(bsa)) {
636640
break;

arch/xtensa/include/xtensa_internal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ void xtensa_userspace_enter(k_thread_entry_t user_entry,
7474
*/
7575
bool xtensa_mem_kernel_has_access(const void *addr, size_t size, int write);
7676

77+
/**
78+
* @brief Handle DTLB multihit exception.
79+
*
80+
* Handle DTLB multihit exception by invalidating all auto-refilled DTLBs of
81+
* a particular memory page.
82+
*/
83+
void xtensa_exc_dtlb_multihit_handle(void);
84+
7785
/**
7886
* @brief Check if it is a true load/store ring exception.
7987
*

0 commit comments

Comments
 (0)