[Git][ghc/ghc][wip/supersven/riscv64-ncg] More instruction cache flushing
Sven Tennie (@supersven)
gitlab at gitlab.haskell.org
Thu Mar 21 20:15:49 UTC 2024
Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC
Commits:
f3921041 by Sven Tennie at 2024-03-21T21:14:36+01:00
More instruction cache flushing
Flush in the Linker, which creates code in the PLT. And, cleanup the
link code by using built-ins instead of inline assembly.
- - - - -
8 changed files:
- rts/adjustor/LibffiAdjustor.c
- rts/linker/Elf.c
- rts/linker/elf_reloc.c
- rts/linker/elf_reloc.h
- rts/linker/elf_reloc_aarch64.c
- rts/linker/elf_reloc_aarch64.h
- rts/linker/elf_reloc_riscv64.c
- rts/linker/elf_reloc_riscv64.h
Changes:
=====================================
rts/adjustor/LibffiAdjustor.c
=====================================
@@ -12,6 +12,7 @@
#include "Adjustor.h"
#include "rts/ghc_ffi.h"
+#include <stdint.h>
#include <string.h>
// Note that ffi_alloc_prep_closure is a non-standard libffi closure
@@ -189,14 +190,18 @@ createAdjustor (int cconv,
#if defined(riscv64_HOST_ARCH)
// Synchronize the memory and instruction cache to prevent illegal
- // instruction exceptions. fence.i works per hart. I'm not sure what happens
- // when the generated code is called on another hart. Probably, the fence on
- // read/write is good enough for that. However, if there are illegal
- // instruction exceptions, this is the place to look at (maybe, that the
- // fence.i needs to be moved closely before the call.)
- asm volatile ("fence rw, rw" : : : "memory");
- asm volatile ("fence.i" ::: "memory");
+ // instruction exceptions.
+
+ // We expect two instructions for address loading, one for the jump.
+ int instrCount = 3;
+ // On Linux the parameters of __builtin___clear_cache are currently unused.
+ // Add them anyways for future compatibility. (I.e. the parameters couldn't
+ // be checked during development.)
+ __builtin___clear_cache((void *)code,
+ (void *)code + instrCount * sizeof(uint64_t));
+ // Memory barrier to ensure nothing circumvents the fence.i / cache flush.
+ SEQ_CST_FENCE();
#endif
- return (void*)code;
+ return (void *)code;
}
=====================================
rts/linker/Elf.c
=====================================
@@ -2015,6 +2015,8 @@ ocResolve_ELF ( ObjectCode* oc )
#if defined(powerpc_HOST_ARCH)
ocFlushInstructionCache( oc );
+#elseif defined(riscv64_HOST_ARCH)
+ flushInstructionCache();
#endif
return ocMprotect_Elf(oc);
=====================================
rts/linker/elf_reloc.c
=====================================
@@ -11,6 +11,11 @@ bool
relocateObjectCode(ObjectCode * oc) {
return ADD_SUFFIX(relocateObjectCode)(oc);
}
+
+
+void flushInstructionCache(){
+ return ADD_SUFFIX(flushInstructionCache)();
+}
#endif
#endif
=====================================
rts/linker/elf_reloc.h
=====================================
@@ -10,5 +10,5 @@
bool
relocateObjectCode(ObjectCode * oc);
-
+void flushInstructionCache();
#endif /* OBJETFORMAT_ELF */
=====================================
rts/linker/elf_reloc_aarch64.c
=====================================
@@ -339,5 +339,10 @@ relocateObjectCodeAarch64(ObjectCode * oc) {
return EXIT_SUCCESS;
}
+void flushInstructionCacheAarch64() {
+ // Looks like we don't need this on Aarch64.
+ /* no-op */
+}
+
#endif /* OBJECTFORMAT_ELF */
#endif /* aarch64_HOST_ARCH */
=====================================
rts/linker/elf_reloc_aarch64.h
=====================================
@@ -7,4 +7,5 @@
bool
relocateObjectCodeAarch64(ObjectCode * oc);
+void flushInstructionCacheAarch64();
#endif /* OBJETFORMAT_ELF */
=====================================
rts/linker/elf_reloc_riscv64.c
=====================================
@@ -588,5 +588,25 @@ bool relocateObjectCodeRISCV64(ObjectCode *oc) {
return EXIT_SUCCESS;
}
+void flushInstructionCacheRISCV64(ObjectCode *oc) {
+ // Synchronize the memory and instruction cache to prevent illegal
+ // instruction exceptions. On Linux the parameters of
+ // __builtin___clear_cache are currently unused. Add them anyways for future
+ // compatibility. (I.e. the parameters couldn't be checked during
+ // development.)
+
+ /* The main object code */
+ void *codeBegin = oc->image + oc->misalignment;
+ __builtin___clear_cache(codeBegin, codeBegin + oc->fileSize);
+
+ /* Jump Islands */
+ __builtin___clear_cache((void *)oc->symbol_extras,
+ (void *)oc->symbol_extras +
+ sizeof(SymbolExtra) * oc->n_symbol_extras);
+
+ // Memory barrier to ensure nothing circumvents the fence.i / cache flushes.
+ SEQ_CST_FENCE();
+}
+
#endif /* OBJECTFORMAT_ELF */
#endif /* riscv64_HOST_ARCH */
=====================================
rts/linker/elf_reloc_riscv64.h
=====================================
@@ -7,4 +7,5 @@
bool
relocateObjectCodeRISCV64(ObjectCode * oc);
+void flushInstructionCacheRISCV64();
#endif /* OBJETFORMAT_ELF */
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f39210417bc758abf4b013c5becaa66545184cbc
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f39210417bc758abf4b013c5becaa66545184cbc
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240321/d67de9b2/attachment-0001.html>
More information about the ghc-commits
mailing list