From 5e44ce9be874aa35712b534379907397b80916bb Mon Sep 17 00:00:00 2001 From: Pranith Kumar Date: Mon, 26 Feb 2018 02:59:13 -0500 Subject: [PATCH] Introduce TCGOpcode for memory barrier This commit introduces the TCGOpcode for memory barrier instruction. This opcode takes an argument which is the type of memory barrier which should be generated. Backports commit f65e19bc2c9e8358e634d309606144ac2a3c2936 from qemu --- qemu/aarch64.h | 1 + qemu/aarch64eb.h | 1 + qemu/arm.h | 1 + qemu/armeb.h | 1 + qemu/header_gen.py | 1 + qemu/m68k.h | 1 + qemu/mips.h | 1 + qemu/mips64.h | 1 + qemu/mips64el.h | 1 + qemu/mipsel.h | 1 + qemu/powerpc.h | 1 + qemu/sparc.h | 1 + qemu/sparc64.h | 1 + qemu/tcg/README | 17 +++++++++++++++++ qemu/tcg/tcg-op.c | 17 +++++++++++++++++ qemu/tcg/tcg-op.h | 2 ++ qemu/tcg/tcg-opc.h | 2 ++ qemu/tcg/tcg.h | 19 ++++++++++++++++++- qemu/x86_64.h | 1 + 19 files changed, 70 insertions(+), 1 deletion(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index c56b7aeb..60c58623 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_aarch64 #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_aarch64 #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_aarch64 +#define tcg_gen_mb tcg_gen_mb_aarch64 #define tcg_gen_mov_i32 tcg_gen_mov_i32_aarch64 #define tcg_gen_mov_i64 tcg_gen_mov_i64_aarch64 #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 7fbae051..100348f7 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_aarch64eb #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_aarch64eb #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_aarch64eb +#define tcg_gen_mb tcg_gen_mb_aarch64eb #define tcg_gen_mov_i32 tcg_gen_mov_i32_aarch64eb #define tcg_gen_mov_i64 tcg_gen_mov_i64_aarch64eb #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 26612074..d34835e9 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_arm #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_arm #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_arm +#define tcg_gen_mb tcg_gen_mb_arm #define tcg_gen_mov_i32 tcg_gen_mov_i32_arm #define tcg_gen_mov_i64 tcg_gen_mov_i64_arm #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 01c17f69..42a0370d 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_armeb #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_armeb #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_armeb +#define tcg_gen_mb tcg_gen_mb_armeb #define tcg_gen_mov_i32 tcg_gen_mov_i32_armeb #define tcg_gen_mov_i64 tcg_gen_mov_i64_armeb #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 61273a3a..187416d1 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2810,6 +2810,7 @@ symbols = ( 'tcg_gen_ld_i64', 'tcg_gen_ldst_op_i32', 'tcg_gen_ldst_op_i64', + 'tcg_gen_mb', 'tcg_gen_mov_i32', 'tcg_gen_mov_i64', 'tcg_gen_movcond_i32', diff --git a/qemu/m68k.h b/qemu/m68k.h index 9def456c..01837d15 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_m68k #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_m68k #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_m68k +#define tcg_gen_mb tcg_gen_mb_m68k #define tcg_gen_mov_i32 tcg_gen_mov_i32_m68k #define tcg_gen_mov_i64 tcg_gen_mov_i64_m68k #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_m68k diff --git a/qemu/mips.h b/qemu/mips.h index d665d6d6..2d34093b 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_mips #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_mips #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_mips +#define tcg_gen_mb tcg_gen_mb_mips #define tcg_gen_mov_i32 tcg_gen_mov_i32_mips #define tcg_gen_mov_i64 tcg_gen_mov_i64_mips #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index f3228165..d58b44cc 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_mips64 #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_mips64 #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_mips64 +#define tcg_gen_mb tcg_gen_mb_mips64 #define tcg_gen_mov_i32 tcg_gen_mov_i32_mips64 #define tcg_gen_mov_i64 tcg_gen_mov_i64_mips64 #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 72a465dd..0bb68a19 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_mips64el #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_mips64el #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_mips64el +#define tcg_gen_mb tcg_gen_mb_mips64el #define tcg_gen_mov_i32 tcg_gen_mov_i32_mips64el #define tcg_gen_mov_i64 tcg_gen_mov_i64_mips64el #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index b69a8ee0..4f054c02 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_mipsel #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_mipsel #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_mipsel +#define tcg_gen_mb tcg_gen_mb_mipsel #define tcg_gen_mov_i32 tcg_gen_mov_i32_mipsel #define tcg_gen_mov_i64 tcg_gen_mov_i64_mipsel #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 401107c6..ad1a143e 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_powerpc #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_powerpc #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_powerpc +#define tcg_gen_mb tcg_gen_mb_powerpc #define tcg_gen_mov_i32 tcg_gen_mov_i32_powerpc #define tcg_gen_mov_i64 tcg_gen_mov_i64_powerpc #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index bb708220..67a357d5 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_sparc #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_sparc #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_sparc +#define tcg_gen_mb tcg_gen_mb_sparc #define tcg_gen_mov_i32 tcg_gen_mov_i32_sparc #define tcg_gen_mov_i64 tcg_gen_mov_i64_sparc #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 2f952b70..ca2f6044 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_sparc64 #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_sparc64 #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_sparc64 +#define tcg_gen_mb tcg_gen_mb_sparc64 #define tcg_gen_mov_i32 tcg_gen_mov_i32_sparc64 #define tcg_gen_mov_i64 tcg_gen_mov_i64_sparc64 #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_sparc64 diff --git a/qemu/tcg/README b/qemu/tcg/README index 34c0775c..908e9704 100644 --- a/qemu/tcg/README +++ b/qemu/tcg/README @@ -402,6 +402,23 @@ double-word product T0. The later is returned in two single-word outputs. Similar to mulu2, except the two inputs T1 and T2 are signed. +********* Memory Barrier support + +* mb <$arg> + +Generate a target memory barrier instruction to ensure memory ordering as being +enforced by a corresponding guest memory barrier instruction. The ordering +enforced by the backend may be stricter than the ordering required by the guest. +It cannot be weaker. This opcode takes a constant argument which is required to +generate the appropriate barrier instruction. The backend should take care to +emit the target barrier instruction only when necessary i.e., for SMP guests and +when MTTCG is enabled. + +The guest translators should generate this opcode for all guest instructions +which have ordering side effects. + +Please see docs/atomics.txt for more information on memory barriers. + ********* 64-bit guest on 32-bit host support The following opcodes are internal to TCG. Thus they are to be implemented by diff --git a/qemu/tcg/tcg-op.c b/qemu/tcg/tcg-op.c index 19fd5f5d..4a74c24c 100644 --- a/qemu/tcg/tcg-op.c +++ b/qemu/tcg/tcg-op.c @@ -147,6 +147,23 @@ void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2, tcg_emit_op(ctx, opc, pi); } +void tcg_gen_mb(TCGContext *ctx, TCGBar mb_type) +{ + bool emit_barriers = true; + +#ifndef CONFIG_USER_ONLY + /* TODO: When MTTCG is available for system mode, we will check + * the following condition and enable emit_barriers + * (qemu_tcg_mttcg_enabled() && smp_cpus > 1) + */ + emit_barriers = false; +#endif + + if (emit_barriers) { + tcg_gen_op1(ctx, INDEX_op_mb, mb_type); + } +} + /* 32 bit ops */ void tcg_gen_addi_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index 7beb1c7c..e360caf4 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -269,6 +269,8 @@ static inline void tcg_gen_br(TCGContext *s, TCGLabel *l) tcg_gen_op1(s, INDEX_op_br, label_arg(s, l)); } +void tcg_gen_mb(TCGContext *, TCGBar); + /* Helper calls. */ /* 32 bit ops */ diff --git a/qemu/tcg/tcg-opc.h b/qemu/tcg/tcg-opc.h index 4d52b5c3..850d71ff 100644 --- a/qemu/tcg/tcg-opc.h +++ b/qemu/tcg/tcg-opc.h @@ -47,6 +47,8 @@ DEF(br, 0, 0, 1, TCG_OPF_BB_END) # define IMPL64 TCG_OPF_64BIT #endif +DEF(mb, 0, 0, 1, 0) + DEF(mov_i32, 1, 1, 0, TCG_OPF_NOT_PRESENT) DEF(movi_i32, 1, 0, 1, TCG_OPF_NOT_PRESENT) DEF(setcond_i32, 1, 2, 1, 0) diff --git a/qemu/tcg/tcg.h b/qemu/tcg/tcg.h index 8014bf02..b69412a3 100644 --- a/qemu/tcg/tcg.h +++ b/qemu/tcg/tcg.h @@ -468,6 +468,23 @@ static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_PTR(TCGv_ptr t) #define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1) #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1)) +typedef enum { + /* Used to indicate the type of accesses on which ordering + is to be ensured. Modeled after SPARC barriers. */ + TCG_MO_LD_LD = 0x01, + TCG_MO_ST_LD = 0x02, + TCG_MO_LD_ST = 0x04, + TCG_MO_ST_ST = 0x08, + TCG_MO_ALL = 0x0F, /* OR of the above */ + + /* Used to indicate the kind of ordering which is to be ensured by the + instruction. These types are derived from x86/aarch64 instructions. + It should be noted that these are different from C11 semantics. */ + TCG_BAR_LDAQ = 0x10, /* Following ops will not come forward */ + TCG_BAR_STRL = 0x20, /* Previous ops will not be delayed */ + TCG_BAR_SC = 0x30, /* No ops cross barrier; OR of the above */ +} TCGBar; + /* Conditions. Note that these are laid out for easy manipulation by the functions below: bit 0 is used for inverting; @@ -963,7 +980,7 @@ static inline bool tcg_op_buf_full(TCGContext *tcg_ctx) } // UNICORN: Added -#define TCG_OP_DEFS_TABLE_SIZE 124 +#define TCG_OP_DEFS_TABLE_SIZE 125 extern const TCGOpDef tcg_op_defs_org[TCG_OP_DEFS_TABLE_SIZE]; typedef struct TCGTargetOpDef { diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 2cf5e716..5ef96f5d 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_x86_64 #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_x86_64 #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_x86_64 +#define tcg_gen_mb tcg_gen_mb_x86_64 #define tcg_gen_mov_i32 tcg_gen_mov_i32_x86_64 #define tcg_gen_mov_i64 tcg_gen_mov_i64_x86_64 #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_x86_64