aboutsummaryrefslogtreecommitdiff
path: root/tcg
diff options
context:
space:
mode:
authorSergey Fedorov <serge.fdrv@gmail.com>2016-04-22 19:08:48 +0300
committerRichard Henderson <rth@twiddle.net>2016-05-12 14:06:41 -1000
commited3d51ecd7fe248d3959e469d53890ac9ffe0cd2 (patch)
tree2bb706344e30ab4fddf8a7c2ade4424f9afa1070 /tcg
parent0d07abf05e98903c7faf204a9a90f7d45b7554dc (diff)
tcg/s390: Make direct jump patching thread-safe
Ensure direct jump patching in s390 is atomic by: * naturally aligning a location of direct jump address; * using atomic_read()/atomic_set() for code patching. Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com> Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org> Message-Id: <1461341333-19646-7-git-send-email-sergey.fedorov@linaro.org> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg')
-rw-r--r--tcg/s390/tcg-target.inc.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c
index 5805532398..8e8064ce73 100644
--- a/tcg/s390/tcg-target.inc.c
+++ b/tcg/s390/tcg-target.inc.c
@@ -219,6 +219,8 @@ typedef enum S390Opcode {
RX_ST = 0x50,
RX_STC = 0x42,
RX_STH = 0x40,
+
+ NOP = 0x0707,
} S390Opcode;
#ifdef CONFIG_DEBUG_TCG
@@ -1716,6 +1718,12 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_goto_tb:
if (s->tb_jmp_offset) {
+ /* branch displacement must be aligned for atomic patching;
+ * see if we need to add extra nop before branch
+ */
+ if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
+ tcg_out16(s, NOP);
+ }
tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
s->code_ptr += 2;