[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 13/19] accel/tcg: Support split-rwx for linux with memfd
From: |
Richard Henderson |
Subject: |
[PATCH v2 13/19] accel/tcg: Support split-rwx for linux with memfd |
Date: |
Thu, 29 Oct 2020 17:49:15 -0700 |
We cannot use a real temp file, because we would need to find
a filesystem that does not have noexec enabled. However, a
memfd is not associated with any filesystem.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/translate-all.c | 87 +++++++++++++++++++++++++++++++++++----
1 file changed, 80 insertions(+), 7 deletions(-)
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 8918a09f10..3e69ebd1d3 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1088,17 +1088,11 @@ static bool alloc_code_gen_buffer(size_t size, int
mirror, Error **errp)
return true;
}
#else
-static bool alloc_code_gen_buffer(size_t size, int mirror, Error **errp)
+static bool alloc_code_gen_buffer_anon(size_t size, int prot, Error **errp)
{
- int prot = PROT_WRITE | PROT_READ | PROT_EXEC;
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
void *buf;
- if (mirror > 0) {
- error_setg(errp, "jit split-rwx not supported");
- return false;
- }
-
buf = mmap(NULL, size, prot, flags, -1, 0);
if (buf == MAP_FAILED) {
error_setg_errno(errp, errno,
@@ -1147,6 +1141,85 @@ static bool alloc_code_gen_buffer(size_t size, int
mirror, Error **errp)
tcg_ctx->code_gen_buffer = buf;
return true;
}
+
+#ifdef CONFIG_LINUX
+#include "qemu/memfd.h"
+
+static bool alloc_code_gen_buffer_mirror_memfd(size_t size, Error **errp)
+{
+ void *buf_rw, *buf_rx;
+ int fd;
+
+ fd = qemu_memfd_create("tcg-jit", size, false, 0, 0, errp);
+ if (fd < 0) {
+ return false;
+ }
+
+ buf_rw = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (buf_rw == MAP_FAILED) {
+ error_setg_errno(errp, errno,
+ "allocate %zu bytes for jit buffer", size);
+ close(fd);
+ return false;
+ }
+
+ buf_rx = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
+ if (buf_rx == MAP_FAILED) {
+ error_setg_errno(errp, errno,
+ "allocate %zu bytes for jit mirror", size);
+ munmap(buf_rw, size);
+ close(fd);
+ return false;
+ }
+ close(fd);
+
+ tcg_ctx->code_gen_buffer = buf_rw;
+ tcg_ctx->code_gen_buffer_size = size;
+ tcg_rx_mirror_diff = buf_rx - buf_rw;
+
+ /* Request large pages for the buffer and the mirror. */
+ qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE);
+ qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE);
+ return true;
+}
+#endif
+
+static bool alloc_code_gen_buffer_mirror(size_t size, Error **errp)
+{
+ if (TCG_TARGET_SUPPORT_MIRROR) {
+#ifdef CONFIG_LINUX
+ return alloc_code_gen_buffer_mirror_memfd(size, errp);
+#endif
+ }
+ error_setg(errp, "jit split-rwx not supported");
+ return false;
+}
+
+static bool alloc_code_gen_buffer(size_t size, int mirror, Error **errp)
+{
+ if (mirror) {
+ Error *local_err = NULL;
+ if (alloc_code_gen_buffer_mirror(size, &local_err)) {
+ return true;
+ }
+ /*
+ * If mirror force-on (1), fail;
+ * if mirror default-on (-1), fall through to mirror off.
+ */
+ if (mirror > 0) {
+ error_propagate(errp, local_err);
+ return false;
+ }
+ }
+
+ int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+#ifdef CONFIG_TCG_INTERPRETER
+ /* The tcg interpreter does not need execute permission. */
+ prot = PROT_READ | PROT_WRITE;
+#endif
+
+ return alloc_code_gen_buffer_anon(size, prot, errp);
+}
#endif /* USE_STATIC_CODE_GEN_BUFFER, WIN32, POSIX */
static bool tb_cmp(const void *ap, const void *bp)
--
2.25.1
- [PATCH v2 09/19] tcg: Make DisasContextBase.tb const, (continued)
- [PATCH v2 09/19] tcg: Make DisasContextBase.tb const, Richard Henderson, 2020/10/29
- [PATCH v2 02/19] tcg: Move tcg prologue pointer out of TCGContext, Richard Henderson, 2020/10/29
- [PATCH v2 04/19] tcg: Introduce tcg_mirror_rw_to_rx/tcg_mirror_rx_to_rw, Richard Henderson, 2020/10/29
- [PATCH v2 10/19] tcg: Make tb arg to synchronize_from_tb const, Richard Henderson, 2020/10/29
- [PATCH v2 11/19] tcg: Use Error with alloc_code_gen_buffer, Richard Henderson, 2020/10/29
- [PATCH v2 12/19] tcg: Add --accel tcg,split-rwx property, Richard Henderson, 2020/10/29
- [PATCH v2 14/19] RFC: accel/tcg: Support split-rwx for darwin/iOS with vm_remap, Richard Henderson, 2020/10/29
- [PATCH v2 15/19] tcg: Return the rx mirror of TranslationBlock from exit_tb, Richard Henderson, 2020/10/29
- [PATCH v2 17/19] tcg/aarch64: Use B not BL for tcg_out_goto_long, Richard Henderson, 2020/10/29
- [PATCH v2 07/19] tcg: Adjust tcg_register_jit for const, Richard Henderson, 2020/10/29
- [PATCH v2 13/19] accel/tcg: Support split-rwx for linux with memfd,
Richard Henderson <=
- [PATCH v2 16/19] tcg/i386: Support split-rwx code generation, Richard Henderson, 2020/10/29
- [PATCH v2 19/19] tcg/aarch64: Support split-rwx code generation, Richard Henderson, 2020/10/29
- [PATCH v2 18/19] tcg/aarch64: Implement flush_idcache_range manually, Richard Henderson, 2020/10/29
- Re: [PATCH v2 00/19] Mirror map JIT memory for TCG, no-reply, 2020/10/29
- Re: [PATCH v2 00/19] Mirror map JIT memory for TCG, Paolo Bonzini, 2020/10/30