diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index c37718db4d..02e1b05c42 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1137,24 +1137,40 @@ static bool alloc_code_gen_buffer_anon(size_t size, int prot, static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp) { - void *buf_rw, *buf_rx; + void *buf_rw = NULL, *buf_rx = MAP_FAILED; int fd = -1; +#ifdef __mips__ + /* Find space for the RX mapping, vs the 256MiB regions. */ + if (!alloc_code_gen_buffer_anon(size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | + MAP_NORESERVE, errp)) { + return false; + } + /* The size of the mapping may have been adjusted. */ + size = tcg_ctx->code_gen_buffer_size; + buf_rx = tcg_ctx->code_gen_buffer; +#endif + buf_rw = qemu_memfd_alloc("tcg-jit", size, 0, &fd, errp); if (buf_rw == NULL) { - return false; + goto fail; } +#ifdef __mips__ + void *tmp = mmap(buf_rx, size, PROT_READ | PROT_EXEC, + MAP_SHARED | MAP_FIXED, fd, 0); + if (tmp != buf_rx) { + goto fail_rx; + } +#else buf_rx = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); if (buf_rx == MAP_FAILED) { - error_setg_errno(errp, errno, - "failed to map shared memory for execute"); - munmap(buf_rw, size); - close(fd); - return false; + goto fail_rx; } - close(fd); +#endif + close(fd); tcg_ctx->code_gen_buffer = buf_rw; tcg_ctx->code_gen_buffer_size = size; tcg_splitwx_diff = buf_rx - buf_rw; @@ -1163,6 +1179,20 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp) qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE); qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE); return true; + + fail_rx: + error_setg_errno(errp, errno, "failed to map shared memory for execute"); + fail: + if (buf_rx != MAP_FAILED) { + munmap(buf_rx, size); + } + if (buf_rw) { + munmap(buf_rw, size); + } + if (fd >= 0) { + close(fd); + } + return false; } #endif /* CONFIG_POSIX */