#include "qemu/cacheinfo.h"
#include "qemu/qtree.h"
#include "qapi/error.h"
-#include "exec/exec-all.h"
#include "tcg/tcg.h"
+#include "exec/translation-block.h"
#include "tcg-internal.h"
+#include "host/cpuinfo.h"
+/*
+ * Local source-level compatibility with Unix.
+ * Used by tcg_region_init below.
+ */
+#if defined(_WIN32)
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+#endif
+
struct tcg_region_tree {
QemuMutex lock;
QTree *tree;
return (size_t)(p - region.start_aligned) <= region.total_size;
}
+#ifndef CONFIG_TCG_INTERPRETER
+static int host_prot_read_exec(void)
+{
+#if defined(CONFIG_LINUX) && defined(HOST_AARCH64) && defined(PROT_BTI)
+ if (cpuinfo & CPUINFO_BTI) {
+ return PROT_READ | PROT_EXEC | PROT_BTI;
+ }
+#endif
+ return PROT_READ | PROT_EXEC;
+}
+#endif
+
#ifdef CONFIG_DEBUG_TCG
const void *tcg_splitwx_to_rx(void *rw)
{
region.start_aligned = buf;
region.total_size = size;
- return PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return PROT_READ | PROT_WRITE | PROT_EXEC;
}
#else
static int alloc_code_gen_buffer_anon(size_t size, int prot,
goto fail;
}
- buf_rx = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
+ buf_rx = mmap(NULL, size, host_prot_read_exec(), MAP_SHARED, fd, 0);
if (buf_rx == MAP_FAILED) {
goto fail_rx;
}
return -1;
}
- if (mprotect((void *)buf_rx, size, PROT_READ | PROT_EXEC) != 0) {
+ if (mprotect((void *)buf_rx, size, host_prot_read_exec()) != 0) {
error_setg_errno(errp, errno, "mprotect for jit splitwx");
munmap((void *)buf_rx, size);
munmap((void *)buf_rw, size);
* and then assigning regions to TCG threads so that the threads can translate
* code in parallel without synchronization.
*
- * In softmmu the number of TCG threads is bounded by max_cpus, so we use at
+ * In system-mode the number of TCG threads is bounded by max_cpus, so we use at
* least max_cpus regions in MTTCG. In !MTTCG we use a single region.
* Note that the TCG options from the command-line (i.e. -accel accel=tcg,[...])
* must have been parsed before calling this function, since it calls
*
* However, this user-mode limitation is unlikely to be a significant problem
* in practice. Multi-threaded guests share most if not all of their translated
- * code, which makes parallel code generation less appealing than in softmmu.
+ * code, which makes parallel code generation less appealing than in system-mode
*/
void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
{
* buffer -- let that one use hugepages throughout.
* Work with the page protections set up with the initial mapping.
*/
- need_prot = PAGE_READ | PAGE_WRITE;
+ need_prot = PROT_READ | PROT_WRITE;
#ifndef CONFIG_TCG_INTERPRETER
if (tcg_splitwx_diff == 0) {
- need_prot |= PAGE_EXEC;
+ need_prot |= host_prot_read_exec();
}
#endif
for (size_t i = 0, n = region.n; i < n; i++) {
if (have_prot != need_prot) {
int rc;
- if (need_prot == (PAGE_READ | PAGE_WRITE | PAGE_EXEC)) {
+ if (need_prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) {
rc = qemu_mprotect_rwx(start, end - start);
- } else if (need_prot == (PAGE_READ | PAGE_WRITE)) {
+ } else if (need_prot == (PROT_READ | PROT_WRITE)) {
rc = qemu_mprotect_rw(start, end - start);
} else {
+#ifdef CONFIG_POSIX
+ rc = mprotect(start, end - start, need_prot);
+#else
g_assert_not_reached();
+#endif
}
if (rc) {
error_setg_errno(&error_fatal, errno,