1
1

patcher/base: improve instruction cache flush for aarch64

This commit updates the patcher component to either use the
__clear_cache intrinsic or the correct assembly to flush the
instruction cache.

Fixes #5631

Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
Этот коммит содержится в:
Nathan Hjelm 2018-08-30 15:20:21 -06:00
родитель 68206a5635
Коммит 1cdbceb095
2 изменённых файлов: 25 добавлений и 4 удалений

Просмотреть файл

@ -858,7 +858,7 @@ OPAL_SEARCH_LIBS_CORE([ceil], [m])
# -lrt might be needed for clock_gettime # -lrt might be needed for clock_gettime
OPAL_SEARCH_LIBS_CORE([clock_gettime], [rt]) OPAL_SEARCH_LIBS_CORE([clock_gettime], [rt])
AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf openpty isatty getpwuid fork waitpid execve pipe ptsname setsid mmap tcgetpgrp posix_memalign strsignal sysconf syslog vsyslog regcmp regexec regfree _NSGetEnviron socketpair strncpy_s usleep mkfifo dbopen dbm_open statfs statvfs setpgid setenv __malloc_initialize_hook]) AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf openpty isatty getpwuid fork waitpid execve pipe ptsname setsid mmap tcgetpgrp posix_memalign strsignal sysconf syslog vsyslog regcmp regexec regfree _NSGetEnviron socketpair strncpy_s usleep mkfifo dbopen dbm_open statfs statvfs setpgid setenv __malloc_initialize_hook __clear_cache])
# Sanity check: ensure that we got at least one of statfs or statvfs. # Sanity check: ensure that we got at least one of statfs or statvfs.
if test $ac_cv_func_statfs = no && test $ac_cv_func_statvfs = no; then if test $ac_cv_func_statfs = no && test $ac_cv_func_statvfs = no; then

Просмотреть файл

@ -1,6 +1,6 @@
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/* /*
* Copyright (c) 2016 Los Alamos National Security, LLC. All rights * Copyright (c) 2016-2018 Los Alamos National Security, LLC. All rights
* reserved. * reserved.
* Copyright (c) 2017 Research Organization for Information Science * Copyright (c) 2017 Research Organization for Information Science
* and Technology (RIST). All rights reserved. * and Technology (RIST). All rights reserved.
@ -107,7 +107,11 @@ static void flush_and_invalidate_cache (unsigned long a)
#elif OPAL_ASSEMBLY_ARCH == OPAL_IA64 #elif OPAL_ASSEMBLY_ARCH == OPAL_IA64
__asm__ volatile ("fc %0;; sync.i;; srlz.i;;" : : "r"(a) : "memory"); __asm__ volatile ("fc %0;; sync.i;; srlz.i;;" : : "r"(a) : "memory");
#elif OPAL_ASSEMBLY_ARCH == OPAL_ARM64 #elif OPAL_ASSEMBLY_ARCH == OPAL_ARM64
__asm__ volatile ("dsb sy"); __asm__ volatile ("dc cvau, %0\n\t"
"dsb ish\n\t"
"ic ivau, %0\n\t"
"dsb ish\n\t"
"isb":: "r" (a));
#endif #endif
} }
@ -138,10 +142,27 @@ static inline void apply_patch (unsigned char *patch_data, uintptr_t address, si
{ {
ModifyMemoryProtection (address, data_size, PROT_EXEC|PROT_READ|PROT_WRITE); ModifyMemoryProtection (address, data_size, PROT_EXEC|PROT_READ|PROT_WRITE);
memcpy ((void *) address, patch_data, data_size); memcpy ((void *) address, patch_data, data_size);
for (size_t i = 0 ; i < data_size ; i += 16) { #if HAVE___CLEAR_CACHE
/* do not allow global declaration of compiler intrinsic */
void __clear_cache(void* beg, void* end);
__clear_cache ((void *) address, (void *) (address + data_size));
#else
size_t offset_jump = 16;
#if OPAL_ASSEMBLY_ARCH == OPAL_ARM64
offset_jump = 32;
#endif
/* align the address */
address &= ~(offset_jump - 1);
for (size_t i = 0 ; i < data_size ; i += offset_jump) {
flush_and_invalidate_cache (address + i); flush_and_invalidate_cache (address + i);
} }
#endif
ModifyMemoryProtection (address, data_size, PROT_EXEC|PROT_READ); ModifyMemoryProtection (address, data_size, PROT_EXEC|PROT_READ);
} }