From 8dbf46ca82e99c97993ffd402ae2f50a2213578a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 19 Feb 2018 01:40:12 -0500 Subject: [PATCH] tcg: Respect highwater in tcg_out_tb_finalize Undo the workaround at b17a6d3390f87620735f7efb03bb1c96682ff449. If there are lots of memory operations in a TB, the slow path code can exceed the highwater reservation. Add a check within the loop. Backports commit 23dceda62a3643f734b7aa474fa6052593ae1a70 from qemu --- qemu/tcg/tcg-be-ldst.h | 11 ++++++++++- qemu/tcg/tcg-be-null.h | 3 ++- qemu/tcg/tcg.c | 6 ++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/qemu/tcg/tcg-be-ldst.h b/qemu/tcg/tcg-be-ldst.h index cafe8ed9..ec1e686a 100644 --- a/qemu/tcg/tcg-be-ldst.h +++ b/qemu/tcg/tcg-be-ldst.h @@ -57,7 +57,7 @@ static inline void tcg_out_tb_init(TCGContext *s) static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l); static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l); -static void tcg_out_tb_finalize(TCGContext *s) +static bool tcg_out_tb_finalize(TCGContext *s) { TCGLabelQemuLdst *lb = s->be->ldst_labels; int i, n = s->be->nb_ldst_labels; @@ -69,7 +69,16 @@ static void tcg_out_tb_finalize(TCGContext *s) } else { tcg_out_qemu_st_slow_path(s, lb + i); } + + /* Test for (pending) buffer overflow. The assumption is that any + one operation beginning below the high water mark cannot overrun + the buffer completely. Thus we can test for overflow after + generating code without having to check during generation. */ + if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) { + return false; + } } + return true; } /* diff --git a/qemu/tcg/tcg-be-null.h b/qemu/tcg/tcg-be-null.h index ba2da3c5..5217d62c 100644 --- a/qemu/tcg/tcg-be-null.h +++ b/qemu/tcg/tcg-be-null.h @@ -40,6 +40,7 @@ static inline void tcg_out_tb_init(TCGContext *s) * Generate TB finalization at the end of block */ -static inline void tcg_out_tb_finalize(TCGContext *s) +static inline bool tcg_out_tb_finalize(TCGContext *s) { + return true; } diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index 7d02f37c..727ebaa7 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -107,7 +107,7 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *target); static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct); static void tcg_out_tb_init(TCGContext *s); -static void tcg_out_tb_finalize(TCGContext *s); +static bool tcg_out_tb_finalize(TCGContext *s); #if TCG_TARGET_INSN_UNIT_SIZE == 1 static QEMU_UNUSED_FUNC inline void tcg_out8(TCGContext *s, uint8_t v) @@ -2497,7 +2497,9 @@ int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) s->gen_insn_end_off[num_insns] = tcg_current_code_size(s); /* Generate TB finalization at the end of block */ - tcg_out_tb_finalize(s); + if (!tcg_out_tb_finalize(s)) { + return -1; + } /* flush instruction cache */ flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);