Skip to content
This repository was archived by the owner on Sep 30, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions opal/mca/memory/patcher/configure.m4
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ AC_DEFUN([MCA_opal_memory_patcher_CONFIG],[
AC_DEFINE_UNQUOTED([OPAL_MEMORY_PATCHER_HAVE___SYSCALL], [$memory_patcher_have___syscall],
[Whether the internal __syscall call exists])

AC_CHECK_HEADERS([linux/mman.h])

[$1]

OPAL_VAR_SCOPE_POP
Expand Down
23 changes: 23 additions & 0 deletions opal/mca/memory/patcher/memory_patcher_component.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
#include <sys/time.h>
#include <sys/syscall.h>

#if defined(HAVE_LINUX_MMAN_H)
#include <linux/mman.h>
#endif

#include "memory_patcher.h"
#undef opal_memory_changed

Expand Down Expand Up @@ -162,11 +166,20 @@ static int intercept_munmap(void *start, size_t length)

#if defined (SYS_mremap)

#if defined(__linux__)
/* on linux this function has an optional extra argument but ... can not be used here because it
* causes issues when intercepting a 4-argument mremap call */
static void *(*original_mremap) (void *, size_t, size_t, int, void *);
#else
/* mremap has a different signature on BSD systems */
static void *(*original_mremap) (void *, size_t, void *, size_t, int);
#endif

#if defined(__linux__)
static void *intercept_mremap (void *start, size_t oldlen, size_t newlen, int flags, void *new_address)
#else
static void *intercept_mremap (void *start, size_t oldlen, void *new_address, size_t newlen, int flags)
#endif
{
OPAL_PATCHER_BEGIN;
void *result = MAP_FAILED;
Expand All @@ -175,15 +188,25 @@ static void *intercept_mremap (void *start, size_t oldlen, size_t newlen, int fl
opal_mem_hooks_release_hook (start, oldlen, true);
}

#if defined(MREMAP_FIXED)
if (!(flags & MREMAP_FIXED)) {
new_address = NULL;
}
#endif

#if defined(__linux__)
if (!original_mremap) {
result = (void *)(intptr_t) memory_patcher_syscall (SYS_mremap, start, oldlen, newlen, flags, new_address);
} else {
result = original_mremap (start, oldlen, newlen, flags, new_address);
}
#else
if (!original_mremap) {
result = (void *)(intptr_t) memory_patcher_syscall (SYS_mremap, start, oldlen, new_address, newlen, flags);
} else {
result = original_mremap (start, oldlen, new_address, newlen, flags);
}
#endif

OPAL_PATCHER_END;
return result;
Expand Down
2 changes: 1 addition & 1 deletion opal/mca/patcher/base/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ OPAL_DECLSPEC int mca_patcher_base_patch_hook (mca_patcher_base_module_t *module
OPAL_DECLSPEC void mca_base_patcher_patch_apply_binary (mca_patcher_base_patch_t *patch);

static inline uintptr_t mca_patcher_base_addr_text (uintptr_t addr) {
#if (defined(__PPC64__) || defined(__powerpc64__) || defined(__PPC__)) && _CALL_ELF != 2
#if (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64) && (!defined (_CALL_ELF) || (_CALL_ELF != 2))
struct odp_t {
uintptr_t text;
uintptr_t toc;
Expand Down
47 changes: 31 additions & 16 deletions opal/mca/patcher/base/patcher_base_patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,37 @@ static int PatchLoadImm (uintptr_t addr, unsigned int reg, size_t value)

#endif

#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)

static void flush_and_invalidate_cache (unsigned long a)
static void flush_and_invalidate_cache (unsigned long a)
{
#if defined(__i386__)
/* does not work with AMD processors */
__asm__ volatile("mfence;clflush %0;mfence" : :"m" (*(char*)a));
#elif defined(__x86_64__)
#if OPAL_ASSEMBLY_ARCH == OPAL_IA32
static int have_clflush = -1;

if (OPAL_UNLIKELY(-1 == have_clflush)) {
int32_t cpuid1, cpuid2, tmp;
const int32_t level = 1;

/* cpuid clobbers ebx but it must be restored for -fPIC so save
* then restore ebx */
__asm__ volatile ("xchgl %%ebx, %2\n"
"cpuid\n"
"xchgl %%ebx, %2\n":
"=a" (cpuid1), "=d" (cpuid2), "=r" (tmp) :
"a" (level) :
"ecx");
/* clflush is in edx bit 19 */
have_clflush = !!(cpuid2 & (1 << 19));
}

if (have_clflush) {
/* does not work with AMD processors */
__asm__ volatile("mfence;clflush %0;mfence" : :"m" (*(char*)a));
}
#elif OPAL_ASSEMBLY_ARCH == OPAL_AMD64
__asm__ volatile("mfence;clflush %0;mfence" : :"m" (*(char*)a));
#elif defined(__ia64__)
#elif OPAL_ASSEMBLY_ARCH == OPAL_IA64
__asm__ volatile ("fc %0;; sync.i;; srlz.i;;" : : "r"(a) : "memory");
#endif
}
#endif

// modify protection of memory range
static void ModifyMemoryProtection (uintptr_t addr, size_t length, int prot)
Expand All @@ -105,7 +122,7 @@ static void ModifyMemoryProtection (uintptr_t addr, size_t length, int prot)
if (mprotect((void *)base, page_size, prot))
perror("MemHook: mprotect failed");
base += page_size;
} while (base < addr + length);
} while (base < bound);
#else
if (mprotect((void *) base, length, prot)) {
perror("MemHook: mprotect failed");
Expand All @@ -117,11 +134,9 @@ static inline void apply_patch (unsigned char *patch_data, uintptr_t address, si
{
ModifyMemoryProtection (address, data_size, PROT_EXEC|PROT_READ|PROT_WRITE);
memcpy ((void *) address, patch_data, data_size);
#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
for (size_t i = 0 ; i < data_size ; i += 16) {
flush_and_invalidate_cache (address + i);
}
#endif

ModifyMemoryProtection (address, data_size, PROT_EXEC|PROT_READ);
}
Expand All @@ -141,26 +156,26 @@ void mca_base_patcher_patch_apply_binary (mca_patcher_base_patch_t *patch)

int mca_patcher_base_patch_hook (mca_patcher_base_module_t *module, uintptr_t hook_addr)
{
#if defined(__PPC64__) || defined(__powerpc64__) || defined(__PPC__)
#if (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64)
mca_patcher_base_patch_t *hook_patch;
const unsigned int nop = 0x60000000;
unsigned int *nop_addr;

hook_patch = OBJ_NEW(mca_patcher_base_patch_t);
if (OPAL_UNLIKELY(NULL == hook_patch)) {
return OPAL_ERR_OUT_OF_RESOURCE;
}

// locate reserved code space in hook function
for (nop_addr = (unsigned int *)hook_addr ; ; nop_addr++) {
for (unsigned int *nop_addr = (unsigned int *)hook_addr ; ; nop_addr++) {
if (nop_addr[0] == nop && nop_addr[1] == nop && nop_addr[2] == nop
&& nop_addr[3] == nop && nop_addr[4] == nop) {
hook_patch->patch_orig = (uintptr_t) nop_addr;
break;
}
}

// generate code to restore TOC
register unsigned long toc asm("r2");
hook_patch->patch_orig = (uintptr_t) nop_addr;
hook_patch->patch_data_size = PatchLoadImm((uintptr_t)hook_patch->patch_data, 2, toc);

/* put the hook patch on the patch list so it will be undone on finalize */
Expand Down
47 changes: 0 additions & 47 deletions opal/mca/patcher/linux/Makefile.am

This file was deleted.

53 changes: 0 additions & 53 deletions opal/mca/patcher/linux/configure.m4

This file was deleted.

45 changes: 0 additions & 45 deletions opal/mca/patcher/linux/patcher_linux.h

This file was deleted.

43 changes: 0 additions & 43 deletions opal/mca/patcher/linux/patcher_linux_component.c

This file was deleted.

Loading