aarch64: userspace: Introduce arch_user_string_nlen

Introduce the arch_user_string_nlen() assembly routine and the necessary
C code bits.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
Carlo Caione 2020-11-11 12:41:37 +01:00 committed by Anas Nashif
commit 9ec1c1a793
2 changed files with 57 additions and 1 deletions

View file

@ -15,9 +15,18 @@
#include <kernel.h> #include <kernel.h>
#include <logging/log.h> #include <logging/log.h>
#include <exc_handle.h>
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
#ifdef CONFIG_USERSPACE
Z_EXC_DECLARE(z_arm64_user_string_nlen);
static const struct z_exc_handle exceptions[] = {
Z_EXC_HANDLE(z_arm64_user_string_nlen),
};
#endif /* CONFIG_USERSPACE */
#ifdef CONFIG_EXCEPTION_DEBUG #ifdef CONFIG_EXCEPTION_DEBUG
static void dump_esr(uint64_t esr, bool *dump_far) static void dump_esr(uint64_t esr, bool *dump_far)
{ {
@ -168,7 +177,18 @@ static bool is_recoverable(z_arch_esf_t *esf, uint64_t esr, uint64_t far,
if (!esf) if (!esf)
return false; return false;
/* Empty */ #ifdef CONFIG_USERSPACE
for (int i = 0; i < ARRAY_SIZE(exceptions); i++) {
/* Mask out instruction mode */
uint64_t start = (uint64_t)exceptions[i].start;
uint64_t end = (uint64_t)exceptions[i].end;
if (esf->elr >= start && esf->elr < end) {
esf->elr = (uint64_t)(exceptions[i].fixup);
return true;
}
}
#endif
return false; return false;
} }

View file

@ -13,6 +13,42 @@
_ASM_FILE_PROLOGUE _ASM_FILE_PROLOGUE
/*
* size_t arch_user_string_nlen(const char *s, size_t maxsize, int *err_arg)
*/
GTEXT(z_arm64_user_string_nlen_fault_start)
GTEXT(z_arm64_user_string_nlen_fault_end)
GTEXT(z_arm64_user_string_nlen_fixup)
GTEXT(arch_user_string_nlen)
SECTION_FUNC(TEXT, arch_user_string_nlen)
mov x3, x0
mov x0, #0
mov x4, #0
strlen_loop:
cmp x0, x1
beq strlen_done
z_arm64_user_string_nlen_fault_start:
ldrb w5, [x3, x0]
z_arm64_user_string_nlen_fault_end:
cbz x5, strlen_done
add x0, x0, #1
b strlen_loop
z_arm64_user_string_nlen_fixup:
mov x4, #-1
mov x0, #0
strlen_done:
str w4, [x2]
ret
/* /*
* Routine to jump into userspace * Routine to jump into userspace
* *