accel/tcg: Support split-wx for linux with memfd
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. Reviewed-by: Joelle van Dyne <j@getutm.app> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
a35b3e1415
commit
a8c35b2cad
|
@ -1078,17 +1078,11 @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
|
static bool alloc_code_gen_buffer_anon(size_t size, int prot,
|
||||||
|
int flags, Error **errp)
|
||||||
{
|
{
|
||||||
int prot = PROT_WRITE | PROT_READ | PROT_EXEC;
|
|
||||||
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
if (splitwx > 0) {
|
|
||||||
error_setg(errp, "jit split-wx not supported");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = mmap(NULL, size, prot, flags, -1, 0);
|
buf = mmap(NULL, size, prot, flags, -1, 0);
|
||||||
if (buf == MAP_FAILED) {
|
if (buf == MAP_FAILED) {
|
||||||
error_setg_errno(errp, errno,
|
error_setg_errno(errp, errno,
|
||||||
|
@ -1137,6 +1131,80 @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
|
||||||
tcg_ctx->code_gen_buffer = buf;
|
tcg_ctx->code_gen_buffer = buf;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_POSIX
|
||||||
|
#include "qemu/memfd.h"
|
||||||
|
|
||||||
|
static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp)
|
||||||
|
{
|
||||||
|
void *buf_rw, *buf_rx;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
buf_rw = qemu_memfd_alloc("tcg-jit", size, 0, &fd, errp);
|
||||||
|
if (buf_rw == NULL) {
|
||||||
|
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,
|
||||||
|
"failed to map shared memory for execute");
|
||||||
|
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_splitwx_diff = buf_rx - buf_rw;
|
||||||
|
|
||||||
|
/* Request large pages for the buffer and the splitwx. */
|
||||||
|
qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE);
|
||||||
|
qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_POSIX */
|
||||||
|
|
||||||
|
static bool alloc_code_gen_buffer_splitwx(size_t size, Error **errp)
|
||||||
|
{
|
||||||
|
if (TCG_TARGET_SUPPORT_MIRROR) {
|
||||||
|
#ifdef CONFIG_POSIX
|
||||||
|
return alloc_code_gen_buffer_splitwx_memfd(size, errp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
error_setg(errp, "jit split-wx not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
|
||||||
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
|
int prot, flags;
|
||||||
|
|
||||||
|
if (splitwx) {
|
||||||
|
if (alloc_code_gen_buffer_splitwx(size, errp)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If splitwx force-on (1), fail;
|
||||||
|
* if splitwx default-on (-1), fall through to splitwx off.
|
||||||
|
*/
|
||||||
|
if (splitwx > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
error_free_or_abort(errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
prot = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||||
|
flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||||
|
#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, flags, errp);
|
||||||
|
}
|
||||||
#endif /* USE_STATIC_CODE_GEN_BUFFER, WIN32, POSIX */
|
#endif /* USE_STATIC_CODE_GEN_BUFFER, WIN32, POSIX */
|
||||||
|
|
||||||
static bool tb_cmp(const void *ap, const void *bp)
|
static bool tb_cmp(const void *ap, const void *bp)
|
||||||
|
|
Loading…
Reference in New Issue