Skip to content

Commit

Permalink
tcg: Introduce tcg_splitwx_to_{rx,rw}
Browse files Browse the repository at this point in the history
Add two helper functions, using a global variable to hold
the displacement.  The displacement is currently always 0,
so no change in behaviour.

Begin using the functions in tcg common code only.

Reviewed-by: Joelle van Dyne <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
  • Loading branch information
rth7680 committed Jan 7, 2021
1 parent 4846cd3 commit db0c51a
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 40 deletions.
2 changes: 1 addition & 1 deletion accel/tcg/cpu-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
uintptr_t ret;
TranslationBlock *last_tb;
int tb_exit;
uint8_t *tb_ptr = itb->tc.ptr;
const void *tb_ptr = itb->tc.ptr;

qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
"Trace %d: %p ["
Expand Down
2 changes: 1 addition & 1 deletion accel/tcg/tcg-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ uint64_t HELPER(ctpop_i64)(uint64_t arg)
return ctpop64(arg);
}

void *HELPER(lookup_tb_ptr)(CPUArchState *env)
const void *HELPER(lookup_tb_ptr)(CPUArchState *env)
{
CPUState *cpu = env_cpu(env);
TranslationBlock *tb;
Expand Down
2 changes: 1 addition & 1 deletion accel/tcg/tcg-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64)

DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, ptr, env)
DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, cptr, env)

DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env)

Expand Down
2 changes: 1 addition & 1 deletion accel/tcg/trace-events
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
exec_tb_exit(void *last_tb, unsigned int flags) "tb:%p flags=0x%x"

# translate-all.c
translate_block(void *tb, uintptr_t pc, uint8_t *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
translate_block(void *tb, uintptr_t pc, const void *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
33 changes: 15 additions & 18 deletions accel/tcg/translate-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,9 @@ static uint8_t *encode_sleb128(uint8_t *p, target_long val)

/* Decode a signed leb128 sequence at *PP; increment *PP past the
decoded value. Return the decoded value. */
static target_long decode_sleb128(uint8_t **pp)
static target_long decode_sleb128(const uint8_t **pp)
{
uint8_t *p = *pp;
const uint8_t *p = *pp;
target_long val = 0;
int byte, shift = 0;

Expand Down Expand Up @@ -342,7 +342,7 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
target_ulong data[TARGET_INSN_START_WORDS] = { tb->pc };
uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
CPUArchState *env = cpu->env_ptr;
uint8_t *p = tb->tc.ptr + tb->tc.size;
const uint8_t *p = tb->tc.ptr + tb->tc.size;
int i, j, num_insns = tb->icount;
#ifdef CONFIG_PROFILER
TCGProfile *prof = &tcg_ctx->prof;
Expand Down Expand Up @@ -393,7 +393,7 @@ void tb_destroy(TranslationBlock *tb)
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
{
/*
* The host_pc has to be in the region of the code buffer.
* The host_pc has to be in the rx region of the code buffer.
* If it is not we will not be able to resolve it here.
* The two cases where host_pc will not be correct are:
*
Expand All @@ -402,7 +402,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
*
* Either way we need return early as we can't resolve it here.
*/
if (in_code_gen_buffer((const void *)host_pc)) {
if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
TranslationBlock *tb = tcg_tb_lookup(host_pc);
if (tb) {
cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit);
Expand Down Expand Up @@ -1712,7 +1712,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
}

gen_code_buf = tcg_ctx->code_gen_ptr;
tb->tc.ptr = gen_code_buf;
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
tb->pc = pc;
tb->cs_base = cs_base;
tb->flags = flags;
Expand Down Expand Up @@ -1806,15 +1806,19 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
qemu_log_in_addr_range(tb->pc)) {
FILE *logfile = qemu_log_lock();
int code_size, data_size = 0;
int code_size, data_size;
const tcg_target_ulong *rx_data_gen_ptr;
size_t chunk_start;
int insn = 0;

if (tcg_ctx->data_gen_ptr) {
code_size = tcg_ctx->data_gen_ptr - tb->tc.ptr;
rx_data_gen_ptr = tcg_splitwx_to_rx(tcg_ctx->data_gen_ptr);
code_size = (const void *)rx_data_gen_ptr - tb->tc.ptr;
data_size = gen_code_size - code_size;
} else {
rx_data_gen_ptr = 0;
code_size = gen_code_size;
data_size = 0;
}

/* Dump header and the first instruction */
Expand Down Expand Up @@ -1849,16 +1853,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
if (data_size) {
int i;
qemu_log(" data: [size=%d]\n", data_size);
for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
if (sizeof(tcg_target_ulong) == 8) {
qemu_log("0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n",
(uintptr_t)tcg_ctx->data_gen_ptr + i,
*(uint64_t *)(tcg_ctx->data_gen_ptr + i));
} else {
qemu_log("0x%08" PRIxPTR ": .long 0x%08x\n",
(uintptr_t)tcg_ctx->data_gen_ptr + i,
*(uint32_t *)(tcg_ctx->data_gen_ptr + i));
}
for (i = 0; i < data_size / sizeof(tcg_target_ulong); i++) {
qemu_log("0x%08" PRIxPTR ": .quad 0x%" TCG_PRIlx "\n",
(uintptr_t)&rx_data_gen_ptr[i], rx_data_gen_ptr[i]);
}
}
qemu_log("\n");
Expand Down
4 changes: 3 additions & 1 deletion disas.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,10 @@ char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size)
}

/* Disassemble this for me please... (debugging). */
void disas(FILE *out, void *code, unsigned long size)
void disas(FILE *out, const void *ccode, unsigned long size)
{
/* TODO: Push constness through the disas backends. */
void *code = (void *)ccode;
uintptr_t pc;
int count;
CPUDebug s;
Expand Down
2 changes: 1 addition & 1 deletion include/disas/disas.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "cpu.h"

/* Disassemble this for me please... (debugging). */
void disas(FILE *out, void *code, unsigned long size);
void disas(FILE *out, const void *code, unsigned long size);
void target_disas(FILE *out, CPUState *cpu, target_ulong code,
target_ulong size);

Expand Down
2 changes: 1 addition & 1 deletion include/exec/exec-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ int probe_access_flags(CPUArchState *env, target_ulong addr,
* Note: the address of search data can be obtained by adding @size to @ptr.
*/
struct tb_tc {
void *ptr; /* pointer to the translated code */
const void *ptr; /* pointer to the translated code */
size_t size;
};

Expand Down
2 changes: 1 addition & 1 deletion include/exec/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static inline void log_target_disas(CPUState *cpu, target_ulong start,
rcu_read_unlock();
}

static inline void log_disas(void *code, unsigned long size)
static inline void log_disas(const void *code, unsigned long size)
{
QemuLogFile *logfile;
rcu_read_lock();
Expand Down
26 changes: 21 additions & 5 deletions include/tcg/tcg.h
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ struct TCGContext {
extern TCGContext tcg_init_ctx;
extern __thread TCGContext *tcg_ctx;
extern void *tcg_code_gen_epilogue;
extern uintptr_t tcg_splitwx_diff;
extern TCGv_env cpu_env;

static inline bool in_code_gen_buffer(const void *p)
Expand All @@ -691,6 +692,21 @@ static inline bool in_code_gen_buffer(const void *p)
return (size_t)(p - s->code_gen_buffer) <= s->code_gen_buffer_size;
}

#ifdef CONFIG_DEBUG_TCG
const void *tcg_splitwx_to_rx(void *rw);
void *tcg_splitwx_to_rw(const void *rx);
#else
static inline const void *tcg_splitwx_to_rx(void *rw)
{
return rw ? rw + tcg_splitwx_diff : NULL;
}

static inline void *tcg_splitwx_to_rw(const void *rx)
{
return rx ? (void *)rx - tcg_splitwx_diff : NULL;
}
#endif

static inline size_t temp_idx(TCGTemp *ts)
{
ptrdiff_t n = ts - tcg_ctx->temps;
Expand Down Expand Up @@ -1111,7 +1127,7 @@ static inline TCGLabel *arg_label(TCGArg i)
* correct result.
*/

static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
static inline ptrdiff_t tcg_ptr_byte_diff(const void *a, const void *b)
{
return a - b;
}
Expand All @@ -1125,9 +1141,9 @@ static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
* to the destination address.
*/

static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, const void *target)
{
return tcg_ptr_byte_diff(target, s->code_ptr);
return tcg_ptr_byte_diff(target, tcg_splitwx_to_rx(s->code_ptr));
}

/**
Expand Down Expand Up @@ -1233,9 +1249,9 @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
#define TB_EXIT_REQUESTED 3

#ifdef CONFIG_TCG_INTERPRETER
uintptr_t tcg_qemu_tb_exec(CPUArchState *env, void *tb_ptr);
uintptr_t tcg_qemu_tb_exec(CPUArchState *env, const void *tb_ptr);
#else
typedef uintptr_t tcg_prologue_fn(CPUArchState *env, void *tb_ptr);
typedef uintptr_t tcg_prologue_fn(CPUArchState *env, const void *tb_ptr);
extern tcg_prologue_fn *tcg_qemu_tb_exec;
#endif

Expand Down
6 changes: 5 additions & 1 deletion tcg/tcg-pool.c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ static int tcg_out_pool_finalize(TCGContext *s)

for (; p != NULL; p = p->next) {
size_t size = sizeof(tcg_target_ulong) * p->nlong;
uintptr_t value;

if (!l || l->nlong != p->nlong || memcmp(l->data, p->data, size)) {
if (unlikely(a > s->code_gen_highwater)) {
return -1;
Expand All @@ -148,7 +150,9 @@ static int tcg_out_pool_finalize(TCGContext *s)
a += size;
l = p;
}
if (!patch_reloc(p->label, p->rtype, (intptr_t)a - size, p->addend)) {

value = (uintptr_t)tcg_splitwx_to_rx(a) - size;
if (!patch_reloc(p->label, p->rtype, value, p->addend)) {
return -2;
}
}
Expand Down
56 changes: 50 additions & 6 deletions tcg/tcg.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ static TCGContext **tcg_ctxs;
static unsigned int n_tcg_ctxs;
TCGv_env cpu_env = 0;
void *tcg_code_gen_epilogue;
uintptr_t tcg_splitwx_diff;

#ifndef CONFIG_TCG_INTERPRETER
tcg_prologue_fn *tcg_qemu_tb_exec;
Expand Down Expand Up @@ -406,8 +407,9 @@ static void tcg_region_trees_init(void)
}
}

static struct tcg_region_tree *tc_ptr_to_region_tree(void *p)
static struct tcg_region_tree *tc_ptr_to_region_tree(const void *cp)
{
void *p = tcg_splitwx_to_rw(cp);
size_t region_idx;

if (p < region.start_aligned) {
Expand Down Expand Up @@ -701,6 +703,7 @@ void tcg_region_init(void)
size_t region_size;
size_t n_regions;
size_t i;
uintptr_t splitwx_diff;

n_regions = tcg_n_regions();

Expand Down Expand Up @@ -731,13 +734,18 @@ void tcg_region_init(void)
region.end -= page_size;

/* set guard pages */
splitwx_diff = tcg_splitwx_diff;
for (i = 0; i < region.n; i++) {
void *start, *end;
int rc;

tcg_region_bounds(i, &start, &end);
rc = qemu_mprotect_none(end, page_size);
g_assert(!rc);
if (splitwx_diff) {
rc = qemu_mprotect_none(end + splitwx_diff, page_size);
g_assert(!rc);
}
}

tcg_region_trees_init();
Expand All @@ -752,6 +760,29 @@ void tcg_region_init(void)
#endif
}

#ifdef CONFIG_DEBUG_TCG
const void *tcg_splitwx_to_rx(void *rw)
{
/* Pass NULL pointers unchanged. */
if (rw) {
g_assert(in_code_gen_buffer(rw));
rw += tcg_splitwx_diff;
}
return rw;
}

void *tcg_splitwx_to_rw(const void *rx)
{
/* Pass NULL pointers unchanged. */
if (rx) {
rx -= tcg_splitwx_diff;
/* Assert that we end with a pointer in the rw region. */
g_assert(in_code_gen_buffer(rx));
}
return (void *)rx;
}
#endif /* CONFIG_DEBUG_TCG */

static void alloc_tcg_plugin_context(TCGContext *s)
{
#ifdef CONFIG_PLUGIN
Expand Down Expand Up @@ -1061,8 +1092,15 @@ void tcg_prologue_init(TCGContext *s)
s->code_buf = buf0;
s->data_gen_ptr = NULL;

/*
* The region trees are not yet configured, but tcg_splitwx_to_rx
* needs the bounds for an assert.
*/
region.start = buf0;
region.end = buf0 + total_size;

#ifndef CONFIG_TCG_INTERPRETER
tcg_qemu_tb_exec = (tcg_prologue_fn *)buf0;
tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(buf0);
#endif

/* Compute a high-water mark, at which we voluntarily flush the buffer
Expand All @@ -1087,7 +1125,7 @@ void tcg_prologue_init(TCGContext *s)

buf1 = s->code_ptr;
#ifndef CONFIG_TCG_INTERPRETER
flush_idcache_range((uintptr_t)buf0, (uintptr_t)buf0,
flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(buf0), (uintptr_t)buf0,
tcg_ptr_byte_diff(buf1, buf0));
#endif

Expand Down Expand Up @@ -4231,8 +4269,13 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)

tcg_reg_alloc_start(s);

s->code_buf = tb->tc.ptr;
s->code_ptr = tb->tc.ptr;
/*
* Reset the buffer pointers when restarting after overflow.
* TODO: Move this into translate-all.c with the rest of the
* buffer management. Having only this done here is confusing.
*/
s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
s->code_ptr = s->code_buf;

#ifdef TCG_TARGET_NEED_LDST_LABELS
QSIMPLEQ_INIT(&s->ldst_labels);
Expand Down Expand Up @@ -4337,7 +4380,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)

#ifndef CONFIG_TCG_INTERPRETER
/* flush instruction cache */
flush_idcache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_buf,
flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
(uintptr_t)s->code_buf,
tcg_ptr_byte_diff(s->code_ptr, s->code_buf));
#endif

Expand Down
6 changes: 4 additions & 2 deletions tcg/tci.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,11 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
* One possible operation in the pseudo code is a call to binary code.
* Therefore, disable CFI checks in the interpreter function
*/
uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env, void *v_tb_ptr)
uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
const void *v_tb_ptr)
{
uint8_t *tb_ptr = v_tb_ptr;
/* TODO: Propagate const through this file. */
uint8_t *tb_ptr = (uint8_t *)v_tb_ptr;
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
long tcg_temps[CPU_TEMP_BUF_NLONGS];
uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
Expand Down

0 comments on commit db0c51a

Please sign in to comment.