diff options
author | Anup Patel <apatel@ventanamicro.com> | 2023-01-20 18:29:50 +0530 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2023-02-07 08:19:23 +1000 |
commit | f008a2d218d17b9be998be0045a7a3c229a3376d (patch) | |
tree | 93a477d2cec2237b65b4f1ac4f730343f5e48025 /target/riscv/insn_trans | |
parent | ae0edf2188b3e4346b3e72bb69c75e70869e0c7f (diff) | |
download | qemu-f008a2d218d17b9be998be0045a7a3c229a3376d.zip qemu-f008a2d218d17b9be998be0045a7a3c229a3376d.tar.gz qemu-f008a2d218d17b9be998be0045a7a3c229a3376d.tar.bz2 |
target/riscv: Ensure opcode is saved for all relevant instructions
We should call decode_save_opc() for all relevant instructions which
can potentially generate a virtual instruction fault or a guest page
fault because generating transformed instruction upon guest page fault
expects opcode to be available. Without this, hypervisor will see
transformed instruction as zero in htinst CSR for guest MMIO emulation
which makes MMIO emulation in hypervisor slow and also breaks nested
virtualization.
Fixes: a9814e3e08d2 ("target/riscv: Minimize the calls to decode_save_opc")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230120125950.2246378-5-apatel@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/insn_trans')
-rw-r--r-- | target/riscv/insn_trans/trans_rva.c.inc | 10 | ||||
-rw-r--r-- | target/riscv/insn_trans/trans_rvd.c.inc | 2 | ||||
-rw-r--r-- | target/riscv/insn_trans/trans_rvf.c.inc | 2 | ||||
-rw-r--r-- | target/riscv/insn_trans/trans_rvh.c.inc | 3 | ||||
-rw-r--r-- | target/riscv/insn_trans/trans_rvi.c.inc | 2 | ||||
-rw-r--r-- | target/riscv/insn_trans/trans_rvzfh.c.inc | 2 | ||||
-rw-r--r-- | target/riscv/insn_trans/trans_svinval.c.inc | 3 |
7 files changed, 21 insertions, 3 deletions
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc index 45db82c..5f194a4 100644 --- a/target/riscv/insn_trans/trans_rva.c.inc +++ b/target/riscv/insn_trans/trans_rva.c.inc @@ -20,8 +20,10 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop) { - TCGv src1 = get_address(ctx, a->rs1, 0); + TCGv src1; + decode_save_opc(ctx); + src1 = get_address(ctx, a->rs1, 0); if (a->rl) { tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL); } @@ -43,6 +45,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGLabel *l1 = gen_new_label(); TCGLabel *l2 = gen_new_label(); + decode_save_opc(ctx); src1 = get_address(ctx, a->rs1, 0); tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1); @@ -81,9 +84,10 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a, MemOp mop) { TCGv dest = dest_gpr(ctx, a->rd); - TCGv src1 = get_address(ctx, a->rs1, 0); - TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE); + decode_save_opc(ctx); + src1 = get_address(ctx, a->rs1, 0); func(dest, src1, src2, ctx->mem_idx, mop); gen_set_gpr(ctx, a->rd, dest); diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc index 1397c1c..6e3159b 100644 --- a/target/riscv/insn_trans/trans_rvd.c.inc +++ b/target/riscv/insn_trans/trans_rvd.c.inc @@ -38,6 +38,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); + decode_save_opc(ctx); addr = get_address(ctx, a->rs1, a->imm); tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ); @@ -52,6 +53,7 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a) REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); + decode_save_opc(ctx); addr = get_address(ctx, a->rs1, a->imm); tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ); return true; diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc index a1d3eb5..965e1f8 100644 --- a/target/riscv/insn_trans/trans_rvf.c.inc +++ b/target/riscv/insn_trans/trans_rvf.c.inc @@ -38,6 +38,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a) REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); + decode_save_opc(ctx); addr = get_address(ctx, a->rs1, a->imm); dest = cpu_fpr[a->rd]; tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL); @@ -54,6 +55,7 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a) REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); + decode_save_opc(ctx); addr = get_address(ctx, a->rs1, a->imm); tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL); return true; diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc index 4f8aecd..9248b48 100644 --- a/target/riscv/insn_trans/trans_rvh.c.inc +++ b/target/riscv/insn_trans/trans_rvh.c.inc @@ -36,6 +36,7 @@ static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop) #ifdef CONFIG_USER_ONLY return false; #else + decode_save_opc(ctx); if (check_access(ctx)) { TCGv dest = dest_gpr(ctx, a->rd); TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); @@ -82,6 +83,7 @@ static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop) #ifdef CONFIG_USER_ONLY return false; #else + decode_save_opc(ctx); if (check_access(ctx)) { TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); TCGv data = get_gpr(ctx, a->rs2, EXT_NONE); @@ -135,6 +137,7 @@ static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a) static bool do_hlvx(DisasContext *ctx, arg_r2 *a, void (*func)(TCGv, TCGv_env, TCGv)) { + decode_save_opc(ctx); if (check_access(ctx)) { TCGv dest = dest_gpr(ctx, a->rd); TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index 5c69b88..4496f21 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -261,6 +261,7 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop) static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop) { + decode_save_opc(ctx); if (get_xl(ctx) == MXL_RV128) { return gen_load_i128(ctx, a, memop); } else { @@ -350,6 +351,7 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop) static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop) { + decode_save_opc(ctx); if (get_xl(ctx) == MXL_RV128) { return gen_store_i128(ctx, a, memop); } else { diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc index 5d07150..2ad5716 100644 --- a/target/riscv/insn_trans/trans_rvzfh.c.inc +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc @@ -49,6 +49,7 @@ static bool trans_flh(DisasContext *ctx, arg_flh *a) REQUIRE_FPU; REQUIRE_ZFH_OR_ZFHMIN(ctx); + decode_save_opc(ctx); t0 = get_gpr(ctx, a->rs1, EXT_NONE); if (a->imm) { TCGv temp = temp_new(ctx); @@ -71,6 +72,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a) REQUIRE_FPU; REQUIRE_ZFH_OR_ZFHMIN(ctx); + decode_save_opc(ctx); t0 = get_gpr(ctx, a->rs1, EXT_NONE); if (a->imm) { TCGv temp = tcg_temp_new(); diff --git a/target/riscv/insn_trans/trans_svinval.c.inc b/target/riscv/insn_trans/trans_svinval.c.inc index 2682bd9..f3cd7d5 100644 --- a/target/riscv/insn_trans/trans_svinval.c.inc +++ b/target/riscv/insn_trans/trans_svinval.c.inc @@ -28,6 +28,7 @@ static bool trans_sinval_vma(DisasContext *ctx, arg_sinval_vma *a) /* Do the same as sfence.vma currently */ REQUIRE_EXT(ctx, RVS); #ifndef CONFIG_USER_ONLY + decode_save_opc(ctx); gen_helper_tlb_flush(cpu_env); return true; #endif @@ -56,6 +57,7 @@ static bool trans_hinval_vvma(DisasContext *ctx, arg_hinval_vvma *a) /* Do the same as hfence.vvma currently */ REQUIRE_EXT(ctx, RVH); #ifndef CONFIG_USER_ONLY + decode_save_opc(ctx); gen_helper_hyp_tlb_flush(cpu_env); return true; #endif @@ -68,6 +70,7 @@ static bool trans_hinval_gvma(DisasContext *ctx, arg_hinval_gvma *a) /* Do the same as hfence.gvma currently */ REQUIRE_EXT(ctx, RVH); #ifndef CONFIG_USER_ONLY + decode_save_opc(ctx); gen_helper_hyp_gvma_tlb_flush(cpu_env); return true; #endif |