aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-10-30 18:59:09 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-01-07 05:09:41 -1000
commit4846cd37df83b24e65a42bb50e5f407cdb50da72 (patch)
treea6844d41dcfeac2e0c0d8bf433e112cd56d22fe7
parent8b5c2b6260c0bb1233f605663bec9582b55d80c9 (diff)
downloadqemu-4846cd37df83b24e65a42bb50e5f407cdb50da72.zip
qemu-4846cd37df83b24e65a42bb50e5f407cdb50da72.tar.gz
qemu-4846cd37df83b24e65a42bb50e5f407cdb50da72.tar.bz2
tcg: Add in_code_gen_buffer
Create a function to determine if a pointer is within the buffer. Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--accel/tcg/translate-all.c26
-rw-r--r--include/tcg/tcg.h11
2 files changed, 19 insertions, 18 deletions
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index a1803a1..3f9e25f 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -392,27 +392,18 @@ void tb_destroy(TranslationBlock *tb)
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
{
- TranslationBlock *tb;
- bool r = false;
- uintptr_t check_offset;
-
- /* The host_pc has to be in the region of current 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:
+ /*
+ * The host_pc has to be in the 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:
*
* - fault during translation (instruction fetch)
* - fault from helper (not using GETPC() macro)
*
* Either way we need return early as we can't resolve it here.
- *
- * We are using unsigned arithmetic so if host_pc <
- * tcg_init_ctx.code_gen_buffer check_offset will wrap to way
- * above the code_gen_buffer_size
*/
- check_offset = host_pc - (uintptr_t) tcg_init_ctx.code_gen_buffer;
-
- if (check_offset < tcg_init_ctx.code_gen_buffer_size) {
- tb = tcg_tb_lookup(host_pc);
+ if (in_code_gen_buffer((const void *)host_pc)) {
+ TranslationBlock *tb = tcg_tb_lookup(host_pc);
if (tb) {
cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit);
if (tb_cflags(tb) & CF_NOCACHE) {
@@ -421,11 +412,10 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
tcg_tb_remove(tb);
tb_destroy(tb);
}
- r = true;
+ return true;
}
}
-
- return r;
+ return false;
}
static void page_init(void)
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index bb1e97b..ef571b6 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -680,6 +680,17 @@ extern __thread TCGContext *tcg_ctx;
extern void *tcg_code_gen_epilogue;
extern TCGv_env cpu_env;
+static inline bool in_code_gen_buffer(const void *p)
+{
+ const TCGContext *s = &tcg_init_ctx;
+ /*
+ * Much like it is valid to have a pointer to the byte past the
+ * end of an array (so long as you don't dereference it), allow
+ * a pointer to the byte past the end of the code gen buffer.
+ */
+ return (size_t)(p - s->code_gen_buffer) <= s->code_gen_buffer_size;
+}
+
static inline size_t temp_idx(TCGTemp *ts)
{
ptrdiff_t n = ts - tcg_ctx->temps;